-
Notifications
You must be signed in to change notification settings - Fork 11
/
Atom.UniTask.When.cs
79 lines (71 loc) · 2.64 KB
/
Atom.UniTask.When.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#if UNIMOB_UNITASK_INTEGRATION && UNIMOB_EXPERIMENTAL_UNITASK
using System;
using Cysharp.Threading.Tasks;
namespace UniMob
{
public static partial class Atom
{
public static partial class UniTask
{
/// <summary>
/// Creates an reaction that observes and runs the given predicate function
/// until it returns true. Once that happens, the returned task is completed
/// and the reaction is deactivated.<br/>
/// <br/>
/// The task will fail if the predicate throws an exception.
/// </summary>
/// <param name="lifetime">Reaction lifetime.</param>
/// <param name="data">An observed predicate function.</param>
/// <param name="debugName">Debug name for this reaction.</param>
/// <returns>UniTask that completes when the predicate returns true or predicate function throws exception.</returns>
/// <example>
///
/// var counter = Atom.Value(1);
///
/// await Atom.UniTask.When(Lifetime, () => counter.Value == 10);
/// Debug.Log("Counter value equals 10");
///
/// </example>
// ReSharper disable once MemberHidesStaticFromOuterClass
public static Cysharp.Threading.Tasks.UniTask When(
Lifetime lifetime,
Func<bool> data,
string debugName = null)
{
var disposer = lifetime.CreateNested(out var reactionLifetime);
var tcs = new UniTaskCompletionSource();
disposer.Register(() => tcs.TrySetCanceled());
Reaction(reactionLifetime, WhenInternal, debugName: debugName);
return tcs.Task;
void WhenInternal()
{
Exception exception = null;
try
{
if (!data())
{
return;
}
}
catch (Exception e)
{
exception = e;
}
using (NoWatch)
{
if (exception != null)
{
tcs.TrySetException(exception);
}
else
{
tcs.TrySetResult();
}
disposer.Dispose();
}
}
}
}
}
}
#endif