com.amanotes.gdk 0.1.8 → 0.1.10

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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.10 - 2023-02-17]
4
+ ### Release AmaGDK v0.1.10
5
+ ### Support accumulated event within session
6
+
7
+ ## [0.1.9 - 2023-02-15]
8
+ ### Release AmaGDK v0.1.9
9
+ ### Change Documentation URL
10
+ ### Support API LogEvent(eventName, parameters)
11
+
3
12
  ## [0.1.8 - 2023-02-15]
4
13
  ### Release AmaGDK v0.1.8
5
14
  ### Add AdapterID
@@ -108,7 +108,10 @@ namespace Amanotes.Core
108
108
  void DrawGUI_ConfigDetail()
109
109
  {
110
110
  CreateCachedEditor(configAsset, null, ref editor);
111
+ var lbWidth = EditorGUIUtility.labelWidth;
112
+ EditorGUIUtility.labelWidth = 200f;
111
113
  editor.OnInspectorGUI();
114
+ EditorGUIUtility.labelWidth = lbWidth;
112
115
  }
113
116
 
114
117
  void DrawGUI_ConfigAsset(){
Binary file
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:313276bb7dcfb6c5dc1a760945f89b413282c7329d1b4856e777c6aee75cc22e
3
+ size 1635
@@ -1,6 +1,5 @@
1
1
  fileFormatVersion: 2
2
- guid: cfbb48f0167d74afa8a2099a218d698e
3
- folderAsset: yes
2
+ guid: 1a3999539db3049c998b0c84b7f92f07
4
3
  DefaultImporter:
5
4
  externalObjects: {}
6
5
  userData:
@@ -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
- public interface IAdapter
12
+
13
+ [Serializable] public class AdapterInfo
12
14
  {
13
- string Id { get; }
14
- bool IsReady { get; }
15
- void Init();
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 class AdapterT<T> : IAdapter where T : IAdapter, new()
40
+ public interface IAdapter
19
41
  {
20
- protected static T _instance;
21
- protected static Status _status = Status.None;
22
- public bool IsReady => _status == Status.Ready;
23
- public string Id => typeof(T).Name.Replace("Adapter", string.Empty);
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 Init()
60
+ public static void Register<T>(string version) where T : IAdapter, new()
26
61
  {
27
- if (_status != Status.None)
62
+ var typeT = typeof(T);
63
+ var id = GetId(typeT);
64
+
65
+ if (AmaGDK._status != Status.None)
28
66
  {
29
- LogWarning($"Invalid status: {_status}");
67
+ LogWarningOnce($"RegisterAdapter - Invalid status: {AmaGDK._status}");
30
68
  return;
31
69
  }
32
70
 
33
- _status = Status.Initialize;
34
- InternalInit((success) =>
71
+ var orderConfig = AmaGDK.Config.initOrder.FirstOrDefault(item => item.id == id);
72
+ listAdapters.Add(new AdapterInfo()
35
73
  {
36
- _status = success ? Status.Ready : Status.Failed;
74
+ id = id,
75
+ version = version,
76
+ initOrder = (orderConfig != null) ? orderConfig.order : 0,
77
+ adapter = new T()
37
78
  });
38
79
  }
39
80
 
40
- protected virtual void InternalInit(Action<bool> onCompleted)
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
  }
@@ -0,0 +1,235 @@
1
+ using System;
2
+ using System.Collections;
3
+
4
+ using UnityEngine;
5
+
6
+ using Amanotes.Core.Internal;
7
+ using static Amanotes.Core.Internal.Logging;
8
+
9
+ namespace Amanotes.Core
10
+ {
11
+ public interface IAds
12
+ {
13
+ bool IsAdReady(AdType Type);
14
+
15
+ #region Interstitial
16
+ event Action InterstitialShowSucceededCallback;
17
+ event Action InterstitialShowFailedCallback;
18
+ event Action InterstitialClickedCallback;
19
+ void RequestInterstitial();
20
+ void ShowInterstitial();
21
+ void ShowInterstitial(string placementName);
22
+ #endregion FullAds
23
+
24
+ #region VideoAds
25
+ event Action RewardedVideoShowFailedCallback;
26
+ event Action RewardedVideoClosedCallback;
27
+ event Action RewardedCallback;
28
+ event Action RewardedVideoClickCallback;
29
+ void RequestRewardedVideo();
30
+ void ShowRewardedVideo();
31
+ void ShowRewardedVideo(string placementName);
32
+ #endregion VideoAds
33
+
34
+ #region Banner
35
+ event Action BannerAdsClickCallback;
36
+ event Action BannerShowCallback;
37
+ void RequestBanner(BannerPosition position = BannerPosition.TOP);
38
+ void RequestBanner(BannerPosition position, string placementName);
39
+ void ShowBanner();
40
+ void HideBanner();
41
+ #endregion Banner
42
+ }
43
+
44
+ public enum BannerPosition
45
+ {
46
+ TOP = 1,
47
+ BOTTOM = 2
48
+ };
49
+
50
+ public enum AdType : byte
51
+ {
52
+ Interstitial,
53
+ Reward,
54
+ Banner
55
+ };
56
+
57
+ public partial class AmaGDK // IAds module
58
+ {
59
+ public static class Ads
60
+ {
61
+ internal static IAds adsModule;
62
+ public static Action<string> OnInterstitalFailCallback;
63
+ public static Action<string> OnRewardedVideoFailCallback;
64
+
65
+ public static void Init()
66
+ {
67
+ var adsModules = Adapter.FindAll<IAds>();
68
+
69
+ if (adsModules == null || adsModules.Count < 1)
70
+ {
71
+ LogError("Ads module not found!");
72
+ return;
73
+ }
74
+
75
+ if (adsModules.Count > 1)
76
+ {
77
+ LogError("Multiple Ads modules is not supported!");
78
+ return;
79
+ }
80
+
81
+ adsModule = adsModules[0].GetAdapterApi<IAds>();
82
+ }
83
+
84
+ public static void RequestBanner(BannerPosition position)
85
+ {
86
+ if (adsModule == null)
87
+ {
88
+ LogWarning("Ads module is not initialized");
89
+ return;
90
+ }
91
+ adsModule.RequestBanner(position);
92
+ }
93
+
94
+ public static void ShowBanner()
95
+ {
96
+ adsModule.ShowBanner();
97
+ }
98
+
99
+ public static void HideBanner()
100
+ {
101
+ if (!adsModule.IsAdReady(AdType.Banner))
102
+ {
103
+ LogWarning("Banner is not ready");
104
+ return;
105
+ }
106
+
107
+ adsModule.HideBanner();
108
+ }
109
+
110
+ public static void RequestInterstitial()
111
+ {
112
+ if (adsModule == null)
113
+ {
114
+ LogWarning("Ads module is not initialized");
115
+ return;
116
+ }
117
+ adsModule.RequestInterstitial();
118
+ }
119
+
120
+ public static void ShowInterstitial()
121
+ {
122
+ if (!adsModule.IsAdReady(AdType.Interstitial))
123
+ {
124
+ LogWarning("Interstitial is not ready");
125
+ BeginCoroutine(IWaitShowInterstitial());
126
+ return;
127
+ }
128
+ adsModule.ShowInterstitial();
129
+ }
130
+
131
+ public static void RequestRewardedVideo()
132
+ {
133
+ if (adsModule == null)
134
+ {
135
+ LogWarning("Ads module is not initialized");
136
+ return;
137
+ }
138
+ adsModule.RequestRewardedVideo();
139
+ }
140
+
141
+ public static void ShowRewardedVideo()
142
+ {
143
+ if (!adsModule.IsAdReady(AdType.Reward))
144
+ {
145
+ LogWarning("Reward is not ready");
146
+ BeginCoroutine(IWaitShowRewardedVideo());
147
+ return;
148
+ }
149
+ adsModule.ShowRewardedVideo();
150
+ }
151
+
152
+ private static IEnumerator IWaitShowRewardedVideo()
153
+ {
154
+ LogWarning("Wait Show Rewarded Video");
155
+ if (adsModule == null)
156
+ {
157
+ OnRewardedVideoFailCallback?.Invoke("Not found ads module");
158
+ OnRewardedVideoFailCallback = null;
159
+ yield break;
160
+ }
161
+
162
+ var startTime = Time.time;
163
+ float timeout = 5;
164
+ string error = null;
165
+ while (!adsModule.IsAdReady(AdType.Reward))
166
+ {
167
+ if (Application.internetReachability == NetworkReachability.NotReachable)
168
+ {
169
+ error = Application.internetReachability.ToString();
170
+ break;
171
+ }
172
+
173
+ if ((Time.time - startTime) > timeout)
174
+ {
175
+ error = "Timeout";
176
+ break;
177
+ }
178
+
179
+ yield return null;
180
+ }
181
+
182
+ if (adsModule.IsAdReady(AdType.Reward))
183
+ {
184
+ adsModule.ShowRewardedVideo();
185
+ }
186
+ else
187
+ {
188
+ OnRewardedVideoFailCallback?.Invoke(error);
189
+ OnRewardedVideoFailCallback = null;
190
+ }
191
+ }
192
+
193
+ private static IEnumerator IWaitShowInterstitial()
194
+ {
195
+ LogWarning("Wait Show Interstitial");
196
+ if (adsModule == null)
197
+ {
198
+ OnInterstitalFailCallback?.Invoke("Not found ads module");
199
+ OnInterstitalFailCallback = null;
200
+ yield break;
201
+ }
202
+
203
+ var startTime = Time.time;
204
+ float timeout = 5;
205
+ string error = null;
206
+ while (!adsModule.IsAdReady(AdType.Interstitial))
207
+ {
208
+ if (Application.internetReachability == NetworkReachability.NotReachable)
209
+ {
210
+ error = Application.internetReachability.ToString();
211
+ break;
212
+ }
213
+
214
+ if ((Time.time - startTime) > timeout)
215
+ {
216
+ error = "Timeout";
217
+ break;
218
+ }
219
+
220
+ yield return null;
221
+ }
222
+
223
+ if (adsModule.IsAdReady(AdType.Interstitial))
224
+ {
225
+ adsModule.ShowInterstitial();
226
+ }
227
+ else
228
+ {
229
+ OnInterstitalFailCallback?.Invoke(error);
230
+ OnInterstitalFailCallback = null;
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
@@ -1,5 +1,5 @@
1
1
  fileFormatVersion: 2
2
- guid: 653a76219edea423ca7f51c1c4c9b02b
2
+ guid: 46425c80eac894185a5609143ace732f
3
3
  MonoImporter:
4
4
  externalObjects: {}
5
5
  serializedVersion: 2
@@ -22,6 +22,7 @@ namespace Amanotes.Core
22
22
  public Dictionary<string, object> parameters = new Dictionary<string, object>();
23
23
  public string funnelSignature;
24
24
  public bool accumulated;
25
+ public bool withinSession;
25
26
  public HashSet<string> ignoreAnalyticIds = new HashSet<string>();
26
27
  public HashSet<string> allowAnalyticIds = new HashSet<string>();
27
28
 
@@ -43,15 +44,44 @@ namespace Amanotes.Core
43
44
  return result;
44
45
  }
45
46
 
47
+ public static IEventParamsBuilder LogEvent(string eventName, Dictionary<string, object> parameters)
48
+ {
49
+ var result = new EventParams(eventName);
50
+ result.AddParam(parameters);
51
+ eventQueue.Enqueue(result);
52
+ return result;
53
+ }
54
+
55
+ public static IEventParamsBuilder LogEvent(string eventName, params (string, object)[] parameters)
56
+ {
57
+ var result = new EventParams(eventName);
58
+ for (var i = 0;i < parameters.Length; i++)
59
+ {
60
+ result.AddParam(parameters[i].Item1, parameters[i].Item2);
61
+ }
62
+ eventQueue.Enqueue(result);
63
+ return result;
64
+ }
65
+
46
66
  public static IEventParamsBuilder LogFunnelEvent(string eventName, string signature = "")
47
67
  {
48
68
  return LogEvent(eventName).SetAsFunnel(signature);
49
69
  }
50
70
 
51
- public static int GetAccumulatedCount(string eventName)
71
+ public static IEventParamsBuilder LogFunnelEvent(string eventName, Dictionary<string, object> parameters, string signature = "")
72
+ {
73
+ return LogEvent(eventName, parameters).SetAsFunnel(signature);
74
+ }
75
+
76
+ public static IEventParamsBuilder LogFunnelEvent(string eventName, string signature = "", params (string, object)[] parameters)
77
+ {
78
+ return LogEvent(eventName, parameters).SetAsFunnel(signature);
79
+ }
80
+
81
+ public static int GetAccumulatedCount(string eventName, bool withinSession = false)
52
82
  {
53
83
  var eventDetail = localData.GetEventDetail(eventName);
54
- return eventDetail != null ? eventDetail.count : 0;
84
+ return eventDetail != null ? (withinSession ? eventDetail.countInSession : eventDetail.totalCount) : 0;
55
85
  }
56
86
 
57
87
  public static void SetLogEventCondition(Predicate<EventDetail> condition)
@@ -70,7 +100,7 @@ namespace Amanotes.Core
70
100
 
71
101
  foreach (var s in listAdapters)
72
102
  {
73
- s.SetUserId(userId);
103
+ s.GetAdapterApi<IAnalyticAdapter>().SetUserId(userId);
74
104
  }
75
105
  }
76
106
 
@@ -84,10 +114,10 @@ namespace Amanotes.Core
84
114
 
85
115
  foreach (var s in listAdapters)
86
116
  {
87
- s.SetUserProperty(key, value);
117
+ s.GetAdapterApi<IAnalyticAdapter>().SetUserProperty(key, value);
88
118
  }
89
119
  }
90
-
120
+
91
121
  private static IntegrityFlag MergeData(List<string> funnelEvents, Dictionary<string, int> eventCountMap, bool sumEventCount)
92
122
  {
93
123
  var flag = IntegrityFlag.Ok;
@@ -108,20 +138,20 @@ namespace Amanotes.Core
108
138
  localData.eventDetails.Add(new EventDetail
109
139
  {
110
140
  eventName = e.Key,
111
- count = e.Value
141
+ totalCount = e.Value
112
142
  });
113
143
  flag |= IntegrityFlag.NewEvent;
114
144
  continue;
115
145
  }
116
146
 
117
- if (eventDetail.count != e.Value)
147
+ if (eventDetail.totalCount != e.Value)
118
148
  {
119
149
  flag |= IntegrityFlag.DifferentCount;
120
150
  }
121
151
 
122
152
  if (sumEventCount)
123
153
  {
124
- eventDetail.count += e.Value;
154
+ eventDetail.totalCount += e.Value;
125
155
  }
126
156
  }
127
157
 
@@ -158,13 +188,16 @@ namespace Amanotes.Core
158
188
  {
159
189
  internal static Predicate<EventDetail> logEventHook = null;
160
190
  internal static readonly Queue<EventParams> eventQueue = new Queue<EventParams>();
161
- internal static readonly List<IAnalyticAdapter> listAdapters = new List<IAnalyticAdapter>();
191
+ internal static readonly List<AdapterInfo> listAdapters = new List<AdapterInfo>();
162
192
  internal static readonly AnalyticsData localData = new AnalyticsData().LoadJsonFromFile();
163
193
 
164
- internal static void GetAnalyticAdapters()
194
+ internal static void Init()
165
195
  {
166
196
  listAdapters.Clear();
167
197
  listAdapters.AddRange(Adapter.FindAll<IAnalyticAdapter>());
198
+
199
+ _frameUpdate -= ProcessEventQueue;
200
+ _frameUpdate += ProcessEventQueue;
168
201
  }
169
202
 
170
203
  internal static void ProcessEventQueue()
@@ -179,24 +212,22 @@ namespace Amanotes.Core
179
212
  if (!NormalizeEventName(ref eventData.eventName))
180
213
  continue;
181
214
 
182
- var counter = localData.IncreaseCounter(eventData.eventName);
215
+ var (countInSession, totalCount) = localData.IncreaseCounter(eventData.eventName);
183
216
 
184
217
  if (!ShouldSendEvent(eventData))
185
218
  continue;
186
219
 
187
220
  if (eventData.accumulated)
188
221
  {
189
- eventData.AddParam("accumulated_count", counter);
222
+ eventData.AddParam("accumulated_count", eventData.withinSession ? countInSession : totalCount);
190
223
  }
191
224
 
192
225
  foreach (var m in listAdapters)
193
226
  {
194
- var id = ((IAdapter)m).Id;
195
- if (eventData.ignoreAnalyticIds.Contains(id))
227
+ if (eventData.ignoreAnalyticIds.Contains(m.id))
196
228
  continue;
197
-
198
- m.LogEvent(eventData);
199
- if (showAnalyticsLog) Debug.Log($"[{id}] Sent event <{eventData.eventName}> ({counter})");
229
+ m.GetAdapterApi<IAnalyticAdapter>().LogEvent(eventData);
230
+ if (showAnalyticsLog) Debug.Log($"[{m.id}] Sent event <{eventData.eventName}> (in session: {countInSession}, total: {totalCount})");
200
231
  }
201
232
  }
202
233
 
@@ -258,7 +289,9 @@ namespace Amanotes.Core
258
289
  public class EventDetail
259
290
  {
260
291
  public string eventName;
261
- public int count;
292
+ public int totalCount;
293
+ [NonSerialized]
294
+ public int countInSession;
262
295
  }
263
296
 
264
297
  [Flags]
@@ -324,12 +357,13 @@ namespace Amanotes.Core
324
357
  return true;
325
358
  }
326
359
 
327
- internal int IncreaseCounter(string eventName)
360
+ internal (int countInSession, int totalCount) IncreaseCounter(string eventName)
328
361
  {
329
362
  var result = GetEventDetail(eventName, true);
330
- result.count++;
363
+ result.totalCount++;
364
+ result.countInSession++;
331
365
  _dirty = true;
332
- return result.count;
366
+ return (result.countInSession, result.totalCount);
333
367
  }
334
368
 
335
369
  internal void SaveIfDirty()
@@ -377,11 +411,13 @@ namespace Amanotes.Core
377
411
  data.funnelSignature = string.IsNullOrEmpty(signature) ? data.eventName : signature;
378
412
  return ap;
379
413
  }
380
- public static IEventParamsBuilder SetAsAccumulated(this IEventParamsBuilder ap)
414
+ public static IEventParamsBuilder SetAsAccumulated(this IEventParamsBuilder ap, bool withinSession = false)
381
415
  {
382
416
  if (ap == null) return null;
383
417
 
384
- (ap as EventParams).accumulated = true;
418
+ EventParams data = ap as EventParams;
419
+ data.accumulated = true;
420
+ if (withinSession) data.withinSession = true;
385
421
  return ap;
386
422
  }
387
423
 
@@ -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] internal partial class SDKConfig {
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,20 +25,21 @@ namespace Amanotes.Core.Internal
25
25
 
26
26
  public static class Res
27
27
  {
28
- #if AMAGDK_DEV
28
+ #if AMAGDK_DEV
29
29
  public const string BASE_PATH = "Assets/AmaGDKCore/";
30
- #else
30
+ #else
31
31
  public const string BASE_PATH = "Packages/com.amanotes.gdk/";
32
- #endif
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",
41
41
  //"AppsflyerAdapter_v6.5.4",
42
+ // "IronsourceAdapter_v7.2.6",
42
43
  };
43
44
  }
44
45
 
@@ -69,55 +70,27 @@ namespace Amanotes.Core.Internal
69
70
  }
