com.amanotes.gdk 0.2.75 → 0.2.77

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 (71) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/Editor/AmaGDKEditor.cs +24 -15
  3. package/Editor/Utils/GDKPackageInstaller.cs +116 -0
  4. package/Editor/Utils/GDKPackageInstaller.cs.meta +11 -0
  5. package/Extra/AmaGDKInstaller.unitypackage +0 -0
  6. package/Extra/AutoEventQC.unitypackage +0 -0
  7. package/{Runtime/GDKAudio/Plugins/iOS.meta → Extra/AutoEventQC.unitypackage.meta} +1 -2
  8. package/Extra/CheckDiskSpace.unitypackage +0 -0
  9. package/Extra/Consent.unitypackage +0 -0
  10. package/Extra/ForceUpdate.unitypackage +0 -0
  11. package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
  12. package/Extra/PostProcessor.unitypackage +0 -0
  13. package/Packages/AmaGDKConfig.unitypackage +0 -0
  14. package/Packages/AmaGDKExample.unitypackage +0 -0
  15. package/Packages/AmaGDKTest.unitypackage +0 -0
  16. package/Packages/AppsFlyerAdapter.AdRevenue.AF6.14AndOlder.unitypackage +0 -0
  17. package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
  18. package/Packages/AppsFlyerAdapter.unitypackage +0 -0
  19. package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
  20. package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
  21. package/Packages/IronSourceAdapter.AdQuality.unitypackage +0 -0
  22. package/{Runtime/GDKAudio/Plugins/macOS.meta → Packages/IronSourceAdapter.AdQuality.unitypackage.meta} +1 -2
  23. package/Packages/IronSourceAdapter.unitypackage +0 -0
  24. package/Packages/MaxAdNetworkAdapter.unitypackage +0 -0
  25. package/Packages/RevenueCatAdapter.unitypackage +0 -0
  26. package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
  27. package/Runtime/Ad/AdLogic.cs +52 -55
  28. package/Runtime/Ad/AdShowContext.cs +1 -1
  29. package/Runtime/AmaGDK.Analytics.cs +18 -15
  30. package/Runtime/AmaGDK.Consent.cs +3 -8
  31. package/Runtime/AmaGDK.Mono.cs +1 -1
  32. package/Runtime/AmaGDK.RemoteConfig.cs +12 -2
  33. package/Runtime/AmaGDK.UserProfile.cs +31 -23
  34. package/Runtime/AmaGDK.cs +76 -40
  35. package/Runtime/Core/GDKDebug.cs +12 -5
  36. package/Runtime/Core/GDKPrefabPool.cs +571 -0
  37. package/Runtime/Core/GDKPrefabPool.cs.meta +11 -0
  38. package/Runtime/Core/GDKRoutine.cs +48 -2
  39. package/Runtime/Internal/AmaGDK.Internal.cs +1 -1
  40. package/Runtime/UI/ScrollView/Editor/GDKScrollViewEditor.cs +50 -0
  41. package/Runtime/UI/ScrollView/Editor/GDKScrollViewEditor.cs.meta +11 -0
  42. package/Runtime/{GDKAudio/Resources.meta → UI/ScrollView/Editor.meta} +1 -1
  43. package/Runtime/UI/ScrollView/GDKScrollView.cs +702 -0
  44. package/Runtime/UI/ScrollView/GDKScrollView.cs.meta +12 -0
  45. package/Runtime/UI/ScrollView.meta +9 -0
  46. package/Runtime/UI/ScrollableText/GDKScrollableText.cs +68 -0
  47. package/Runtime/UI/ScrollableText/GDKScrollableText.cs.meta +3 -0
  48. package/Runtime/UI/ScrollableText/GDKScrollableText.prefab +806 -0
  49. package/Runtime/UI/ScrollableText/GDKScrollableText.prefab.meta +7 -0
  50. package/Runtime/UI/ScrollableText.meta +3 -0
  51. package/Runtime/{GDKAudio/Plugins.meta → UI.meta} +1 -1
  52. package/Runtime/Utils/GDKUtils.cs +18 -0
  53. package/package.json +1 -1
  54. package/Packages/AppsFlyerAdapter.AdRevenue.unitypackage +0 -0
  55. package/Runtime/GDKAudio/GDKAudio.cs +0 -483
  56. package/Runtime/GDKAudio/GDKAudio.cs.meta +0 -3
  57. package/Runtime/GDKAudio/Plugins/Android/atensor-release.aar +0 -0
  58. package/Runtime/GDKAudio/Plugins/Android/atensor-release.aar.meta +0 -32
  59. package/Runtime/GDKAudio/Plugins/Android.meta +0 -3
  60. package/Runtime/GDKAudio/Plugins/iOS/libatensor.a +0 -0
  61. package/Runtime/GDKAudio/Plugins/iOS/libatensor.a.meta +0 -68
  62. package/Runtime/GDKAudio/Plugins/iOS/libcrypto.a +0 -0
  63. package/Runtime/GDKAudio/Plugins/iOS/libcrypto.a.meta +0 -68
  64. package/Runtime/GDKAudio/Plugins/iOS/libssl.a +0 -0
  65. package/Runtime/GDKAudio/Plugins/iOS/libssl.a.meta +0 -68
  66. package/Runtime/GDKAudio/Plugins/macOS/libatensor.dylib +0 -0
  67. package/Runtime/GDKAudio/Plugins/macOS/libatensor.dylib.meta +0 -81
  68. package/Runtime/GDKAudio/Resources/GDKAudioMixer.mixer +0 -133
  69. package/Runtime/GDKAudio/Resources/GDKAudioMixer.mixer.meta +0 -8
  70. package/Runtime/GDKAudio.meta +0 -3
  71. /package/Packages/{AppsFlyerAdapter.AdRevenue.unitypackage.meta → AppsFlyerAdapter.AdRevenue.AF6.14AndOlder.unitypackage.meta} +0 -0
