com.backnd.database 0.0.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/Attributes/ColumnAttribute.cs +46 -0
- package/Attributes/ColumnAttribute.cs.meta +11 -0
- package/Attributes/PrimaryKeyAttribute.cs +12 -0
- package/Attributes/PrimaryKeyAttribute.cs.meta +11 -0
- package/Attributes/TableAttribute.cs +44 -0
- package/Attributes/TableAttribute.cs.meta +11 -0
- package/Attributes.meta +8 -0
- package/BACKND.Database.asmdef +14 -0
- package/BACKND.Database.asmdef.meta +7 -0
- package/BaseModel.cs +22 -0
- package/BaseModel.cs.meta +11 -0
- package/Client.cs +490 -0
- package/Client.cs.meta +11 -0
- package/Editor/BACKND.Database.Editor.asmdef +18 -0
- package/Editor/BACKND.Database.Editor.asmdef.meta +7 -0
- package/Editor/PackageAssetInstaller.cs +251 -0
- package/Editor/PackageAssetInstaller.cs.meta +11 -0
- package/Editor.meta +8 -0
- package/Exceptions/DatabaseException.cs +34 -0
- package/Exceptions/DatabaseException.cs.meta +11 -0
- package/Exceptions.meta +8 -0
- package/Internal/ExpressionAnalyzer.cs +433 -0
- package/Internal/ExpressionAnalyzer.cs.meta +11 -0
- package/Internal/QueryTypes.cs +61 -0
- package/Internal/QueryTypes.cs.meta +11 -0
- package/Internal/SqlBuilder.cs +375 -0
- package/Internal/SqlBuilder.cs.meta +11 -0
- package/Internal/ValueFormatter.cs +103 -0
- package/Internal/ValueFormatter.cs.meta +11 -0
- package/Internal.meta +8 -0
- package/Network/DatabaseExecutor.cs +171 -0
- package/Network/DatabaseExecutor.cs.meta +11 -0
- package/Network/DatabaseRequest.cs +16 -0
- package/Network/DatabaseRequest.cs.meta +11 -0
- package/Network/DatabaseResponse.cs +81 -0
- package/Network/DatabaseResponse.cs.meta +11 -0
- package/Network.meta +8 -0
- package/QueryBuilder.cs +1001 -0
- package/QueryBuilder.cs.meta +11 -0
- package/README.md +24 -0
- package/TheBackend~/Plugins/Android/Backend.aar +0 -0
- package/TheBackend~/Plugins/Backend.dll +0 -0
- package/TheBackend~/Plugins/Editor/TheBackendMultiSettingEditor.dll +0 -0
- package/TheBackend~/Plugins/Editor/TheBackendSettingEditor.dll +0 -0
- package/TheBackend~/Plugins/LitJSON.dll +0 -0
- package/TheBackend~/Plugins/Settings/TheBackendHashKeySettings.dll +0 -0
- package/TheBackend~/Plugins/Settings/TheBackendMultiSettings.dll +0 -0
- package/TheBackend~/Plugins/Settings/TheBackendSettings.dll +0 -0
- package/Tools/BTask.cs +905 -0
- package/Tools/BTask.cs.meta +11 -0
- package/Tools/DatabaseLoop.cs +110 -0
- package/Tools/DatabaseLoop.cs.meta +11 -0
- package/Tools/JsonHelper.cs +82 -0
- package/Tools/JsonHelper.cs.meta +11 -0
- package/Tools.meta +8 -0
- package/TransactionBuilder.cs +154 -0
- package/TransactionBuilder.cs.meta +11 -0
- package/TransactionQueryBuilder.cs +205 -0
- package/TransactionQueryBuilder.cs.meta +11 -0
- package/TransactionResult.cs +33 -0
- package/TransactionResult.cs.meta +11 -0
- package/package.json +20 -0
- package/package.json.meta +7 -0
package/Tools/BTask.cs
ADDED
|
@@ -0,0 +1,905 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections;
|
|
3
|
+
using System.Runtime.CompilerServices;
|
|
4
|
+
using System.Threading;
|
|
5
|
+
|
|
6
|
+
using UnityEngine;
|
|
7
|
+
using UnityEngine.Networking;
|
|
8
|
+
|
|
9
|
+
namespace BACKND.Database
|
|
10
|
+
{
|
|
11
|
+
[AsyncMethodBuilder(typeof(BTaskMethodBuilder))]
|
|
12
|
+
public class BTask : IEnumerator
|
|
13
|
+
{
|
|
14
|
+
protected bool isCompleted;
|
|
15
|
+
protected Exception exception;
|
|
16
|
+
protected Action continuation;
|
|
17
|
+
protected CancellationToken cancellationToken;
|
|
18
|
+
|
|
19
|
+
public bool IsCompleted => isCompleted;
|
|
20
|
+
public bool IsFaulted => exception != null;
|
|
21
|
+
public bool IsCanceled => cancellationToken.IsCancellationRequested;
|
|
22
|
+
|
|
23
|
+
public Exception GetException() => exception;
|
|
24
|
+
|
|
25
|
+
public BTask()
|
|
26
|
+
{
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public BTask(CancellationToken cancellationToken)
|
|
30
|
+
{
|
|
31
|
+
this.cancellationToken = cancellationToken;
|
|
32
|
+
cancellationToken.Register(OnCanceled);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected void ScheduleContinuation(Action action)
|
|
36
|
+
{
|
|
37
|
+
if (action == null)
|
|
38
|
+
{
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
#if UNITY_EDITOR
|
|
44
|
+
if (!Application.isPlaying)
|
|
45
|
+
{
|
|
46
|
+
void EditorUpdate()
|
|
47
|
+
{
|
|
48
|
+
UnityEditor.EditorApplication.update -= EditorUpdate;
|
|
49
|
+
action();
|
|
50
|
+
}
|
|
51
|
+
UnityEditor.EditorApplication.update += EditorUpdate;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
#endif
|
|
55
|
+
|
|
56
|
+
DatabaseLoop.OnLateUpdate += ExecuteAction;
|
|
57
|
+
|
|
58
|
+
void ExecuteAction()
|
|
59
|
+
{
|
|
60
|
+
DatabaseLoop.OnLateUpdate -= ExecuteAction;
|
|
61
|
+
action();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public void SetResult()
|
|
66
|
+
{
|
|
67
|
+
if (isCompleted) return;
|
|
68
|
+
|
|
69
|
+
isCompleted = true;
|
|
70
|
+
if (continuation != null)
|
|
71
|
+
{
|
|
72
|
+
ScheduleContinuation(continuation);
|
|
73
|
+
#if UNITY_EDITOR
|
|
74
|
+
if (!Application.isPlaying)
|
|
75
|
+
{
|
|
76
|
+
UnityEditor.EditorApplication.QueuePlayerLoopUpdate();
|
|
77
|
+
}
|
|
78
|
+
#endif
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public void SetException(Exception ex)
|
|
83
|
+
{
|
|
84
|
+
if (isCompleted) return;
|
|
85
|
+
|
|
86
|
+
exception = ex;
|
|
87
|
+
isCompleted = true;
|
|
88
|
+
if (continuation != null)
|
|
89
|
+
{
|
|
90
|
+
ScheduleContinuation(continuation);
|
|
91
|
+
#if UNITY_EDITOR
|
|
92
|
+
if (!Application.isPlaying)
|
|
93
|
+
{
|
|
94
|
+
UnityEditor.EditorApplication.QueuePlayerLoopUpdate();
|
|
95
|
+
}
|
|
96
|
+
#endif
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
protected virtual void OnCanceled()
|
|
101
|
+
{
|
|
102
|
+
SetException(new OperationCanceledException(cancellationToken));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public BTaskAwaiter GetAwaiter()
|
|
106
|
+
{
|
|
107
|
+
return new BTaskAwaiter(this);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
internal void OnCompleted(Action continuation)
|
|
111
|
+
{
|
|
112
|
+
this.continuation = continuation;
|
|
113
|
+
if (isCompleted)
|
|
114
|
+
{
|
|
115
|
+
ScheduleContinuation(continuation);
|
|
116
|
+
#if UNITY_EDITOR
|
|
117
|
+
if (!Application.isPlaying)
|
|
118
|
+
{
|
|
119
|
+
UnityEditor.EditorApplication.QueuePlayerLoopUpdate();
|
|
120
|
+
}
|
|
121
|
+
#endif
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public BTask ContinueWith(Action<BTask> continuation)
|
|
126
|
+
{
|
|
127
|
+
var nextTask = new BTask();
|
|
128
|
+
|
|
129
|
+
OnCompleted(() =>
|
|
130
|
+
{
|
|
131
|
+
try
|
|
132
|
+
{
|
|
133
|
+
continuation(this);
|
|
134
|
+
nextTask.SetResult();
|
|
135
|
+
}
|
|
136
|
+
catch (Exception ex)
|
|
137
|
+
{
|
|
138
|
+
nextTask.SetException(ex);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return nextTask;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public BTask<TResult> ContinueWith<TResult>(Func<BTask, TResult> continuation)
|
|
146
|
+
{
|
|
147
|
+
var nextTask = new BTask<TResult>();
|
|
148
|
+
|
|
149
|
+
OnCompleted(() =>
|
|
150
|
+
{
|
|
151
|
+
try
|
|
152
|
+
{
|
|
153
|
+
if (IsFaulted)
|
|
154
|
+
{
|
|
155
|
+
nextTask.SetException(GetException());
|
|
156
|
+
}
|
|
157
|
+
else
|
|
158
|
+
{
|
|
159
|
+
var result = continuation(this);
|
|
160
|
+
nextTask.SetResult(result);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (Exception ex)
|
|
164
|
+
{
|
|
165
|
+
nextTask.SetException(ex);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return nextTask;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public object Current => null;
|
|
173
|
+
|
|
174
|
+
public bool MoveNext()
|
|
175
|
+
{
|
|
176
|
+
return !IsCompleted;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public void Reset()
|
|
180
|
+
{
|
|
181
|
+
throw new NotSupportedException();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public static BTask Yield()
|
|
185
|
+
{
|
|
186
|
+
var task = new BTask();
|
|
187
|
+
|
|
188
|
+
#if UNITY_EDITOR
|
|
189
|
+
if (!Application.isPlaying)
|
|
190
|
+
{
|
|
191
|
+
UnityEditor.EditorApplication.delayCall += () => task.SetResult();
|
|
192
|
+
return task;
|
|
193
|
+
}
|
|
194
|
+
#endif
|
|
195
|
+
|
|
196
|
+
task.ScheduleContinuation(() => task.SetResult());
|
|
197
|
+
return task;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public static BTask NextFrame()
|
|
201
|
+
{
|
|
202
|
+
var task = new BTask();
|
|
203
|
+
var currentFrameTime = Time.realtimeSinceStartup;
|
|
204
|
+
|
|
205
|
+
#if UNITY_EDITOR
|
|
206
|
+
if (!Application.isPlaying)
|
|
207
|
+
{
|
|
208
|
+
UnityEditor.EditorApplication.delayCall += () => task.SetResult();
|
|
209
|
+
return task;
|
|
210
|
+
}
|
|
211
|
+
#endif
|
|
212
|
+
|
|
213
|
+
void CheckFrame()
|
|
214
|
+
{
|
|
215
|
+
if (Time.realtimeSinceStartup > currentFrameTime)
|
|
216
|
+
{
|
|
217
|
+
task.SetResult();
|
|
218
|
+
}
|
|
219
|
+
else
|
|
220
|
+
{
|
|
221
|
+
task.ScheduleContinuation(CheckFrame);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
task.ScheduleContinuation(CheckFrame);
|
|
226
|
+
return task;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
public static BTask Delay(float seconds)
|
|
230
|
+
{
|
|
231
|
+
var task = new BTask();
|
|
232
|
+
var targetTime = Time.realtimeSinceStartup + seconds;
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
#if UNITY_EDITOR
|
|
236
|
+
if (!Application.isPlaying)
|
|
237
|
+
{
|
|
238
|
+
void EditorUpdate()
|
|
239
|
+
{
|
|
240
|
+
if (Time.realtimeSinceStartup >= targetTime)
|
|
241
|
+
{
|
|
242
|
+
UnityEditor.EditorApplication.update -= EditorUpdate;
|
|
243
|
+
task.SetResult();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
UnityEditor.EditorApplication.update += EditorUpdate;
|
|
247
|
+
return task;
|
|
248
|
+
}
|
|
249
|
+
#endif
|
|
250
|
+
|
|
251
|
+
void CheckTime()
|
|
252
|
+
{
|
|
253
|
+
if (Time.realtimeSinceStartup >= targetTime)
|
|
254
|
+
{
|
|
255
|
+
task.SetResult();
|
|
256
|
+
}
|
|
257
|
+
else
|
|
258
|
+
{
|
|
259
|
+
task.ScheduleContinuation(CheckTime);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
task.ScheduleContinuation(CheckTime);
|
|
264
|
+
return task;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
public static BTask CompletedTask
|
|
268
|
+
{
|
|
269
|
+
get
|
|
270
|
+
{
|
|
271
|
+
var task = new BTask();
|
|
272
|
+
task.SetResult();
|
|
273
|
+
return task;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
public static BTask FromException(Exception exception)
|
|
278
|
+
{
|
|
279
|
+
var task = new BTask();
|
|
280
|
+
task.SetException(exception);
|
|
281
|
+
return task;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
public static BTask FromCanceled(CancellationToken cancellationToken)
|
|
285
|
+
{
|
|
286
|
+
var task = new BTask(cancellationToken);
|
|
287
|
+
task.SetException(new OperationCanceledException(cancellationToken));
|
|
288
|
+
return task;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
public static BTask Run(Action action)
|
|
292
|
+
{
|
|
293
|
+
var task = new BTask();
|
|
294
|
+
|
|
295
|
+
try
|
|
296
|
+
{
|
|
297
|
+
action();
|
|
298
|
+
task.SetResult();
|
|
299
|
+
}
|
|
300
|
+
catch (Exception ex)
|
|
301
|
+
{
|
|
302
|
+
task.SetException(ex);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return task;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
public static BTask<T> Run<T>(Func<T> function)
|
|
309
|
+
{
|
|
310
|
+
var task = new BTask<T>();
|
|
311
|
+
|
|
312
|
+
try
|
|
313
|
+
{
|
|
314
|
+
var result = function();
|
|
315
|
+
task.SetResult(result);
|
|
316
|
+
}
|
|
317
|
+
catch (Exception ex)
|
|
318
|
+
{
|
|
319
|
+
task.SetException(ex);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return task;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
public static BTask WhenAll(params BTask[] tasks)
|
|
326
|
+
{
|
|
327
|
+
var resultTask = new BTask();
|
|
328
|
+
|
|
329
|
+
if (tasks == null || tasks.Length == 0)
|
|
330
|
+
{
|
|
331
|
+
resultTask.SetResult();
|
|
332
|
+
return resultTask;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
var remainingCount = tasks.Length;
|
|
336
|
+
Exception firstException = null;
|
|
337
|
+
|
|
338
|
+
foreach (var task in tasks)
|
|
339
|
+
{
|
|
340
|
+
task.OnCompleted(() =>
|
|
341
|
+
{
|
|
342
|
+
if (task.IsFaulted && firstException == null)
|
|
343
|
+
{
|
|
344
|
+
firstException = task.GetException();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (Interlocked.Decrement(ref remainingCount) == 0)
|
|
348
|
+
{
|
|
349
|
+
if (firstException != null)
|
|
350
|
+
{
|
|
351
|
+
resultTask.SetException(firstException);
|
|
352
|
+
}
|
|
353
|
+
else
|
|
354
|
+
{
|
|
355
|
+
resultTask.SetResult();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return resultTask;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
public static BTask<T[]> WhenAll<T>(params BTask<T>[] tasks)
|
|
365
|
+
{
|
|
366
|
+
var resultTask = new BTask<T[]>();
|
|
367
|
+
|
|
368
|
+
if (tasks == null || tasks.Length == 0)
|
|
369
|
+
{
|
|
370
|
+
resultTask.SetResult(new T[0]);
|
|
371
|
+
return resultTask;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
var results = new T[tasks.Length];
|
|
375
|
+
var remainingCount = tasks.Length;
|
|
376
|
+
Exception firstException = null;
|
|
377
|
+
|
|
378
|
+
for (int i = 0; i < tasks.Length; i++)
|
|
379
|
+
{
|
|
380
|
+
var index = i;
|
|
381
|
+
var task = tasks[i];
|
|
382
|
+
|
|
383
|
+
task.OnCompleted(() =>
|
|
384
|
+
{
|
|
385
|
+
if (task.IsFaulted)
|
|
386
|
+
{
|
|
387
|
+
if (firstException == null)
|
|
388
|
+
{
|
|
389
|
+
firstException = task.GetException();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
else
|
|
393
|
+
{
|
|
394
|
+
results[index] = task.Result;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (Interlocked.Decrement(ref remainingCount) == 0)
|
|
398
|
+
{
|
|
399
|
+
if (firstException != null)
|
|
400
|
+
{
|
|
401
|
+
resultTask.SetException(firstException);
|
|
402
|
+
}
|
|
403
|
+
else
|
|
404
|
+
{
|
|
405
|
+
resultTask.SetResult(results);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return resultTask;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
public static BTask<BTask> WhenAny(params BTask[] tasks)
|
|
415
|
+
{
|
|
416
|
+
var resultTask = new BTask<BTask>();
|
|
417
|
+
|
|
418
|
+
if (tasks == null || tasks.Length == 0)
|
|
419
|
+
{
|
|
420
|
+
resultTask.SetException(new ArgumentException("tasks array is empty"));
|
|
421
|
+
return resultTask;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
var isCompleted = 0;
|
|
425
|
+
|
|
426
|
+
foreach (var task in tasks)
|
|
427
|
+
{
|
|
428
|
+
task.OnCompleted(() =>
|
|
429
|
+
{
|
|
430
|
+
if (Interlocked.CompareExchange(ref isCompleted, 1, 0) == 0)
|
|
431
|
+
{
|
|
432
|
+
resultTask.SetResult(task);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return resultTask;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
[AsyncMethodBuilder(typeof(BTaskMethodBuilder<>))]
|
|
443
|
+
public class BTask<T> : BTask, IEnumerator
|
|
444
|
+
{
|
|
445
|
+
private T result;
|
|
446
|
+
|
|
447
|
+
public T Result
|
|
448
|
+
{
|
|
449
|
+
get
|
|
450
|
+
{
|
|
451
|
+
if (IsFaulted)
|
|
452
|
+
throw GetException();
|
|
453
|
+
if (!IsCompleted)
|
|
454
|
+
throw new InvalidOperationException("Task not completed");
|
|
455
|
+
return result;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
public BTask() : base()
|
|
460
|
+
{
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
public BTask(CancellationToken cancellationToken) : base(cancellationToken)
|
|
464
|
+
{
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
public void SetResult(T value)
|
|
468
|
+
{
|
|
469
|
+
if (isCompleted) return;
|
|
470
|
+
|
|
471
|
+
result = value;
|
|
472
|
+
base.SetResult();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
public new BTaskAwaiter<T> GetAwaiter()
|
|
476
|
+
{
|
|
477
|
+
return new BTaskAwaiter<T>(this);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
public static BTask<T> FromResult(T result)
|
|
481
|
+
{
|
|
482
|
+
var task = new BTask<T>();
|
|
483
|
+
task.SetResult(result);
|
|
484
|
+
return task;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
public static new BTask<T> FromException(Exception exception)
|
|
488
|
+
{
|
|
489
|
+
var task = new BTask<T>();
|
|
490
|
+
task.SetException(exception);
|
|
491
|
+
return task;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
public static new BTask<T> FromCanceled(CancellationToken cancellationToken)
|
|
495
|
+
{
|
|
496
|
+
var task = new BTask<T>(cancellationToken);
|
|
497
|
+
task.SetException(new OperationCanceledException(cancellationToken));
|
|
498
|
+
return task;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
public BTask ContinueWith(Action<BTask<T>> continuation)
|
|
502
|
+
{
|
|
503
|
+
var nextTask = new BTask();
|
|
504
|
+
|
|
505
|
+
OnCompleted(() =>
|
|
506
|
+
{
|
|
507
|
+
try
|
|
508
|
+
{
|
|
509
|
+
continuation(this);
|
|
510
|
+
nextTask.SetResult();
|
|
511
|
+
}
|
|
512
|
+
catch (Exception ex)
|
|
513
|
+
{
|
|
514
|
+
nextTask.SetException(ex);
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
return nextTask;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
public BTask<TResult> ContinueWith<TResult>(Func<BTask<T>, TResult> continuation)
|
|
522
|
+
{
|
|
523
|
+
var nextTask = new BTask<TResult>();
|
|
524
|
+
|
|
525
|
+
OnCompleted(() =>
|
|
526
|
+
{
|
|
527
|
+
try
|
|
528
|
+
{
|
|
529
|
+
if (IsFaulted)
|
|
530
|
+
{
|
|
531
|
+
nextTask.SetException(GetException());
|
|
532
|
+
}
|
|
533
|
+
else
|
|
534
|
+
{
|
|
535
|
+
var result = continuation(this);
|
|
536
|
+
nextTask.SetResult(result);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
catch (Exception ex)
|
|
540
|
+
{
|
|
541
|
+
nextTask.SetException(ex);
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
return nextTask;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
public BTask<TResult> Then<TResult>(Func<T, TResult> selector)
|
|
549
|
+
{
|
|
550
|
+
var nextTask = new BTask<TResult>();
|
|
551
|
+
|
|
552
|
+
OnCompleted(() =>
|
|
553
|
+
{
|
|
554
|
+
try
|
|
555
|
+
{
|
|
556
|
+
if (IsFaulted)
|
|
557
|
+
{
|
|
558
|
+
nextTask.SetException(GetException());
|
|
559
|
+
}
|
|
560
|
+
else
|
|
561
|
+
{
|
|
562
|
+
var result = selector(this.Result);
|
|
563
|
+
nextTask.SetResult(result);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
catch (Exception ex)
|
|
567
|
+
{
|
|
568
|
+
nextTask.SetException(ex);
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
return nextTask;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
public BTask<TResult> Then<TResult>(Func<T, BTask<TResult>> selector)
|
|
576
|
+
{
|
|
577
|
+
var nextTask = new BTask<TResult>();
|
|
578
|
+
|
|
579
|
+
OnCompleted(() =>
|
|
580
|
+
{
|
|
581
|
+
try
|
|
582
|
+
{
|
|
583
|
+
if (IsFaulted)
|
|
584
|
+
{
|
|
585
|
+
nextTask.SetException(GetException());
|
|
586
|
+
}
|
|
587
|
+
else
|
|
588
|
+
{
|
|
589
|
+
var innerTask = selector(this.Result);
|
|
590
|
+
innerTask.OnCompleted(() =>
|
|
591
|
+
{
|
|
592
|
+
if (innerTask.IsFaulted)
|
|
593
|
+
{
|
|
594
|
+
nextTask.SetException(innerTask.GetException());
|
|
595
|
+
}
|
|
596
|
+
else
|
|
597
|
+
{
|
|
598
|
+
nextTask.SetResult(innerTask.Result);
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
catch (Exception ex)
|
|
604
|
+
{
|
|
605
|
+
nextTask.SetException(ex);
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
return nextTask;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
public struct BTaskAwaiter : INotifyCompletion
|
|
614
|
+
{
|
|
615
|
+
private readonly BTask task;
|
|
616
|
+
|
|
617
|
+
public BTaskAwaiter(BTask task)
|
|
618
|
+
{
|
|
619
|
+
this.task = task;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
public bool IsCompleted => task.IsCompleted;
|
|
623
|
+
|
|
624
|
+
public void GetResult()
|
|
625
|
+
{
|
|
626
|
+
if (task.IsFaulted)
|
|
627
|
+
{
|
|
628
|
+
throw task.GetException();
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
public void OnCompleted(Action continuation)
|
|
633
|
+
{
|
|
634
|
+
task.OnCompleted(continuation);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
public struct BTaskAwaiter<T> : INotifyCompletion
|
|
639
|
+
{
|
|
640
|
+
private readonly BTask<T> task;
|
|
641
|
+
|
|
642
|
+
public BTaskAwaiter(BTask<T> task)
|
|
643
|
+
{
|
|
644
|
+
this.task = task;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
public bool IsCompleted => task.IsCompleted;
|
|
648
|
+
|
|
649
|
+
public T GetResult()
|
|
650
|
+
{
|
|
651
|
+
return task.Result;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
public void OnCompleted(Action continuation)
|
|
655
|
+
{
|
|
656
|
+
task.OnCompleted(continuation);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
public class BTaskMethodBuilder
|
|
661
|
+
{
|
|
662
|
+
private BTask _task;
|
|
663
|
+
|
|
664
|
+
public static BTaskMethodBuilder Create()
|
|
665
|
+
{
|
|
666
|
+
return new BTaskMethodBuilder { _task = new BTask() };
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
|
|
670
|
+
{
|
|
671
|
+
stateMachine.MoveNext();
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
public void SetStateMachine(IAsyncStateMachine stateMachine) { }
|
|
675
|
+
|
|
676
|
+
public void SetResult()
|
|
677
|
+
{
|
|
678
|
+
_task.SetResult();
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
public void SetException(Exception exception)
|
|
682
|
+
{
|
|
683
|
+
_task.SetException(exception);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
public BTask Task => _task;
|
|
687
|
+
|
|
688
|
+
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
|
689
|
+
where TAwaiter : INotifyCompletion
|
|
690
|
+
where TStateMachine : IAsyncStateMachine
|
|
691
|
+
{
|
|
692
|
+
awaiter.OnCompleted(stateMachine.MoveNext);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
|
696
|
+
where TAwaiter : ICriticalNotifyCompletion
|
|
697
|
+
where TStateMachine : IAsyncStateMachine
|
|
698
|
+
{
|
|
699
|
+
awaiter.OnCompleted(stateMachine.MoveNext);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
public class BTaskMethodBuilder<T>
|
|
704
|
+
{
|
|
705
|
+
private BTask<T> _task;
|
|
706
|
+
|
|
707
|
+
public static BTaskMethodBuilder<T> Create()
|
|
708
|
+
{
|
|
709
|
+
return new BTaskMethodBuilder<T> { _task = new BTask<T>() };
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
|
|
713
|
+
{
|
|
714
|
+
stateMachine.MoveNext();
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
public void SetStateMachine(IAsyncStateMachine stateMachine) { }
|
|
718
|
+
|
|
719
|
+
public void SetResult(T result)
|
|
720
|
+
{
|
|
721
|
+
_task.SetResult(result);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
public void SetException(Exception exception)
|
|
725
|
+
{
|
|
726
|
+
_task.SetException(exception);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
public BTask<T> Task => _task;
|
|
730
|
+
|
|
731
|
+
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
|
732
|
+
where TAwaiter : INotifyCompletion
|
|
733
|
+
where TStateMachine : IAsyncStateMachine
|
|
734
|
+
{
|
|
735
|
+
awaiter.OnCompleted(stateMachine.MoveNext);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
|
739
|
+
where TAwaiter : ICriticalNotifyCompletion
|
|
740
|
+
where TStateMachine : IAsyncStateMachine
|
|
741
|
+
{
|
|
742
|
+
awaiter.OnCompleted(stateMachine.MoveNext);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
public static class BTaskWebRequestExtensions
|
|
747
|
+
{
|
|
748
|
+
public static BTaskWebRequest GetWebRequestAsBTask(this UnityWebRequest request)
|
|
749
|
+
{
|
|
750
|
+
return new BTaskWebRequest(request);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
public static BTaskWebRequest SendWebRequestAsBTask(this UnityWebRequest request, CancellationToken cancellationToken = default)
|
|
754
|
+
{
|
|
755
|
+
request.SendWebRequest();
|
|
756
|
+
return new BTaskWebRequest(request, cancellationToken);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
public class BTaskWebRequest : BTask<UnityWebRequest>
|
|
761
|
+
{
|
|
762
|
+
private readonly UnityWebRequest webRequest;
|
|
763
|
+
|
|
764
|
+
public BTaskWebRequest(UnityWebRequest webRequest, CancellationToken cancellationToken = default) : base(cancellationToken)
|
|
765
|
+
{
|
|
766
|
+
this.webRequest = webRequest;
|
|
767
|
+
|
|
768
|
+
if (webRequest.isDone)
|
|
769
|
+
{
|
|
770
|
+
HandleCompletion();
|
|
771
|
+
}
|
|
772
|
+
else
|
|
773
|
+
{
|
|
774
|
+
StartPolling();
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (cancellationToken != default)
|
|
778
|
+
{
|
|
779
|
+
cancellationToken.Register(() =>
|
|
780
|
+
{
|
|
781
|
+
webRequest.Abort();
|
|
782
|
+
OnCanceled();
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
private void StartPolling()
|
|
788
|
+
{
|
|
789
|
+
void CheckCompletion()
|
|
790
|
+
{
|
|
791
|
+
if (webRequest.isDone)
|
|
792
|
+
{
|
|
793
|
+
HandleCompletion();
|
|
794
|
+
}
|
|
795
|
+
else if (!IsCanceled)
|
|
796
|
+
{
|
|
797
|
+
ScheduleContinuation(CheckCompletion);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
ScheduleContinuation(CheckCompletion);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
private void HandleCompletion()
|
|
805
|
+
{
|
|
806
|
+
if (webRequest.result == UnityWebRequest.Result.Success)
|
|
807
|
+
{
|
|
808
|
+
SetResult(webRequest);
|
|
809
|
+
}
|
|
810
|
+
else
|
|
811
|
+
{
|
|
812
|
+
var error = new UnityWebRequestException(
|
|
813
|
+
webRequest.error,
|
|
814
|
+
webRequest.responseCode,
|
|
815
|
+
webRequest.result
|
|
816
|
+
);
|
|
817
|
+
SetException(error);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
public class UnityWebRequestException : Exception
|
|
823
|
+
{
|
|
824
|
+
public long ResponseCode { get; }
|
|
825
|
+
public UnityWebRequest.Result Result { get; }
|
|
826
|
+
|
|
827
|
+
public UnityWebRequestException(string message, long responseCode, UnityWebRequest.Result result)
|
|
828
|
+
: base($"WebRequest failed: {message} (Code: {responseCode}, Result: {result})")
|
|
829
|
+
{
|
|
830
|
+
ResponseCode = responseCode;
|
|
831
|
+
Result = result;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
public static class BTaskAsyncOperationExtensions
|
|
836
|
+
{
|
|
837
|
+
public static BTaskAsyncOperation ToBTask(this AsyncOperation operation)
|
|
838
|
+
{
|
|
839
|
+
return new BTaskAsyncOperation(operation);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
public class BTaskAsyncOperation : BTask<AsyncOperation>
|
|
844
|
+
{
|
|
845
|
+
private readonly AsyncOperation operation;
|
|
846
|
+
|
|
847
|
+
public BTaskAsyncOperation(AsyncOperation operation) : base()
|
|
848
|
+
{
|
|
849
|
+
this.operation = operation;
|
|
850
|
+
|
|
851
|
+
if (operation.isDone)
|
|
852
|
+
{
|
|
853
|
+
SetResult(operation);
|
|
854
|
+
}
|
|
855
|
+
else
|
|
856
|
+
{
|
|
857
|
+
operation.completed += OnCompleted;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
private void OnCompleted(AsyncOperation op)
|
|
862
|
+
{
|
|
863
|
+
SetResult(op);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
public class BTaskCompletionSource
|
|
868
|
+
{
|
|
869
|
+
private BTask _task;
|
|
870
|
+
private bool _completed = false;
|
|
871
|
+
private readonly object _lock = new object();
|
|
872
|
+
|
|
873
|
+
public BTaskCompletionSource()
|
|
874
|
+
{
|
|
875
|
+
_task = new BTask();
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
public BTask Task => _task;
|
|
879
|
+
|
|
880
|
+
public void SetResult()
|
|
881
|
+
{
|
|
882
|
+
lock (_lock)
|
|
883
|
+
{
|
|
884
|
+
if (_completed) return;
|
|
885
|
+
_completed = true;
|
|
886
|
+
_task.SetResult();
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
public void SetException(System.Exception exception)
|
|
891
|
+
{
|
|
892
|
+
lock (_lock)
|
|
893
|
+
{
|
|
894
|
+
if (_completed) return;
|
|
895
|
+
_completed = true;
|
|
896
|
+
_task.SetException(exception);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
public void SetCanceled()
|
|
901
|
+
{
|
|
902
|
+
SetException(new System.OperationCanceledException());
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|