70
71
  }
71
72
 
72
- public static class Adapter {
73
- internal static readonly List<IAdapter> listAdapters = new List<IAdapter>();
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 {
73
+ public static class Forbidden
74
+ {
103
75
  public static void DestroyAndReset()
104
76
  {
105
- if (AmaGDK._instance != null) {
77
+ if (AmaGDK._instance != null)
78
+ {
106
79
  UnityObject.Destroy(AmaGDK._instance);
107
80
  AmaGDK._instance = null;
108
81
  }
109
82
 
110
83
  var result = Resources.FindObjectsOfTypeAll<AmaGDK>();
111
- for (var i = 0;i < result.Length; i++)
112
- {
84
+ for (var i = 0; i < result.Length; i++)
85
+ {
113
86
  if (result[i] == null) continue;
114
-
115
- #if UNITY_EDITOR // Ignore loaded prefabs assets
87
+
88
+ #if UNITY_EDITOR // Ignore loaded prefabs assets
116
89
  {
117
90
  var path = UnityEditor.AssetDatabase.GetAssetPath(result[i]);
118
91
  if (!string.IsNullOrEmpty(path)) continue;
119
92
  }
120
- #endif
93
+ #endif
121
94
 
122
95
  // Logging.LogWarning("Something wrong: another AmaGDK instance found!");
123
96
  UnityObject.Destroy(result[i].gameObject);
package/Runtime/AmaGDK.cs CHANGED
@@ -12,9 +12,10 @@ namespace Amanotes.Core
12
12
  {
13
13
  public partial class AmaGDK : MonoBehaviour
14
14
  {
15
- public const string VERSION = "0.1.8";
15
+ public const string VERSION = "0.1.10";
16
16
 
17
17
  internal static AmaGDK _instance;
18
+ internal static event Action _frameUpdate;
18
19
  private static ConfigAsset _config = null;
19
20
  internal static ConfigAsset Config {
20
21
  get {
@@ -24,7 +25,7 @@ namespace Amanotes.Core
24
25
  return _config;
25
26
  }
26
27
  }
27
-
28
+
28
29
  internal static Status _status = Status.None;
29
30
  internal static Action _onReadyCallback;
30
31
  internal static bool _allowInit = false;
@@ -51,9 +52,7 @@ namespace Amanotes.Core
51
52
  _allowInit = _allowInit || autoInit;
52
53
  StartCoroutine(InitRoutine());
53
54
  }
54
-
55
-
56
-
55
+
57
56
  IEnumerator InitRoutine()
58
57
  {
59
58
  if (Config == null)
@@ -63,10 +62,7 @@ namespace Amanotes.Core
63
62
 
64
63
  float time = 0;
65
64
  float timeout = 3;
66
-
67
- // Wait 1 frame to make sure all adapters have finished registering
68
- yield return null;
69
-
65
+
70
66
  var counter = 0;
71
67
  const int INIT_TOLERANCE = 10 * 60;
72
68
  const int INIT_WARN_CYCLE = 5 * 60;
@@ -83,8 +79,12 @@ namespace Amanotes.Core
83
79
  }
84
80
 
85
81
  _status = Status.Initialize;
82
+
83
+ // sort on priority
84
+ Adapter.listAdapters.Sort((a1, a2)=> a1.initOrder.CompareTo(a2.initOrder));
86
85
  foreach (var adapter in Adapter.listAdapters)
87
86
  {
87
+ Log($"Initing {adapter.id} --> initOrder: {adapter.initOrder}");
88
88
  adapter.Init();
89
89
 
90
90
  while (!adapter.IsReady)
@@ -92,13 +92,16 @@ namespace Amanotes.Core
92
92
  time += Time.deltaTime;
93
93
  yield return null;
94
94
  if (time <= timeout) continue;
95
- LogWarningOnce($"{adapter.Id} is time out");
95
+ LogWarningOnce($"{adapter.id} init time out: {timeout}");
96
96
  }
97
- }
98
97
 
99
- // Init adapters
100
- Analytics.GetAnalyticAdapters();
98
+ Log($"Adapter {adapter.id} inited!");
99
+ }
101
100
 
101
+ // Init modules (Adapter managers)
102
+ Analytics.Init();
103
+ Ads.Init();
104
+
102
105
  _status = Status.Ready;
103
106
  _onReadyCallback?.Invoke();
104
107
  _onReadyCallback = null;
@@ -108,7 +111,7 @@ namespace Amanotes.Core
108
111
  private void Update()
109
112
  {
110
113
  if (!isReady) return;
111
- Analytics.ProcessEventQueue();
114
+ _frameUpdate?.Invoke();
112
115
  }
113
116
  }
114
117
 
@@ -144,6 +147,16 @@ namespace Amanotes.Core
144
147
  _instance = sdk.AddComponent<AmaGDK>();
145
148
  }
146
149
 
150
+ public static void BeginCoroutine(IEnumerator enumerator)
151
+ {
152
+ _instance.StartCoroutine(enumerator);
153
+ }
154
+
155
+ public static void EndCoroutine(IEnumerator enumerator)
156
+ {
157
+ _instance.StopCoroutine(enumerator);
158
+ }
159
+
147
160
  public static void AddCallback(Action onReady)
148
161
  {
149
162
  if (onReady == null)
@@ -70,8 +70,7 @@ public class AmaGDKCoreTest
70
70
 
71
71
  AmaGDK.Init();
72
72
  SceneManager.LoadScene(SCENE_WITH_AUTOINIT_OFF, LoadSceneMode.Single);
73
- LogAssert.NoUnexpectedReceived();
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
  }
@@ -123,7 +123,7 @@ public class MigrationTest
123
123
  analyticsData.eventDetails.Add(new EventDetail
124
124
  {
125
125
  eventName = e.Key,
126
- count = e.Value
126
+ totalCount = e.Value
127
127
  });
128
128
  }
129
129
 
@@ -132,7 +132,7 @@ public class MigrationTest
132
132
  analyticsData.eventDetails.Add(new EventDetail
133
133
  {
134
134
  eventName = "migration_error",
135
- count = migrationError
135
+ totalCount = migrationError
136
136
  });
137
137
  }
138
138
 
@@ -154,7 +154,7 @@ public class MigrationTest
154
154
  var eventDetail = analyticsData.GetEventDetail(errEventName);
155
155
  if (eventDetail != null)
156
156
  {
157
- Assert.IsTrue(eventDetail.count == 1);
157
+ Assert.IsTrue(eventDetail.totalCount == 1);
158
158
  }
159
159
  else
160
160
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.amanotes.gdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
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
  }
@@ -1,6 +0,0 @@
1
- using System.Collections.Generic;
2
-
3
- namespace Amanotes.Core
4
- {
5
-
6
- }
@@ -1,8 +0,0 @@
1
- fileFormatVersion: 2
2
- guid: d1a686515ec7946df9492f35e9638fea
3
- folderAsset: yes
4
- DefaultImporter:
5
- externalObjects: {}
6
- userData:
7
- assetBundleName:
8
- assetBundleVariant: