diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityBindingExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityBindingExtensions.cs index 510763d..2592cd3 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityBindingExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityBindingExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using UnityEngine; using UnityEngine.UI; namespace Cysharp.Threading.Tasks @@ -40,11 +41,6 @@ namespace Cysharp.Threading.Tasks if (rebindOnError && !repeat) { repeat = true; - if (e != null) - { - await e.DisposeAsync(); - } - goto BIND_AGAIN; } else @@ -106,11 +102,6 @@ namespace Cysharp.Threading.Tasks if (rebindOnError && !repeat) { repeat = true; - if (e != null) - { - await e.DisposeAsync(); - } - goto BIND_AGAIN; } else @@ -167,11 +158,6 @@ namespace Cysharp.Threading.Tasks if (rebindOnError && !repeat) { repeat = true; - if (e != null) - { - await e.DisposeAsync(); - } - goto BIND_AGAIN; } else @@ -195,6 +181,63 @@ namespace Cysharp.Threading.Tasks } } + // -> Action + + public static void BindTo(this IUniTaskAsyncEnumerable source, TObject monoBehaviour, Action bindAction, bool rebindOnError = true) + where TObject : MonoBehaviour + { + BindToCore(source, monoBehaviour, bindAction, monoBehaviour.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + public static void BindTo(this IUniTaskAsyncEnumerable source, TObject bindTarget, Action bindAction, CancellationToken cancellationToken, bool rebindOnError = true) + { + BindToCore(source, bindTarget, bindAction, cancellationToken, rebindOnError).Forget(); + } + + static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, TObject bindTarget, Action 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(); + } + } + } + // TMP #if UNITASK_TEXTMESHPRO_SUPPORT @@ -231,11 +274,6 @@ namespace Cysharp.Threading.Tasks if (rebindOnError && !repeat) { repeat = true; - if (e != null) - { - await e.DisposeAsync(); - } - goto BIND_AGAIN; } else