com.amanotes.gdk 0.2.70 → 0.2.71

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/Editor/Extra/GDKCIBuildCommand.cs +55 -0
  3. package/Extra/AmaGDKInstaller.unitypackage +0 -0
  4. package/Extra/CheckDiskSpace.unitypackage +0 -0
  5. package/Extra/Consent.unitypackage +0 -0
  6. package/Extra/ForceUpdate.unitypackage +0 -0
  7. package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
  8. package/Extra/PostProcessor.unitypackage +0 -0
  9. package/Packages/AmaGDKConfig.unitypackage +0 -0
  10. package/Packages/AmaGDKExample.unitypackage +0 -0
  11. package/Packages/AmaGDKTest.unitypackage +0 -0
  12. package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
  13. package/Packages/AppsFlyerAdapter.unitypackage +0 -0
  14. package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
  15. package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
  16. package/Packages/IronSourceAdapter.unitypackage +0 -0
  17. package/Packages/MaxAdNetworkAdapter.unitypackage +0 -0
  18. package/Packages/RevenueCatAdapter.unitypackage +0 -0
  19. package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
  20. package/Runtime/Ad/AdModuleConfig.cs +19 -4
  21. package/Runtime/Ad/AmaGDK.Ads.cs +19 -7
  22. package/Runtime/AmaGDK.Analytics.cs +63 -48
  23. package/Runtime/AmaGDK.Device.cs +2 -2
  24. package/Runtime/AmaGDK.RemoteConfig.cs +1 -1
  25. package/Runtime/AmaGDK.cs +2 -2
  26. package/Runtime/AnalyticQualityAsset.cs +5 -4
  27. package/Runtime/AudioToolkit/Plugins/AudioDeviceDetector.cs +2 -2
  28. package/Runtime/Core/GDKPool.cs +337 -55
  29. package/Runtime/Fps/AmaFPS.Utils.cs +1 -1
  30. package/Runtime/GDKAudio/GDKAudio.cs +305 -0
  31. package/Runtime/GDKAudio/GDKAudio.cs.meta +3 -0
  32. package/Runtime/GDKAudio/Plugins/Android/atensor-release.aar +0 -0
  33. package/Runtime/GDKAudio/Plugins/Android/atensor-release.aar.meta +32 -0
  34. package/Runtime/GDKAudio/Plugins/Android.meta +3 -0
  35. package/Runtime/GDKAudio/Plugins/iOS/libatensor.a +0 -0
  36. package/Runtime/GDKAudio/Plugins/iOS/libatensor.a.meta +68 -0
  37. package/Runtime/GDKAudio/Plugins/iOS/libcrypto.a +0 -0
  38. package/Runtime/GDKAudio/Plugins/iOS/libcrypto.a.meta +68 -0
  39. package/Runtime/GDKAudio/Plugins/iOS/libssl.a +0 -0
  40. package/Runtime/GDKAudio/Plugins/iOS/libssl.a.meta +68 -0
  41. package/Runtime/GDKAudio/Plugins/iOS.meta +8 -0
  42. package/Runtime/GDKAudio/Plugins/macOS/libatensor.dylib +0 -0
  43. package/Runtime/GDKAudio/Plugins/macOS/libatensor.dylib.meta +81 -0
  44. package/Runtime/GDKAudio/Plugins/macOS.meta +8 -0
  45. package/Runtime/GDKAudio/Plugins.meta +8 -0
  46. package/Runtime/GDKAudio.meta +3 -0
  47. package/Runtime/Internal/AmaGDK.Utils.cs +3 -3
  48. package/Runtime/Internal/ForceQuitMonitor.cs +7 -2
  49. package/Runtime/Utils/GDKUtils.cs +34 -3
  50. package/package.json +1 -1
@@ -1,103 +1,385 @@
1
- using System;
1
+ using System;
2
2
  using System.Collections.Concurrent;
3
3
  using System.Collections.Generic;
4
+ using System.Reflection;
4
5
  using System.Text;
5
-
6
+ using Unity.Collections.LowLevel.Unsafe;
7
+ using UnityEngine;
8
+ using UnityEngine.Assertions;
9
+ using UnityEngine.Profiling;
6
10
  namespace Amanotes.Core.Internal
