import from UniRx and some modified.

This commit is contained in:
Yoshifumi Kawai
2019-05-20 00:14:47 +09:00
parent d5dab7fd1a
commit 5aaeb13c5d
246 changed files with 20742 additions and 19 deletions

View File

@@ -0,0 +1,28 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or
using System;
namespace UniRx.Async
{
public struct AsyncUnit : IEquatable<AsyncUnit>
{
public static readonly AsyncUnit Default = new AsyncUnit();
public override int GetHashCode()
{
return 0;
}
public bool Equals(AsyncUnit other)
{
return true;
}
public override string ToString()
{
return "()";
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f95ac245430d304bb5128d13b6becc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
namespace UniRx.Async
{
public class CancellationTokenEqualityComparer : IEqualityComparer<CancellationToken>
{
public static readonly IEqualityComparer<CancellationToken> Default = new CancellationTokenEqualityComparer();
public bool Equals(CancellationToken x, CancellationToken y)
{
return x.Equals(y);
}
public int GetHashCode(CancellationToken obj)
{
return obj.GetHashCode();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7d739f510b125b74fa7290ac4335e46e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace UniRx.Async
{
public static class CancellationTokenExtensions
{
static readonly Action<object> cancellationTokenCallback = Callback;
public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cts)
{
if (cts.IsCancellationRequested)
{
return (UniTask.FromCanceled(cts), default(CancellationTokenRegistration));
}
var promise = new UniTaskCompletionSource<AsyncUnit>();
return (promise.Task, cts.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
}
static void Callback(object state)
{
var promise = (UniTaskCompletionSource<AsyncUnit>)state;
promise.TrySetResult(AsyncUnit.Default);
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action callback)
{
var restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action<object> callback, object state)
{
var restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, state, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4be7209f04146bd45ac5ee775a5f7c26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Threading;
using UnityEngine;
using UniRx.Async.Triggers;
using System;
namespace UniRx.Async
{
public static class CancellationTokenSourceExtensions
{
public static void CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{
var delay = UniTask.Delay(millisecondsDelay, ignoreTimeScale, delayTiming, cts.Token);
CancelAfterCore(cts, delay).Forget();
}
public static void CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{
var delay = UniTask.Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cts.Token);
CancelAfterCore(cts, delay).Forget();
}
static async UniTaskVoid CancelAfterCore(CancellationTokenSource cts, UniTask delayTask)
{
var alreadyCanceled = await delayTask.SuppressCancellationThrow();
if (!alreadyCanceled)
{
cts.Cancel();
cts.Dispose();
}
}
public static void RegisterRaiseCancelOnDestroy(this CancellationTokenSource cts, Component component)
{
RegisterRaiseCancelOnDestroy(cts, component.gameObject);
}
public static void RegisterRaiseCancelOnDestroy(this CancellationTokenSource cts, GameObject gameObject)
{
var trigger = gameObject.GetAsyncDestroyTrigger();
trigger.AddCancellationTriggerOnDestory(cts);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22d85d07f1e70ab42a7a4c25bd65e661
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 64b064347ca7a404494a996b072e2e29
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
namespace System.Runtime.CompilerServices
{
public sealed class AsyncMethodBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public AsyncMethodBuilderAttribute(Type builderType)
{
BuilderType = builderType;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 02ce354d37b10454e8376062f7cbe57a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,274 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Security;
namespace UniRx.Async.CompilerServices
{
public struct AsyncUniTaskMethodBuilder
{
UniTaskCompletionSource promise;
Action moveNext;
// 1. Static Create method.
[DebuggerHidden]
public static AsyncUniTaskMethodBuilder Create()
{
var builder = new AsyncUniTaskMethodBuilder();
return builder;
}
// 2. TaskLike Task property.
[DebuggerHidden]
public UniTask Task
{
get
{
if (promise != null)
{
return promise.Task;
}
if (moveNext == null)
{
return UniTask.CompletedTask;
}
else
{
promise = new UniTaskCompletionSource();
return promise.Task;
}
}
}
// 3. SetException
[DebuggerHidden]
public void SetException(Exception exception)
{
if (promise == null)
{
promise = new UniTaskCompletionSource();
}
if (exception is OperationCanceledException ex)
{
promise.TrySetCanceled(ex);
}
else
{
promise.TrySetException(exception);
}
}
// 4. SetResult
[DebuggerHidden]
public void SetResult()
{
if (moveNext == null)
{
}
else
{
if (promise == null)
{
promise = new UniTaskCompletionSource();
}
promise.TrySetResult();
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (moveNext == null)
{
if (promise == null)
{
promise = new UniTaskCompletionSource(); // built future.
}
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
}
awaiter.OnCompleted(moveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (moveNext == null)
{
if (promise == null)
{
promise = new UniTaskCompletionSource(); // built future.
}
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
}
awaiter.UnsafeOnCompleted(moveNext);
}
// 7. Start
[DebuggerHidden]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
}
public struct AsyncUniTaskMethodBuilder<T>
{
T result;
UniTaskCompletionSource<T> promise;
Action moveNext;
// 1. Static Create method.
[DebuggerHidden]
public static AsyncUniTaskMethodBuilder<T> Create()
{
var builder = new AsyncUniTaskMethodBuilder<T>();
return builder;
}
// 2. TaskLike Task property.
[DebuggerHidden]
public UniTask<T> Task
{
get
{
if (promise != null)
{
return new UniTask<T>(promise);
}
if (moveNext == null)
{
return new UniTask<T>(result);
}
else
{
promise = new UniTaskCompletionSource<T>();
return new UniTask<T>(promise);
}
}
}
// 3. SetException
[DebuggerHidden]
public void SetException(Exception exception)
{
if (promise == null)
{
promise = new UniTaskCompletionSource<T>();
}
if (exception is OperationCanceledException ex)
{
promise.TrySetCanceled(ex);
}
else
{
promise.TrySetException(exception);
}
}
// 4. SetResult
[DebuggerHidden]
public void SetResult(T result)
{
if (moveNext == null)
{
this.result = result;
}
else
{
if (promise == null)
{
promise = new UniTaskCompletionSource<T>();
}
promise.TrySetResult(result);
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (moveNext == null)
{
if (promise == null)
{
promise = new UniTaskCompletionSource<T>(); // built future.
}
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
}
awaiter.OnCompleted(moveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (moveNext == null)
{
if (promise == null)
{
promise = new UniTaskCompletionSource<T>(); // built future.
}
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
}
awaiter.UnsafeOnCompleted(moveNext);
}
// 7. Start
[DebuggerHidden]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68d72a45afdec574ebc26e7de2c38330
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,90 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Security;
namespace UniRx.Async.CompilerServices
{
public struct AsyncUniTaskVoidMethodBuilder
{
Action moveNext;
// 1. Static Create method.
[DebuggerHidden]
public static AsyncUniTaskVoidMethodBuilder Create()
{
var builder = new AsyncUniTaskVoidMethodBuilder();
return builder;
}
// 2. TaskLike Task property(void)
public UniTaskVoid Task => default(UniTaskVoid);
// 3. SetException
[DebuggerHidden]
public void SetException(Exception exception)
{
UniTaskScheduler.PublishUnobservedTaskException(exception);
}
// 4. SetResult
[DebuggerHidden]
public void SetResult()
{
// do nothing
}
// 5. AwaitOnCompleted
[DebuggerHidden]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (moveNext == null)
{
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
}
awaiter.OnCompleted(moveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (moveNext == null)
{
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
}
awaiter.UnsafeOnCompleted(moveNext);
}
// 7. Start
[DebuggerHidden]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e891aaac17b933a47a9d7fa3b8e1226f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace UniRx.Async.CompilerServices
{
internal class MoveNextRunner<TStateMachine>
where TStateMachine : IAsyncStateMachine
{
public TStateMachine StateMachine;
[DebuggerHidden]
public void Run()
{
StateMachine.MoveNext();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98649642833cabf44a9dc060ce4c84a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,270 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace UniRx.Async
{
public static class DiagnosticsExtensions
{
static bool displayFilenames = true;
static readonly Regex typeBeautifyRegex = new Regex("`.+$", RegexOptions.Compiled);
static readonly Dictionary<Type, string> builtInTypeNames = new Dictionary<Type, string>
{
{ typeof(void), "void" },
{ typeof(bool), "bool" },
{ typeof(byte), "byte" },
{ typeof(char), "char" },
{ typeof(decimal), "decimal" },
{ typeof(double), "double" },
{ typeof(float), "float" },
{ typeof(int), "int" },
{ typeof(long), "long" },
{ typeof(object), "object" },
{ typeof(sbyte), "sbyte" },
{ typeof(short), "short" },
{ typeof(string), "string" },
{ typeof(uint), "uint" },
{ typeof(ulong), "ulong" },
{ typeof(ushort), "ushort" },
{ typeof(Task), "Task" },
{ typeof(UniTask), "UniTask" },
{ typeof(UniTaskVoid), "UniTaskVoid" }
};
public static string ToStringWithCleanupAsyncStackTrace(this Exception exception)
{
if (exception == null) return "";
String message = exception.Message;
String s;
if (message == null || message.Length <= 0)
{
s = exception.GetType().ToString();
}
else
{
s = exception.GetType().ToString() + ": " + message;
}
if (exception.InnerException != null)
{
s = s + " ---> " + exception.InnerException.ToString() + Environment.NewLine + " Exception_EndOfInnerExceptionStack";
}
string stackTrace = new StackTrace(exception).CleanupAsyncStackTrace();
if (stackTrace != null)
{
s += Environment.NewLine + stackTrace;
}
return s;
}
public static string CleanupAsyncStackTrace(this StackTrace stackTrace)
{
if (stackTrace == null) return "";
var sb = new StringBuilder();
for (int i = 0; i < stackTrace.FrameCount; i++)
{
var sf = stackTrace.GetFrame(i);
var mb = sf.GetMethod();
if (IgnoreLine(mb)) continue;
if (IsAsync(mb))
{
sb.Append("async ");
TryResolveStateMachineMethod(ref mb, out var decType);
}
// return type
if (mb is MethodInfo mi)
{
sb.Append(BeautifyType(mi.ReturnType, false));
sb.Append(" ");
}
// method name
sb.Append(BeautifyType(mb.DeclaringType, false));
if (!mb.IsConstructor)
{
sb.Append(".");
}
sb.Append(mb.Name);
if (mb.IsGenericMethod)
{
sb.Append("<");
foreach (var item in mb.GetGenericArguments())
{
sb.Append(BeautifyType(item, true));
}
sb.Append(">");
}
// parameter
sb.Append("(");
sb.Append(string.Join(", ", mb.GetParameters().Select(p => BeautifyType(p.ParameterType, true) + " " + p.Name)));
sb.Append(")");
// file name
if (displayFilenames && (sf.GetILOffset() != -1))
{
String fileName = null;
try
{
fileName = sf.GetFileName();
}
catch (NotSupportedException)
{
displayFilenames = false;
}
catch (SecurityException)
{
displayFilenames = false;
}
if (fileName != null)
{
sb.Append(' ');
sb.AppendFormat(CultureInfo.InvariantCulture, "in {0}:{1}", SimplifyPath(fileName), sf.GetFileLineNumber());
}
}
sb.AppendLine();
}
return sb.ToString();
}
static bool IsAsync(MethodBase methodInfo)
{
var declareType = methodInfo.DeclaringType;
return typeof(IAsyncStateMachine).IsAssignableFrom(declareType);
}
// code from Ben.Demystifier/EnhancedStackTrace.Frame.cs
static bool TryResolveStateMachineMethod(ref MethodBase method, out Type declaringType)
{
declaringType = method.DeclaringType;
var parentType = declaringType.DeclaringType;
if (parentType == null)
{
return false;
}
var methods = parentType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
if (methods == null)
{
return false;
}
foreach (var candidateMethod in methods)
{
var attributes = candidateMethod.GetCustomAttributes<StateMachineAttribute>();
if (attributes == null)
{
continue;
}
foreach (var asma in attributes)
{
if (asma.StateMachineType == declaringType)
{
method = candidateMethod;
declaringType = candidateMethod.DeclaringType;
// Mark the iterator as changed; so it gets the + annotation of the original method
// async statemachines resolve directly to their builder methods so aren't marked as changed
return asma is IteratorStateMachineAttribute;
}
}
}
return false;
}
static string BeautifyType(Type t, bool shortName)
{
if (builtInTypeNames.TryGetValue(t, out var builtin))
{
return builtin;
}
if (t.IsGenericParameter) return t.Name;
if (t.IsArray) return BeautifyType(t.GetElementType(), shortName) + "[]";
if (t.FullName?.StartsWith("System.ValueTuple") ?? false)
{
return "(" + string.Join(", ", t.GetGenericArguments().Select(x => BeautifyType(x, true))) + ")";
}
if (!t.IsGenericType) return shortName ? t.Name : t.FullName ?? t.Name;
var innerFormat = string.Join(", ", t.GetGenericArguments().Select(x => BeautifyType(x, true)));
var genericType = t.GetGenericTypeDefinition().FullName;
if (genericType == "System.Threading.Tasks.Task`1")
{
genericType = "Task";
}
return typeBeautifyRegex.Replace(genericType, "") + "<" + innerFormat + ">";
}
static bool IgnoreLine(MethodBase methodInfo)
{
var declareType = methodInfo.DeclaringType.FullName;
if (declareType == "System.Threading.ExecutionContext")
{
return true;
}
else if (declareType.StartsWith("System.Runtime.CompilerServices"))
{
return true;
}
else if (declareType.StartsWith("UniRx.Async.CompilerServices"))
{
return true;
}
else if (declareType == "System.Threading.Tasks.AwaitTaskContinuation")
{
return true;
}
else if (declareType.StartsWith("System.Threading.Tasks.Task"))
{
return true;
}
return false;
}
static string SimplifyPath(string path)
{
var fi = new FileInfo(path);
if (fi.Directory == null)
{
return fi.Name;
}
else
{
return fi.Directory.Name + "/" + fi.Name;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f80fb1c9ed4c99447be1b0a47a8d980b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 275b87293edc6634f9d72387851dbbdf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace UniRx.Async.Editor
{
// reflection call of UnityEditor.SplitterGUILayout
internal static class SplitterGUILayout
{
static BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
static Lazy<Type> splitterStateType = new Lazy<Type>(() =>
{
var type = typeof(EditorWindow).Assembly.GetTypes().First(x => x.FullName == "UnityEditor.SplitterState");
return type;
});
static Lazy<ConstructorInfo> splitterStateCtor = new Lazy<ConstructorInfo>(() =>
{
var type = splitterStateType.Value;
return type.GetConstructor(flags, null, new Type[] { typeof(float[]), typeof(int[]), typeof(int[]) }, null);
});
static Lazy<Type> splitterGUILayoutType = new Lazy<Type>(() =>
{
var type = typeof(EditorWindow).Assembly.GetTypes().First(x => x.FullName == "UnityEditor.SplitterGUILayout");
return type;
});
static Lazy<MethodInfo> beginVerticalSplit = new Lazy<MethodInfo>(() =>
{
var type = splitterGUILayoutType.Value;
return type.GetMethod("BeginVerticalSplit", flags, null, new Type[] { splitterStateType.Value, typeof(GUILayoutOption[]) }, null);
});
static Lazy<MethodInfo> endVerticalSplit = new Lazy<MethodInfo>(() =>
{
var type = splitterGUILayoutType.Value;
return type.GetMethod("EndVerticalSplit", flags, null, Type.EmptyTypes, null);
});
public static object CreateSplitterState(float[] relativeSizes, int[] minSizes, int[] maxSizes)
{
return splitterStateCtor.Value.Invoke(new object[] { relativeSizes, minSizes, maxSizes });
}
public static void BeginVerticalSplit(object splitterState, params GUILayoutOption[] options)
{
beginVerticalSplit.Value.Invoke(null, new object[] { splitterState, options });
}
public static void EndVerticalSplit()
{
endVerticalSplit.Value.Invoke(null, Type.EmptyTypes);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40ef2e46f900131419e869398a8d3c9d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
{
"name": "UniRx.Async.Editor",
"references": [
"GUID:f51ebe6a0ceec4240a699833d6309b23"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4129704b5a1a13841ba16f230bf24a57
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,180 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;
using UnityEditor.IMGUI.Controls;
using UniRx.Async.Internal;
using System.Text;
namespace UniRx.Async.Editor
{
public class UniTaskTrackerViewItem : TreeViewItem
{
public string TaskType { get; set; }
public string Elapsed { get; set; }
public string Status { get; set; }
string position;
public string Position
{
get { return position; }
set
{
position = value;
PositionFirstLine = GetFirstLine(position);
}
}
public string PositionFirstLine { get; private set; }
static string GetFirstLine(string str)
{
var sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
if (str[i] == '\r' || str[i] == '\n')
{
break;
}
sb.Append(str[i]);
}
return sb.ToString();
}
public UniTaskTrackerViewItem(int id) : base(id)
{
}
}
public class UniTaskTrackerTreeView : TreeView
{
const string sortedColumnIndexStateKey = "UniTaskTrackerTreeView_sortedColumnIndex";
public IReadOnlyList<TreeViewItem> CurrentBindingItems;
public UniTaskTrackerTreeView()
: this(new TreeViewState(), new MultiColumnHeader(new MultiColumnHeaderState(new[]
{
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("TaskType"), width = 20},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Elapsed"), width = 10},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Status"), width = 10},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Position")},
})))
{
}
UniTaskTrackerTreeView(TreeViewState state, MultiColumnHeader header)
: base(state, header)
{
rowHeight = 20;
showAlternatingRowBackgrounds = true;
showBorder = true;
header.sortingChanged += Header_sortingChanged;
header.ResizeToFit();
Reload();
header.sortedColumnIndex = SessionState.GetInt(sortedColumnIndexStateKey, 1);
}
public void ReloadAndSort()
{
var currentSelected = this.state.selectedIDs;
Reload();
Header_sortingChanged(this.multiColumnHeader);
this.state.selectedIDs = currentSelected;
}
private void Header_sortingChanged(MultiColumnHeader multiColumnHeader)
{
SessionState.SetInt(sortedColumnIndexStateKey, multiColumnHeader.sortedColumnIndex);
var index = multiColumnHeader.sortedColumnIndex;
var ascending = multiColumnHeader.IsSortedAscending(multiColumnHeader.sortedColumnIndex);
var items = rootItem.children.Cast<UniTaskTrackerViewItem>();
IOrderedEnumerable<UniTaskTrackerViewItem> orderedEnumerable;
switch (index)
{
case 0:
orderedEnumerable = ascending ? items.OrderBy(item => item.TaskType) : items.OrderByDescending(item => item.TaskType);
break;
case 1:
orderedEnumerable = ascending ? items.OrderBy(item => double.Parse(item.Elapsed)) : items.OrderByDescending(item => double.Parse(item.Elapsed));
break;
case 2:
orderedEnumerable = ascending ? items.OrderBy(item => item.Status) : items.OrderByDescending(item => item.Elapsed);
break;
case 3:
orderedEnumerable = ascending ? items.OrderBy(item => item.Position) : items.OrderByDescending(item => item.PositionFirstLine);
break;
default:
throw new ArgumentOutOfRangeException(nameof(index), index, null);
}
CurrentBindingItems = rootItem.children = orderedEnumerable.Cast<TreeViewItem>().ToList();
BuildRows(rootItem);
}
protected override TreeViewItem BuildRoot()
{
var root = new TreeViewItem { depth = -1 };
var children = new List<TreeViewItem>();
TaskTracker.ForEachActiveTask((trackingId, awaiterType, status, created, stackTrace) =>
{
children.Add(new UniTaskTrackerViewItem(trackingId) { TaskType = awaiterType, Status = status.ToString(), Elapsed = (DateTime.UtcNow - created).TotalSeconds.ToString("00.00"), Position = stackTrace });
});
CurrentBindingItems = children;
root.children = CurrentBindingItems as List<TreeViewItem>;
return root;
}
protected override bool CanMultiSelect(TreeViewItem item)
{
return false;
}
protected override void RowGUI(RowGUIArgs args)
{
var item = args.item as UniTaskTrackerViewItem;
for (var visibleColumnIndex = 0; visibleColumnIndex < args.GetNumVisibleColumns(); visibleColumnIndex++)
{
var rect = args.GetCellRect(visibleColumnIndex);
var columnIndex = args.GetColumn(visibleColumnIndex);
var labelStyle = args.selected ? EditorStyles.whiteLabel : EditorStyles.label;
labelStyle.alignment = TextAnchor.MiddleLeft;
switch (columnIndex)
{
case 0:
EditorGUI.LabelField(rect, item.TaskType, labelStyle);
break;
case 1:
EditorGUI.LabelField(rect, item.Elapsed, labelStyle);
break;
case 2:
EditorGUI.LabelField(rect, item.Status, labelStyle);
break;
case 3:
EditorGUI.LabelField(rect, item.PositionFirstLine, labelStyle);
break;
default:
throw new ArgumentOutOfRangeException(nameof(columnIndex), columnIndex, null);
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 52e2d973a2156674e8c1c9433ed031f7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,211 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;
using UnityEditor.IMGUI.Controls;
using UniRx.Async.Internal;
namespace UniRx.Async.Editor
{
public class UniTaskTrackerWindow : EditorWindow
{
static int interval;
static UniTaskTrackerWindow window;
[MenuItem("Window/UniRx/UniTask Tracker")]
public static void OpenWindow()
{
if (window != null)
{
window.Close();
}
// will called OnEnable(singleton instance will be set).
GetWindow<UniTaskTrackerWindow>("UniTask Tracker").Show();
}
static readonly GUILayoutOption[] EmptyLayoutOption = new GUILayoutOption[0];
UniTaskTrackerTreeView treeView;
object splitterState;
void OnEnable()
{
window = this; // set singleton.
splitterState = SplitterGUILayout.CreateSplitterState(new float[] { 75f, 25f }, new int[] { 32, 32 }, null);
treeView = new UniTaskTrackerTreeView();
TaskTracker.EditorEnableState.EnableAutoReload = EditorPrefs.GetBool(TaskTracker.EnableAutoReloadKey, false);
TaskTracker.EditorEnableState.EnableTracking = EditorPrefs.GetBool(TaskTracker.EnableTrackingKey, false);
TaskTracker.EditorEnableState.EnableStackTrace = EditorPrefs.GetBool(TaskTracker.EnableStackTraceKey, false);
}
void OnGUI()
{
// Head
RenderHeadPanel();
// Splittable
SplitterGUILayout.BeginVerticalSplit(this.splitterState, EmptyLayoutOption);
{
// Column Tabble
RenderTable();
// StackTrace details
RenderDetailsPanel();
}
SplitterGUILayout.EndVerticalSplit();
}
#region HeadPanel
public static bool EnableAutoReload => TaskTracker.EditorEnableState.EnableAutoReload;
public static bool EnableTracking => TaskTracker.EditorEnableState.EnableTracking;
public static bool EnableStackTrace => TaskTracker.EditorEnableState.EnableStackTrace;
static readonly GUIContent EnableAutoReloadHeadContent = EditorGUIUtility.TrTextContent("Enable AutoReload", "Reload automatically.", (Texture)null);
static readonly GUIContent ReloadHeadContent = EditorGUIUtility.TrTextContent("Reload", "Reload View.", (Texture)null);
static readonly GUIContent GCHeadContent = EditorGUIUtility.TrTextContent("GC.Collect", "Invoke GC.Collect.", (Texture)null);
static readonly GUIContent EnableTrackingHeadContent = EditorGUIUtility.TrTextContent("Enable Tracking", "Start to track async/await UniTask. Performance impact: low", (Texture)null);
static readonly GUIContent EnableStackTraceHeadContent = EditorGUIUtility.TrTextContent("Enable StackTrace", "Capture StackTrace when task is started. Performance impact: high", (Texture)null);
// [Enable Tracking] | [Enable StackTrace]
void RenderHeadPanel()
{
EditorGUILayout.BeginVertical(EmptyLayoutOption);
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, EmptyLayoutOption);
if (GUILayout.Toggle(EnableAutoReload, EnableAutoReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableAutoReload)
{
TaskTracker.EditorEnableState.EnableAutoReload = !EnableAutoReload;
}
if (GUILayout.Toggle(EnableTracking, EnableTrackingHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableTracking)
{
TaskTracker.EditorEnableState.EnableTracking = !EnableTracking;
}
if (GUILayout.Toggle(EnableStackTrace, EnableStackTraceHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableStackTrace)
{
TaskTracker.EditorEnableState.EnableStackTrace = !EnableStackTrace;
}
GUILayout.FlexibleSpace();
if (GUILayout.Button(ReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
{
TaskTracker.CheckAndResetDirty();
treeView.ReloadAndSort();
Repaint();
}
if (GUILayout.Button(GCHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
{
GC.Collect(0);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
#endregion
#region TableColumn
Vector2 tableScroll;
GUIStyle tableListStyle;
void RenderTable()
{
if (tableListStyle == null)
{
tableListStyle = new GUIStyle("CN Box");
tableListStyle.margin.top = 0;
tableListStyle.padding.left = 3;
}
EditorGUILayout.BeginVertical(tableListStyle, EmptyLayoutOption);
this.tableScroll = EditorGUILayout.BeginScrollView(this.tableScroll, new GUILayoutOption[]
{
GUILayout.ExpandWidth(true),
GUILayout.MaxWidth(2000f)
});
var controlRect = EditorGUILayout.GetControlRect(new GUILayoutOption[]
{
GUILayout.ExpandHeight(true),
GUILayout.ExpandWidth(true)
});
treeView?.OnGUI(controlRect);
EditorGUILayout.EndScrollView();
EditorGUILayout.EndVertical();
}
private void Update()
{
if (EnableAutoReload)
{
if (interval++ % 120 == 0)
{
if (TaskTracker.CheckAndResetDirty())
{
treeView.ReloadAndSort();
Repaint();
}
}
}
}
#endregion
#region Details
static GUIStyle detailsStyle;
Vector2 detailsScroll;
void RenderDetailsPanel()
{
if (detailsStyle == null)
{
detailsStyle = new GUIStyle(EditorStyles.wordWrappedLabel);
detailsStyle.wordWrap = false;
detailsStyle.stretchHeight = true;
detailsStyle.margin.right = 15;
}
string message = "";
var selected = treeView.state.selectedIDs;
if (selected.Count > 0)
{
var first = selected[0];
var item = treeView.CurrentBindingItems.FirstOrDefault(x => x.id == first) as UniTaskTrackerViewItem;
if (item != null)
{
message = item.Position;
}
}
detailsScroll = EditorGUILayout.BeginScrollView(this.detailsScroll, EmptyLayoutOption);
var vector = detailsStyle.CalcSize(new GUIContent(message));
EditorGUILayout.SelectableLabel(message, detailsStyle, new GUILayoutOption[]
{
GUILayout.ExpandHeight(true),
GUILayout.ExpandWidth(true),
GUILayout.MinWidth(vector.x),
GUILayout.MinHeight(vector.y)
});
EditorGUILayout.EndScrollView();
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5bee3e3860e37484aa3b861bf76d129f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
namespace UniRx.Async
{
public static class EnumerableAsyncExtensions
{
// overload resolver - .Select(async x => { }) : IEnumerable<UniTask<T>>
public static IEnumerable<UniTask> Select<T>(this IEnumerable<T> source, Func<T, UniTask> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask<TR>> Select<T, TR>(this IEnumerable<T> source, Func<T, UniTask<TR>> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask> Select<T>(this IEnumerable<T> source, Func<T, int, UniTask> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask<TR>> Select<T, TR>(this IEnumerable<T> source, Func<T, int, UniTask<TR>> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ff50260d74bd54c4b92cf99895549445
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,149 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections;
using System.Runtime.ExceptionServices;
using System.Threading;
using UniRx.Async.Internal;
namespace UniRx.Async
{
public static class EnumeratorAsyncExtensions
{
public static IAwaiter GetAwaiter(this IEnumerator enumerator)
{
var awaiter = new EnumeratorAwaiter(enumerator, CancellationToken.None);
if (!awaiter.IsCompleted)
{
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, awaiter);
}
return awaiter;
}
public static UniTask ToUniTask(this IEnumerator enumerator)
{
var awaiter = new EnumeratorAwaiter(enumerator, CancellationToken.None);
if (!awaiter.IsCompleted)
{
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, awaiter);
}
return new UniTask(awaiter);
}
public static UniTask ConfigureAwait(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
{
var awaiter = new EnumeratorAwaiter(enumerator, cancellationToken);
if (!awaiter.IsCompleted)
{
PlayerLoopHelper.AddAction(timing, awaiter);
}
return new UniTask(awaiter);
}
class EnumeratorAwaiter : IAwaiter, IPlayerLoopItem
{
IEnumerator innerEnumerator;
CancellationToken cancellationToken;
Action continuation;
AwaiterStatus status;
ExceptionDispatchInfo exception;
public EnumeratorAwaiter(IEnumerator innerEnumerator, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
status = AwaiterStatus.Canceled;
return;
}
this.innerEnumerator = innerEnumerator;
this.status = AwaiterStatus.Pending;
this.cancellationToken = cancellationToken;
this.continuation = null;
TaskTracker.TrackActiveTask(this, 2);
}
public bool IsCompleted => status.IsCompleted();
public AwaiterStatus Status => status;
public void GetResult()
{
switch (status)
{
case AwaiterStatus.Succeeded:
break;
case AwaiterStatus.Pending:
Error.ThrowNotYetCompleted();
break;
case AwaiterStatus.Faulted:
exception.Throw();
break;
case AwaiterStatus.Canceled:
Error.ThrowOperationCanceledException();
break;
default:
break;
}
}
public bool MoveNext()
{
if (cancellationToken.IsCancellationRequested)
{
InvokeContinuation(AwaiterStatus.Canceled);
return false;
}
var success = false;
try
{
if (innerEnumerator.MoveNext())
{
return true;
}
else
{
success = true;
}
}
catch (Exception ex)
{
exception = ExceptionDispatchInfo.Capture(ex);
}
InvokeContinuation(success ? AwaiterStatus.Succeeded : AwaiterStatus.Faulted);
return false;
}
void InvokeContinuation(AwaiterStatus status)
{
this.status = status;
var cont = this.continuation;
// cleanup
TaskTracker.RemoveTracking(this);
this.continuation = null;
this.cancellationToken = CancellationToken.None;
this.innerEnumerator = null;
if (cont != null) cont.Invoke();
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
Error.ThrowWhenContinuationIsAlreadyRegistered(this.continuation);
this.continuation = continuation;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc661232f11e4a741af54ba1c175d5ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
using System;
namespace UniRx.Async
{
public static class ExceptionExtensions
{
public static bool IsOperationCanceledException(this Exception exception)
{
return exception is OperationCanceledException;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 930800098504c0d46958ce23a0495202
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591
using System.Runtime.CompilerServices;
namespace UniRx.Async
{
public enum AwaiterStatus
{
/// <summary>The operation has not yet completed.</summary>
Pending = 0,
/// <summary>The operation completed successfully.</summary>
Succeeded = 1,
/// <summary>The operation completed with an error.</summary>
Faulted = 2,
/// <summary>The operation completed due to cancellation.</summary>
Canceled = 3
}
public interface IAwaiter : ICriticalNotifyCompletion
{
AwaiterStatus Status { get; }
bool IsCompleted { get; }
void GetResult();
}
public interface IAwaiter<out T> : IAwaiter
{
new T GetResult();
}
public static class AwaiterStatusExtensions
{
/// <summary>!= Pending.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCompleted(this AwaiterStatus status)
{
return status != AwaiterStatus.Pending;
}
/// <summary>== Succeeded.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCompletedSuccessfully(this AwaiterStatus status)
{
return status == AwaiterStatus.Succeeded;
}
/// <summary>== Canceled.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCanceled(this AwaiterStatus status)
{
return status == AwaiterStatus.Canceled;
}
/// <summary>== Faulted.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsFaulted(this AwaiterStatus status)
{
return status == AwaiterStatus.Faulted;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3e4d023d8404ab742b5e808c98097c3c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 633f49a8aafb6fa43894cd4646c71743
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,152 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace UniRx.Async.Internal
{
// Same interface as System.Buffers.ArrayPool<T> but only provides Shared.
internal sealed class ArrayPool<T>
{
// Same size as System.Buffers.DefaultArrayPool<T>
const int DefaultMaxNumberOfArraysPerBucket = 50;
static readonly T[] EmptyArray = new T[0];
public static readonly ArrayPool<T> Shared = new ArrayPool<T>();
readonly MinimumQueue<T[]>[] buckets;
readonly SpinLock[] locks;
ArrayPool()
{
// see: GetQueueIndex
buckets = new MinimumQueue<T[]>[18];
locks = new SpinLock[18];
for (int i = 0; i < buckets.Length; i++)
{
buckets[i] = new MinimumQueue<T[]>(4);
locks[i] = new SpinLock(false);
}
}
public T[] Rent(int minimumLength)
{
if (minimumLength < 0)
{
throw new ArgumentOutOfRangeException("minimumLength");
}
else if (minimumLength == 0)
{
return EmptyArray;
}
var size = CalculateSize(minimumLength);
var index = GetQueueIndex(size);
if (index != -1)
{
var q = buckets[index];
var lockTaken = false;
try
{
locks[index].Enter(ref lockTaken);
if (q.Count != 0)
{
return q.Dequeue();
}
}
finally
{
if (lockTaken) locks[index].Exit(false);
}
}
return new T[size];
}
public void Return(T[] array, bool clearArray = false)
{
if (array == null || array.Length == 0)
{
return;
}
var index = GetQueueIndex(array.Length);
if (index != -1)
{
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
var q = buckets[index];
var lockTaken = false;
try
{
locks[index].Enter(ref lockTaken);
if (q.Count > DefaultMaxNumberOfArraysPerBucket)
{
return;
}
q.Enqueue(array);
}
finally
{
if (lockTaken) locks[index].Exit(false);
}
}
}
static int CalculateSize(int size)
{
size--;
size |= size >> 1;
size |= size >> 2;
size |= size >> 4;
size |= size >> 8;
size |= size >> 16;
size += 1;
if (size < 8)
{
size = 8;
}
return size;
}
static int GetQueueIndex(int size)
{
switch (size)
{
case 8: return 0;
case 16: return 1;
case 32: return 2;
case 64: return 3;
case 128: return 4;
case 256: return 5;
case 512: return 6;
case 1024: return 7;
case 2048: return 8;
case 4096: return 9;
case 8192: return 10;
case 16384: return 11;
case 32768: return 12;
case 65536: return 13;
case 131072: return 14;
case 262144: return 15;
case 524288: return 16;
case 1048576: return 17; // max array length
default:
return -1;
}
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f83ebad81fb89fb4882331616ca6d248
timeCreated: 1532361008
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,112 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace UniRx.Async.Internal
{
internal static class ArrayPoolUtil
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void EnsureCapacity<T>(ref T[] array, int index, ArrayPool<T> pool)
{
if (array.Length <= index)
{
EnsureCapacityCore(ref array, index, pool);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void EnsureCapacityCore<T>(ref T[] array, int index, ArrayPool<T> pool)
{
if (array.Length <= index)
{
var newSize = array.Length * 2;
var newArray = pool.Rent((index < newSize) ? newSize : (index * 2));
Array.Copy(array, 0, newArray, 0, array.Length);
pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType<T>());
array = newArray;
}
}
public static RentArray<T> Materialize<T>(IEnumerable<T> source)
{
if (source is T[] array)
{
return new RentArray<T>(array, array.Length, null);
}
var defaultCount = 4;
if (source is ICollection<T> coll)
{
defaultCount = coll.Count;
var pool = ArrayPool<T>.Shared;
var buffer = pool.Rent(defaultCount);
coll.CopyTo(buffer, 0);
return new RentArray<T>(buffer, coll.Count, pool);
}
else if (source is IReadOnlyCollection<T> rcoll)
{
defaultCount = rcoll.Count;
}
if (defaultCount == 0)
{
return new RentArray<T>(Array.Empty<T>(), 0, null);
}
{
var pool = ArrayPool<T>.Shared;
var index = 0;
var buffer = pool.Rent(defaultCount);
foreach (var item in source)
{
EnsureCapacity(ref buffer, index, pool);
buffer[index++] = item;
}
return new RentArray<T>(buffer, index, pool);
}
}
public struct RentArray<T> : IDisposable
{
public readonly T[] Array;
public readonly int Length;
ArrayPool<T> pool;
public RentArray(T[] array, int length, ArrayPool<T> pool)
{
this.Array = array;
this.Length = length;
this.pool = pool;
}
public void Dispose()
{
DisposeManually(!RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType<T>());
}
public void DisposeManually(bool clearArray)
{
if (pool != null)
{
if (clearArray)
{
System.Array.Clear(Array, 0, Length);
}
pool.Return(Array, clearArray: false);
pool = null;
}
}
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 424cc208fb61d4e448b08fcfa0eee25e
timeCreated: 1532361007
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace UniRx.Async.Internal
{
internal static class ArrayUtil
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void EnsureCapacity<T>(ref T[] array, int index)
{
if (array.Length <= index)
{
EnsureCore(ref array, index);
}
}
// rare case, no inlining.
[MethodImpl(MethodImplOptions.NoInlining)]
static void EnsureCore<T>(ref T[] array, int index)
{
var newSize = array.Length * 2;
var newArray = new T[(index < newSize) ? newSize : (index * 2)];
Array.Copy(array, 0, newArray, 0, array.Length);
array = newArray;
}
/// <summary>
/// Optimizing utility to avoid .ToArray() that creates buffer copy(cut to just size).
/// </summary>
public static (T[] array, int length) Materialize<T>(IEnumerable<T> source)
{
if (source is T[] array)
{
return (array, array.Length);
}
var defaultCount = 4;
if (source is ICollection<T> coll)
{
defaultCount = coll.Count;
var buffer = new T[defaultCount];
coll.CopyTo(buffer, 0);
return (buffer, defaultCount);
}
else if (source is IReadOnlyCollection<T> rcoll)
{
defaultCount = rcoll.Count;
}
if (defaultCount == 0)
{
return (Array.Empty<T>(), 0);
}
{
var index = 0;
var buffer = new T[defaultCount];
foreach (var item in source)
{
EnsureCapacity(ref buffer, index);
buffer[index++] = item;
}
return (buffer, index);
}
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 23146a82ec99f2542a87971c8d3d7988
timeCreated: 1532361007
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Threading;
namespace UniRx.Async.Internal
{
internal static class CancellationTokenHelper
{
public static bool TrySetOrLinkCancellationToken(ref CancellationToken field, CancellationToken newCancellationToken)
{
if (newCancellationToken == CancellationToken.None)
{
return false;
}
else if (field == CancellationToken.None)
{
field = newCancellationToken;
return true;
}
else if (field == newCancellationToken)
{
return false;
}
field = CancellationTokenSource.CreateLinkedTokenSource(field, newCancellationToken).Token;
return true;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 53d1b536fc7e2d4458294ee2c7d9b743
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,115 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace UniRx.Async.Internal
{
internal class ContinuationQueue
{
const int MaxArrayLength = 0X7FEFFFFF;
const int InitialSize = 16;
SpinLock gate = new SpinLock();
bool dequing = false;
int actionListCount = 0;
Action[] actionList = new Action[InitialSize];
int waitingListCount = 0;
Action[] waitingList = new Action[InitialSize];
public void Enqueue(Action continuation)
{
bool lockTaken = false;
try
{
gate.Enter(ref lockTaken);
if (dequing)
{
// Ensure Capacity
if (waitingList.Length == waitingListCount)
{
var newLength = waitingListCount * 2;
if ((uint)newLength > MaxArrayLength) newLength = MaxArrayLength;
var newArray = new Action[newLength];
Array.Copy(waitingList, newArray, waitingListCount);
waitingList = newArray;
}
waitingList[waitingListCount] = continuation;
waitingListCount++;
}
else
{
// Ensure Capacity
if (actionList.Length == actionListCount)
{
var newLength = actionListCount * 2;
if ((uint)newLength > MaxArrayLength) newLength = MaxArrayLength;
var newArray = new Action[newLength];
Array.Copy(actionList, newArray, actionListCount);
actionList = newArray;
}
actionList[actionListCount] = continuation;
actionListCount++;
}
}
finally
{
if (lockTaken) gate.Exit(false);
}
}
public void Run()
{
{
bool lockTaken = false;
try
{
gate.Enter(ref lockTaken);
if (actionListCount == 0) return;
dequing = true;
}
finally
{
if (lockTaken) gate.Exit(false);
}
}
for (int i = 0; i < actionListCount; i++)
{
var action = actionList[i];
actionList[i] = null;
action();
}
{
bool lockTaken = false;
try
{
gate.Enter(ref lockTaken);
dequing = false;
var swapTempActionList = actionList;
actionListCount = waitingListCount;
actionList = waitingList;
waitingListCount = 0;
waitingList = swapTempActionList;
}
finally
{
if (lockTaken) gate.Exit(false);
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f66c32454e50f2546b17deadc80a4c77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Runtime.CompilerServices;
namespace UniRx.Async.Internal
{
internal static class Error
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ThrowArgumentNullException<T>(T value, string paramName)
where T : class
{
if (value == null) ThrowArgumentNullExceptionCore(paramName);
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void ThrowArgumentNullExceptionCore(string paramName)
{
throw new ArgumentNullException(paramName);
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowArgumentException<T>(string message)
{
throw new ArgumentException(message);
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowNotYetCompleted()
{
throw new InvalidOperationException("Not yet completed.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static T ThrowNotYetCompleted<T>()
{
throw new InvalidOperationException("Not yet completed.");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ThrowWhenContinuationIsAlreadyRegistered<T>(T continuationField)
where T : class
{
if (continuationField != null) ThrowInvalidOperationExceptionCore("continuation is already registered.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void ThrowInvalidOperationExceptionCore(string message)
{
throw new InvalidOperationException(message);
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowOperationCanceledException()
{
throw new OperationCanceledException();
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5f39f495294d4604b8082202faf98554
timeCreated: 1532361007
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
#if NET_4_6 || NET_STANDARD_2_0 || CSHARP_7_OR_LATER
using System;
namespace UniRx.Async.Internal
{
internal static class FuncExtensions
{
// avoid lambda capture
internal static Action<T> AsFuncOfT<T>(this Action action)
{
return new Action<T>(action.Invoke);
}
static void Invoke<T>(this Action action, T unused)
{
action();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4d5a9a3e1f0f069478969f752fde29a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,130 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace UniRx.Async.Internal
{
internal sealed class LazyPromise : IAwaiter
{
Func<UniTask> factory;
UniTask value;
public LazyPromise(Func<UniTask> factory)
{
this.factory = factory;
}
void Create()
{
var f = Interlocked.Exchange(ref factory, null);
if (f != null)
{
value = f();
}
}
public bool IsCompleted
{
get
{
Create();
return value.IsCompleted;
}
}
public AwaiterStatus Status
{
get
{
Create();
return value.Status;
}
}
public void GetResult()
{
Create();
value.GetResult();
}
void IAwaiter.GetResult()
{
GetResult();
}
public void UnsafeOnCompleted(Action continuation)
{
Create();
value.GetAwaiter().UnsafeOnCompleted(continuation);
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
}
internal sealed class LazyPromise<T> : IAwaiter<T>
{
Func<UniTask<T>> factory;
UniTask<T> value;
public LazyPromise(Func<UniTask<T>> factory)
{
this.factory = factory;
}
void Create()
{
var f = Interlocked.Exchange(ref factory, null);
if (f != null)
{
value = f();
}
}
public bool IsCompleted
{
get
{
Create();
return value.IsCompleted;
}
}
public AwaiterStatus Status
{
get
{
Create();
return value.Status;
}
}
public T GetResult()
{
Create();
return value.Result;
}
void IAwaiter.GetResult()
{
GetResult();
}
public void UnsafeOnCompleted(Action continuation)
{
Create();
value.GetAwaiter().UnsafeOnCompleted(continuation);
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe7a4187b7f89f84582fd1e466a7f27e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,122 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#endif
using System;
using System.Runtime.CompilerServices;
namespace UniRx.Async.Internal
{
// optimized version of Standard Queue<T>.
internal class MinimumQueue<T>
{
const int MinimumGrow = 4;
const int GrowFactor = 200;
T[] array;
int head;
int tail;
int size;
public MinimumQueue(int capacity)
{
if (capacity < 0) throw new ArgumentOutOfRangeException("capacity");
array = new T[capacity];
head = tail = size = 0;
}
public int Count
{
#if NET_4_6 || NET_STANDARD_2_0
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
get { return size; }
}
public T Peek()
{
if (size == 0) ThrowForEmptyQueue();
return array[head];
}
#if NET_4_6 || NET_STANDARD_2_0
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
public void Enqueue(T item)
{
if (size == array.Length)
{
Grow();
}
array[tail] = item;
MoveNext(ref tail);
size++;
}
#if NET_4_6 || NET_STANDARD_2_0
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
public T Dequeue()
{
if (size == 0) ThrowForEmptyQueue();
int head = this.head;
T[] array = this.array;
T removed = array[head];
array[head] = default(T);
MoveNext(ref this.head);
size--;
return removed;
}
void Grow()
{
int newcapacity = (int)((long)array.Length * (long)GrowFactor / 100);
if (newcapacity < array.Length + MinimumGrow)
{
newcapacity = array.Length + MinimumGrow;
}
SetCapacity(newcapacity);
}
void SetCapacity(int capacity)
{
T[] newarray = new T[capacity];
if (size > 0)
{
if (head < tail)
{
Array.Copy(array, head, newarray, 0, size);
}
else
{
Array.Copy(array, head, newarray, 0, array.Length - head);
Array.Copy(array, 0, newarray, array.Length - head, tail);
}
}
array = newarray;
head = 0;
tail = (size == capacity) ? 0 : size;
}
#if NET_4_6 || NET_STANDARD_2_0
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
void MoveNext(ref int index)
{
int tmp = index + 1;
if (tmp == array.Length)
{
tmp = 0;
}
index = tmp;
}
void ThrowForEmptyQueue()
{
throw new InvalidOperationException("EmptyQueue");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7d63add489ccc99498114d79702b904d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,153 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
using System;
using UnityEngine;
namespace UniRx.Async.Internal
{
internal sealed class PlayerLoopRunner
{
const int InitialSize = 16;
readonly object runningAndQueueLock = new object();
readonly object arrayLock = new object();
readonly Action<Exception> unhandledExceptionCallback;
int tail = 0;
bool running = false;
IPlayerLoopItem[] loopItems = new IPlayerLoopItem[InitialSize];
MinimumQueue<IPlayerLoopItem> waitQueue = new MinimumQueue<IPlayerLoopItem>(InitialSize);
public PlayerLoopRunner()
{
this.unhandledExceptionCallback = ex => Debug.LogException(ex);
}
public void AddAction(IPlayerLoopItem item)
{
lock (runningAndQueueLock)
{
if (running)
{
waitQueue.Enqueue(item);
return;
}
}
lock (arrayLock)
{
// Ensure Capacity
if (loopItems.Length == tail)
{
Array.Resize(ref loopItems, checked(tail * 2));
}
loopItems[tail++] = item;
}
}
public void Run()
{
lock (runningAndQueueLock)
{
running = true;
}
lock (arrayLock)
{
var j = tail - 1;
// eliminate array-bound check for i
for (int i = 0; i < loopItems.Length; i++)
{
var action = loopItems[i];
if (action != null)
{
try
{
if (!action.MoveNext())
{
loopItems[i] = null;
}
else
{
continue; // next i
}
}
catch (Exception ex)
{
loopItems[i] = null;
try
{
unhandledExceptionCallback(ex);
}
catch { }
}
}
// find null, loop from tail
while (i < j)
{
var fromTail = loopItems[j];
if (fromTail != null)
{
try
{
if (!fromTail.MoveNext())
{
loopItems[j] = null;
j--;
continue; // next j
}
else
{
// swap
loopItems[i] = fromTail;
loopItems[j] = null;
j--;
goto NEXT_LOOP; // next i
}
}
catch (Exception ex)
{
loopItems[j] = null;
j--;
try
{
unhandledExceptionCallback(ex);
}
catch { }
continue; // next j
}
}
else
{
j--;
}
}
tail = i; // loop end
break; // LOOP END
NEXT_LOOP:
continue;
}
lock (runningAndQueueLock)
{
running = false;
while (waitQueue.Count != 0)
{
if (loopItems.Length == tail)
{
Array.Resize(ref loopItems, checked(tail * 2));
}
loopItems[tail++] = waitQueue.Dequeue();
}
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 340c6d420bb4f484aa8683415ea92571
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
namespace UniRx.Async.Internal
{
internal static class PromiseHelper
{
internal static void TrySetResultAll<TPromise, T>(IEnumerable<TPromise> source, T value)
where TPromise : class, IResolvePromise<T>
{
var rentArray = ArrayPoolUtil.Materialize(source);
var clearArray = true;
try
{
var array = rentArray.Array;
var len = rentArray.Length;
for (int i = 0; i < len; i++)
{
array[i].TrySetResult(value);
array[i] = null;
}
clearArray = false;
}
finally
{
rentArray.DisposeManually(clearArray);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 173f9b763911bf847b7dfbf31ee87fc4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,395 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Diagnostics;
using System.Runtime.ExceptionServices;
using System.Threading;
namespace UniRx.Async.Internal
{
// public for some types uses it.
public abstract class ReusablePromise : IAwaiter
{
ExceptionDispatchInfo exception;
object continuation; // Action or Queue<Action>
AwaiterStatus status;
public UniTask Task => new UniTask(this);
// can override for control 'start/reset' timing.
public virtual bool IsCompleted => status.IsCompleted();
public virtual void GetResult()
{
switch (status)
{
case AwaiterStatus.Succeeded:
return;
case AwaiterStatus.Faulted:
exception.Throw();
break;
case AwaiterStatus.Canceled:
throw new OperationCanceledException();
default:
break;
}
throw new InvalidOperationException("Invalid Status:" + status);
}
public AwaiterStatus Status => status;
void IAwaiter.GetResult()
{
GetResult();
}
public void ResetStatus(bool forceReset)
{
if (forceReset)
{
status = AwaiterStatus.Pending;
}
else if (status == AwaiterStatus.Succeeded)
{
status = AwaiterStatus.Pending;
}
}
public virtual bool TrySetCanceled()
{
if (status == AwaiterStatus.Pending)
{
status = AwaiterStatus.Canceled;
TryInvokeContinuation();
return true;
}
return false;
}
public virtual bool TrySetException(Exception ex)
{
if (status == AwaiterStatus.Pending)
{
status = AwaiterStatus.Faulted;
exception = ExceptionDispatchInfo.Capture(ex);
TryInvokeContinuation();
return true;
}
return false;
}
public virtual bool TrySetResult()
{
if (status == AwaiterStatus.Pending)
{
status = AwaiterStatus.Succeeded;
TryInvokeContinuation();
return true;
}
return false;
}
void TryInvokeContinuation()
{
if (continuation == null) return;
if (continuation is Action act)
{
continuation = null;
act();
}
else
{
// reuse Queue(don't null clear)
var q = (MinimumQueue<Action>)continuation;
var size = q.Count;
for (int i = 0; i < size; i++)
{
q.Dequeue().Invoke();
}
}
}
public void OnCompleted(Action action)
{
UnsafeOnCompleted(action);
}
public void UnsafeOnCompleted(Action action)
{
if (continuation == null)
{
continuation = action;
return;
}
else
{
if (continuation is Action act)
{
var q = new MinimumQueue<Action>(4);
q.Enqueue(act);
q.Enqueue(action);
continuation = q;
return;
}
else
{
((MinimumQueue<Action>)continuation).Enqueue(action);
}
}
}
}
public abstract class ReusablePromise<T> : IAwaiter<T>
{
T result;
ExceptionDispatchInfo exception;
object continuation; // Action or Queue<Action>
AwaiterStatus status;
public UniTask<T> Task => new UniTask<T>(this);
// can override for control 'start/reset' timing.
public virtual bool IsCompleted => status.IsCompleted();
protected T RawResult => result;
protected void ForceSetResult(T result)
{
this.result = result;
}
public virtual T GetResult()
{
switch (status)
{
case AwaiterStatus.Succeeded:
return result;
case AwaiterStatus.Faulted:
exception.Throw();
break;
case AwaiterStatus.Canceled:
throw new OperationCanceledException();
default:
break;
}
throw new InvalidOperationException("Invalid Status:" + status);
}
public AwaiterStatus Status => status;
void IAwaiter.GetResult()
{
GetResult();
}
public void ResetStatus(bool forceReset)
{
if (forceReset)
{
status = AwaiterStatus.Pending;
}
else if (status == AwaiterStatus.Succeeded)
{
status = AwaiterStatus.Pending;
}
}
public virtual bool TrySetCanceled()
{
if (status == AwaiterStatus.Pending)
{
status = AwaiterStatus.Canceled;
TryInvokeContinuation();
return true;
}
return false;
}
public virtual bool TrySetException(Exception ex)
{
if (status == AwaiterStatus.Pending)
{
status = AwaiterStatus.Faulted;
exception = ExceptionDispatchInfo.Capture(ex);
TryInvokeContinuation();
return true;
}
return false;
}
public virtual bool TrySetResult(T result)
{
if (status == AwaiterStatus.Pending)
{
status = AwaiterStatus.Succeeded;
this.result = result;
TryInvokeContinuation();
return true;
}
return false;
}
protected void TryInvokeContinuation()
{
if (continuation == null) return;
if (continuation is Action act)
{
continuation = null;
act();
}
else
{
// reuse Queue(don't null clear)
var q = (MinimumQueue<Action>)continuation;
var size = q.Count;
for (int i = 0; i < size; i++)
{
q.Dequeue().Invoke();
}
}
}
public void OnCompleted(Action action)
{
UnsafeOnCompleted(action);
}
public void UnsafeOnCompleted(Action action)
{
if (continuation == null)
{
continuation = action;
return;
}
else
{
if (continuation is Action act)
{
var q = new MinimumQueue<Action>(4);
q.Enqueue(act);
q.Enqueue(action);
continuation = q;
return;
}
else
{
((MinimumQueue<Action>)continuation).Enqueue(action);
}
}
}
}
public abstract class PlayerLoopReusablePromiseBase : ReusablePromise, IPlayerLoopItem
{
readonly PlayerLoopTiming timing;
protected readonly CancellationToken cancellationToken;
bool isRunning = false;
#if UNITY_EDITOR
string capturedStackTraceForDebugging;
#endif
public PlayerLoopReusablePromiseBase(PlayerLoopTiming timing, CancellationToken cancellationToken, int skipTrackFrameCountAdditive)
{
this.timing = timing;
this.cancellationToken = cancellationToken;
#if UNITY_EDITOR
this.capturedStackTraceForDebugging = TaskTracker.CaptureStackTrace(skipTrackFrameCountAdditive + 1); // 1 is self,
#endif
}
public override bool IsCompleted
{
get
{
if (Status == AwaiterStatus.Canceled || Status == AwaiterStatus.Faulted) return true;
if (!isRunning)
{
isRunning = true;
ResetStatus(false);
OnRunningStart();
#if UNITY_EDITOR
TaskTracker.TrackActiveTask(this, capturedStackTraceForDebugging);
#endif
PlayerLoopHelper.AddAction(timing, this);
}
return false;
}
}
protected abstract void OnRunningStart();
protected void Complete()
{
isRunning = false;
#if UNITY_EDITOR
TaskTracker.RemoveTracking(this);
#endif
}
public abstract bool MoveNext();
}
public abstract class PlayerLoopReusablePromiseBase<T> : ReusablePromise<T>, IPlayerLoopItem
{
readonly PlayerLoopTiming timing;
protected readonly CancellationToken cancellationToken;
bool isRunning = false;
#if UNITY_EDITOR
string capturedStackTraceForDebugging;
#endif
public PlayerLoopReusablePromiseBase(PlayerLoopTiming timing, CancellationToken cancellationToken, int skipTrackFrameCountAdditive)
{
this.timing = timing;
this.cancellationToken = cancellationToken;
#if UNITY_EDITOR
this.capturedStackTraceForDebugging = TaskTracker.CaptureStackTrace(skipTrackFrameCountAdditive + 1); // 1 is self,
#endif
}
public override bool IsCompleted
{
get
{
if (Status == AwaiterStatus.Canceled || Status == AwaiterStatus.Faulted) return true;
if (!isRunning)
{
isRunning = true;
ResetStatus(false);
OnRunningStart();
#if UNITY_EDITOR
TaskTracker.TrackActiveTask(this, capturedStackTraceForDebugging);
#endif
PlayerLoopHelper.AddAction(timing, this);
}
return false;
}
}
protected abstract void OnRunningStart();
protected void Complete()
{
isRunning = false;
#if UNITY_EDITOR
TaskTracker.RemoveTracking(this);
#endif
}
public abstract bool MoveNext();
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a8cfc99b5928c0242919aac2121b02bb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using UnityEngine;
namespace UniRx.Async.Internal
{
internal static class RuntimeHelpersAbstraction
{
// If we can use RuntimeHelpers.IsReferenceOrContainsReferences(.NET Core 2.0), use it.
public static bool IsWellKnownNoReferenceContainsType<T>()
{
return WellKnownNoReferenceContainsType<T>.IsWellKnownType;
}
static bool WellKnownNoReferenceContainsTypeInitialize(Type t)
{
// The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single.
if (t.IsPrimitive) return true;
if (t.IsEnum) return true;
if (t == typeof(DateTime)) return true;
if (t == typeof(DateTimeOffset)) return true;
if (t == typeof(Guid)) return true;
if (t == typeof(decimal)) return true;
// unwrap nullable
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return WellKnownNoReferenceContainsTypeInitialize(t.GetGenericArguments()[0]);
}
// or add other wellknown types(Vector, etc...) here
if (t == typeof(Vector2)) return true;
if (t == typeof(Vector3)) return true;
if (t == typeof(Vector4)) return true;
if (t == typeof(Color)) return true;
if (t == typeof(Rect)) return true;
if (t == typeof(Bounds)) return true;
if (t == typeof(Quaternion)) return true;
if (t == typeof(Vector2Int)) return true;
if (t == typeof(Vector3Int)) return true;
return false;
}
static class WellKnownNoReferenceContainsType<T>
{
public static readonly bool IsWellKnownType;
static WellKnownNoReferenceContainsType()
{
IsWellKnownType = WellKnownNoReferenceContainsTypeInitialize(typeof(T));
}
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 94975e4d4e0c0ea4ba787d3872ce9bb4
timeCreated: 1532361007
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,152 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace UniRx.Async.Internal
{
// public for add user custom.
public static class TaskTracker
{
#if UNITY_EDITOR
static int trackingId = 0;
public const string EnableAutoReloadKey = "UniTaskTrackerWindow_EnableAutoReloadKey";
public const string EnableTrackingKey = "UniTaskTrackerWindow_EnableTrackingKey";
public const string EnableStackTraceKey = "UniTaskTrackerWindow_EnableStackTraceKey";
public static class EditorEnableState
{
static bool enableAutoReload;
public static bool EnableAutoReload
{
get { return enableAutoReload; }
set
{
enableAutoReload = value;
UnityEditor.EditorPrefs.SetBool(EnableAutoReloadKey, value);
}
}
static bool enableTracking;
public static bool EnableTracking
{
get { return enableTracking; }
set
{
enableTracking = value;
UnityEditor.EditorPrefs.SetBool(EnableTrackingKey, value);
}
}
static bool enableStackTrace;
public static bool EnableStackTrace
{
get { return enableStackTrace; }
set
{
enableStackTrace = value;
UnityEditor.EditorPrefs.SetBool(EnableStackTraceKey, value);
}
}
}
#endif
static List<KeyValuePair<IAwaiter, (int trackingId, DateTime addTime, string stackTrace)>> listPool = new List<KeyValuePair<IAwaiter, (int trackingId, DateTime addTime, string stackTrace)>>();
static readonly WeakDictionary<IAwaiter, (int trackingId, DateTime addTime, string stackTrace)> tracking = new WeakDictionary<IAwaiter, (int trackingId, DateTime addTime, string stackTrace)>();
[Conditional("UNITY_EDITOR")]
public static void TrackActiveTask(IAwaiter task, int skipFrame = 1)
{
#if UNITY_EDITOR
dirty = true;
if (!EditorEnableState.EnableTracking) return;
var stackTrace = EditorEnableState.EnableStackTrace ? new StackTrace(skipFrame, true).CleanupAsyncStackTrace() : "";
tracking.TryAdd(task, (Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace));
#endif
}
[Conditional("UNITY_EDITOR")]
public static void TrackActiveTask(IAwaiter task, string stackTrace)
{
#if UNITY_EDITOR
dirty = true;
if (!EditorEnableState.EnableTracking) return;
var success = tracking.TryAdd(task, (Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace));
#endif
}
public static string CaptureStackTrace(int skipFrame)
{
#if UNITY_EDITOR
if (!EditorEnableState.EnableTracking) return "";
var stackTrace = EditorEnableState.EnableStackTrace ? new StackTrace(skipFrame + 1, true).CleanupAsyncStackTrace() : "";
return stackTrace;
#else
return null;
#endif
}
[Conditional("UNITY_EDITOR")]
public static void RemoveTracking(IAwaiter task)
{
#if UNITY_EDITOR
dirty = true;
if (!EditorEnableState.EnableTracking) return;
var success = tracking.TryRemove(task);
#endif
}
static bool dirty;
public static bool CheckAndResetDirty()
{
var current = dirty;
dirty = false;
return current;
}
/// <summary>(trackingId, awaiterType, awaiterStatus, createdTime, stackTrace)</summary>
public static void ForEachActiveTask(Action<int, string, AwaiterStatus, DateTime, string> action)
{
lock (listPool)
{
var count = tracking.ToList(ref listPool, clear: false);
try
{
for (int i = 0; i < count; i++)
{
string typeName = null;
var keyType = listPool[i].Key.GetType();
if (keyType.IsNested)
{
typeName = keyType.DeclaringType.Name + "." + keyType.Name;
}
else
{
typeName = keyType.Name;
}
action(listPool[i].Value.trackingId, typeName, listPool[i].Key.Status, listPool[i].Value.addTime, listPool[i].Value.stackTrace);
listPool[i] = new KeyValuePair<IAwaiter, (int trackingId, DateTime addTime, string stackTrace)>(null, (0, default(DateTime), null)); // clear
}
}
catch
{
listPool.Clear();
throw;
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a203c73eb4ccdbb44bddfd82d38fdda9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,271 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#endif
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UniRx.Async.Internal
{
internal static class UnityEqualityComparer
{
public static readonly IEqualityComparer<Vector2> Vector2 = new Vector2EqualityComparer();
public static readonly IEqualityComparer<Vector3> Vector3 = new Vector3EqualityComparer();
public static readonly IEqualityComparer<Vector4> Vector4 = new Vector4EqualityComparer();
public static readonly IEqualityComparer<Color> Color = new ColorEqualityComparer();
public static readonly IEqualityComparer<Color32> Color32 = new Color32EqualityComparer();
public static readonly IEqualityComparer<Rect> Rect = new RectEqualityComparer();
public static readonly IEqualityComparer<Bounds> Bounds = new BoundsEqualityComparer();
public static readonly IEqualityComparer<Quaternion> Quaternion = new QuaternionEqualityComparer();
static readonly RuntimeTypeHandle vector2Type = typeof(Vector2).TypeHandle;
static readonly RuntimeTypeHandle vector3Type = typeof(Vector3).TypeHandle;
static readonly RuntimeTypeHandle vector4Type = typeof(Vector4).TypeHandle;
static readonly RuntimeTypeHandle colorType = typeof(Color).TypeHandle;
static readonly RuntimeTypeHandle color32Type = typeof(Color32).TypeHandle;
static readonly RuntimeTypeHandle rectType = typeof(Rect).TypeHandle;
static readonly RuntimeTypeHandle boundsType = typeof(Bounds).TypeHandle;
static readonly RuntimeTypeHandle quaternionType = typeof(Quaternion).TypeHandle;
#if UNITY_2017_2_OR_NEWER
public static readonly IEqualityComparer<Vector2Int> Vector2Int = new Vector2IntEqualityComparer();
public static readonly IEqualityComparer<Vector3Int> Vector3Int = new Vector3IntEqualityComparer();
public static readonly IEqualityComparer<RangeInt> RangeInt = new RangeIntEqualityComparer();
public static readonly IEqualityComparer<RectInt> RectInt = new RectIntEqualityComparer();
public static readonly IEqualityComparer<BoundsInt> BoundsInt = new BoundsIntEqualityComparer();
static readonly RuntimeTypeHandle vector2IntType = typeof(Vector2Int).TypeHandle;
static readonly RuntimeTypeHandle vector3IntType = typeof(Vector3Int).TypeHandle;
static readonly RuntimeTypeHandle rangeIntType = typeof(RangeInt).TypeHandle;
static readonly RuntimeTypeHandle rectIntType = typeof(RectInt).TypeHandle;
static readonly RuntimeTypeHandle boundsIntType = typeof(BoundsInt).TypeHandle;
#endif
static class Cache<T>
{
public static readonly IEqualityComparer<T> Comparer;
static Cache()
{
var comparer = GetDefaultHelper(typeof(T));
if (comparer == null)
{
Comparer = EqualityComparer<T>.Default;
}
else
{
Comparer = (IEqualityComparer<T>)comparer;
}
}
}
public static IEqualityComparer<T> GetDefault<T>()
{
return Cache<T>.Comparer;
}
static object GetDefaultHelper(Type type)
{
var t = type.TypeHandle;
if (t.Equals(vector2Type)) return (object)UnityEqualityComparer.Vector2;
if (t.Equals(vector3Type)) return (object)UnityEqualityComparer.Vector3;
if (t.Equals(vector4Type)) return (object)UnityEqualityComparer.Vector4;
if (t.Equals(colorType)) return (object)UnityEqualityComparer.Color;
if (t.Equals(color32Type)) return (object)UnityEqualityComparer.Color32;
if (t.Equals(rectType)) return (object)UnityEqualityComparer.Rect;
if (t.Equals(boundsType)) return (object)UnityEqualityComparer.Bounds;
if (t.Equals(quaternionType)) return (object)UnityEqualityComparer.Quaternion;
#if UNITY_2017_2_OR_NEWER
if (t.Equals(vector2IntType)) return (object)UnityEqualityComparer.Vector2Int;
if (t.Equals(vector3IntType)) return (object)UnityEqualityComparer.Vector3Int;
if (t.Equals(rangeIntType)) return (object)UnityEqualityComparer.RangeInt;
if (t.Equals(rectIntType)) return (object)UnityEqualityComparer.RectInt;
if (t.Equals(boundsIntType)) return (object)UnityEqualityComparer.BoundsInt;
#endif
return null;
}
sealed class Vector2EqualityComparer : IEqualityComparer<Vector2>
{
public bool Equals(Vector2 self, Vector2 vector)
{
return self.x.Equals(vector.x) && self.y.Equals(vector.y);
}
public int GetHashCode(Vector2 obj)
{
return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2;
}
}
sealed class Vector3EqualityComparer : IEqualityComparer<Vector3>
{
public bool Equals(Vector3 self, Vector3 vector)
{
return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z);
}
public int GetHashCode(Vector3 obj)
{
return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2;
}
}
sealed class Vector4EqualityComparer : IEqualityComparer<Vector4>
{
public bool Equals(Vector4 self, Vector4 vector)
{
return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z) && self.w.Equals(vector.w);
}
public int GetHashCode(Vector4 obj)
{
return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2 ^ obj.w.GetHashCode() >> 1;
}
}
sealed class ColorEqualityComparer : IEqualityComparer<Color>
{
public bool Equals(Color self, Color other)
{
return self.r.Equals(other.r) && self.g.Equals(other.g) && self.b.Equals(other.b) && self.a.Equals(other.a);
}
public int GetHashCode(Color obj)
{
return obj.r.GetHashCode() ^ obj.g.GetHashCode() << 2 ^ obj.b.GetHashCode() >> 2 ^ obj.a.GetHashCode() >> 1;
}
}
sealed class RectEqualityComparer : IEqualityComparer<Rect>
{
public bool Equals(Rect self, Rect other)
{
return self.x.Equals(other.x) && self.width.Equals(other.width) && self.y.Equals(other.y) && self.height.Equals(other.height);
}
public int GetHashCode(Rect obj)
{
return obj.x.GetHashCode() ^ obj.width.GetHashCode() << 2 ^ obj.y.GetHashCode() >> 2 ^ obj.height.GetHashCode() >> 1;
}
}
sealed class BoundsEqualityComparer : IEqualityComparer<Bounds>
{
public bool Equals(Bounds self, Bounds vector)
{
return self.center.Equals(vector.center) && self.extents.Equals(vector.extents);
}
public int GetHashCode(Bounds obj)
{
return obj.center.GetHashCode() ^ obj.extents.GetHashCode() << 2;
}
}
sealed class QuaternionEqualityComparer : IEqualityComparer<Quaternion>
{
public bool Equals(Quaternion self, Quaternion vector)
{
return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z) && self.w.Equals(vector.w);
}
public int GetHashCode(Quaternion obj)
{
return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2 ^ obj.w.GetHashCode() >> 1;
}
}
sealed class Color32EqualityComparer : IEqualityComparer<Color32>
{
public bool Equals(Color32 self, Color32 vector)
{
return self.a.Equals(vector.a) && self.r.Equals(vector.r) && self.g.Equals(vector.g) && self.b.Equals(vector.b);
}
public int GetHashCode(Color32 obj)
{
return obj.a.GetHashCode() ^ obj.r.GetHashCode() << 2 ^ obj.g.GetHashCode() >> 2 ^ obj.b.GetHashCode() >> 1;
}
}
#if UNITY_2017_2_OR_NEWER
sealed class Vector2IntEqualityComparer : IEqualityComparer<Vector2Int>
{
public bool Equals(Vector2Int self, Vector2Int vector)
{
return self.x.Equals(vector.x) && self.y.Equals(vector.y);
}
public int GetHashCode(Vector2Int obj)
{
return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2;
}
}
sealed class Vector3IntEqualityComparer : IEqualityComparer<Vector3Int>
{
public static readonly Vector3IntEqualityComparer Default = new Vector3IntEqualityComparer();
public bool Equals(Vector3Int self, Vector3Int vector)
{
return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z);
}
public int GetHashCode(Vector3Int obj)
{
return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2;
}
}
sealed class RangeIntEqualityComparer : IEqualityComparer<RangeInt>
{
public bool Equals(RangeInt self, RangeInt vector)
{
return self.start.Equals(vector.start) && self.length.Equals(vector.length);
}
public int GetHashCode(RangeInt obj)
{
return obj.start.GetHashCode() ^ obj.length.GetHashCode() << 2;
}
}
sealed class RectIntEqualityComparer : IEqualityComparer<RectInt>
{
public bool Equals(RectInt self, RectInt other)
{
return self.x.Equals(other.x) && self.width.Equals(other.width) && self.y.Equals(other.y) && self.height.Equals(other.height);
}
public int GetHashCode(RectInt obj)
{
return obj.x.GetHashCode() ^ obj.width.GetHashCode() << 2 ^ obj.y.GetHashCode() >> 2 ^ obj.height.GetHashCode() >> 1;
}
}
sealed class BoundsIntEqualityComparer : IEqualityComparer<BoundsInt>
{
public bool Equals(BoundsInt self, BoundsInt vector)
{
return Vector3IntEqualityComparer.Default.Equals(self.position, vector.position)
&& Vector3IntEqualityComparer.Default.Equals(self.size, vector.size);
}
public int GetHashCode(BoundsInt obj)
{
return Vector3IntEqualityComparer.Default.GetHashCode(obj.position) ^ Vector3IntEqualityComparer.Default.GetHashCode(obj.size) << 2;
}
}
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ebaaf14253c9cfb47b23283218ff9b67
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,336 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Threading;
namespace UniRx.Async.Internal
{
// Add, Remove, Enumerate with sweep. All operations are thread safe(in spinlock).
internal class WeakDictionary<TKey, TValue>
where TKey : class
{
Entry[] buckets;
int size;
SpinLock gate; // mutable struct(not readonly)
readonly float loadFactor;
readonly IEqualityComparer<TKey> keyEqualityComparer;
public WeakDictionary(int capacity = 4, float loadFactor = 0.75f, IEqualityComparer<TKey> keyComparer = null)
{
var tableSize = CalculateCapacity(capacity, loadFactor);
this.buckets = new Entry[tableSize];
this.loadFactor = loadFactor;
this.gate = new SpinLock(false);
this.keyEqualityComparer = keyComparer ?? EqualityComparer<TKey>.Default;
}
public bool TryAdd(TKey key, TValue value)
{
bool lockTaken = false;
try
{
gate.Enter(ref lockTaken);
return TryAddInternal(key, value);
}
finally
{
if (lockTaken) gate.Exit(false);
}
}
public bool TryGetValue(TKey key, out TValue value)
{
bool lockTaken = false;
try
{
gate.Enter(ref lockTaken);
if (TryGetEntry(key, out _, out var entry))
{
value = entry.Value;
return true;
}
value = default(TValue);
return false;
}
finally
{
if (lockTaken) gate.Exit(false);
}
}
public bool TryRemove(TKey key)
{
bool lockTaken = false;
try
{
gate.Enter(ref lockTaken);
if (TryGetEntry(key, out var hashIndex, out var entry))
{
Remove(hashIndex, entry);
return true;
}
return false;
}
finally
{
if (lockTaken) gate.Exit(false);
}
}
bool TryAddInternal(TKey key, TValue value)
{
var nextCapacity = CalculateCapacity(size + 1, loadFactor);
TRY_ADD_AGAIN:
if (buckets.Length < nextCapacity)
{
// rehash
var nextBucket = new Entry[nextCapacity];
for (int i = 0; i < buckets.Length; i++)
{
var e = buckets[i];
while (e != null)
{
AddToBuckets(nextBucket, key, e.Value, e.Hash);
e = e.Next;
}
}
buckets = nextBucket;
goto TRY_ADD_AGAIN;
}
else
{
// add entry
var successAdd = AddToBuckets(buckets, key, value, keyEqualityComparer.GetHashCode(key));
if (successAdd) size++;
return successAdd;
}
}
bool AddToBuckets(Entry[] targetBuckets, TKey newKey, TValue value, int keyHash)
{
var h = keyHash;
var hashIndex = h & (targetBuckets.Length - 1);
TRY_ADD_AGAIN:
if (targetBuckets[hashIndex] == null)
{
targetBuckets[hashIndex] = new Entry
{
Key = new WeakReference<TKey>(newKey, false),
Value = value,
Hash = h
};
return true;
}
else
{
// add to last.
var entry = targetBuckets[hashIndex];
while (entry != null)
{
if (entry.Key.TryGetTarget(out var target))
{
if (keyEqualityComparer.Equals(newKey, target))
{
return false; // duplicate
}
}
else
{
Remove(hashIndex, entry);
if (targetBuckets[hashIndex] == null) goto TRY_ADD_AGAIN; // add new entry
}
if (entry.Next != null)
{
entry = entry.Next;
}
else
{
// found last
entry.Next = new Entry
{
Key = new WeakReference<TKey>(newKey, false),
Value = value,
Hash = h
};
entry.Next.Prev = entry;
}
}
return false;
}
}
bool TryGetEntry(TKey key, out int hashIndex, out Entry entry)
{
var table = buckets;
var hash = keyEqualityComparer.GetHashCode(key);
hashIndex = hash & table.Length - 1;
entry = table[hashIndex];
while (entry != null)
{
if (entry.Key.TryGetTarget(out var target))
{
if (keyEqualityComparer.Equals(key, target))
{
return true;
}
}
else
{
// sweap
Remove(hashIndex, entry);
}
entry = entry.Next;
}
return false;
}
void Remove(int hashIndex, Entry entry)
{
if (entry.Prev == null && entry.Next == null)
{
buckets[hashIndex] = null;
}
else
{
if (entry.Prev == null)
{
buckets[hashIndex] = entry.Next;
}
if (entry.Prev != null)
{
entry.Prev.Next = entry.Next;
}
if (entry.Next != null)
{
entry.Next.Prev = entry.Prev;
}
}
size--;
}
public List<KeyValuePair<TKey, TValue>> ToList()
{
var list = new List<KeyValuePair<TKey, TValue>>(size);
ToList(ref list, false);
return list;
}
// avoid allocate everytime.
public int ToList(ref List<KeyValuePair<TKey, TValue>> list, bool clear = true)
{
if (clear)
{
list.Clear();
}
var listIndex = 0;
bool lockTaken = false;
try
{
for (int i = 0; i < buckets.Length; i++)
{
var entry = buckets[i];
while (entry != null)
{
if (entry.Key.TryGetTarget(out var target))
{
var item = new KeyValuePair<TKey, TValue>(target, entry.Value);
if (listIndex < list.Count)
{
list[listIndex++] = item;
}
else
{
list.Add(item);
listIndex++;
}
}
else
{
// sweap
Remove(i, entry);
}
entry = entry.Next;
}
}
}
finally
{
if (lockTaken) gate.Exit(false);
}
return listIndex;
}
static int CalculateCapacity(int collectionSize, float loadFactor)
{
var size = (int)(((float)collectionSize) / loadFactor);
size--;
size |= size >> 1;
size |= size >> 2;
size |= size >> 4;
size |= size >> 8;
size |= size >> 16;
size += 1;
if (size < 8)
{
size = 8;
}
return size;
}
class Entry
{
public WeakReference<TKey> Key;
public TValue Value;
public int Hash;
public Entry Prev;
public Entry Next;
// debug only
public override string ToString()
{
if (Key.TryGetTarget(out var target))
{
return target + "(" + Count() + ")";
}
else
{
return "(Dead)";
}
}
int Count()
{
var count = 1;
var n = this;
while (n.Next != null)
{
count++;
n = n.Next;
}
return count;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6c78563864409714593226af59bcb6f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Linq;
using UnityEngine;
using UniRx.Async.Internal;
using System.Threading;
#if UNITY_2019_3_OR_NEWER
using UnityEngine.LowLevel;
#else
using UnityEngine.Experimental.LowLevel;
#endif
namespace UniRx.Async
{
public static class UniTaskLoopRunners
{
public struct UniTaskLoopRunnerInitialization { };
public struct UniTaskLoopRunnerEarlyUpdate { };
public struct UniTaskLoopRunnerFixedUpdate { };
public struct UniTaskLoopRunnerPreUpdate { };
public struct UniTaskLoopRunnerUpdate { };
public struct UniTaskLoopRunnerPreLateUpdate { };
public struct UniTaskLoopRunnerPostLateUpdate { };
// Yield
public struct UniTaskLoopRunnerYieldInitialization { };
public struct UniTaskLoopRunnerYieldEarlyUpdate { };
public struct UniTaskLoopRunnerYieldFixedUpdate { };
public struct UniTaskLoopRunnerYieldPreUpdate { };
public struct UniTaskLoopRunnerYieldUpdate { };
public struct UniTaskLoopRunnerYieldPreLateUpdate { };
public struct UniTaskLoopRunnerYieldPostLateUpdate { };
}
public enum PlayerLoopTiming
{
Initialization = 0,
EarlyUpdate = 1,
FixedUpdate = 2,
PreUpdate = 3,
Update = 4,
PreLateUpdate = 5,
PostLateUpdate = 6
}
public interface IPlayerLoopItem
{
bool MoveNext();
}
public static class PlayerLoopHelper
{
public static SynchronizationContext UnitySynchronizationContext => unitySynchronizationContetext;
public static int MainThreadId => mainThreadId;
static int mainThreadId;
static SynchronizationContext unitySynchronizationContetext;
static ContinuationQueue[] yielders;
static PlayerLoopRunner[] runners;
static PlayerLoopSystem[] InsertRunner(PlayerLoopSystem loopSystem, Type loopRunnerYieldType, ContinuationQueue cq, Type loopRunnerType, PlayerLoopRunner runner)
{
var yieldLoop = new PlayerLoopSystem
{
type = loopRunnerYieldType,
updateDelegate = cq.Run
};
var runnerLoop = new PlayerLoopSystem
{
type = loopRunnerType,
updateDelegate = runner.Run
};
var dest = new PlayerLoopSystem[loopSystem.subSystemList.Length + 2];
Array.Copy(loopSystem.subSystemList, 0, dest, 2, loopSystem.subSystemList.Length);
dest[0] = yieldLoop;
dest[1] = runnerLoop;
return dest;
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void Init()
{
// capture default(unity) sync-context.
unitySynchronizationContetext = SynchronizationContext.Current;
mainThreadId = Thread.CurrentThread.ManagedThreadId;
if (runners != null) return; // already initialized
var playerLoop =
#if UNITY_2019_3_OR_NEWER
PlayerLoop.GetCurrentPlayerLoop();
#else
PlayerLoop.GetDefaultPlayerLoop();
#endif
Initialize(ref playerLoop);
}
public static void Initialize(ref PlayerLoopSystem playerLoop)
{
yielders = new ContinuationQueue[7];
runners = new PlayerLoopRunner[7];
var copyList = playerLoop.subSystemList.ToArray();
copyList[0].subSystemList = InsertRunner(copyList[0], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldInitialization), yielders[0] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization), runners[0] = new PlayerLoopRunner());
copyList[1].subSystemList = InsertRunner(copyList[1], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldEarlyUpdate), yielders[1] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerEarlyUpdate), runners[1] = new PlayerLoopRunner());
copyList[2].subSystemList = InsertRunner(copyList[2], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldFixedUpdate), yielders[2] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerFixedUpdate), runners[2] = new PlayerLoopRunner());
copyList[3].subSystemList = InsertRunner(copyList[3], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreUpdate), yielders[3] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreUpdate), runners[3] = new PlayerLoopRunner());
copyList[4].subSystemList = InsertRunner(copyList[4], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldUpdate), yielders[4] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerUpdate), runners[4] = new PlayerLoopRunner());
copyList[5].subSystemList = InsertRunner(copyList[5], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreLateUpdate), yielders[5] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreLateUpdate), runners[5] = new PlayerLoopRunner());
copyList[6].subSystemList = InsertRunner(copyList[6], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPostLateUpdate), yielders[6] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPostLateUpdate), runners[6] = new PlayerLoopRunner());
playerLoop.subSystemList = copyList;
PlayerLoop.SetPlayerLoop(playerLoop);
}
public static void AddAction(PlayerLoopTiming timing, IPlayerLoopItem action)
{
runners[(int)timing].AddAction(action);
}
public static void AddContinuation(PlayerLoopTiming timing, Action continuation)
{
yielders[(int)timing].Enqueue(continuation);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15fb5b85042f19640b973ce651795aca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
#if NET_4_6 || NET_STANDARD_2_0 || CSHARP_7_OR_LATER
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using UniRx.Async.Internal;
namespace UniRx.Async
{
/// <summary>
/// Lightweight IProgress[T] factory.
/// </summary>
public static class Progress
{
public static IProgress<T> Create<T>(Action<T> handler)
{
if (handler == null) return NullProgress<T>.Instance;
return new AnonymousProgress<T>(handler);
}
public static IProgress<T> CreateOnlyValueChanged<T>(Action<T> handler, IEqualityComparer<T> comparer = null)
{
if (handler == null) return NullProgress<T>.Instance;
return new OnlyValueChangedProgress<T>(handler, comparer ?? UnityEqualityComparer.GetDefault<T>());
}
sealed class NullProgress<T> : IProgress<T>
{
public static readonly IProgress<T> Instance = new NullProgress<T>();
NullProgress()
{
}
public void Report(T value)
{
}
}
sealed class AnonymousProgress<T> : IProgress<T>
{
readonly Action<T> action;
public AnonymousProgress(Action<T> action)
{
this.action = action;
}
public void Report(T value)
{
action(value);
}
}
sealed class OnlyValueChangedProgress<T> : IProgress<T>
{
readonly Action<T> action;
readonly IEqualityComparer<T> comparer;
bool isFirstCall;
T latestValue;
public OnlyValueChangedProgress(Action<T> action, IEqualityComparer<T> comparer)
{
this.action = action;
this.comparer = comparer;
this.isFirstCall = true;
}
public void Report(T value)
{
if (isFirstCall)
{
isFirstCall = false;
}
else if (comparer.Equals(value, latestValue))
{
return;
}
latestValue = value;
action(value);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e3377e2ae934ed54fb8fd5388e2d9eb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 85c0c768ced512e42b24021b3258b669
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncAnimatorTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<int> onAnimatorIK;
AsyncTriggerPromiseDictionary<int> onAnimatorIKs;
AsyncTriggerPromise<AsyncUnit> onAnimatorMove;
AsyncTriggerPromiseDictionary<AsyncUnit> onAnimatorMoves;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onAnimatorIK, onAnimatorIKs, onAnimatorMove, onAnimatorMoves);
}
void OnAnimatorIK(int layerIndex)
{
TrySetResult(onAnimatorIK, onAnimatorIKs, layerIndex);
}
public UniTask OnAnimatorIKAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onAnimatorIK, ref onAnimatorIKs, cancellationToken);
}
void OnAnimatorMove()
{
TrySetResult(onAnimatorMove, onAnimatorMoves, AsyncUnit.Default);
}
public UniTask OnAnimatorMoveAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onAnimatorMove, ref onAnimatorMoves, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae912c37ac7f4cd42b25f22452435103
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using UnityEngine;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncAwakeTrigger : MonoBehaviour
{
bool called = false;
UniTaskCompletionSource promise;
void Awake()
{
called = true;
promise?.TrySetResult();
}
public UniTask AwakeAsync()
{
if (called) return UniTask.CompletedTask;
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, new AwakeMonitor(this));
return new UniTask(promise ?? (promise = new UniTaskCompletionSource()));
}
private void OnDestroy()
{
promise?.TrySetCanceled();
}
class AwakeMonitor : IPlayerLoopItem
{
readonly AsyncAwakeTrigger trigger;
public AwakeMonitor(AsyncAwakeTrigger trigger)
{
this.trigger = trigger;
}
public bool MoveNext()
{
if (trigger.called) return false;
if (trigger == null)
{
trigger.OnDestroy();
return false;
}
return true;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef2840a2586894741a0ae211b8fd669b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncBeginDragTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<PointerEventData> onBeginDrag;
AsyncTriggerPromiseDictionary<PointerEventData> onBeginDrags;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onBeginDrag, onBeginDrags);
}
void OnBeginDrag(PointerEventData eventData)
{
TrySetResult(onBeginDrag, onBeginDrags, eventData);
}
public UniTask OnBeginDragAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onBeginDrag, ref onBeginDrags, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 171fd2191eb22af4fbd92b51815ca757
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncCancelTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<BaseEventData> onCancel;
AsyncTriggerPromiseDictionary<BaseEventData> onCancels;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onCancel, onCancels);
}
void OnCancel(BaseEventData eventData)
{
TrySetResult(onCancel, onCancels, eventData);
}
public UniTask OnCancelAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onCancel, ref onCancels, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 291886b6e5f2d044a85b2a4dedcaca97
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncCanvasGroupChangedTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<AsyncUnit> onCanvasGroupChanged;
AsyncTriggerPromiseDictionary<AsyncUnit> onCanvasGroupChangeds;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onCanvasGroupChanged, onCanvasGroupChangeds);
}
void OnCanvasGroupChanged()
{
TrySetResult(onCanvasGroupChanged, onCanvasGroupChangeds, AsyncUnit.Default);
}
public UniTask OnCanvasGroupChangedAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onCanvasGroupChanged, ref onCanvasGroupChangeds, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eddba832648f83046a320ffcacfc771d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncCollision2DTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<Collision2D> onCollisionEnter2D;
AsyncTriggerPromiseDictionary<Collision2D> onCollisionEnter2Ds;
AsyncTriggerPromise<Collision2D> onCollisionExit2D;
AsyncTriggerPromiseDictionary<Collision2D> onCollisionExit2Ds;
AsyncTriggerPromise<Collision2D> onCollisionStay2D;
AsyncTriggerPromiseDictionary<Collision2D> onCollisionStay2Ds;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onCollisionEnter2D, onCollisionEnter2Ds, onCollisionExit2D, onCollisionExit2Ds, onCollisionStay2D, onCollisionStay2Ds);
}
void OnCollisionEnter2D(Collision2D coll)
{
TrySetResult(onCollisionEnter2D, onCollisionEnter2Ds, coll);
}
public UniTask OnCollisionEnter2DAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onCollisionEnter2D, ref onCollisionEnter2Ds, cancellationToken);
}
void OnCollisionExit2D(Collision2D coll)
{
TrySetResult(onCollisionExit2D, onCollisionExit2Ds, coll);
}
public UniTask OnCollisionExit2DAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onCollisionExit2D, ref onCollisionExit2Ds, cancellationToken);
}
void OnCollisionStay2D(Collision2D coll)
{
TrySetResult(onCollisionStay2D, onCollisionStay2Ds, coll);
}
public UniTask OnCollisionStay2DAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onCollisionStay2D, ref onCollisionStay2Ds, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fbeb63f69bedec44f8003730887f914b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncCollisionTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<Collision> onCollisionEnter;
AsyncTriggerPromiseDictionary<Collision> onCollisionEnters;
AsyncTriggerPromise<Collision> onCollisionExit;
AsyncTriggerPromiseDictionary<Collision> onCollisionExits;
AsyncTriggerPromise<Collision> onCollisionStay;
AsyncTriggerPromiseDictionary<Collision> onCollisionStays;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onCollisionEnter, onCollisionEnters, onCollisionExit, onCollisionExits, onCollisionStay, onCollisionStays);
}
void OnCollisionEnter(Collision collision)
{
TrySetResult(onCollisionEnter, onCollisionEnters, collision);
}
public UniTask OnCollisionEnterAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onCollisionEnter, ref onCollisionEnters, cancellationToken);
}
void OnCollisionExit(Collision collisionInfo)
{
TrySetResult(onCollisionExit, onCollisionExits, collisionInfo);
}
public UniTask OnCollisionExitAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onCollisionExit, ref onCollisionExits, cancellationToken);
}
void OnCollisionStay(Collision collisionInfo)
{
TrySetResult(onCollisionStay, onCollisionStays, collisionInfo);
}
public UniTask OnCollisionStayAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onCollisionStay, ref onCollisionStays, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 72db4a683be8f6a428823502599014a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncDeselectTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<BaseEventData> onDeselect;
AsyncTriggerPromiseDictionary<BaseEventData> onDeselects;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onDeselect, onDeselects);
}
void OnDeselect(BaseEventData eventData)
{
TrySetResult(onDeselect, onDeselects, eventData);
}
public UniTask OnDeselectAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onDeselect, ref onDeselects, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30faa9be5bd883e488bdc52f4825c4da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,93 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Threading;
using UniRx.Async.Internal;
using UnityEngine;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncDestroyTrigger : MonoBehaviour
{
bool called = false;
UniTaskCompletionSource promise;
CancellationTokenSource cancellationTokenSource; // main cancellation
object canellationTokenSourceOrQueue; // external from AddCancellationTriggerOnDestory
public CancellationToken CancellationToken
{
get
{
if (cancellationTokenSource == null)
{
cancellationTokenSource = new CancellationTokenSource();
}
return cancellationTokenSource.Token;
}
}
/// <summary>This function is called when the MonoBehaviour will be destroyed.</summary>
void OnDestroy()
{
called = true;
promise?.TrySetResult();
cancellationTokenSource?.Cancel();
cancellationTokenSource?.Dispose();
if (canellationTokenSourceOrQueue != null)
{
if (canellationTokenSourceOrQueue is CancellationTokenSource cts)
{
cts.Cancel();
cts.Dispose();
}
else
{
var q = (MinimumQueue<CancellationTokenSource>)canellationTokenSourceOrQueue;
while (q.Count != 0)
{
var c = q.Dequeue();
c.Cancel();
c.Dispose();
}
}
canellationTokenSourceOrQueue = null;
}
}
/// <summary>This function is called when the MonoBehaviour will be destroyed.</summary>
public UniTask OnDestroyAsync()
{
if (called) return UniTask.CompletedTask;
return new UniTask(promise ?? (promise = new UniTaskCompletionSource()));
}
/// <summary>Add Cancellation Triggers on destroy</summary>
public void AddCancellationTriggerOnDestory(CancellationTokenSource cts)
{
if (called)
{
cts.Cancel();
cts.Dispose();
}
if (canellationTokenSourceOrQueue == null)
{
canellationTokenSourceOrQueue = cts;
}
else if (canellationTokenSourceOrQueue is CancellationTokenSource c)
{
var q = new MinimumQueue<CancellationTokenSource>(4);
q.Enqueue(c);
q.Enqueue(cts);
canellationTokenSourceOrQueue = q;
}
else
{
((MinimumQueue<CancellationTokenSource>)canellationTokenSourceOrQueue).Enqueue(cts);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f4afdcb1cbadf954ba8b1cf465429e17
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncDragTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<PointerEventData> onDrag;
AsyncTriggerPromiseDictionary<PointerEventData> onDrags;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onDrag, onDrags);
}
void OnDrag(PointerEventData eventData)
{
TrySetResult(onDrag, onDrags, eventData);
}
public UniTask OnDragAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onDrag, ref onDrags, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 52242547ba60ea74f8a2e3bbab5fcdfa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncDropTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<PointerEventData> onDrop;
AsyncTriggerPromiseDictionary<PointerEventData> onDrops;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onDrop, onDrops);
}
void OnDrop(PointerEventData eventData)
{
TrySetResult(onDrop, onDrops, eventData);
}
public UniTask OnDropAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onDrop, ref onDrops, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42d65fd5e4be25f41a927eca25b0acf7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncEnableDisableTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<AsyncUnit> onEnable;
AsyncTriggerPromiseDictionary<AsyncUnit> onEnables;
AsyncTriggerPromise<AsyncUnit> onDisable;
AsyncTriggerPromiseDictionary<AsyncUnit> onDisables;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onEnable, onEnables, onDisable, onDisables);
}
void OnEnable()
{
TrySetResult(onEnable, onEnables, AsyncUnit.Default);
}
public UniTask OnEnableAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onEnable, ref onEnables, cancellationToken);
}
void OnDisable()
{
TrySetResult(onDisable, onDisables, AsyncUnit.Default);
}
public UniTask OnDisableAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onDisable, ref onDisables, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d0bf9142b63b4cb43b693f0b83b3dbe7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UniRx.Async.Triggers
{
[DisallowMultipleComponent]
public class AsyncEndDragTrigger : AsyncTriggerBase
{
AsyncTriggerPromise<PointerEventData> onEndDrag;
AsyncTriggerPromiseDictionary<PointerEventData> onEndDrags;
protected override IEnumerable<ICancelablePromise> GetPromises()
{
return Concat(onEndDrag, onEndDrags);
}
void OnEndDrag(PointerEventData eventData)
{
TrySetResult(onEndDrag, onEndDrags, eventData);
}
public UniTask OnEndDragAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return GetOrAddPromise(ref onEndDrag, ref onEndDrags, cancellationToken);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8298d43de348acc4aa4e7dbf30472dbf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More