com.amanotes.gdk 0.2.63 → 0.2.65-1
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 +25 -0
- package/Editor/AmaGDKEditor.cs +23 -7
- package/Editor/HideInNormalInspectorDrawer.cs +22 -0
- package/Editor/HideInNormalInspectorDrawer.cs.meta +3 -0
- package/Extra/AmaGDKInstaller.unitypackage +0 -0
- package/Extra/CheckDiskSpace.unitypackage +0 -0
- package/Extra/ForceUpdate.unitypackage +0 -0
- package/Extra/GoogleCMP.unitypackage +0 -0
- package/Extra/GoogleCMP.unitypackage.meta +7 -0
- package/Extra/PostProcessor.unitypackage +0 -0
- package/Extra/SDKVersionTracking.unitypackage +0 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/AmaGDKExample.unitypackage +0 -0
- package/Packages/AmaGDKTest.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage.meta +7 -0
- package/Packages/AppsFlyerAdapter.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
- package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
- package/Packages/IronSourceAdapter.unitypackage +0 -0
- package/Packages/RevenueCatAdapter.unitypackage +0 -0
- package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
- package/Runtime/AmaGDK.Adapters.cs +14 -3
- package/Runtime/AmaGDK.Ads.cs +29 -2
- package/Runtime/AmaGDK.Analytics.cs +9 -20
- package/Runtime/AmaGDK.Mono.cs +111 -0
- package/Runtime/AmaGDK.Mono.cs.meta +3 -0
- package/Runtime/AmaGDK.RemoteConfig.cs +3 -0
- package/Runtime/AmaGDK.Singleton.cs +27 -0
- package/Runtime/AmaGDK.Singleton.cs.meta +3 -0
- package/Runtime/AmaGDK.UserProfile.cs +119 -40
- package/Runtime/AmaGDK.cs +38 -59
- package/Runtime/Core/GDKRoutine.cs +61 -0
- package/Runtime/Core/GDKRoutine.cs.meta +3 -0
- package/Runtime/Core/GDKUnityCallback.cs +141 -0
- package/Runtime/Core/GDKUnityCallback.cs.meta +3 -0
- package/Runtime/Core.meta +8 -0
- package/Runtime/Internal/AmaGDK.Internal.AmaGUI.cs +19 -2
- package/Runtime/Internal/AmaGDK.Internal.cs +4 -8
- package/Runtime/Internal/AmaGDK.Utils.cs +3 -56
- package/Runtime/Internal/HideInNormalInspectorAttribute.cs +9 -0
- package/Runtime/Internal/HideInNormalInspectorAttribute.cs.meta +3 -0
- package/Runtime/Klavar/Attributes/AccumulatedCountAttribute.cs +0 -1
- package/Runtime/Klavar/Attributes/MinMaxAttribute.cs +86 -79
- package/Runtime/Klavar/Attributes/MinMaxLengthAttribute.cs +47 -26
- package/Runtime/Klavar/Attributes/NotNullAttribute.cs +1 -1
- package/Runtime/Klavar/Attributes/RegexPatternAttribute.cs +10 -7
- package/Runtime/Klavar/Attributes/ToStringAttribute.cs +1 -1
- package/Runtime/Klavar/KlavarContainer.cs +21 -5
- package/Runtime/Klavar/KlavarEvent.cs +4 -1
- package/Runtime/Utils/GDKUtils.cs +35 -0
- package/Runtime/Utils/GDKUtils.cs.meta +3 -0
- package/Runtime/Utils.meta +8 -0
- package/package.json +1 -1
|
@@ -72,83 +72,152 @@ namespace Amanotes.Core
|
|
|
72
72
|
_userId = value;
|
|
73
73
|
Logging.Log($"GDK UserID Updated: {_userId}");
|
|
74
74
|
dispatcher.Dispatch(Event.GDK_USER_ID_UPDATED, _userId);
|
|
75
|
-
|
|
75
|
+
_dirty = true;
|
|
76
|
+
if (isReady) SendMapUserId();
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
public string GAId
|
|
80
81
|
{
|
|
81
82
|
get => _gaid;
|
|
82
|
-
set
|
|
83
|
+
set
|
|
84
|
+
{
|
|
85
|
+
if (!ValidateId(value, ALPHANUMERIC_HYPHEN_PATTERN))
|
|
86
|
+
{
|
|
87
|
+
Logging.LogError($"[UserProfile] Wrong format for GAId. Value: {value}");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
_gaid = value;
|
|
91
|
+
UpdateUserId();
|
|
92
|
+
}
|
|
83
93
|
}
|
|
84
94
|
|
|
85
95
|
public string IDFA
|
|
86
96
|
{
|
|
87
97
|
get => _idfa;
|
|
88
|
-
set
|
|
98
|
+
set
|
|
99
|
+
{
|
|
100
|
+
if (!ValidateId(value, ALPHANUMERIC_HYPHEN_PATTERN))
|
|
101
|
+
{
|
|
102
|
+
Logging.LogError($"[UserProfile] Wrong format for IDFA. Value: {value}");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
_idfa = value;
|
|
106
|
+
UpdateUserId();
|
|
107
|
+
}
|
|
89
108
|
}
|
|
90
|
-
|
|
109
|
+
|
|
91
110
|
public string IDFV
|
|
92
111
|
{
|
|
93
112
|
get => _idfv;
|
|
94
|
-
set
|
|
113
|
+
set
|
|
114
|
+
{
|
|
115
|
+
if (!ValidateId(value, ALPHANUMERIC_HYPHEN_PATTERN))
|
|
116
|
+
{
|
|
117
|
+
Logging.LogError($"[UserProfile] Wrong format for IDFV. Value: {value}");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
_idfv = value;
|
|
121
|
+
UpdateUserId();
|
|
122
|
+
}
|
|
95
123
|
}
|
|
96
|
-
|
|
124
|
+
|
|
97
125
|
public string AndroidId
|
|
98
126
|
{
|
|
99
127
|
get => _androidId;
|
|
100
|
-
set
|
|
128
|
+
set
|
|
129
|
+
{
|
|
130
|
+
if (!ValidateId(value, ALPHANUMERIC_PATTERN))
|
|
131
|
+
{
|
|
132
|
+
Logging.LogError($"[UserProfile] Wrong format for AndroidId. Value: {value}");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
_androidId = value;
|
|
136
|
+
UpdateUserId();
|
|
137
|
+
}
|
|
101
138
|
}
|
|
102
|
-
|
|
139
|
+
|
|
103
140
|
public string PseudoId
|
|
104
141
|
{
|
|
105
142
|
get => _pseudoId;
|
|
106
|
-
set
|
|
143
|
+
set
|
|
144
|
+
{
|
|
145
|
+
if (!ValidateId(value, ALPHANUMERIC_PATTERN))
|
|
146
|
+
{
|
|
147
|
+
Logging.LogError($"[UserProfile] Wrong format for PseudoId. Value: {value}");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
_pseudoId = value;
|
|
151
|
+
UpdateUserId();
|
|
152
|
+
}
|
|
107
153
|
}
|
|
108
154
|
|
|
109
|
-
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
110
155
|
public string AmaDeviceId
|
|
111
156
|
{
|
|
112
157
|
get => _amaDeviceId;
|
|
113
|
-
set
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
158
|
+
set
|
|
159
|
+
{
|
|
160
|
+
var pattern = ALPHANUMERIC_HYPHEN_PATTERN;
|
|
161
|
+
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
162
|
+
pattern = ALPHANUMERIC_PATTERN;
|
|
163
|
+
#endif
|
|
164
|
+
if (!ValidateId(value, pattern))
|
|
165
|
+
{
|
|
166
|
+
Logging.LogError($"[UserProfile] Wrong format for AmaDeviceId. Value: {value}");
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
_amaDeviceId = value;
|
|
170
|
+
UpdateUserId();
|
|
171
|
+
}
|
|
120
172
|
}
|
|
121
|
-
|
|
173
|
+
|
|
122
174
|
|
|
123
175
|
public string AppsFlyerId
|
|
124
176
|
{
|
|
125
177
|
get => _appsFlyerId;
|
|
126
|
-
set
|
|
178
|
+
set
|
|
179
|
+
{
|
|
180
|
+
if (!Application.isEditor && !ValidateId(value, NUMERIC_HYPHEN_PATTERN))
|
|
181
|
+
{
|
|
182
|
+
Logging.LogError($"[UserProfile] Wrong format for AppsFlyerId. Value: {value}");
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
_appsFlyerId = value;
|
|
186
|
+
UpdateUserId();
|
|
187
|
+
}
|
|
127
188
|
}
|
|
128
|
-
|
|
189
|
+
|
|
129
190
|
public string InstallationId
|
|
130
191
|
{
|
|
131
192
|
get => _installationId;
|
|
132
|
-
set
|
|
193
|
+
set
|
|
194
|
+
{
|
|
195
|
+
if (!ValidateId(value, ALPHANUMERIC_PATTERN))
|
|
196
|
+
{
|
|
197
|
+
Logging.LogError($"[UserProfile] Wrong format for InstallationId. Value: {value}");
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
_installationId = value;
|
|
201
|
+
UpdateUserId();
|
|
202
|
+
}
|
|
133
203
|
}
|
|
134
204
|
|
|
135
|
-
public int Session
|
|
136
|
-
{
|
|
137
|
-
get => _session;
|
|
138
|
-
}
|
|
205
|
+
public int Session => _session;
|
|
139
206
|
|
|
140
207
|
public string Country
|
|
141
208
|
{
|
|
142
209
|
get => _country;
|
|
143
210
|
set
|
|
144
211
|
{
|
|
145
|
-
|
|
146
|
-
|
|
212
|
+
if (!ValidateId(value, COUNTRY_CODE_PATTERN)) return;
|
|
213
|
+
_country = value;
|
|
214
|
+
_dirty = true;
|
|
147
215
|
}
|
|
148
216
|
}
|
|
149
217
|
|
|
150
|
-
|
|
218
|
+
private void UpdateUserId()
|
|
151
219
|
{
|
|
220
|
+
_dirty = true;
|
|
152
221
|
#if UNITY_ANDROID
|
|
153
222
|
if (!string.IsNullOrWhiteSpace(_gaid))
|
|
154
223
|
{
|
|
@@ -241,14 +310,14 @@ namespace Amanotes.Core
|
|
|
241
310
|
{
|
|
242
311
|
User.LoadJsonFromFile();
|
|
243
312
|
|
|
244
|
-
#if UNITY_ANDROID
|
|
313
|
+
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
245
314
|
AndroidId = SystemInfo.deviceUniqueIdentifier;
|
|
246
315
|
#elif UNITY_IOS
|
|
247
316
|
IDFV = SystemInfo.deviceUniqueIdentifier;
|
|
248
317
|
#endif
|
|
249
318
|
GetAmaDeviceId();
|
|
250
319
|
UpdateUserId();
|
|
251
|
-
_session
|
|
320
|
+
_session += 1;
|
|
252
321
|
_dirty = true;
|
|
253
322
|
}
|
|
254
323
|
|
|
@@ -257,8 +326,20 @@ namespace Amanotes.Core
|
|
|
257
326
|
// Always get the latest advertising id
|
|
258
327
|
GetAdvertisingId();
|
|
259
328
|
Logging.Log($"[UserProfile] user_id: {_userId}");
|
|
260
|
-
|
|
261
|
-
|
|
329
|
+
GDKUtils.OnFrameUpdate(SaveIfDirty);
|
|
330
|
+
|
|
331
|
+
var adsId = Application.platform == RuntimePlatform.Android ? GAId : IDFA;
|
|
332
|
+
var delay = string.IsNullOrEmpty(AppsFlyerId)
|
|
333
|
+
|| string.IsNullOrEmpty(adsId)
|
|
334
|
+
|| string.IsNullOrEmpty(PseudoId);
|
|
335
|
+
|
|
336
|
+
GDKUtils.DelayCall(delay ? 1 : 0, SendMapUserId);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private void SendMapUserId()
|
|
340
|
+
{
|
|
341
|
+
Analytics.LogEvent("map_user_id", AmaGDK.User.CollectAllUserIds())
|
|
342
|
+
.OnlyTo(AmaGDK.AdapterID.FIREBASE_ANALYTICS);
|
|
262
343
|
}
|
|
263
344
|
|
|
264
345
|
private void SetAdvertisingID(string id)
|
|
@@ -280,8 +361,7 @@ namespace Amanotes.Core
|
|
|
280
361
|
{
|
|
281
362
|
GDKUtils.DelayCall(0, () =>
|
|
282
363
|
{
|
|
283
|
-
SetAdvertisingID(advertisingId);
|
|
284
|
-
Save();
|
|
364
|
+
SetAdvertisingID(advertisingId);
|
|
285
365
|
});
|
|
286
366
|
});
|
|
287
367
|
}
|
|
@@ -292,7 +372,7 @@ namespace Amanotes.Core
|
|
|
292
372
|
switch (Application.platform)
|
|
293
373
|
{
|
|
294
374
|
case RuntimePlatform.IPhonePlayer:
|
|
295
|
-
|
|
375
|
+
var v = KeyChain.GetKeyChain(AMA_DEVICE_ID_KEY);
|
|
296
376
|
if (string.IsNullOrEmpty(v))
|
|
297
377
|
{
|
|
298
378
|
v = Guid.NewGuid().ToString();
|
|
@@ -302,7 +382,7 @@ namespace Amanotes.Core
|
|
|
302
382
|
break;
|
|
303
383
|
|
|
304
384
|
case RuntimePlatform.Android:
|
|
305
|
-
|
|
385
|
+
var cachedAmaDeviceId = PlayerPrefs.GetString(AMA_DEVICE_ID_KEY);
|
|
306
386
|
if (string.IsNullOrEmpty(cachedAmaDeviceId))
|
|
307
387
|
{
|
|
308
388
|
cachedAmaDeviceId = SystemInfo.deviceUniqueIdentifier;
|
|
@@ -318,11 +398,10 @@ namespace Amanotes.Core
|
|
|
318
398
|
Save();
|
|
319
399
|
}
|
|
320
400
|
|
|
321
|
-
private
|
|
401
|
+
private bool ValidateId (string id, string pattern)
|
|
322
402
|
{
|
|
323
|
-
if (string.IsNullOrWhiteSpace(id)) return
|
|
324
|
-
|
|
325
|
-
return id;
|
|
403
|
+
if (string.IsNullOrWhiteSpace(id)) return false;
|
|
404
|
+
return Regex.IsMatch(id, pattern);
|
|
326
405
|
}
|
|
327
406
|
}
|
|
328
407
|
}
|
package/Runtime/AmaGDK.cs
CHANGED
|
@@ -17,17 +17,16 @@ namespace Amanotes.Core
|
|
|
17
17
|
{
|
|
18
18
|
public partial class AmaGDK : MonoBehaviour
|
|
19
19
|
{
|
|
20
|
-
public const string VERSION = "0.2.
|
|
21
|
-
|
|
22
|
-
internal static AmaGDK _instance;
|
|
23
|
-
internal static bool _allowInit = false;
|
|
20
|
+
public const string VERSION = "0.2.66";
|
|
21
|
+
|
|
24
22
|
internal static Status _status = Status.None;
|
|
25
23
|
private static ConfigAsset _config = null;
|
|
26
24
|
internal static readonly GDKGeoLocation GeoLocation = new GDKGeoLocation();
|
|
27
25
|
internal static readonly GDKServerTime ServerTime = new GDKServerTime();
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
internal static bool _allowInit = false;
|
|
30
28
|
public bool autoInit = true;
|
|
29
|
+
|
|
31
30
|
internal static partial class Event
|
|
32
31
|
{
|
|
33
32
|
public const string GDK_HOOK_START = nameof(GDK_HOOK_START);
|
|
@@ -48,26 +47,6 @@ namespace Amanotes.Core
|
|
|
48
47
|
return _config;
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
private void Awake()
|
|
53
|
-
{
|
|
54
|
-
if (_instance != null)
|
|
55
|
-
{
|
|
56
|
-
if (_instance != this)
|
|
57
|
-
{
|
|
58
|
-
LogWarning(MULTIPLE_INSTANCE);
|
|
59
|
-
Destroy(this);
|
|
60
|
-
}
|
|
61
|
-
LogWarning("Should never be here!");
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
_instance = this;
|
|
66
|
-
DontDestroyOnLoad(this);
|
|
67
|
-
|
|
68
|
-
_allowInit = _allowInit || autoInit;
|
|
69
|
-
StartCoroutine(InitRoutine());
|
|
70
|
-
}
|
|
71
50
|
|
|
72
51
|
IEnumerator InitHook()
|
|
73
52
|
{
|
|
@@ -174,21 +153,24 @@ namespace Amanotes.Core
|
|
|
174
153
|
|
|
175
154
|
IEnumerator InitRoutine()
|
|
176
155
|
{
|
|
156
|
+
_allowInit = _allowInit || autoInit;
|
|
157
|
+
|
|
177
158
|
if (Config == null)
|
|
178
159
|
{
|
|
179
160
|
throw new Exception("[AmaGDK] " + CONFIG_NOT_FOUND);
|
|
180
161
|
}
|
|
181
162
|
|
|
182
|
-
|
|
163
|
+
var startTime = Time.realtimeSinceStartup;
|
|
183
164
|
var sb = new StringBuilder();
|
|
184
165
|
|
|
185
166
|
InitModules();
|
|
186
167
|
|
|
187
|
-
|
|
168
|
+
var moduleTime = Time.realtimeSinceStartup - startTime;
|
|
188
169
|
sb.Append($"- InitModules() took (~ {moduleTime:#0.00}s)\n");
|
|
189
170
|
|
|
190
171
|
yield return InitHook(); //Google CMP takes long at first time (~ 1.7s)
|
|
191
|
-
|
|
172
|
+
|
|
173
|
+
var hookTime = Time.realtimeSinceStartup - moduleTime - startTime;
|
|
192
174
|
sb.Append($"- InitHook() took (~ {hookTime:#0.00}s)\n\n");
|
|
193
175
|
|
|
194
176
|
_status = Status.Initialize;
|
|
@@ -206,9 +188,12 @@ namespace Amanotes.Core
|
|
|
206
188
|
|
|
207
189
|
_status = Status.Ready;
|
|
208
190
|
dispatcher.Dispatch(Event.GDK_READY);
|
|
191
|
+
|
|
192
|
+
var initDuration = Time.realtimeSinceStartup - startTime;
|
|
193
|
+
LogEvent_GDKInit(Mathf.RoundToInt(initDuration));
|
|
209
194
|
|
|
210
195
|
sb.Append($"\nMapping UserId: {User.UserId}\n");
|
|
211
|
-
Debug.Log($"AmaGDK v{VERSION} | {READY} in {
|
|
196
|
+
Debug.Log($"AmaGDK v{VERSION} | {READY} in {initDuration:#0.00}s\n\n{sb}");
|
|
212
197
|
}
|
|
213
198
|
|
|
214
199
|
private void ConfigGeoLocation()
|
|
@@ -230,6 +215,29 @@ namespace Amanotes.Core
|
|
|
230
215
|
}
|
|
231
216
|
}
|
|
232
217
|
}
|
|
218
|
+
|
|
219
|
+
private static void LogEvent_GDKInit(int initDuration)
|
|
220
|
+
{
|
|
221
|
+
var _dicKey = new Dictionary<string, object>
|
|
222
|
+
{
|
|
223
|
+
["gdk_version"] = VERSION,
|
|
224
|
+
["session"] = User.Session,
|
|
225
|
+
["gdk_init_duration"] = initDuration,
|
|
226
|
+
["user_id"] = User.UserId
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
void AppendServiceKey(string adapterId, string paramName)
|
|
230
|
+
{
|
|
231
|
+
var serviceKey = Adapter2.GetAdapterById(adapterId)?.GetServiceKey();
|
|
232
|
+
if (string.IsNullOrEmpty(serviceKey)) return;
|
|
233
|
+
_dicKey[paramName] = serviceKey;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
AppendServiceKey(AdapterID.APPSFLYER, "appsflyer_key");
|
|
237
|
+
AppendServiceKey(AdapterID.IRONSOURCE, "ironsource_key");
|
|
238
|
+
AppendServiceKey(AdapterID.REVENUECAT, "revenuecat_key");
|
|
239
|
+
Analytics.LogEvent("gdk_init", _dicKey);
|
|
240
|
+
}
|
|
233
241
|
}
|
|
234
242
|
|
|
235
243
|
public partial class AmaGDK // PUBLIC APIS
|
|
@@ -330,35 +338,6 @@ namespace Amanotes.Core
|
|
|
330
338
|
public const string REVENUECAT = "RevenueCat";
|
|
331
339
|
}
|
|
332
340
|
}
|
|
333
|
-
|
|
334
|
-
public partial class AmaGDK
|
|
335
|
-
{
|
|
336
|
-
internal static event Action onFrameUpdate;
|
|
337
|
-
internal static event Action<bool> onApplicationPause;
|
|
338
|
-
internal static event Action<bool> applicationFocus;
|
|
339
|
-
internal static event Action applicationQuit;
|
|
340
|
-
|
|
341
|
-
private void OnApplicationPause(bool pauseStatus)
|
|
342
|
-
{
|
|
343
|
-
onApplicationPause?.Invoke(pauseStatus);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
private void OnApplicationFocus(bool hasFocus)
|
|
347
|
-
{
|
|
348
|
-
applicationFocus?.Invoke(hasFocus);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
private void Update()
|
|
352
|
-
{
|
|
353
|
-
if (!isReady) return;
|
|
354
|
-
onFrameUpdate?.Invoke();
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
private void OnApplicationQuit()
|
|
358
|
-
{
|
|
359
|
-
applicationQuit?.Invoke();
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
341
|
|
|
363
342
|
public partial class AmaGDK // Switch dev mode
|
|
364
343
|
{
|
|
@@ -472,7 +451,7 @@ namespace Amanotes.Core
|
|
|
472
451
|
{
|
|
473
452
|
if (completed)
|
|
474
453
|
{
|
|
475
|
-
LogWarning("
|
|
454
|
+
LogWarning("Add happen too late: Hook completed!");
|
|
476
455
|
return;
|
|
477
456
|
}
|
|
478
457
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
namespace Amanotes.Core.Internal
|
|
5
|
+
{
|
|
6
|
+
[Flags]
|
|
7
|
+
internal enum RoutineStatus
|
|
8
|
+
{
|
|
9
|
+
None,
|
|
10
|
+
Started = 1,
|
|
11
|
+
Stopped = 2
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public class GDKRoutine
|
|
15
|
+
{
|
|
16
|
+
private RoutineStatus status;
|
|
17
|
+
private readonly IEnumerator action;
|
|
18
|
+
private Coroutine routine;
|
|
19
|
+
|
|
20
|
+
public bool isAlive => (status & RoutineStatus.Stopped) == 0;
|
|
21
|
+
|
|
22
|
+
public GDKRoutine(IEnumerator action)
|
|
23
|
+
{
|
|
24
|
+
this.action = action;
|
|
25
|
+
status = RoutineStatus.None;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public void StartRoutine()
|
|
29
|
+
{
|
|
30
|
+
if (!isAlive)
|
|
31
|
+
{
|
|
32
|
+
// StopRoutine() called before start: do nothing
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
status |= RoutineStatus.Started;
|
|
37
|
+
routine = AmaGDK._instance.StartCoroutine(action);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public void StopRoutine()
|
|
41
|
+
{
|
|
42
|
+
status |= RoutineStatus.Stopped;
|
|
43
|
+
if (routine != null) AmaGDK._instance.StopCoroutine(routine);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public static partial class GDKUtils
|
|
48
|
+
{
|
|
49
|
+
public static GDKRoutine StartCoroutine(IEnumerator action)
|
|
50
|
+
{
|
|
51
|
+
var routine = new GDKRoutine(action);
|
|
52
|
+
DoOnMainThread(routine.StartRoutine);
|
|
53
|
+
return routine;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public static void StopCoroutine(GDKRoutine gdkRoutine)
|
|
57
|
+
{
|
|
58
|
+
gdkRoutine.StopRoutine();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
|
|
3
|
+
namespace Amanotes.Core.Internal
|
|
4
|
+
{
|
|
5
|
+
public interface IOnApplicationPause { void OnApplicationPause(bool pauseStatus); }
|
|
6
|
+
public interface IOnApplicationQuit { void OnApplicationQuit(); }
|
|
7
|
+
public interface IOnApplicationFocus { void OnApplicationFocus(bool hasFocus); }
|
|
8
|
+
public interface IOnFrameUpdate { void OnFrameUpdate(); }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
namespace Amanotes.Core.Internal
|
|
12
|
+
{
|
|
13
|
+
public class GDKUnityCallback
|
|
14
|
+
{
|
|
15
|
+
public Action<bool> OnApplicationPause;
|
|
16
|
+
public Action<bool> OnApplicationFocus;
|
|
17
|
+
public Action OnApplicationQuit;
|
|
18
|
+
public Action OnFrameUpdate;
|
|
19
|
+
public Action DoOnceNextFrame;
|
|
20
|
+
|
|
21
|
+
// Lock object to ensure thread-safe operations
|
|
22
|
+
private readonly object _locker = new object();
|
|
23
|
+
|
|
24
|
+
// Add Listener
|
|
25
|
+
public void AddCallback(ref Action source, Action callback)
|
|
26
|
+
{
|
|
27
|
+
if (callback == null) return;
|
|
28
|
+
lock (_locker)
|
|
29
|
+
{
|
|
30
|
+
source -= callback;
|
|
31
|
+
source += callback;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
public void AddCallback<T>(ref Action<T> source, Action<T> callback)
|
|
35
|
+
{
|
|
36
|
+
if (callback == null) return;
|
|
37
|
+
lock (_locker)
|
|
38
|
+
{
|
|
39
|
+
source -= callback;
|
|
40
|
+
source += callback;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
// Remove Listener
|
|
46
|
+
public void RemoveCallback(ref Action source, Action callback)
|
|
47
|
+
{
|
|
48
|
+
if (callback == null) return;
|
|
49
|
+
lock (_locker)
|
|
50
|
+
{
|
|
51
|
+
source -= callback;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
public void RemoveCallback<T>(ref Action<T> source, Action<T> callback)
|
|
55
|
+
{
|
|
56
|
+
if (callback == null) return;
|
|
57
|
+
lock (_locker)
|
|
58
|
+
{
|
|
59
|
+
source -= callback;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
// Invoke
|
|
65
|
+
public void Invoke(ref Action source)
|
|
66
|
+
{
|
|
67
|
+
if (source == null) return;
|
|
68
|
+
Action actionsToInvoke;
|
|
69
|
+
lock (_locker)
|
|
70
|
+
{
|
|
71
|
+
bool remove = source == DoOnceNextFrame;
|
|
72
|
+
actionsToInvoke = source;
|
|
73
|
+
if (remove) source = null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
GDKUtils.SafeInvoke(actionsToInvoke);
|
|
77
|
+
}
|
|
78
|
+
public void Invoke<T>(ref Action<T> source, T data)
|
|
79
|
+
{
|
|
80
|
+
if (source == null) return;
|
|
81
|
+
Action<T> actionsToInvoke;
|
|
82
|
+
lock (_locker)
|
|
83
|
+
{
|
|
84
|
+
actionsToInvoke = source;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
GDKUtils.SafeInvoke(actionsToInvoke, data);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
// Observer
|
|
92
|
+
public void AddObserver<T>(T observer)
|
|
93
|
+
{
|
|
94
|
+
if (observer == null) return;
|
|
95
|
+
|
|
96
|
+
if (observer is IOnFrameUpdate u)
|
|
97
|
+
{
|
|
98
|
+
AddCallback(ref OnFrameUpdate, u.OnFrameUpdate);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (observer is IOnApplicationPause p)
|
|
102
|
+
{
|
|
103
|
+
AddCallback(ref OnApplicationPause, p.OnApplicationPause);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (observer is IOnApplicationFocus f)
|
|
107
|
+
{
|
|
108
|
+
AddCallback(ref OnApplicationFocus, f.OnApplicationFocus);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (observer is IOnApplicationQuit q)
|
|
112
|
+
{
|
|
113
|
+
AddCallback(ref OnApplicationQuit, q.OnApplicationQuit);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
public void RemoveObserver<T>(T observer)
|
|
117
|
+
{
|
|
118
|
+
if (observer == null) return;
|
|
119
|
+
|
|
120
|
+
if (observer is IOnFrameUpdate u)
|
|
121
|
+
{
|
|
122
|
+
RemoveCallback(ref OnFrameUpdate, u.OnFrameUpdate);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (observer is IOnApplicationPause p)
|
|
126
|
+
{
|
|
127
|
+
RemoveCallback(ref OnApplicationPause, p.OnApplicationPause);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (observer is IOnApplicationFocus f)
|
|
131
|
+
{
|
|
132
|
+
RemoveCallback(ref OnApplicationFocus, f.OnApplicationFocus);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (observer is IOnApplicationQuit q)
|
|
136
|
+
{
|
|
137
|
+
RemoveCallback(ref OnApplicationQuit, q.OnApplicationQuit);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -149,10 +149,27 @@ namespace Amanotes.Core.Internal
|
|
|
149
149
|
return true;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
public static bool Foldout(string label, ref bool isOpen, Action drawFunc, Action titleFunc = null
|
|
152
|
+
public static bool Foldout(string label, ref bool isOpen, Action drawFunc, Action titleFunc = null)
|
|
153
|
+
{
|
|
154
|
+
return Foldout(label, null, ref isOpen, drawFunc, titleFunc);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public static bool Foldout(string label, Texture icon, ref bool isOpen, Action drawFunc, Action titleFunc = null)
|
|
153
158
|
{
|
|
154
159
|
GUILayout.BeginHorizontal();
|
|
155
|
-
|
|
160
|
+
float labelWidth = EditorGUIUtility.labelWidth;
|
|
161
|
+
|
|
162
|
+
var content = new GUIContent(label, icon);
|
|
163
|
+
float w = EditorStyles.foldoutHeader.CalcSize(content).x;
|
|
164
|
+
EditorGUIUtility.labelWidth = w;
|
|
165
|
+
|
|
166
|
+
// var c = GUI.color;
|
|
167
|
+
// GUI.color = Color.red;
|
|
168
|
+
Rect rect = GUILayoutUtility.GetRect(w, w, 18f, 18f);
|
|
169
|
+
bool newValue = EditorGUI.Foldout(rect, isOpen, content, EditorStyles.foldoutHeader);
|
|
170
|
+
EditorGUIUtility.labelWidth = labelWidth;
|
|
171
|
+
// GUI.color = c;
|
|
172
|
+
|
|
156
173
|
bool changed = newValue != isOpen;
|
|
157
174
|
titleFunc?.Invoke();
|
|
158
175
|
GUILayout.EndHorizontal();
|