7
11
  {
8
- public interface IPoolItem
12
+ internal static class GDKPoolExtension
9
13
  {
10
- void Reset();
14
+ internal static T Pop<T>(this List<T> list)
15
+ {
16
+ if (list == null || list.Count == 0) return default;
17
+
18
+ T result = list[list.Count - 1];
19
+ list.RemoveAt(list.Count - 1);
20
+ return result;
21
+ }
22
+ }
23
+
24
+ public static partial class GDKPool // TypeHandler
25
+ {
26
+ private const int STRING_BUILDER_DEFAULT_LEN = 64;
27
+ private static readonly Dictionary<Type, object> typeHandlerMap = new Dictionary<Type, object>
28
+ {
29
+ { typeof(StringBuilder), new TypeHandler<StringBuilder>(() => new StringBuilder(), h => h.Clear()) },
30
+ { typeof(HashSet<string>), new TypeHandler<HashSet<string>>(() => new HashSet<string>(), h => h.Clear()) },
31
+ { typeof(Dictionary<string, object>), new TypeHandler<Dictionary<string, object>>(() => new Dictionary<string, object>(), d => d.Clear()) }
32
+ };
33
+
34
+ public static TypeHandler<T> GetTypeHandler<T>() where T : class
35
+ {
36
+ return typeHandlerMap.TryGetValue(typeof(T), out object result)
37
+ ? UnsafeUtility.As<object, TypeHandler<T>>(ref result)
38
+ : null;
39
+ }
40
+
41
+ public static TypeHandler<T> AddTypeHandler<T>(Func<T> newT, Action<T> resetT = null) where T : class
42
+ {
43
+ if (typeof(IPoolItem).IsAssignableFrom(typeof(T)))
44
+ {
45
+ if (resetT != null) Debug.LogWarning("Unsupported custom resetT() when T: IPoolItem!");
46
+ resetT = item => { (item as IPoolItem)?.Reset(); };
47
+ }
48
+
49
+ var result = new TypeHandler<T>(newT, resetT);
50
+ typeHandlerMap.Add(typeof(T), result);
51
+ return result;
52
+ }
53
+ public static TypeHandler<T> AddTypeHandler<T>(Action<T> resetT = null) where T : class, new()
54
+ {
55
+ return AddTypeHandler(() => new T(), resetT);
56
+ }
57
+ public class TypeHandler<T> where T : class
58
+ {
59
+ public readonly Func<T> newT;
60
+ public readonly Action<T> resetT;
61
+
62
+ public TypeHandler(Func<T> newT, Action<T> resetT)
63
+ {
64
+ this.newT = newT;
65
+ this.resetT = resetT;
66
+ }
67
+ }
11
68
  }
12
69
 
13
- public static class GDKPool
70
+ public static partial class GDKPool // Interface
71
+ {
72
+ public interface IPoolItem
73
+ {
74
+ void Reset();
75
+ }
76
+ public interface IPool<T> where T : class
77
+ {
78
+ int Count { get; } // Added to get the number of items currently in the pool
79
+ T Take();
80
+ void Return(T item);
81
+ }
82
+ public interface IPoolMap
83
+ {
84
+ IPool<T> GetPool<T>() where T : class;
85
+ IPool<T> CreatePool<T>(TypeHandler<T> handler = null) where T : class;
86
+ IPool<T> GetOrCreatePool<T>(TypeHandler<T> handler = null) where T : class;
87
+ }
88
+ }
89
+ public static partial class GDKPool // POOLs
14
90
  {
15
- internal class Pool<T> where T : new()
91
+ internal abstract class BasePool<T, T1> : IPool<T>
92
+ where T : class
93
+ where T1 : new()
16
94
  {
17
- private readonly ConcurrentQueue<T> _pool;
18
- public Pool(int initialCapacity = 4)
95
+ internal readonly TypeHandler<T> handler;
96
+ internal readonly T1 pool;
97
+ protected BasePool(TypeHandler<T> handler)
19
98
  {
20
- _pool = new ConcurrentQueue<T>();
21
- for (var i = 0; i < initialCapacity; i++)
99
+ pool = new T1();
100
+ this.handler = handler;
101
+ }
102
+
103
+ public abstract T Take();
104
+ public abstract void Return(T item);
105
+ public abstract int Count { get; }
106
+ }
107
+ internal sealed class ListPool<T> : BasePool<T, List<T>> where T : class
108
+ {
109
+ public ListPool(TypeHandler<T> handler, int capacity) : base(handler)
110
+ {
111
+ for (var i = 0; i < capacity; i++)
22
112
  {
23
- _pool.Enqueue(new T());
113
+ Return(handler.newT());
24
114
  }
25
115
  }
26
-
27
- public Pool(int initialCapacity, Func<T> newT)
116
+ public override int Count => pool.Count;
117
+
118
+ public override T Take()
28
119
  {
29
- _pool = new ConcurrentQueue<T>();
30
- for (var i = 0; i < initialCapacity; i++)
120
+ if (pool.Count == 0) return handler.newT();
121
+ T last = pool.Pop();
122
+ handler.resetT?.Invoke(last); // Take from pool: Do Reset
123
+ return last;
124
+ }
125
+
126
+ internal T TakeAt(int idx)
127
+ {
128
+ if (idx < 0 || idx >= pool.Count - 1) return Take();
129
+
130
+ // swap last item to index
131
+ T item = pool[idx];
132
+ pool[idx] = pool.Pop();
133
+ handler.resetT?.Invoke(item);
134
+ return item;
135
+ }
136
+
137
+ public override void Return(T item)
138
+ {
139
+ if (item == null) return;
140
+ pool.Add(item);
141
+ }
142
+ }
143
+ internal sealed class ConcurrentPool<T> : BasePool<T, ConcurrentBag<T>> where T : class
144
+ {
145
+ public ConcurrentPool(TypeHandler<T> handler, int capacity) : base(handler)
146
+ {
147
+ for (var i = 0; i < capacity; i++)
31
148
  {
32
- _pool.Enqueue(newT());
149
+ Return(handler.newT());
33
150
  }
34
151
  }
35
-
36
- public T Get()
152
+
153
+ public override int Count => pool.Count;
154
+
155
+ public override T Take()
156
+ {
157
+ if (!pool.TryTake(out T result)) return handler.newT();
158
+ handler.resetT?.Invoke(result);
159
+ return result;
160
+ }
161
+
162
+ public override void Return(T item)
163
+ {
164
+ if (item == null) return;
165
+ pool.Add(item);
166
+ }
167
+ }
168
+ }
169
+
170
+ public static partial class GDKPool // POOL MAP
171
+ {
172
+ internal abstract class BasePoolMap<TDict> : IPoolMap where TDict : IDictionary<Type, object>, new()
173
+ {
174
+ internal readonly TDict map = new TDict();
175
+
176
+ // IPoolMap
177
+ public IPool<T> GetPool<T>() where T : class
37
178
  {
38
- if (!_pool.TryDequeue(out var obj)) return new T();
39
- if (obj is IPoolItem poolItem) poolItem.Reset();
40
- return obj;
179
+ return map.TryGetValue(typeof(T), out object result)
180
+ ? UnsafeUtility.As<object, IPool<T>>(ref result)
181
+ : null;
41
182
  }
42
183
 
43
- public void Return(T obj)
184
+ public IPool<T> CreatePool<T>(TypeHandler<T> handler = null) where T : class
44
185
  {
45
- _pool.Enqueue(obj);
186
+ return CreatePoolInternal(handler ?? GetTypeHandler<T>());
46
187
  }
47
188
 
48
- public int Count => _pool.Count;
189
+ public IPool<T> GetOrCreatePool<T>(TypeHandler<T> handler = null) where T : class
190
+ {
191
+ return GetPool<T>() ?? CreatePoolInternal(handler ?? GetTypeHandler<T>());
192
+ }
193
+ internal abstract IPool<T> CreatePoolInternal<T>(TypeHandler<T> handler) where T : class;
49
194
  }
50
- private static readonly Pool<StringBuilder> sbPool1KB = new Pool<StringBuilder>(8, () => new StringBuilder(1024));
51
- private static readonly Pool<StringBuilder> sbPool8KB = new Pool<StringBuilder>(8, () => new StringBuilder(8*1024));
52
- private static readonly Pool<HashSet<string>> hashsetPool = new Pool<HashSet<string>>(4);
53
-
54
- public static StringBuilder GetStringBuilder(int capacityInKb = 1)
195
+ internal class ListPoolMap : BasePoolMap<Dictionary<Type, object>>
55
196
  {
56
- StringBuilder result = capacityInKb <= 1 ? sbPool1KB.Get() : sbPool8KB.Get();
57
- result.Clear();
58
- return result;
197
+ internal override IPool<T> CreatePoolInternal<T>(TypeHandler<T> handler) where T : class
198
+ {
199
+ var result = new ListPool<T>(handler, 1);
200
+ map.Add(typeof(T), result);
201
+ return result;
202
+ }
203
+ }
204
+ internal class ConcurrentPoolMap : BasePoolMap<ConcurrentDictionary<Type, object>>
205
+ {
206
+ internal override IPool<T> CreatePoolInternal<T>(TypeHandler<T> handler) where T : class
207
+ {
208
+ var result = new ConcurrentPool<T>(handler, 1);
209
+ map.TryAdd(typeof(T), result);
210
+ return result;
211
+ }
212
+ }
213
+ }
214
+
215
+ public static partial class GDKPool
216
+ {
217
+ private static readonly ListPoolMap mainPM = new ListPoolMap();
218
+ private static readonly ConcurrentPoolMap threadPM = new ConcurrentPoolMap();
219
+
220
+ // HashSet<T> support
221
+ private static readonly ListPool<HashSet<string>> hPool; // cached reference for main-thread
222
+ private static readonly ListPool<StringBuilder> sbPool;
223
+
224
+ // StringBuilder support
225
+ private static readonly ListPool<StringBuilder> fixedSBPool;
226
+
227
+ // Dictionary support
228
+ private static readonly ListPool<Dictionary<string, object>> dictPool;
229
+
230
+ // SPECIAL APIs
231
+ static GDKPool()
232
+ {
233
+ // Main-thread: Use fixed-length StringBuilder
234
+ sbPool = (ListPool<StringBuilder>) mainPM.CreatePool<StringBuilder>();
235
+ hPool = (ListPool<HashSet<string>>) mainPM.CreatePool<HashSet<string>>();
236
+ dictPool = (ListPool<Dictionary<string, object>>)mainPM.CreatePool<Dictionary<string, object>>();
237
+ fixedSBPool = new ListPool<StringBuilder>(new TypeHandler<StringBuilder>(null, sb => sb.Clear()), 0);
59
238
  }
60
239
 
61
- public static HashSet<string> GetHashSet()
240
+ private static IPoolMap poolMap => GDKUtils.isOnMainThread ? mainPM : (IPoolMap)threadPM;
241
+ internal static void ClearAndReset()
62
242
  {
63
- HashSet<string> result = hashsetPool.Get();
64
- result.Clear();
65
- return result;
243
+ // main thread
244
+ mainPM.map.Clear();
245
+ mainPM.map.Add(typeof(StringBuilder), sbPool);
246
+ mainPM.map.Add(typeof(HashSet<string>), hPool);
247
+ mainPM.map.Add(typeof(Dictionary<string, object>), dictPool);
248
+
249
+ // other threads
250
+ threadPM.map.Clear();
251
+ }
252
+
253
+ public static T Take<T>(bool autoCreatePool = true) where T : class, new()
254
+ {
255
+ IPool<T> pool = poolMap.GetPool<T>() ?? CreatePool<T>();
256
+ return pool.Take();
66
257
  }
67
258
 
68
- public static string ReturnString(StringBuilder sb)
259
+ public static T Take<T>(Action<T> resetT) where T : class, new()
69
260
  {
70
- if (sb == null) return null;
71
- var result = sb.ToString();
72
- Return(sb);
73
- return result;
261
+ IPool<T> pool = poolMap.GetPool<T>() ?? CreatePool(() => new T(), resetT);
262
+ return pool.Take();
74
263
  }
75
264
 
76
- public static void Return(StringBuilder sb)
265
+ public static void Return<T>(T item) where T : class
77
266
  {
78
- if (sb == null) return;
79
- int capacity = sb.Capacity;
80
-
81
- if (capacity == 1024)
267
+ if (typeof(T) == typeof(StringBuilder))
82
268
  {
83
- sbPool1KB.Return(sb);
84
- return;
269
+ StringBuilder sb = UnsafeUtility.As<T, StringBuilder>(ref item);
270
+ if (sb.Capacity == sb.MaxCapacity)
271
+ {
272
+ fixedSBPool.Return(sb);
273
+ return;
274
+ }
85
275
  }
86
276
 
87
- sbPool8KB.Return(sb);
277
+ poolMap.GetPool<T>()?.Return(item);
88
278
  }
89
-
90
- public static void Return(HashSet<string> hashset)
279
+
280
+ public static IPool<T> GetPool<T>(bool autoCreatePool = false) where T : class, new()
91
281
  {
92
- if (hashset == null) return;
93
- hashsetPool.Return(hashset);
282
+ IPool<T> result = poolMap.GetPool<T>();
283
+ if (result != null) return result;
284
+ return autoCreatePool ? CreatePool<T>() : null;
94
285
  }
95
-
286
+ private static IPool<T> TryCreatePoolUsingTypeHandler<T>() where T : class
287
+ {
288
+ TypeHandler<T> handler = GetTypeHandler<T>();
289
+ return handler != null ? poolMap.CreatePool(handler) : null;
290
+ }
291
+ public static IPool<T> CreatePool<T>(Func<T> newT, Action<T> resetT) where T : class
292
+ {
293
+ IPool<T> result = TryCreatePoolUsingTypeHandler<T>();
294
+ if (result != null) return result;
295
+ return poolMap.CreatePool(AddTypeHandler(newT, resetT));
296
+ }
297
+
298
+ public static IPool<T> CreatePool<T>(Action<T> resetT = null) where T : class, new()
299
+ {
300
+ IPool<T> result = TryCreatePoolUsingTypeHandler<T>();
301
+ if (result != null) return result;
302
+ return poolMap.CreatePool(AddTypeHandler(() => new T(), resetT));
303
+ }
304
+ public static HashSet<T> TakeHashSet<T>()
305
+ {
306
+ var result = Take<HashSet<T>>();
307
+ return result ?? CreatePool<HashSet<T>>(h => h.Clear()).Take();
308
+ }
309
+ public static HashSet<string> TakeHashSet()
310
+ {
311
+ return GDKUtils.isOnMainThread ? hPool.Take() : TakeHashSet<string>();
312
+ }
313
+
96
314
  public static void ReturnAndNullize(ref HashSet<string> hashset)
97
315
  {
98
316
  if (hashset == null) return;
99
- hashsetPool.Return(hashset);
317
+ hashset.Clear();
318
+ Return(hashset);
100
319
  hashset = null;
101
320
  }
321
+
322
+ public static StringBuilder TakeStringBuilder(int fixedLength = 0)
323
+ {
324
+ if (!GDKUtils.isOnMainThread)
325
+ {
326
+ if (fixedLength != 0) Logging.LogWarningOnce("Fixed length StringBuilder only work for Main Thread!");
327
+ return Take<StringBuilder>();
328
+ }
329
+
330
+ if (fixedLength == 0) return Take<StringBuilder>();
331
+
332
+ if (fixedSBPool.Count == 0) return new StringBuilder(fixedLength, fixedLength);
333
+ List<StringBuilder> pool = fixedSBPool.pool;
334
+ for (var i = 0; i < pool.Count; i++)
335
+ {
336
+ if (pool[i].Capacity != fixedLength) continue;
337
+ return fixedSBPool.TakeAt(i);
338
+ }
339
+
340
+ return new StringBuilder(fixedLength, fixedLength);
341
+ }
342
+
343
+ private static FieldInfo sbStringValueField;
344
+ private static readonly Dictionary<StringBuilder, string> internalSB = new Dictionary<StringBuilder, string>();
345
+ public static string ReturnAndStringify(StringBuilder sb)
346
+ {
347
+ if (sb == null) return null;
348
+
349
+ // if (GDKUtils.isOnMainThread && sb.Capacity == sb.MaxCapacity)
350
+ // {
351
+ // string str;
352
+ // Profiler.BeginSample("GDKPool.ReturnAndStringify()");
353
+ // {
354
+ // if (!internalSB.TryGetValue(sb, out str))
355
+ // {
356
+ // sbStringValueField ??= typeof(StringBuilder)
357
+ // .GetField("m_StringValue", BindingFlags.NonPublic | BindingFlags.Instance);
358
+ //
359
+ // str = (string)sbStringValueField?.GetValue(sb);
360
+ // internalSB.Add(sb, str);
361
+ // }
362
+ //
363
+ // fixedSBPool.Return(sb);
364
+ // }
365
+ // Profiler.EndSample();
366
+ // return str;
367
+ // }
368
+
369
+ string result = null;
370
+ Profiler.BeginSample("GDKPool.ReturnAndStringify()");
371
+ {
372
+ result = sb.ToString();
373
+ sb.Clear();
374
+ Return(sb);
375
+ }
376
+ Profiler.EndSample();
377
+
378
+ return result;
379
+ }
380
+ public static Dictionary<string, object> TakeDictionary()
381
+ {
382
+ return GDKUtils.isOnMainThread ? dictPool.Take() : Take<Dictionary<string, object>>();
383
+ }
102
384
  }
103
385
  }
@@ -27,7 +27,7 @@ namespace Amanotes.Core
27
27
  var resolution = Screen.currentResolution;
28
28
  dictionary.Add("system_memory_size", SystemInfo.systemMemorySize);
29
29
  dictionary.Add("graphics_memory_size", SystemInfo.graphicsMemorySize);
30
- dictionary.Add("graphics_device_type", SystemInfo.graphicsDeviceType);
30
+ dictionary.Add("graphics_device_type", SystemInfo.graphicsDeviceType.ToString());
31
31
  dictionary.Add("graphics_shader_level", SystemInfo.graphicsShaderLevel);
32
32
  dictionary.Add("processor_count", SystemInfo.processorCount);
33
33
  dictionary.Add("processor_frequency", SystemInfo.processorFrequency);