@@ -9,11 +9,6 @@ namespace Amanotes.Core
9
9
  {
10
10
  public partial class AmaGDK //User profile
11
11
  {
12
- partial class Event
13
- {
14
- public const string GDK_USER_ID_UPDATED = nameof(GDK_USER_ID_UPDATED);
15
- }
16
-
17
12
  private static readonly Lazy<UserProfile> _user = new Lazy<UserProfile>(() => new UserProfile());
18
13
  public static UserProfile User => _user.Value;
19
14
 
@@ -22,9 +17,13 @@ namespace Amanotes.Core
22
17
  /// The callback triggers when a better UserID (gaid, idfv, pseudoId,...) was found and replace the current UserId
23
18
  /// </summary>
24
19
  /// <param name="onUserIdChange"></param>
25
- public static void SetCallback_OnUserIdUpdated(Action<string> onUserIdChange)
20
+
21
+ private static Action<string> _onUserIdChange;
22
+ public static void SetCallback_OnUserIdUpdated(Action<string> callback)
26
23
  {
27
- dispatcher.AddListener(Event.GDK_USER_ID_UPDATED, onUserIdChange);
24
+ if (callback == null) return;
25
+ _onUserIdChange -= callback;
26
+ _onUserIdChange += callback;
28
27
  }
29
28
 
30
29
  [Serializable]
@@ -47,18 +46,18 @@ namespace Amanotes.Core
47
46
 
48
47
  public partial class UserProfile //PUBLIC
49
48
  {
49
+ private readonly Dictionary<string, object> allUserIds = new Dictionary<string, object>();
50
50
  public Dictionary<string, object> CollectAllUserIds()
51
51
  {
52
- var dic = new Dictionary<string, object>();
53
- if (!string.IsNullOrWhiteSpace(IDFA)) dic["idfa"] = IDFA;
54
- if (!string.IsNullOrWhiteSpace(IDFV)) dic["idfv"] = IDFV;
55
- if (!string.IsNullOrWhiteSpace(GAId)) dic["gaid"] = GAId;
56
- if (!string.IsNullOrWhiteSpace(AndroidId)) dic["android_id"] = AndroidId;
57
- if (!string.IsNullOrWhiteSpace(PseudoId)) dic["pseudo_id"] = PseudoId;
58
- if (!string.IsNullOrWhiteSpace(AmaDeviceId)) dic["ama_device_id"] = AmaDeviceId;
59
- if (!string.IsNullOrWhiteSpace(AppsFlyerId)) dic["appsflyer_id"] = AppsFlyerId;
60
- if (!string.IsNullOrWhiteSpace(InstallationId)) dic["installation_id"] = InstallationId;
61
- return dic;
52
+ if (!string.IsNullOrWhiteSpace(IDFA)) allUserIds["idfa"] = IDFA;
53
+ if (!string.IsNullOrWhiteSpace(IDFV)) allUserIds["idfv"] = IDFV;
54
+ if (!string.IsNullOrWhiteSpace(GAId)) allUserIds["gaid"] = GAId;
55
+ if (!string.IsNullOrWhiteSpace(AndroidId)) allUserIds["android_id"] = AndroidId;
56
+ if (!string.IsNullOrWhiteSpace(PseudoId)) allUserIds["pseudo_id"] = PseudoId;
57
+ if (!string.IsNullOrWhiteSpace(AmaDeviceId)) allUserIds["ama_device_id"] = AmaDeviceId;
58
+ if (!string.IsNullOrWhiteSpace(AppsFlyerId)) allUserIds["appsflyer_id"] = AppsFlyerId;
59
+ if (!string.IsNullOrWhiteSpace(InstallationId)) allUserIds["installation_id"] = InstallationId;
60
+ return allUserIds;
62
61
  }
63
62
 
64
63
  public string UserId
@@ -72,8 +71,10 @@ namespace Amanotes.Core
72
71
  {
73
72
  if (_userId == value) return;
74
73
  _userId = value;
74
+
75
75
  Log($"GDK UserID Updated: {_userId}");
76
- dispatcher.Dispatch(Event.GDK_USER_ID_UPDATED, _userId);
76
+ if (_onUserIdChange != null) _onUserIdChange(_userId);
77
+
77
78
  _dirty = true;
78
79
  if (isReady) SendMapUserId();
79
80
  }
@@ -159,11 +160,7 @@ namespace Amanotes.Core
159
160
  get => _amaDeviceId;
160
161
  set
161
162
  {
162
- var pattern = ALPHANUMERIC_HYPHEN_PATTERN;
163
- #if UNITY_ANDROID && !UNITY_EDITOR_OSX
164
- pattern = ALPHANUMERIC_PATTERN;
165
- #endif
166
- if (!ValidateId(value, pattern))
163
+ if (!ValidateId(value, ALPHANUMERIC_OPTIONAL_HYPHEN_PATTERN))
167
164
  {
168
165
  LogError($"[UserProfile] Wrong format for AmaDeviceId. Value: {value}");
169
166
  return;
@@ -301,6 +298,7 @@ namespace Amanotes.Core
301
298
  [SerializeField]
302
299
  private string _country;
303
300
 
301
+ private const string ALPHANUMERIC_OPTIONAL_HYPHEN_PATTERN = @"^(?=.*\d)(?=.*[a-zA-Z])[a-zA-Z\d-]+$";
304
302
  private const string ALPHANUMERIC_HYPHEN_PATTERN = @"^(?=.*\d)(?=.*[a-zA-Z])(?=.*-).+$";
305
303
  private const string ALPHANUMERIC_PATTERN = @"^(?=.*\d)(?=.*[a-zA-Z])[a-zA-Z\d]+$";
306
304
  private const string NUMERIC_HYPHEN_PATTERN = @"^(?=.*\d)(?=.*-)[\d-]+$";
@@ -349,9 +347,19 @@ namespace Amanotes.Core
349
347
  switch (Application.platform)
350
348
  {
351
349
  case RuntimePlatform.IPhonePlayer:
350
+ if (!ValidateId(id, ALPHANUMERIC_HYPHEN_PATTERN))
351
+ {
352
+ LogWarning($"[UserProfile] Wrong format for IDFA. Value: {id}");
353
+ return;
354
+ }
352
355
  IDFA = id;
353
356
  break;
354
357
  case RuntimePlatform.Android:
358
+ if (!ValidateId(id, ALPHANUMERIC_HYPHEN_PATTERN))
359
+ {
360
+ LogWarning($"[UserProfile] Wrong format for GAId. Value: {id}");
361
+ return;
362
+ }
355
363
  GAId = id;
356
364
  break;
357
365
  }
package/Runtime/AmaGDK.cs CHANGED
@@ -24,7 +24,7 @@ namespace Amanotes.Core
24
24
  {
25
25
  public partial class AmaGDK : MonoBehaviour
26
26
  {
27
- public const string VERSION = "0.2.75";
27
+ public const string VERSION = "0.2.77";
28
28
 
29
29
  internal static Status _status = Status.None;
30
30
  private static ConfigAsset _config = null;
@@ -44,33 +44,46 @@ namespace Amanotes.Core
44
44
 
45
45
  internal static partial class Event
46
46
  {
47
- public const string GDK_HOOK_START = nameof(GDK_HOOK_START);
48
- public const string GDK_HOOK_END = nameof(GDK_HOOK_END);
49
-
50
- public const string GDK_INIT = nameof(GDK_INIT);
51
- public const string GDK_READY = nameof(GDK_READY);
52
- public const string ADAPTER_READY = nameof(ADAPTER_READY);
47
+ // public const string GDK_HOOK_START = nameof(GDK_HOOK_START);
48
+ // public const string GDK_HOOK_END = nameof(GDK_HOOK_END);
49
+ // public const string GDK_INIT = nameof(GDK_INIT);
50
+ // public const string GDK_READY = nameof(GDK_READY);
51
+ // public const string ADAPTER_READY = nameof(ADAPTER_READY);
53
52
  }
54
53
 
54
+ /// <summary>
55
+ /// Gets the ConfigAsset for the AmaGDK.
56
+ /// If the config hasn't been loaded yet, it loads the AmaGDKConfig from Resources.
57
+ /// In the Unity Editor's Play mode, it creates an instance of the config to avoid modifying the original asset.
58
+ /// In all other cases, it uses the loaded config directly.
59
+ /// </summary>
55
60
  public static ConfigAsset Config
56
61
  {
57
62
  get
58
63
  {
59
64
  if (_config != null) return _config;
60
- _config = Resources.Load<ConfigAsset>("AmaGDKConfig");
61
- GDKDebug.logLevel = _config.common.logLevel;
65
+ var config = Resources.Load<ConfigAsset>("AmaGDKConfig");
66
+ #if UNITY_EDITOR
67
+ if (EditorApplication.isPlayingOrWillChangePlaymode)
68
+ {
69
+ _config = Instantiate(config);
70
+ return _config;
71
+ }
72
+ #endif
73
+ _config = config;
62
74
  return _config;
63
75
  }
64
76
  }
65
77
 
66
78
  IEnumerator InitHook()
67
79
  {
68
- dispatcher.Dispatch(Event.GDK_HOOK_START);
80
+ // dispatcher.Dispatch(Event.GDK_HOOK_START);
81
+ if (_onHookStart!= null) GDKUtils.SafeInvokeAndClear(ref _onHookStart);
69
82
  int nHooks = Hook.hooks.Count;
70
83
  if (nHooks == 0)
71
84
  {
72
85
  Log($"[Hook] No hook registered!");
73
- dispatcher.Dispatch(Event.GDK_HOOK_END);
86
+ if (_onHookEnd!= null) GDKUtils.SafeInvokeAndClear(ref _onHookEnd);
74
87
  yield break;
75
88
  }
76
89
 
@@ -85,7 +98,7 @@ namespace Amanotes.Core
85
98
  yield return new WaitUntil(() => hookCompleted);
86
99
  float elapsed = Time.realtimeSinceStartup - stTime;
87
100
  Log($"[Hook] {nHooks} hooks complete after {elapsed} secs");
88
- dispatcher.Dispatch(Event.GDK_HOOK_END);
101
+ if (_onHookEnd!= null) GDKUtils.SafeInvokeAndClear(ref _onHookEnd);
89
102
  }
90
103
 
91
104
  IEnumerator WaitForManualInit()
@@ -169,7 +182,8 @@ namespace Amanotes.Core
169
182
  Log($"{adapter.adapterId} init took: {(endTime-beginTime):#0.00} s");
170
183
  }
171
184
  }
172
- dispatcher.Dispatch(Event.ADAPTER_READY, adapter.adapterId);
185
+
186
+ GDKUtils.SafeInvoke(_onAdapterReady, adapter.adapterId);
173
187
  sb.AppendLine($"[{(adapter.IsReady ? " OK " : "FAIL")}] {adapter.adapterId} (~ {Time.realtimeSinceStartup - startTime:#0.00}s)");
174
188
 
175
189
  // Wait for postprocessing of each adapter
@@ -200,8 +214,9 @@ namespace Amanotes.Core
200
214
  sb.Append($"- InitHook() took (~ {hookTime:#0.00}s)\n\n");
201
215
 
202
216
  _status = Status.Initialize;
203
- dispatcher.Dispatch(Event.GDK_INIT);
204
- yield return WaitForManualInit();
217
+ GDKUtils.SafeInvokeAndClear(ref _onGDKInit);
218
+
219
+ if (!_allowInit) yield return WaitForManualInit();
205
220
  yield return InitAdapters(sb);
206
221
 
207
222
  StartModules();
@@ -215,14 +230,17 @@ namespace Amanotes.Core
215
230
  ForceQuit.Init();
216
231
 
217
232
  _status = Status.Ready;
218
- dispatcher.Dispatch(Event.GDK_READY);
233
+ GDKUtils.SafeInvokeAndClear(ref _onGDKReady);
219
234
 
220
- var initDuration = Time.realtimeSinceStartup - startTime;
235
+ float initDuration = Time.realtimeSinceStartup - startTime;
221
236
  LogEvent_GDKInit(Mathf.RoundToInt(initDuration));
222
237
 
223
238
  sb.Append($"\nMapping UserId: {User.UserId}\n");
224
239
  ForceLog($"v{VERSION} | {READY} in {initDuration:#0.00}s\n\n{sb}");
225
240
  GDKPool.Return(sb);
241
+
242
+ // also clear callbacks
243
+ _onAdapterReady = null;
226
244
  }
227
245
 
228
246
  private void ConfigGeoLocation()
@@ -247,12 +265,21 @@ namespace Amanotes.Core
247
265
 
248
266
  private static void LogEvent_GDKInit(int initDuration)
249
267
  {
268
+ var BToMB = 1.0 / (1024 * 1024);
269
+ var reservedMemory = Math.Round(Profiler.GetTotalReservedMemoryLong() * BToMB, 2); // in MB
270
+ var allocatedMemory = Math.Round(Profiler.GetTotalAllocatedMemoryLong() * BToMB, 2); // in MB
271
+ var unusedReservedMemory = Math.Round(Profiler.GetTotalUnusedReservedMemoryLong() * BToMB, 2); // in MB
272
+
250
273
  var _dicKey = new Dictionary<string, object>
251
274
  {
252
275
  ["gdk_version"] = VERSION,
253
276
  ["session"] = User.Session,
254
277
  ["gdk_init_duration"] = initDuration,
255
- ["user_id"] = User.UserId
278
+ ["user_id"] = User.UserId,
279
+ ["device_spec"] = Device.GetDeviceSpec().ToString(),
280
+ ["reserved_memory"] = reservedMemory,
281
+ ["allocated_memory"] = allocatedMemory,
282
+ ["unused_memory"] = unusedReservedMemory
256
283
  };
257
284
 
258
285
  void AppendServiceKey(string adapterId, string paramName)
@@ -276,8 +303,8 @@ namespace Amanotes.Core
276
303
 
277
304
  public static LogLevel logLevel
278
305
  {
279
- get => _config == null ? Config.common.logLevel : GDKDebug.logLevel;
280
- set => GDKDebug.logLevel = value;
306
+ get => Config.common.logLevel;
307
+ set => Config.common.logLevel = value;
281
308
  }
282
309
 
283
310
  public static void Init(Action onReady = null)
@@ -285,13 +312,14 @@ namespace Amanotes.Core
285
312
  if (isReady)
286
313
  {
287
314
  LogWarning(SDK_INIT_CALLED);
288
- onReady?.Invoke();
315
+ if (onReady != null) onReady();
289
316
  return;
290
317
  }
291
318
 
292
319
  if (onReady != null)
293
320
  {
294
- dispatcher.AddListener(Event.GDK_READY, onReady, true);
321
+ _onGDKReady -= onReady;
322
+ _onGDKReady += onReady;
295
323
  }
296
324
 
297
325
  if (_allowInit)
@@ -307,6 +335,12 @@ namespace Amanotes.Core
307
335
  _instance = sdk.AddComponent<AmaGDK>();
308
336
  }
309
337
 
338
+ private static Action _onGDKInit;
339
+ private static Action _onGDKReady;
340
+ internal static Action _onHookStart;
341
+ internal static Action _onHookEnd;
342
+ private static Action<string> _onAdapterReady;
343
+
310
344
  /// <summary>
311
345
  /// Will be triggered right after all the cached data being loaded
312
346
  /// And before any Adapter has been called to Init
@@ -314,13 +348,15 @@ namespace Amanotes.Core
314
348
  /// <param name="onInit"></param>
315
349
  public static void SetCallback_OnGDKInit(Action onInit)
316
350
  {
351
+ if (onInit == null) return;
317
352
  if (isInitted)
318
353
  {
319
- onInit.Invoke();
354
+ onInit();
320
355
  return;
321
356
  }
322
-
323
- dispatcher.AddListener(Event.GDK_INIT, onInit, true);
357
+
358
+ _onGDKInit += onInit;
359
+ _onGDKInit -= onInit;
324
360
  }
325
361
 
326
362
  /// <summary>
@@ -329,30 +365,30 @@ namespace Amanotes.Core
329
365
  /// <param name="onReady"></param>
330
366
  public static void SetCallback_OnGDKReady(Action onReady)
331
367
  {
368
+ if (onReady == null) return;
369
+
332
370
  if (isReady)
333
371
  {
334
- onReady.Invoke();
372
+ onReady();
335
373
  return;
336
374
  }
337
375
 
338
- dispatcher.AddListener(Event.GDK_READY, onReady, true);
376
+ _onGDKReady -= onReady;
377
+ _onGDKReady += onReady;
339
378
  }
340
379
 
341
- public static void SetAdapterReadyCallback(Action<string> onAdapterReady)
380
+ public static void SetCallback_AdapterReady(Action<string> onReady)
342
381
  {
343
- if (onAdapterReady == null)
344
- {
345
- LogWarning("Cannot add a null callback!");
346
- return;
347
- }
348
-
349
- if (AmaGDK.isReady)
350
- {
351
- LogWarning("All adapters has been init / ready!");
352
- return;
353
- }
382
+ if (onReady == null || isReady) return;
354
383
 
355
- dispatcher.AddListener(Event.ADAPTER_READY, onAdapterReady);
384
+ _onAdapterReady -= onReady;
385
+ _onAdapterReady += onReady;
386
+ }
387
+
388
+ [Obsolete("Use SetCallback_AdapterReady instead")]
389
+ public static void SetAdapterReadyCallback(Action<string> onReady)
390
+ {
391
+ SetCallback_AdapterReady(onReady);
356
392
  }
357
393
  }
358
394
 
@@ -36,14 +36,13 @@ namespace Amanotes.Core
36
36
 
37
37
  public class GDKDebug
38
38
  {
39
- public static LogLevel logLevel;
40
39
  public static Action<string> logNonfatalErrorHook = null;
41
40
  private static readonly HashSet<string> nonFatalDict = new HashSet<string>();
42
41
  public static readonly HashSet<string> logWarningDict = new HashSet<string>();
43
42
 
44
43
  public static void LogWarningOnce(string message, string key = null)
45
44
  {
46
- if (logLevel < LogLevel.Warning) return;
45
+ if (AmaGDK.logLevel < LogLevel.Warning) return;
47
46
  if (string.IsNullOrEmpty(key)) key = message;
48
47
  if (!logWarningDict.Add(key)) return;
49
48
 
@@ -54,7 +53,7 @@ namespace Amanotes.Core
54
53
  }
55
54
  public static void LogWarning(string message)
56
55
  {
57
- if (logLevel < LogLevel.Warning) return;
56
+ if (AmaGDK.logLevel < LogLevel.Warning) return;
58
57
  using (NoStackTrace.Warning)
59
58
  {
60
59
  Debug.LogWarning($"AmaGDK {message}");
@@ -62,13 +61,21 @@ namespace Amanotes.Core
62
61
  }
63
62
  public static void LogError(string message)
64
63
  {
65
- if (logLevel < LogLevel.Error) return;
64
+ if (AmaGDK.logLevel < LogLevel.Error) return;
66
65
  using (NoStackTrace.Error)
67
66
  {
68
67
  Debug.LogError($"AmaGDK {message}");
69
68
  }
70
69
 
71
70
  if (logNonfatalErrorHook == null) return;
71
+
72
+ if (GDKUtils.isOnMainThread) // Most of the time
73
+ {
74
+ if (!nonFatalDict.Add(message)) return;
75
+ logNonfatalErrorHook(message);
76
+ return;
77
+ }
78
+
72
79
  GDKUtils.DoOnMainThread(() =>
73
80
  {
74
81
  if (!nonFatalDict.Add(message)) return; // LogOnce
@@ -78,7 +85,7 @@ namespace Amanotes.Core
78
85
 
79
86
  public static void Log(string message)
80
87
  {
81
- if (logLevel < LogLevel.Verbose) return;
88
+ if (AmaGDK.logLevel < LogLevel.Verbose) return;
82
89
  using (NoStackTrace.Log)
83
90
  {
84
91
  Debug.Log($"AmaGDK {message}");