同步
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
Yarn Spinner is licensed to you under the terms found in the file LICENSE.md.
|
||||
*/
|
||||
|
||||
// If we don't already have a directive telling us what to use...
|
||||
#if !YARNTASKS_ARE_AWAITABLES && !YARNTASKS_ARE_SYSTEMTASKS && !YARNTASKS_ARE_UNITASKS
|
||||
// ...then figure out what the best option is. We'll try to use UniTask, if
|
||||
// installed; then Awaitables, if >= Unity 2023.1; then System.Threading.Tasks.
|
||||
#if USE_UNITASK
|
||||
#define YARNTASKS_ARE_UNITASKS
|
||||
#elif UNITY_2023_1_OR_NEWER
|
||||
#define YARNTASKS_ARE_AWAITABLES
|
||||
#else
|
||||
#define YARNTASKS_ARE_SYSTEMTASKS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Yarn.Unity
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security;
|
||||
using UnityEngine;
|
||||
|
||||
#if YARNTASKS_ARE_AWAITABLES
|
||||
public partial struct YarnTaskMethodBuilder
|
||||
{
|
||||
private Awaitable.AwaitableAsyncMethodBuilder methodBuilder;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static private Awaitable.AwaitableAsyncMethodBuilder GetBuilder() => Awaitable.AwaitableAsyncMethodBuilder.Create();
|
||||
}
|
||||
public partial struct YarnTaskMethodBuilder<T>
|
||||
{
|
||||
private Awaitable.AwaitableAsyncMethodBuilder<T> methodBuilder;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static private Awaitable.AwaitableAsyncMethodBuilder<T> GetBuilder() => Awaitable.AwaitableAsyncMethodBuilder<T>.Create();
|
||||
}
|
||||
#elif YARNTASKS_ARE_UNITASKS
|
||||
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks.CompilerServices;
|
||||
|
||||
public partial struct YarnTaskMethodBuilder
|
||||
{
|
||||
private AsyncUniTaskMethodBuilder methodBuilder;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static private AsyncUniTaskMethodBuilder GetBuilder() => AsyncUniTaskMethodBuilder.Create();
|
||||
}
|
||||
public partial struct YarnTaskMethodBuilder<T>
|
||||
{
|
||||
private AsyncUniTaskMethodBuilder<T> methodBuilder;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static private AsyncUniTaskMethodBuilder<T> GetBuilder() => AsyncUniTaskMethodBuilder<T>.Create();
|
||||
}
|
||||
|
||||
#elif YARNTASKS_ARE_SYSTEMTASKS
|
||||
public partial struct YarnTaskMethodBuilder
|
||||
{
|
||||
private AsyncTaskMethodBuilder methodBuilder;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static private AsyncTaskMethodBuilder GetBuilder() => AsyncTaskMethodBuilder.Create();
|
||||
}
|
||||
public partial struct YarnTaskMethodBuilder<T>
|
||||
{
|
||||
private AsyncTaskMethodBuilder<T> methodBuilder;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static private AsyncTaskMethodBuilder<T> GetBuilder() => AsyncTaskMethodBuilder<T>.Create();
|
||||
}
|
||||
#endif
|
||||
|
||||
public partial struct YarnTaskMethodBuilder
|
||||
{
|
||||
// 1. Static Create method.
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static YarnTaskMethodBuilder Create()
|
||||
{
|
||||
YarnTaskMethodBuilder result = default;
|
||||
result.methodBuilder = GetBuilder();
|
||||
return result;
|
||||
}
|
||||
// 2. TaskLike Task property.
|
||||
public YarnTask Task
|
||||
{
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => methodBuilder.Task;
|
||||
}
|
||||
// 3. SetException
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetException(Exception exception) => methodBuilder.SetException(exception);
|
||||
|
||||
// 4. SetResult
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetResult() => methodBuilder.SetResult();
|
||||
|
||||
// 5. AwaitOnCompleted
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine => methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
|
||||
|
||||
// 6. AwaitUnsafeOnCompleted
|
||||
[DebuggerHidden]
|
||||
[SecuritySafeCritical]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine => methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
|
||||
|
||||
// 7. Start
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine => methodBuilder.Start(ref stateMachine);
|
||||
|
||||
// 8. SetStateMachine
|
||||
[DebuggerHidden]
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
methodBuilder.SetStateMachine(stateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
public partial struct YarnTaskMethodBuilder<T>
|
||||
{
|
||||
// 1. Static Create method.
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static YarnTaskMethodBuilder<T> Create()
|
||||
{
|
||||
YarnTaskMethodBuilder<T> result = default;
|
||||
result.methodBuilder = GetBuilder();
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. TaskLike Task property.
|
||||
public YarnTask<T> Task
|
||||
{
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => methodBuilder.Task;
|
||||
}
|
||||
|
||||
// 3. SetException
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
methodBuilder.SetException(exception);
|
||||
}
|
||||
|
||||
// 4. SetResult
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetResult(T result) => methodBuilder.SetResult(result);
|
||||
|
||||
// 5. AwaitOnCompleted
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine => methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
|
||||
|
||||
// 6. AwaitUnsafeOnCompleted
|
||||
[DebuggerHidden]
|
||||
[SecuritySafeCritical]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine => methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
|
||||
|
||||
// 7. Start
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine => methodBuilder.Start(ref stateMachine);
|
||||
|
||||
// 8. SetStateMachine
|
||||
[DebuggerHidden]
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
methodBuilder.SetStateMachine(stateMachine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2df1481feeab420fb74bc4ad84f343b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
Yarn Spinner is licensed to you under the terms found in the file LICENSE.md.
|
||||
*/
|
||||
|
||||
// If we don't already have a directive telling us what to use...
|
||||
#if !YARNTASKS_ARE_AWAITABLES && !YARNTASKS_ARE_SYSTEMTASKS && !YARNTASKS_ARE_UNITASKS
|
||||
// ...then figure out what the best option is. We'll try to use UniTask, if
|
||||
// installed; then Awaitables, if >= Unity 2023.1; then System.Threading.Tasks.
|
||||
#if USE_UNITASK
|
||||
#define YARNTASKS_ARE_UNITASKS
|
||||
#elif UNITY_2023_1_OR_NEWER
|
||||
#define YARNTASKS_ARE_AWAITABLES
|
||||
#else
|
||||
#define YARNTASKS_ARE_SYSTEMTASKS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if YARNTASKS_ARE_AWAITABLES
|
||||
|
||||
namespace Yarn.Unity
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
#if USE_ADDRESSABLES
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
#endif
|
||||
|
||||
public readonly partial struct YarnTask
|
||||
{
|
||||
public readonly Awaitable.Awaiter GetAwaiter() => Awaitable.GetAwaiter();
|
||||
|
||||
readonly Awaitable Awaitable;
|
||||
readonly public bool IsCompleted() => Awaitable.IsCompleted;
|
||||
readonly public bool IsCompletedSuccessfully() => Awaitable.IsCompleted;
|
||||
|
||||
// Thanks to sisus_co on the Unity Discussions forum:
|
||||
// https://discussions.unity.com/t/awaitable-equivalent-of-task-completedtask/1546128/4
|
||||
static readonly AwaitableCompletionSource completionSource = new();
|
||||
|
||||
public static YarnTask CompletedTask
|
||||
{
|
||||
get
|
||||
{
|
||||
completionSource.SetResult();
|
||||
var awaitable = completionSource.Awaitable;
|
||||
completionSource.Reset();
|
||||
return awaitable;
|
||||
}
|
||||
}
|
||||
|
||||
private YarnTask(Awaitable awaitable)
|
||||
{
|
||||
Awaitable = awaitable;
|
||||
}
|
||||
|
||||
public static implicit operator Awaitable(YarnTask demoYarnTask)
|
||||
{
|
||||
return demoYarnTask.Awaitable;
|
||||
}
|
||||
|
||||
public static implicit operator YarnTask(Awaitable awaitable)
|
||||
{
|
||||
return new YarnTask(awaitable);
|
||||
}
|
||||
|
||||
public static implicit operator YarnTask(System.Threading.Tasks.Task task)
|
||||
{
|
||||
if (task == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(task),"You are attempting to convert a null Task into a YarnTask, did you mean to use YarnTask.CompletedTask?");
|
||||
}
|
||||
async Awaitable Awaiter()
|
||||
{
|
||||
await task;
|
||||
}
|
||||
return new YarnTask(Awaiter());
|
||||
}
|
||||
|
||||
#if USE_UNITASK
|
||||
public static implicit operator YarnTask(Cysharp.Threading.Tasks.UniTask uniTask)
|
||||
{
|
||||
return new YarnTask { Awaitable = uniTask.AsAwaitable() };
|
||||
}
|
||||
#endif
|
||||
|
||||
readonly public async void Forget()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Awaitable;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static partial async YarnTask Yield()
|
||||
{
|
||||
await Awaitable.NextFrameAsync();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public async static partial YarnTask WaitUntilCanceled(System.Threading.CancellationToken token)
|
||||
{
|
||||
while (token.IsCancellationRequested == false)
|
||||
{
|
||||
await Awaitable.NextFrameAsync();
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static partial YarnTask Delay(TimeSpan timeSpan, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Awaitable.WaitForSecondsAsync((float)timeSpan.TotalSeconds, token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return YarnTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public async static partial YarnTask WaitUntil(System.Func<bool> predicate, System.Threading.CancellationToken token)
|
||||
{
|
||||
while (token.IsCancellationRequested == false && predicate() == false)
|
||||
{
|
||||
await Awaitable.NextFrameAsync(token);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static partial IEnumerator ToCoroutine(Func<YarnTask> factory)
|
||||
{
|
||||
return factory().Awaitable;
|
||||
}
|
||||
|
||||
public static partial YarnTask WhenAll(params YarnTask[] tasks)
|
||||
{
|
||||
return WhenAll((IEnumerable<YarnTask>)tasks);
|
||||
}
|
||||
public static partial async YarnTask WhenAll(IEnumerable<YarnTask> tasks)
|
||||
{
|
||||
foreach (var awaitable in tasks)
|
||||
{
|
||||
await awaitable;
|
||||
}
|
||||
}
|
||||
|
||||
public static partial YarnTask<T[]> WhenAll<T>(params YarnTask<T>[] tasks)
|
||||
{
|
||||
return WhenAll((IEnumerable<YarnTask<T>>)tasks);
|
||||
}
|
||||
public static partial async YarnTask<T[]> WhenAll<T>(IEnumerable<YarnTask<T>> tasks)
|
||||
{
|
||||
List<T> results = new List<T>(tasks is Array taskArray ? taskArray.Length : 4);
|
||||
|
||||
foreach (var awaitable in tasks)
|
||||
{
|
||||
var result = await awaitable;
|
||||
results.Add(result);
|
||||
}
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
#if USE_ADDRESSABLES
|
||||
|
||||
public static partial async YarnTask WaitForAsyncOperation(AsyncOperationHandle operationHandle, CancellationToken cancellationToken)
|
||||
{
|
||||
var tcs = new AwaitableCompletionSource();
|
||||
operationHandle.Completed += (t) =>
|
||||
{
|
||||
switch (t.Status)
|
||||
{
|
||||
case AsyncOperationStatus.Succeeded:
|
||||
tcs.TrySetResult();
|
||||
break;
|
||||
case AsyncOperationStatus.Failed:
|
||||
tcs.TrySetException(t.OperationException);
|
||||
break;
|
||||
}
|
||||
};
|
||||
await tcs.Awaitable;
|
||||
}
|
||||
|
||||
public static partial async YarnTask<T> WaitForAsyncOperation<T>(AsyncOperationHandle<T> operationHandle, CancellationToken cancellationToken)
|
||||
{
|
||||
var tcs = new AwaitableCompletionSource<T>();
|
||||
operationHandle.Completed += (t) =>
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
tcs.TrySetCanceled();
|
||||
return;
|
||||
}
|
||||
switch (t.Status)
|
||||
{
|
||||
case AsyncOperationStatus.Succeeded:
|
||||
tcs.TrySetResult(t.Result);
|
||||
break;
|
||||
case AsyncOperationStatus.Failed:
|
||||
tcs.TrySetException(t.OperationException);
|
||||
break;
|
||||
}
|
||||
};
|
||||
return await tcs.Awaitable;
|
||||
}
|
||||
#endif
|
||||
|
||||
public readonly partial async YarnTask<bool> SuppressCancellationThrow()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Awaitable;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public partial struct YarnTask<T>
|
||||
{
|
||||
public readonly Awaitable<T>.Awaiter GetAwaiter() => Awaitable.GetAwaiter();
|
||||
|
||||
Awaitable<T> Awaitable;
|
||||
readonly public bool IsCompleted() => Awaitable.GetAwaiter().IsCompleted;
|
||||
readonly public bool IsCompletedSuccessfully() => Awaitable.GetAwaiter().IsCompleted;
|
||||
|
||||
public static implicit operator Awaitable<T>(YarnTask<T> demoYarnTask)
|
||||
{
|
||||
return demoYarnTask.Awaitable;
|
||||
}
|
||||
|
||||
public static implicit operator YarnTask<T>(Awaitable<T> awaitable)
|
||||
{
|
||||
if (awaitable == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(awaitable),$"You are attempting to convert a null Awaitable<{typeof(T).Name}> into a YarnTask, did you mean to use YarnTask<{typeof(T).Name}>.FromResult(null) instead?");
|
||||
}
|
||||
return new YarnTask<T> { Awaitable = awaitable };
|
||||
}
|
||||
|
||||
#if USE_UNITASK
|
||||
public static implicit operator YarnTask<T>(Cysharp.Threading.Tasks.UniTask<T> uniTask)
|
||||
{
|
||||
return new YarnTask<T> { Awaitable = uniTask.AsAwaitable() };
|
||||
}
|
||||
#endif
|
||||
|
||||
readonly public async void Forget()
|
||||
{
|
||||
// Run the task, and if it throws an exception, log it (instead of
|
||||
// letting it disappear.)
|
||||
try
|
||||
{
|
||||
await this.Awaitable;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
public static partial YarnTask<T> FromResult(T value)
|
||||
{
|
||||
// this is based on https://discussions.unity.com/t/awaitable-fromresult/943659/7
|
||||
var nullStateMachine = new NullStateMachine();
|
||||
var builder = UnityEngine.Awaitable.AwaitableAsyncMethodBuilder<T>.Create();
|
||||
builder.Start(ref nullStateMachine);
|
||||
builder.SetResult(value);
|
||||
return builder.Task;
|
||||
}
|
||||
|
||||
private readonly struct NullStateMachine : IAsyncStateMachine
|
||||
{
|
||||
public void MoveNext() { }
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public partial class YarnTaskCompletionSource
|
||||
{
|
||||
private AwaitableCompletionSource awaitableCompletionSource = new();
|
||||
|
||||
public partial bool TrySetResult() => awaitableCompletionSource.TrySetResult();
|
||||
public partial bool TrySetException(Exception exception) => awaitableCompletionSource.TrySetException(exception);
|
||||
public partial bool TrySetCanceled() => awaitableCompletionSource.TrySetCanceled();
|
||||
|
||||
public YarnTask Task => awaitableCompletionSource.Awaitable;
|
||||
}
|
||||
|
||||
public partial class YarnTaskCompletionSource<T>
|
||||
{
|
||||
private AwaitableCompletionSource<T> awaitableCompletionSource = new();
|
||||
|
||||
public partial bool TrySetResult(T value) => awaitableCompletionSource.TrySetResult(value);
|
||||
public partial bool TrySetException(Exception exception) => awaitableCompletionSource.TrySetException(exception);
|
||||
public partial bool TrySetCanceled() => awaitableCompletionSource.TrySetCanceled();
|
||||
|
||||
public YarnTask<T> Task => awaitableCompletionSource.Awaitable;
|
||||
}
|
||||
|
||||
static class AwaitableUtility
|
||||
{
|
||||
#if USE_UNITASK
|
||||
public static async Awaitable AsAwaitable(this Cysharp.Threading.Tasks.UniTask awaitable)
|
||||
{
|
||||
await awaitable;
|
||||
}
|
||||
|
||||
public static async Awaitable<T> AsAwaitable<T>(this Cysharp.Threading.Tasks.UniTask<T> awaitable)
|
||||
{
|
||||
return await awaitable;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public static class ActionRegistrationYarnTaskExtension
|
||||
{
|
||||
// These registrations for Awaitable were generated by action-gyb.py
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler(this IActionRegistration registration, string commandName, System.Func<Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1>(this IActionRegistration registration, string commandName, System.Func<T1, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2>(this IActionRegistration registration, string commandName, System.Func<T1, T2, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, Awaitable> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6ba28eb09510491e807475acb40fee3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
284
Packages/dev.yarnspinner.unity/Runtime/YarnTask/YarnTask.Task.cs
Normal file
284
Packages/dev.yarnspinner.unity/Runtime/YarnTask/YarnTask.Task.cs
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
Yarn Spinner is licensed to you under the terms found in the file LICENSE.md.
|
||||
*/
|
||||
|
||||
// If we don't already have a directive telling us what to use...
|
||||
#if !YARNTASKS_ARE_AWAITABLES && !YARNTASKS_ARE_SYSTEMTASKS && !YARNTASKS_ARE_UNITASKS
|
||||
// ...then figure out what the best option is. We'll try to use UniTask, if
|
||||
// installed; then Awaitables, if >= Unity 2023.1; then System.Threading.Tasks.
|
||||
#if USE_UNITASK
|
||||
#define YARNTASKS_ARE_UNITASKS
|
||||
#elif UNITY_2023_1_OR_NEWER
|
||||
#define YARNTASKS_ARE_AWAITABLES
|
||||
#else
|
||||
#define YARNTASKS_ARE_SYSTEMTASKS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if YARNTASKS_ARE_SYSTEMTASKS
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
#if USE_ADDRESSABLES
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
#endif
|
||||
|
||||
namespace Yarn.Unity
|
||||
{
|
||||
|
||||
public partial struct YarnTask
|
||||
{
|
||||
public TaskAwaiter GetAwaiter() => Task.GetAwaiter();
|
||||
|
||||
Task Task;
|
||||
readonly public bool IsCompleted() => Task.IsCompleted;
|
||||
readonly public bool IsCompletedSuccessfully() => Task.IsCompletedSuccessfully;
|
||||
|
||||
public static implicit operator Task(YarnTask YarnTask)
|
||||
{
|
||||
return YarnTask.Task;
|
||||
}
|
||||
|
||||
public static implicit operator YarnTask(Task task)
|
||||
{
|
||||
return new YarnTask { Task = task };
|
||||
}
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
public static implicit operator YarnTask(Awaitable awaitable)
|
||||
{
|
||||
return new YarnTask { Task = awaitable.AsTask() };
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_UNITASK
|
||||
public static implicit operator YarnTask(Cysharp.Threading.Tasks.UniTask uniTask)
|
||||
{
|
||||
return new YarnTask { Task = Cysharp.Threading.Tasks.UniTaskExtensions.AsTask(uniTask) };
|
||||
}
|
||||
#endif
|
||||
|
||||
readonly public async void Forget()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static partial async YarnTask WaitUntilCanceled(System.Threading.CancellationToken token)
|
||||
{
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
public static YarnTask CompletedTask => Task.CompletedTask;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="YarnTask"/> that delays for the time indicated
|
||||
/// by <paramref name="timeSpan"/>, and then returns.
|
||||
/// </summary>
|
||||
/// <param name="timeSpan">The amount of time to wait.</param>
|
||||
/// <param name="token">A token that can be used to cancel the
|
||||
/// task.</param>
|
||||
/// <returns>A new <see cref="YarnTask"/>.</returns>
|
||||
public static partial YarnTask Delay(TimeSpan timeSpan, CancellationToken token)
|
||||
{
|
||||
return Task.Delay(timeSpan, token);
|
||||
}
|
||||
|
||||
public static partial async YarnTask WaitUntil(System.Func<bool> predicate, System.Threading.CancellationToken token)
|
||||
{
|
||||
while (!token.IsCancellationRequested && predicate() == false)
|
||||
{
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
public static partial IEnumerator ToCoroutine(Func<YarnTask> factory)
|
||||
{
|
||||
IEnumerator InnerCoroutine(Task t)
|
||||
{
|
||||
while (!t.IsCompleted)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
if (t.IsFaulted)
|
||||
{
|
||||
Debug.LogException(t.Exception);
|
||||
}
|
||||
}
|
||||
return InnerCoroutine(factory());
|
||||
}
|
||||
public static partial async YarnTask Yield()
|
||||
{
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
public static partial YarnTask WhenAll(params YarnTask[] tasks)
|
||||
{
|
||||
return WhenAll((IEnumerable<YarnTask>)tasks);
|
||||
}
|
||||
public static partial async YarnTask WhenAll(IEnumerable<YarnTask> tasks)
|
||||
{
|
||||
// Don't love this allocation here; try and find a better approach
|
||||
List<Task> taskList = new List<Task>();
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
taskList.Add(task);
|
||||
}
|
||||
|
||||
await Task.WhenAll(taskList.ToArray());
|
||||
|
||||
}
|
||||
|
||||
public static async partial YarnTask<T[]> WhenAll<T>(params YarnTask<T>[] tasks)
|
||||
{
|
||||
return await Task.WhenAll(Array.ConvertAll<YarnTask<T>, Task<T>>(tasks, t => t));
|
||||
}
|
||||
|
||||
public static async partial YarnTask<T[]> WhenAll<T>(IEnumerable<YarnTask<T>> tasks)
|
||||
{
|
||||
var uniTasks = new List<Task<T>>();
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
uniTasks.Add(task);
|
||||
}
|
||||
return await Task.WhenAll(uniTasks);
|
||||
|
||||
}
|
||||
|
||||
public readonly async partial YarnTask<bool> SuppressCancellationThrow()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
#if USE_ADDRESSABLES
|
||||
public static partial async YarnTask WaitForAsyncOperation(AsyncOperationHandle operationHandle, CancellationToken cancellationToken)
|
||||
{
|
||||
await operationHandle.Task;
|
||||
}
|
||||
|
||||
public static partial async YarnTask<T> WaitForAsyncOperation<T>(AsyncOperationHandle<T> operationHandle, CancellationToken cancellationToken)
|
||||
{
|
||||
return await operationHandle.Task;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
public partial struct YarnTask<T>
|
||||
{
|
||||
Task<T> Task;
|
||||
public TaskAwaiter<T> GetAwaiter() => Task.GetAwaiter();
|
||||
|
||||
readonly public bool IsCompleted() => Task.IsCompleted;
|
||||
readonly public bool IsCompletedSuccessfully() => Task.IsCompletedSuccessfully;
|
||||
|
||||
public static implicit operator Task<T>(YarnTask<T> YarnTask)
|
||||
{
|
||||
return YarnTask.Task;
|
||||
}
|
||||
|
||||
public static implicit operator YarnTask<T>(Task<T> task)
|
||||
{
|
||||
return new YarnTask<T> { Task = task };
|
||||
}
|
||||
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
public static implicit operator YarnTask<T>(Awaitable<T> awaitable)
|
||||
{
|
||||
return new YarnTask<T> { Task = awaitable.AsTask() };
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_UNITASK
|
||||
public static implicit operator YarnTask<T>(Cysharp.Threading.Tasks.UniTask<T> uniTask)
|
||||
{
|
||||
return new YarnTask<T> { Task = Cysharp.Threading.Tasks.UniTaskExtensions.AsTask(uniTask) };
|
||||
}
|
||||
#endif
|
||||
|
||||
public static partial YarnTask<T> FromResult(T value)
|
||||
{
|
||||
return Task<T>.FromResult(value);
|
||||
}
|
||||
|
||||
readonly public void Forget() { }
|
||||
}
|
||||
|
||||
public partial class YarnTaskCompletionSource
|
||||
{
|
||||
private TaskCompletionSource<int> taskCompletionSource = new TaskCompletionSource<int>();
|
||||
|
||||
public partial bool TrySetResult()
|
||||
{
|
||||
return taskCompletionSource.TrySetResult(1);
|
||||
}
|
||||
public partial bool TrySetException(System.Exception exception)
|
||||
{
|
||||
return taskCompletionSource.TrySetException(exception);
|
||||
}
|
||||
public partial bool TrySetCanceled()
|
||||
{
|
||||
return taskCompletionSource.TrySetCanceled();
|
||||
}
|
||||
|
||||
public YarnTask Task => taskCompletionSource.Task;
|
||||
}
|
||||
public partial class YarnTaskCompletionSource<T>
|
||||
{
|
||||
private TaskCompletionSource<T> taskCompletionSource = new TaskCompletionSource<T>();
|
||||
|
||||
public partial bool TrySetResult(T value)
|
||||
{
|
||||
return taskCompletionSource.TrySetResult(value);
|
||||
}
|
||||
public partial bool TrySetException(System.Exception exception)
|
||||
{
|
||||
return taskCompletionSource.TrySetException(exception);
|
||||
}
|
||||
public partial bool TrySetCanceled()
|
||||
{
|
||||
return taskCompletionSource.TrySetCanceled();
|
||||
}
|
||||
|
||||
public YarnTask<T> Task => taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
static class TaskUtility
|
||||
{
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
public static async Task AsTask(this Awaitable awaitable)
|
||||
{
|
||||
await awaitable;
|
||||
}
|
||||
|
||||
public static async Task<T> AsTask<T>(this Awaitable<T> awaitable)
|
||||
{
|
||||
return await awaitable;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43dfb2f38447f467a9d718337ba0a595
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
Yarn Spinner is licensed to you under the terms found in the file LICENSE.md.
|
||||
*/
|
||||
|
||||
// If we don't already have a directive telling us what to use...
|
||||
#if !YARNTASKS_ARE_AWAITABLES && !YARNTASKS_ARE_SYSTEMTASKS && !YARNTASKS_ARE_UNITASKS
|
||||
// ...then figure out what the best option is. We'll try to use UniTask, if
|
||||
// installed; then Awaitables, if >= Unity 2023.1; then System.Threading.Tasks.
|
||||
#if USE_UNITASK
|
||||
#define YARNTASKS_ARE_UNITASKS
|
||||
#elif UNITY_2023_1_OR_NEWER
|
||||
#define YARNTASKS_ARE_AWAITABLES
|
||||
#else
|
||||
#define YARNTASKS_ARE_SYSTEMTASKS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if YARNTASKS_ARE_UNITASKS
|
||||
namespace Yarn.Unity
|
||||
{
|
||||
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
#if USE_ADDRESSABLES
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
#endif
|
||||
|
||||
public partial struct YarnTask
|
||||
{
|
||||
public UniTask.Awaiter GetAwaiter() => Task.GetAwaiter();
|
||||
|
||||
UniTask Task;
|
||||
readonly public bool IsCompleted() => Task.Status != UniTaskStatus.Pending;
|
||||
readonly public bool IsCompletedSuccessfully() => Task.Status == UniTaskStatus.Succeeded;
|
||||
|
||||
public static YarnTask CompletedTask => UniTask.CompletedTask;
|
||||
|
||||
public static implicit operator UniTask(YarnTask demoYarnTask)
|
||||
{
|
||||
return demoYarnTask.Task;
|
||||
}
|
||||
|
||||
public static implicit operator YarnTask(UniTask task)
|
||||
{
|
||||
return new YarnTask { Task = task };
|
||||
}
|
||||
|
||||
public static implicit operator YarnTask(System.Threading.Tasks.Task task)
|
||||
{
|
||||
return new YarnTask { Task = task.AsUniTask() };
|
||||
}
|
||||
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
// Allow implicitly converting Awaitables to YarnTasks
|
||||
public static implicit operator YarnTask(UnityEngine.Awaitable awaitable)
|
||||
{
|
||||
return new YarnTask { Task = awaitable.AsUniTask() };
|
||||
}
|
||||
#endif
|
||||
|
||||
readonly public void Forget() => Task.Forget();
|
||||
|
||||
public static partial YarnTask WaitUntilCanceled(System.Threading.CancellationToken token)
|
||||
{
|
||||
return UniTask.WaitUntilCanceled(token);
|
||||
}
|
||||
|
||||
public static partial YarnTask Delay(TimeSpan timeSpan, CancellationToken token)
|
||||
{
|
||||
return UniTask.Delay(timeSpan, cancellationToken: token);
|
||||
}
|
||||
|
||||
public static partial YarnTask WaitUntil(System.Func<bool> predicate, System.Threading.CancellationToken token)
|
||||
{
|
||||
return UniTask.WaitUntil(predicate, cancellationToken: token);
|
||||
}
|
||||
|
||||
public static partial IEnumerator ToCoroutine(Func<YarnTask> factory)
|
||||
{
|
||||
return UniTask.ToCoroutine(async () => await factory());
|
||||
}
|
||||
|
||||
public static partial async YarnTask Yield() => await UniTask.Yield();
|
||||
|
||||
public static partial YarnTask WhenAll(params YarnTask[] tasks)
|
||||
{
|
||||
return WhenAll((IEnumerable<YarnTask>)tasks);
|
||||
}
|
||||
public static partial async YarnTask WhenAll(IEnumerable<YarnTask> tasks)
|
||||
{
|
||||
// Don't love this allocation here; try and find a better approach
|
||||
List<UniTask> taskList = new List<UniTask>();
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
taskList.Add(task);
|
||||
}
|
||||
|
||||
await UniTask.WhenAll(taskList.ToArray());
|
||||
|
||||
}
|
||||
|
||||
public static async partial YarnTask<T[]> WhenAll<T>(params YarnTask<T>[] tasks)
|
||||
{
|
||||
return await UniTask.WhenAll(Array.ConvertAll<YarnTask<T>, UniTask<T>>(tasks, t => t));
|
||||
}
|
||||
|
||||
public static async partial YarnTask<T[]> WhenAll<T>(IEnumerable<YarnTask<T>> tasks)
|
||||
{
|
||||
var uniTasks = new List<UniTask<T>>();
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
uniTasks.Add(task);
|
||||
}
|
||||
return await UniTask.WhenAll(uniTasks);
|
||||
|
||||
}
|
||||
|
||||
#if USE_ADDRESSABLES
|
||||
public static partial async YarnTask WaitForAsyncOperation(AsyncOperationHandle operationHandle, CancellationToken cancellationToken)
|
||||
{
|
||||
await operationHandle.ToUniTask(cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static partial async YarnTask<T> WaitForAsyncOperation<T>(AsyncOperationHandle<T> operationHandle, CancellationToken cancellationToken)
|
||||
{
|
||||
return await operationHandle.ToUniTask(cancellationToken: cancellationToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
public readonly partial async YarnTask<bool> SuppressCancellationThrow()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public partial struct YarnTask<T>
|
||||
{
|
||||
UniTask<T> Task;
|
||||
public UniTask<T>.Awaiter GetAwaiter() => Task.GetAwaiter();
|
||||
|
||||
readonly public bool IsCompleted() => Task.Status != UniTaskStatus.Pending;
|
||||
readonly public bool IsCompletedSuccessfully() => Task.Status == UniTaskStatus.Succeeded;
|
||||
|
||||
public static implicit operator UniTask<T>(YarnTask<T> demoYarnTask)
|
||||
{
|
||||
return demoYarnTask.Task;
|
||||
}
|
||||
|
||||
public static implicit operator YarnTask<T>(UniTask<T> task)
|
||||
{
|
||||
return new YarnTask<T> { Task = task };
|
||||
}
|
||||
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
// Allow implicitly converting Awaitables to YarnTasks
|
||||
public static implicit operator YarnTask<T>(UnityEngine.Awaitable<T> awaitable)
|
||||
{
|
||||
return new YarnTask<T> { Task = awaitable.AsUniTask() };
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
readonly public void Forget() => Task.Forget();
|
||||
|
||||
public static partial YarnTask<T> FromResult(T value)
|
||||
{
|
||||
return UniTask.FromResult(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public partial class YarnTaskCompletionSource
|
||||
{
|
||||
private UniTaskCompletionSource awaitableCompletionSource = new();
|
||||
public partial bool TrySetResult()
|
||||
{
|
||||
return awaitableCompletionSource.TrySetResult();
|
||||
}
|
||||
|
||||
public partial bool TrySetException(System.Exception exception)
|
||||
{
|
||||
return awaitableCompletionSource.TrySetException(exception);
|
||||
}
|
||||
|
||||
public partial bool TrySetCanceled()
|
||||
{
|
||||
return awaitableCompletionSource.TrySetCanceled();
|
||||
}
|
||||
|
||||
public YarnTask Task => awaitableCompletionSource.Task;
|
||||
}
|
||||
|
||||
public partial class YarnTaskCompletionSource<T>
|
||||
{
|
||||
private UniTaskCompletionSource<T> awaitableCompletionSource = new();
|
||||
public partial bool TrySetResult(T value)
|
||||
{
|
||||
return awaitableCompletionSource.TrySetResult(value);
|
||||
}
|
||||
|
||||
public partial bool TrySetException(System.Exception exception)
|
||||
{
|
||||
return awaitableCompletionSource.TrySetException(exception);
|
||||
}
|
||||
|
||||
public partial bool TrySetCanceled()
|
||||
{
|
||||
return awaitableCompletionSource.TrySetCanceled();
|
||||
}
|
||||
public YarnTask<T> Task => awaitableCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="IActionRegistration"/>
|
||||
/// objects.
|
||||
/// </summary>
|
||||
public static class ActionRegistrationUniTaskExtension
|
||||
{
|
||||
// These registrations for UniTask were generated by action-gyb.py
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler(this IActionRegistration registration, string commandName, System.Func<UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1>(this IActionRegistration registration, string commandName, System.Func<T1, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2>(this IActionRegistration registration, string commandName, System.Func<T1, T2, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
/// <inheritdoc cref="IActionRegistration.AddCommandHandler(string, Delegate)"/>
|
||||
public static void AddCommandHandler<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this IActionRegistration registration, string commandName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, UniTask> handler) => registration.AddCommandHandler(commandName, (Delegate)handler);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0a25558997764437a6ded8fc0448fe5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
121
Packages/dev.yarnspinner.unity/Runtime/YarnTask/YarnTask.cs
Normal file
121
Packages/dev.yarnspinner.unity/Runtime/YarnTask/YarnTask.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
Yarn Spinner is licensed to you under the terms found in the file LICENSE.md.
|
||||
*/
|
||||
|
||||
// If we don't already have a directive telling us what to use...
|
||||
#if !YARNTASKS_ARE_AWAITABLES && !YARNTASKS_ARE_SYSTEMTASKS && !YARNTASKS_ARE_UNITASKS
|
||||
// ...then figure out what the best option is. We'll try to use UniTask, if
|
||||
// installed; then Awaitables, if >= Unity 2023.1; then System.Threading.Tasks.
|
||||
#if USE_UNITASK
|
||||
#define YARNTASKS_ARE_UNITASKS
|
||||
#elif UNITY_2023_1_OR_NEWER
|
||||
#define YARNTASKS_ARE_AWAITABLES
|
||||
#else
|
||||
#define YARNTASKS_ARE_SYSTEMTASKS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
#if USE_ADDRESSABLES
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
#endif
|
||||
|
||||
namespace Yarn.Unity
|
||||
{
|
||||
public interface IYarnTask
|
||||
{
|
||||
bool IsCompleted();
|
||||
bool IsCompletedSuccessfully();
|
||||
void Forget();
|
||||
}
|
||||
|
||||
[AsyncMethodBuilder(typeof(YarnTaskMethodBuilder))]
|
||||
public partial struct YarnTask { }
|
||||
|
||||
[AsyncMethodBuilder(typeof(YarnTaskMethodBuilder<>))]
|
||||
public partial struct YarnTask<T>
|
||||
{
|
||||
public static partial YarnTask<T> FromResult(T value);
|
||||
}
|
||||
|
||||
public partial class YarnTaskCompletionSource
|
||||
{
|
||||
public partial bool TrySetResult();
|
||||
public partial bool TrySetException(System.Exception exception);
|
||||
public partial bool TrySetCanceled();
|
||||
}
|
||||
|
||||
public partial class YarnTaskCompletionSource<T>
|
||||
{
|
||||
public partial bool TrySetResult(T value);
|
||||
public partial bool TrySetException(System.Exception exception);
|
||||
public partial bool TrySetCanceled();
|
||||
}
|
||||
|
||||
// Static implementation-dependent utility methods
|
||||
public partial struct YarnTask
|
||||
{
|
||||
public static partial YarnTask WaitUntilCanceled(System.Threading.CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="YarnTask"/> that delays for the time indicated
|
||||
/// by <paramref name="timeSpan"/>, and then returns.
|
||||
/// </summary>
|
||||
/// <param name="timeSpan">The amount of time to wait.</param>
|
||||
/// <param name="token">A token that can be used to cancel the
|
||||
/// task.</param>
|
||||
/// <returns>A new <see cref="YarnTask"/>.</returns>
|
||||
public static partial YarnTask Delay(TimeSpan timeSpan, CancellationToken token = default);
|
||||
public static YarnTask Delay(int milliseconds, CancellationToken token = default) => Delay(TimeSpan.FromMilliseconds(milliseconds), token);
|
||||
public static partial YarnTask WaitUntil(System.Func<bool> predicate, System.Threading.CancellationToken token = default);
|
||||
public static partial IEnumerator ToCoroutine(Func<YarnTask> factory);
|
||||
public static partial YarnTask Yield();
|
||||
|
||||
public static partial YarnTask WhenAll(params YarnTask[] tasks);
|
||||
public static partial YarnTask WhenAll(IEnumerable<YarnTask> tasks);
|
||||
public static partial YarnTask<T[]> WhenAll<T>(params YarnTask<T>[] tasks);
|
||||
public static partial YarnTask<T[]> WhenAll<T>(IEnumerable<YarnTask<T>> tasks);
|
||||
|
||||
public readonly partial YarnTask<bool> SuppressCancellationThrow();
|
||||
|
||||
public static YarnTask<T> FromResult<T>(T value) => YarnTask<T>.FromResult(value);
|
||||
}
|
||||
|
||||
// Addressables
|
||||
#if USE_ADDRESSABLES
|
||||
public partial struct YarnTask
|
||||
{
|
||||
public static partial YarnTask WaitForAsyncOperation(AsyncOperationHandle operationHandle, CancellationToken cancellationToken);
|
||||
public static partial YarnTask<T> WaitForAsyncOperation<T>(AsyncOperationHandle<T> operationHandle, CancellationToken cancellationToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static class YarnTaskExtensions
|
||||
{
|
||||
public static YarnTask WaitForCoroutine(this MonoBehaviour runner, IEnumerator coroutine)
|
||||
{
|
||||
return WaitForCoroutine(runner, runner.StartCoroutine(coroutine));
|
||||
}
|
||||
public static YarnTask WaitForCoroutine(this MonoBehaviour runner, Coroutine coroutine)
|
||||
{
|
||||
var tcs = new YarnTaskCompletionSource();
|
||||
IEnumerator InnerCoroutine()
|
||||
{
|
||||
yield return coroutine;
|
||||
tcs.TrySetResult();
|
||||
}
|
||||
runner.StartCoroutine(InnerCoroutine());
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dfe2f9081225433b93694de53ecb40f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user