Add BindTo<TSource, TObject>(Action<TObject, TSource> bindAction)

master
neuecc 2020-05-18 02:35:13 +09:00
parent dd18c9fff8
commit 6f4d1183cc
1 changed files with 58 additions and 20 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Threading; using System.Threading;
using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
namespace Cysharp.Threading.Tasks namespace Cysharp.Threading.Tasks
@ -40,11 +41,6 @@ namespace Cysharp.Threading.Tasks
if (rebindOnError && !repeat) if (rebindOnError && !repeat)
{ {
repeat = true; repeat = true;
if (e != null)
{
await e.DisposeAsync();
}
goto BIND_AGAIN; goto BIND_AGAIN;
} }
else else
@ -106,11 +102,6 @@ namespace Cysharp.Threading.Tasks
if (rebindOnError && !repeat) if (rebindOnError && !repeat)
{ {
repeat = true; repeat = true;
if (e != null)
{
await e.DisposeAsync();
}
goto BIND_AGAIN; goto BIND_AGAIN;
} }
else else
@ -167,11 +158,6 @@ namespace Cysharp.Threading.Tasks
if (rebindOnError && !repeat) if (rebindOnError && !repeat)
{ {
repeat = true; repeat = true;
if (e != null)
{
await e.DisposeAsync();
}
goto BIND_AGAIN; goto BIND_AGAIN;
} }
else else
@ -195,6 +181,63 @@ namespace Cysharp.Threading.Tasks
} }
} }
// <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();
}
}
}
// TMP // TMP
#if UNITASK_TEXTMESHPRO_SUPPORT #if UNITASK_TEXTMESHPRO_SUPPORT
@ -231,11 +274,6 @@ namespace Cysharp.Threading.Tasks
if (rebindOnError && !repeat) if (rebindOnError && !repeat)
{ {
repeat = true; repeat = true;
if (e != null)
{
await e.DisposeAsync();
}
goto BIND_AGAIN; goto BIND_AGAIN;
} }
else else