com.amanotes.gdk 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter_v9.1.0.unitypackage +0 -0
- package/Runtime/AmaGDK.Adapters.cs +85 -17
- package/Runtime/AmaGDK.Analytics.cs +15 -9
- package/Runtime/AmaGDK.Config.cs +82 -1
- package/Runtime/AmaGDK.Internal.cs +13 -41
- package/Runtime/AmaGDK.cs +10 -9
- package/Tests/Runtime/AmaGDKCoreTest.cs +2 -3
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -5,41 +5,109 @@ using ConfigAsset = Amanotes.Core.Internal.ConfigAsset;
|
|
|
5
5
|
using Status = Amanotes.Core.Internal.Status;
|
|
6
6
|
using static Amanotes.Core.Internal.Logging;
|
|
7
7
|
using static Amanotes.Core.Internal.Messsage;
|
|
8
|
+
using System.Linq;
|
|
8
9
|
|
|
9
10
|
namespace Amanotes.Core.Internal
|
|
10
11
|
{
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
[Serializable] public class AdapterInfo
|
|
12
14
|
{
|
|
13
|
-
string
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
public string id;
|
|
16
|
+
public string version;
|
|
17
|
+
public int initOrder;
|
|
18
|
+
public Status status = Status.None;
|
|
19
|
+
public IAdapter adapter;
|
|
20
|
+
|
|
21
|
+
public bool IsReady { get { return status == Status.Ready; }}
|
|
22
|
+
|
|
23
|
+
public void Init(){
|
|
24
|
+
if (status != Status.None)
|
|
25
|
+
{
|
|
26
|
+
LogWarning($"Invalid status: {status}");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
status = Status.Initialize;
|
|
31
|
+
adapter.Init((success) =>
|
|
32
|
+
{
|
|
33
|
+
status = success ? Status.Ready : Status.Failed;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public T GetAdapterApi<T>(){ return (T)adapter; }
|
|
16
38
|
}
|
|
17
39
|
|
|
18
|
-
public
|
|
40
|
+
public interface IAdapter
|
|
19
41
|
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
42
|
+
void Init(Action<bool> onCompleted);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// public static class AdapterExtension
|
|
46
|
+
// {
|
|
47
|
+
// public static string GetId<T>(this T adapter) where T: IAdapter {
|
|
48
|
+
// return Adapter.GetId(typeof(T));
|
|
49
|
+
// }
|
|
50
|
+
// }
|
|
51
|
+
|
|
52
|
+
public static class Adapter
|
|
53
|
+
{
|
|
54
|
+
internal static readonly List<AdapterInfo> listAdapters = new List<AdapterInfo>();
|
|
55
|
+
|
|
56
|
+
public static string GetId(Type adapterType) {
|
|
57
|
+
return adapterType.Name.Replace("Adapter", string.Empty);
|
|
58
|
+
}
|
|
24
59
|
|
|
25
|
-
public void
|
|
60
|
+
public static void Register<T>(string version) where T : IAdapter, new()
|
|
26
61
|
{
|
|
27
|
-
|
|
62
|
+
var typeT = typeof(T);
|
|
63
|
+
var id = GetId(typeT);
|
|
64
|
+
|
|
65
|
+
if (AmaGDK._status != Status.None)
|
|
28
66
|
{
|
|
29
|
-
|
|
67
|
+
LogWarningOnce($"RegisterAdapter - Invalid status: {AmaGDK._status}");
|
|
30
68
|
return;
|
|
31
69
|
}
|
|
32
70
|
|
|
33
|
-
|
|
34
|
-
|
|
71
|
+
var orderConfig = AmaGDK.Config.initOrder.FirstOrDefault(item => item.id == id);
|
|
72
|
+
listAdapters.Add(new AdapterInfo()
|
|
35
73
|
{
|
|
36
|
-
|
|
74
|
+
id = id,
|
|
75
|
+
version = version,
|
|
76
|
+
initOrder = (orderConfig != null) ? orderConfig.order : 0,
|
|
77
|
+
adapter = new T()
|
|
37
78
|
});
|
|
38
79
|
}
|
|
39
80
|
|
|
40
|
-
|
|
81
|
+
public static AdapterInfo Find<T>()
|
|
41
82
|
{
|
|
42
|
-
|
|
83
|
+
for (var i = 0; i < listAdapters.Count; i++)
|
|
84
|
+
{
|
|
85
|
+
var item = listAdapters[i];
|
|
86
|
+
var itemType = item.adapter.GetType();
|
|
87
|
+
if (!typeof(T).IsAssignableFrom(itemType)) continue;
|
|
88
|
+
return item;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return default;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public static List<AdapterInfo> FindAll<T>()
|
|
95
|
+
{
|
|
96
|
+
var result = new List<AdapterInfo>();
|
|
97
|
+
for (var i = 0; i < listAdapters.Count; i++)
|
|
98
|
+
{
|
|
99
|
+
var item = listAdapters[i];
|
|
100
|
+
var itemType = item.adapter.GetType();
|
|
101
|
+
if (!typeof(T).IsAssignableFrom(itemType)) continue;
|
|
102
|
+
result.Add(item);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public static T GetConfig<T>() where T : ConfigAsset
|
|
109
|
+
{
|
|
110
|
+
return (T)AmaGDK.Config;
|
|
43
111
|
}
|
|
44
112
|
}
|
|
45
113
|
}
|
|
@@ -43,6 +43,14 @@ namespace Amanotes.Core
|
|
|
43
43
|
return result;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
public static IEventParamsBuilder LogEvent(string eventName, Dictionary<string, object> parameters)
|
|
47
|
+
{
|
|
48
|
+
var result = new EventParams(eventName);
|
|
49
|
+
result.AddParam(parameters);
|
|
50
|
+
eventQueue.Enqueue(result);
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
public static IEventParamsBuilder LogFunnelEvent(string eventName, string signature = "")
|
|
47
55
|
{
|
|
48
56
|
return LogEvent(eventName).SetAsFunnel(signature);
|
|
@@ -70,7 +78,7 @@ namespace Amanotes.Core
|
|
|
70
78
|
|
|
71
79
|
foreach (var s in listAdapters)
|
|
72
80
|
{
|
|
73
|
-
s.SetUserId(userId);
|
|
81
|
+
s.GetAdapterApi<IAnalyticAdapter>().SetUserId(userId);
|
|
74
82
|
}
|
|
75
83
|
}
|
|
76
84
|
|
|
@@ -84,10 +92,10 @@ namespace Amanotes.Core
|
|
|
84
92
|
|
|
85
93
|
foreach (var s in listAdapters)
|
|
86
94
|
{
|
|
87
|
-
s.SetUserProperty(key, value);
|
|
95
|
+
s.GetAdapterApi<IAnalyticAdapter>().SetUserProperty(key, value);
|
|
88
96
|
}
|
|
89
97
|
}
|
|
90
|
-
|
|
98
|
+
|
|
91
99
|
private static IntegrityFlag MergeData(List<string> funnelEvents, Dictionary<string, int> eventCountMap, bool sumEventCount)
|
|
92
100
|
{
|
|
93
101
|
var flag = IntegrityFlag.Ok;
|
|
@@ -158,7 +166,7 @@ namespace Amanotes.Core
|
|
|
158
166
|
{
|
|
159
167
|
internal static Predicate<EventDetail> logEventHook = null;
|
|
160
168
|
internal static readonly Queue<EventParams> eventQueue = new Queue<EventParams>();
|
|
161
|
-
internal static readonly List<
|
|
169
|
+
internal static readonly List<AdapterInfo> listAdapters = new List<AdapterInfo>();
|
|
162
170
|
internal static readonly AnalyticsData localData = new AnalyticsData().LoadJsonFromFile();
|
|
163
171
|
|
|
164
172
|
internal static void GetAnalyticAdapters()
|
|
@@ -191,12 +199,10 @@ namespace Amanotes.Core
|
|
|
191
199
|
|
|
192
200
|
foreach (var m in listAdapters)
|
|
193
201
|
{
|
|
194
|
-
|
|
195
|
-
if (eventData.ignoreAnalyticIds.Contains(id))
|
|
202
|
+
if (eventData.ignoreAnalyticIds.Contains(m.id))
|
|
196
203
|
continue;
|
|
197
|
-
|
|
198
|
-
m.
|
|
199
|
-
if (showAnalyticsLog) Debug.Log($"[{id}] Sent event <{eventData.eventName}> ({counter})");
|
|
204
|
+
m.GetAdapterApi<IAnalyticAdapter>().LogEvent(eventData);
|
|
205
|
+
if (showAnalyticsLog) Debug.Log($"[{m.id}] Sent event <{eventData.eventName}> ({counter})");
|
|
200
206
|
}
|
|
201
207
|
}
|
|
202
208
|
|
package/Runtime/AmaGDK.Config.cs
CHANGED
|
@@ -1,13 +1,94 @@
|
|
|
1
1
|
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Reflection;
|
|
2
4
|
using UnityEngine;
|
|
3
5
|
|
|
6
|
+
#if UNITY_EDITOR
|
|
7
|
+
using UnityEditor;
|
|
8
|
+
#endif
|
|
9
|
+
|
|
4
10
|
namespace Amanotes.Core.Internal {
|
|
5
11
|
public partial class ConfigAsset : ScriptableObject
|
|
6
12
|
{
|
|
13
|
+
[SerializeField] internal bool simpleOrder = true;
|
|
14
|
+
[SerializeField] internal List<InitOrder> initOrder = new List<InitOrder>();
|
|
7
15
|
[SerializeField] internal SDKConfig common;
|
|
16
|
+
|
|
17
|
+
#if UNITY_EDITOR
|
|
18
|
+
void OnValidate()
|
|
19
|
+
{
|
|
20
|
+
if (Application.isPlaying) return;
|
|
21
|
+
if (simpleOrder) {
|
|
22
|
+
EditorApplication.update -= DelayCheckOrder;
|
|
23
|
+
EditorApplication.update += DelayCheckOrder;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
void DelayCheckOrder()
|
|
28
|
+
{
|
|
29
|
+
EditorApplication.update -= DelayCheckOrder;
|
|
30
|
+
var dirty = false;
|
|
31
|
+
for (var i =0 ;i < initOrder.Count;i++){
|
|
32
|
+
if (initOrder[i].order == i) continue;
|
|
33
|
+
dirty = true;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!dirty) return;
|
|
38
|
+
initOrder.Sort((a1, a2)=> a1.order.CompareTo(a2.order));
|
|
39
|
+
for (var i =0 ;i < initOrder.Count;i++){
|
|
40
|
+
initOrder[i].order = i;
|
|
41
|
+
}
|
|
42
|
+
EditorUtility.SetDirty(this);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
[ContextMenu("Scan Adapters")]
|
|
46
|
+
void ScanAdapters()
|
|
47
|
+
{
|
|
48
|
+
initOrder.Clear();
|
|
49
|
+
|
|
50
|
+
var counter = 0;
|
|
51
|
+
foreach (var adapter in GetAllAdapters<IAdapter>())
|
|
52
|
+
{
|
|
53
|
+
var id = adapter.Name.Replace("Adapter", string.Empty);
|
|
54
|
+
initOrder.Add(new InitOrder(){ id = id, order = counter++ });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
[ContextMenu("Refresh Order")]
|
|
59
|
+
void UpdateOrderToPosition()
|
|
60
|
+
{
|
|
61
|
+
for (var i =0 ;i < initOrder.Count; i++)
|
|
62
|
+
{
|
|
63
|
+
initOrder[i].order = i;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public static IEnumerable<Type> GetAllAdapters<T>()
|
|
68
|
+
{
|
|
69
|
+
var typeT = typeof(T);
|
|
70
|
+
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
|
|
71
|
+
{
|
|
72
|
+
if (!a.FullName.Contains("Assembly-CSharp")) continue;
|
|
73
|
+
|
|
74
|
+
foreach (var type in a.GetTypes()){
|
|
75
|
+
if (typeT.IsAssignableFrom(type)) yield return type;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
#endif
|
|
8
80
|
}
|
|
9
81
|
|
|
10
|
-
[Serializable]
|
|
82
|
+
[Serializable]
|
|
83
|
+
internal partial class SDKConfig
|
|
84
|
+
{
|
|
11
85
|
public bool verboseLog = false;
|
|
12
86
|
}
|
|
87
|
+
|
|
88
|
+
[Serializable]
|
|
89
|
+
internal class InitOrder
|
|
90
|
+
{
|
|
91
|
+
public string id;
|
|
92
|
+
public int order;
|
|
93
|
+
}
|
|
13
94
|
}
|
|
@@ -25,16 +25,16 @@ namespace Amanotes.Core.Internal
|
|
|
25
25
|
|
|
26
26
|
public static class Res
|
|
27
27
|
{
|
|
28
|
-
|
|
28
|
+
#if AMAGDK_DEV
|
|
29
29
|
public const string BASE_PATH = "Assets/AmaGDKCore/";
|
|
30
|
-
|
|
30
|
+
#else
|
|
31
31
|
public const string BASE_PATH = "Packages/com.amanotes.gdk/";
|
|
32
|
-
|
|
32
|
+
#endif
|
|
33
33
|
|
|
34
34
|
public const string PACKAGE_PATH = BASE_PATH + "Packages/";
|
|
35
35
|
public const string AMAGDK_PREFAB = BASE_PATH + "Runtime/AmaGDK.prefab";
|
|
36
36
|
public const string AMAGDK_CONFIG_PACKAGE = PACKAGE_PATH + "AmaGDKConfig.unitypackage";
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
public static readonly string[] AMAGDK_ADAPTERS = new string[]
|
|
39
39
|
{
|
|
40
40
|
"FirebaseAnalyticsAdapter_v9.1.0",
|
|
@@ -69,55 +69,27 @@ namespace Amanotes.Core.Internal
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
public static class
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
public static void Register(IAdapter adapter)
|
|
76
|
-
{
|
|
77
|
-
if (AmaGDK._status != Status.None)
|
|
78
|
-
{
|
|
79
|
-
Logging.LogWarningOnce($"RegisterAdapter - Invalid status: {AmaGDK._status}");
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
listAdapters.Add(adapter);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
public static T Find<T>()
|
|
87
|
-
{
|
|
88
|
-
return listAdapters.OfType<T>().FirstOrDefault();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
public static T[] FindAll<T>()
|
|
92
|
-
{
|
|
93
|
-
return listAdapters.OfType<T>().ToArray();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
public static T GetConfig<T>() where T: ConfigAsset {
|
|
98
|
-
return (T) AmaGDK.Config;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
public static class Forbidden {
|
|
72
|
+
public static class Forbidden
|
|
73
|
+
{
|
|
103
74
|
public static void DestroyAndReset()
|
|
104
75
|
{
|
|
105
|
-
if (AmaGDK._instance != null)
|
|
76
|
+
if (AmaGDK._instance != null)
|
|
77
|
+
{
|
|
106
78
|
UnityObject.Destroy(AmaGDK._instance);
|
|
107
79
|
AmaGDK._instance = null;
|
|
108
80
|
}
|
|
109
81
|
|
|
110
82
|
var result = Resources.FindObjectsOfTypeAll<AmaGDK>();
|
|
111
|
-
for (var i = 0;i < result.Length; i++)
|
|
112
|
-
{
|
|
83
|
+
for (var i = 0; i < result.Length; i++)
|
|
84
|
+
{
|
|
113
85
|
if (result[i] == null) continue;
|
|
114
|
-
|
|
115
|
-
|
|
86
|
+
|
|
87
|
+
#if UNITY_EDITOR // Ignore loaded prefabs assets
|
|
116
88
|
{
|
|
117
89
|
var path = UnityEditor.AssetDatabase.GetAssetPath(result[i]);
|
|
118
90
|
if (!string.IsNullOrEmpty(path)) continue;
|
|
119
91
|
}
|
|
120
|
-
|
|
92
|
+
#endif
|
|
121
93
|
|
|
122
94
|
// Logging.LogWarning("Something wrong: another AmaGDK instance found!");
|
|
123
95
|
UnityObject.Destroy(result[i].gameObject);
|
package/Runtime/AmaGDK.cs
CHANGED
|
@@ -12,7 +12,7 @@ namespace Amanotes.Core
|
|
|
12
12
|
{
|
|
13
13
|
public partial class AmaGDK : MonoBehaviour
|
|
14
14
|
{
|
|
15
|
-
public const string VERSION = "0.1.
|
|
15
|
+
public const string VERSION = "0.1.9";
|
|
16
16
|
|
|
17
17
|
internal static AmaGDK _instance;
|
|
18
18
|
private static ConfigAsset _config = null;
|
|
@@ -51,9 +51,7 @@ namespace Amanotes.Core
|
|
|
51
51
|
_allowInit = _allowInit || autoInit;
|
|
52
52
|
StartCoroutine(InitRoutine());
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
|
|
57
55
|
IEnumerator InitRoutine()
|
|
58
56
|
{
|
|
59
57
|
if (Config == null)
|
|
@@ -63,10 +61,7 @@ namespace Amanotes.Core
|
|
|
63
61
|
|
|
64
62
|
float time = 0;
|
|
65
63
|
float timeout = 3;
|
|
66
|
-
|
|
67
|
-
// Wait 1 frame to make sure all adapters have finished registering
|
|
68
|
-
yield return null;
|
|
69
|
-
|
|
64
|
+
|
|
70
65
|
var counter = 0;
|
|
71
66
|
const int INIT_TOLERANCE = 10 * 60;
|
|
72
67
|
const int INIT_WARN_CYCLE = 5 * 60;
|
|
@@ -83,8 +78,12 @@ namespace Amanotes.Core
|
|
|
83
78
|
}
|
|
84
79
|
|
|
85
80
|
_status = Status.Initialize;
|
|
81
|
+
|
|
82
|
+
// sort on priority
|
|
83
|
+
Adapter.listAdapters.Sort((a1, a2)=> a1.initOrder.CompareTo(a2.initOrder));
|
|
86
84
|
foreach (var adapter in Adapter.listAdapters)
|
|
87
85
|
{
|
|
86
|
+
Log($"Initing {adapter.id} --> initOrder: {adapter.initOrder}");
|
|
88
87
|
adapter.Init();
|
|
89
88
|
|
|
90
89
|
while (!adapter.IsReady)
|
|
@@ -92,8 +91,10 @@ namespace Amanotes.Core
|
|
|
92
91
|
time += Time.deltaTime;
|
|
93
92
|
yield return null;
|
|
94
93
|
if (time <= timeout) continue;
|
|
95
|
-
LogWarningOnce($"{adapter.
|
|
94
|
+
LogWarningOnce($"{adapter.id} init time out: {timeout}");
|
|
96
95
|
}
|
|
96
|
+
|
|
97
|
+
Log($"Adapter {adapter.id} inited!");
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
// Init adapters
|
|
@@ -70,8 +70,7 @@ public class AmaGDKCoreTest
|
|
|
70
70
|
|
|
71
71
|
AmaGDK.Init();
|
|
72
72
|
SceneManager.LoadScene(SCENE_WITH_AUTOINIT_OFF, LoadSceneMode.Single);
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
|
|
75
74
|
yield return new WaitForSeconds(AMAGDK_INIT_DURATION);
|
|
76
75
|
Assert.IsTrue(AmaGDK.isReady);
|
|
77
76
|
}
|
|
@@ -85,8 +84,8 @@ public class AmaGDKCoreTest
|
|
|
85
84
|
SceneManager.LoadScene(SCENE_WITH_AUTOINIT_OFF, LoadSceneMode.Single);
|
|
86
85
|
yield return null; // Took 1 frame for scene ready (call Awake)
|
|
87
86
|
AmaGDK.Init();
|
|
88
|
-
LogAssert.NoUnexpectedReceived();
|
|
89
87
|
|
|
88
|
+
|
|
90
89
|
yield return new WaitForSeconds(AMAGDK_INIT_DURATION);
|
|
91
90
|
Assert.IsTrue(AmaGDK.isReady);
|
|
92
91
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "com.amanotes.gdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"displayName": "AmaGDK",
|
|
5
5
|
"description": "Amanotes Game Development Kit",
|
|
6
6
|
"unity": "2020.3",
|
|
@@ -14,5 +14,6 @@
|
|
|
14
14
|
"email": "tech.support@amanotes.com",
|
|
15
15
|
"url": "https://amanotes.com"
|
|
16
16
|
},
|
|
17
|
+
"documentationUrl": "https://amagdk.notion.site/amagdk/Ama-GDK-a73596617ab247b6a43c8f12a1581415",
|
|
17
18
|
"license": "MIT"
|
|
18
19
|
}
|