You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
8.2 KiB
245 lines
8.2 KiB
using System; |
|
using System.Threading; |
|
using UnityEngine; |
|
#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT |
|
using UnityEngine.UI; |
|
#endif |
|
|
|
namespace Cysharp.Threading.Tasks |
|
{ |
|
public static class UnityBindingExtensions |
|
{ |
|
#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT |
|
// <string> -> Text |
|
|
|
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, UnityEngine.UI.Text text, bool rebindOnError = true) |
|
{ |
|
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); |
|
} |
|
|
|
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError = true) |
|
{ |
|
BindToCore(source, text, cancellationToken, rebindOnError).Forget(); |
|
} |
|
|
|
static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable<string> source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError) |
|
{ |
|
var repeat = false; |
|
BIND_AGAIN: |
|
var e = source.GetAsyncEnumerator(cancellationToken); |
|
try |
|
{ |
|
while (true) |
|
{ |
|
bool moveNext; |
|
try |
|
{ |
|
moveNext = await e.MoveNextAsync(); |
|
repeat = false; |
|
} |
|
catch (Exception ex) |
|
{ |
|
if (ex is OperationCanceledException) return; |
|
|
|
if (rebindOnError && !repeat) |
|
{ |
|
repeat = true; |
|
goto BIND_AGAIN; |
|
} |
|
else |
|
{ |
|
throw; |
|
} |
|
} |
|
|
|
if (!moveNext) return; |
|
|
|
text.text = e.Current; |
|
} |
|
} |
|
finally |
|
{ |
|
if (e != null) |
|
{ |
|
await e.DisposeAsync(); |
|
} |
|
} |
|
} |
|
|
|
// <T> -> Text |
|
|
|
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, UnityEngine.UI.Text text, bool rebindOnError = true) |
|
{ |
|
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); |
|
} |
|
|
|
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError = true) |
|
{ |
|
BindToCore(source, text, cancellationToken, rebindOnError).Forget(); |
|
} |
|
|
|
public static void BindTo<T>(this AsyncReactiveProperty<T> source, UnityEngine.UI.Text text, bool rebindOnError = true) |
|
{ |
|
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); |
|
} |
|
|
|
static async UniTaskVoid BindToCore<T>(IUniTaskAsyncEnumerable<T> source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError) |
|
{ |
|
var repeat = false; |
|
BIND_AGAIN: |
|
var e = source.GetAsyncEnumerator(cancellationToken); |
|
try |
|
{ |
|
while (true) |
|
{ |
|
bool moveNext; |
|
try |
|
{ |
|
moveNext = await e.MoveNextAsync(); |
|
repeat = false; |
|
} |
|
catch (Exception ex) |
|
{ |
|
if (ex is OperationCanceledException) return; |
|
|
|
if (rebindOnError && !repeat) |
|
{ |
|
repeat = true; |
|
goto BIND_AGAIN; |
|
} |
|
else |
|
{ |
|
throw; |
|
} |
|
} |
|
|
|
if (!moveNext) return; |
|
|
|
text.text = e.Current.ToString(); |
|
} |
|
} |
|
finally |
|
{ |
|
if (e != null) |
|
{ |
|
await e.DisposeAsync(); |
|
} |
|
} |
|
} |
|
|
|
// <bool> -> Selectable |
|
|
|
public static void BindTo(this IUniTaskAsyncEnumerable<bool> source, Selectable selectable, bool rebindOnError = true) |
|
{ |
|
BindToCore(source, selectable, selectable.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); |
|
} |
|
|
|
public static void BindTo(this IUniTaskAsyncEnumerable<bool> source, Selectable selectable, CancellationToken cancellationToken, bool rebindOnError = true) |
|
{ |
|
BindToCore(source, selectable, cancellationToken, rebindOnError).Forget(); |
|
} |
|
|
|
static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable<bool> source, Selectable selectable, CancellationToken cancellationToken, bool rebindOnError) |
|
{ |
|
var repeat = false; |
|
BIND_AGAIN: |
|
var e = source.GetAsyncEnumerator(cancellationToken); |
|
try |
|
{ |
|
while (true) |
|
{ |
|
bool moveNext; |
|
try |
|
{ |
|
moveNext = await e.MoveNextAsync(); |
|
repeat = false; |
|
} |
|
catch (Exception ex) |
|
{ |
|
if (ex is OperationCanceledException) return; |
|
|
|
if (rebindOnError && !repeat) |
|
{ |
|
repeat = true; |
|
goto BIND_AGAIN; |
|
} |
|
else |
|
{ |
|
throw; |
|
} |
|
} |
|
|
|
if (!moveNext) return; |
|
|
|
|
|
selectable.interactable = e.Current; |
|
} |
|
} |
|
finally |
|
{ |
|
if (e != null) |
|
{ |
|
await e.DisposeAsync(); |
|
} |
|
} |
|
} |
|
#endif |
|
|
|
// <T> -> Action |
|
|
|
public static void BindTo<TSource, TObject>(this IUniTaskAsyncEnumerable<TSource> source, TObject monoBehaviour, Action<TObject, TSource> bindAction, bool rebindOnError = true) |
|
where TObject : MonoBehaviour |
|
{ |
|
BindToCore(source, monoBehaviour, bindAction, monoBehaviour.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); |
|
} |
|
|
|
public static void BindTo<TSource, TObject>(this IUniTaskAsyncEnumerable<TSource> source, TObject bindTarget, Action<TObject, TSource> bindAction, CancellationToken cancellationToken, bool rebindOnError = true) |
|
{ |
|
BindToCore(source, bindTarget, bindAction, cancellationToken, rebindOnError).Forget(); |
|
} |
|
|
|
static async UniTaskVoid BindToCore<TSource, TObject>(IUniTaskAsyncEnumerable<TSource> source, TObject bindTarget, Action<TObject, TSource> bindAction, CancellationToken cancellationToken, bool rebindOnError) |
|
{ |
|
var repeat = false; |
|
BIND_AGAIN: |
|
var e = source.GetAsyncEnumerator(cancellationToken); |
|
try |
|
{ |
|
while (true) |
|
{ |
|
bool moveNext; |
|
try |
|
{ |
|
moveNext = await e.MoveNextAsync(); |
|
repeat = false; |
|
} |
|
catch (Exception ex) |
|
{ |
|
if (ex is OperationCanceledException) return; |
|
|
|
if (rebindOnError && !repeat) |
|
{ |
|
repeat = true; |
|
goto BIND_AGAIN; |
|
} |
|
else |
|
{ |
|
throw; |
|
} |
|
} |
|
|
|
if (!moveNext) return; |
|
|
|
bindAction(bindTarget, e.Current); |
|
} |
|
} |
|
finally |
|
{ |
|
if (e != null) |
|
{ |
|
await e.DisposeAsync(); |
|
} |
|
} |
|
} |
|
} |
|
}
|
|
|