Init TEngine4.0.0

Init TEngine4.0.0
This commit is contained in:
ALEXTANG
2023-10-08 15:21:33 +08:00
parent 4c8c37ffd8
commit 8c3d6308b9
3773 changed files with 49313 additions and 150734 deletions

View File

@@ -0,0 +1,150 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks.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;
}
}
}
}

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,115 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.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 = 32;
if (source is ICollection<T> coll)
{
if (coll.Count == 0)
{
return new RentArray<T>(Array.Empty<T>(), 0, null);
}
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;
}
}
}
}
}

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,73 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.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);
}
}
}
}

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,225 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks.Internal
{
internal sealed class ContinuationQueue
{
const int MaxArrayLength = 0X7FEFFFFF;
const int InitialSize = 16;
readonly PlayerLoopTiming timing;
SpinLock gate = new SpinLock(false);
bool dequing = false;
int actionListCount = 0;
Action[] actionList = new Action[InitialSize];
int waitingListCount = 0;
Action[] waitingList = new Action[InitialSize];
public ContinuationQueue(PlayerLoopTiming timing)
{
this.timing = timing;
}
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 int Clear()
{
var rest = actionListCount + waitingListCount;
actionListCount = 0;
actionList = new Action[InitialSize];
waitingListCount = 0;
waitingList = new Action[InitialSize];
return rest;
}
// delegate entrypoint.
public void Run()
{
// for debugging, create named stacktrace.
#if DEBUG
switch (timing)
{
case PlayerLoopTiming.Initialization:
Initialization();
break;
case PlayerLoopTiming.LastInitialization:
LastInitialization();
break;
case PlayerLoopTiming.EarlyUpdate:
EarlyUpdate();
break;
case PlayerLoopTiming.LastEarlyUpdate:
LastEarlyUpdate();
break;
case PlayerLoopTiming.FixedUpdate:
FixedUpdate();
break;
case PlayerLoopTiming.LastFixedUpdate:
LastFixedUpdate();
break;
case PlayerLoopTiming.PreUpdate:
PreUpdate();
break;
case PlayerLoopTiming.LastPreUpdate:
LastPreUpdate();
break;
case PlayerLoopTiming.Update:
Update();
break;
case PlayerLoopTiming.LastUpdate:
LastUpdate();
break;
case PlayerLoopTiming.PreLateUpdate:
PreLateUpdate();
break;
case PlayerLoopTiming.LastPreLateUpdate:
LastPreLateUpdate();
break;
case PlayerLoopTiming.PostLateUpdate:
PostLateUpdate();
break;
case PlayerLoopTiming.LastPostLateUpdate:
LastPostLateUpdate();
break;
#if UNITY_2020_2_OR_NEWER
case PlayerLoopTiming.TimeUpdate:
TimeUpdate();
break;
case PlayerLoopTiming.LastTimeUpdate:
LastTimeUpdate();
break;
#endif
default:
break;
}
#else
RunCore();
#endif
}
void Initialization() => RunCore();
void LastInitialization() => RunCore();
void EarlyUpdate() => RunCore();
void LastEarlyUpdate() => RunCore();
void FixedUpdate() => RunCore();
void LastFixedUpdate() => RunCore();
void PreUpdate() => RunCore();
void LastPreUpdate() => RunCore();
void Update() => RunCore();
void LastUpdate() => RunCore();
void PreLateUpdate() => RunCore();
void LastPreLateUpdate() => RunCore();
void PostLateUpdate() => RunCore();
void LastPostLateUpdate() => RunCore();
#if UNITY_2020_2_OR_NEWER
void TimeUpdate() => RunCore();
void LastTimeUpdate() => RunCore();
#endif
[System.Diagnostics.DebuggerHidden]
void RunCore()
{
{
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;
try
{
action();
}
catch (Exception ex)
{
UnityEngine.Debug.LogException(ex);
}
}
{
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);
}
}
}
}
}

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,249 @@
#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;
using UnityEngine;
namespace Cysharp.Threading.Tasks.Internal
{
internal 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 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, "(at {0})", AppendHyperLink(fileName, sf.GetFileLineNumber().ToString()));
}
}
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>(false);
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.Replace("Cysharp.Threading.Tasks.Triggers.", "").Replace("Cysharp.Threading.Tasks.Internal.", "").Replace("Cysharp.Threading.Tasks.", "") ?? 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, "").Replace("Cysharp.Threading.Tasks.Triggers.", "").Replace("Cysharp.Threading.Tasks.Internal.", "").Replace("Cysharp.Threading.Tasks.", "") + "<" + 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("Cysharp.Threading.Tasks.CompilerServices"))
{
return true;
}
else if (declareType == "System.Threading.Tasks.AwaitTaskContinuation")
{
return true;
}
else if (declareType.StartsWith("System.Threading.Tasks.Task"))
{
return true;
}
else if (declareType.StartsWith("Cysharp.Threading.Tasks.UniTaskCompletionSourceCore"))
{
return true;
}
else if (declareType.StartsWith("Cysharp.Threading.Tasks.AwaiterActions"))
{
return true;
}
return false;
}
static string AppendHyperLink(string path, string line)
{
var fi = new FileInfo(path);
if (fi.Directory == null)
{
return fi.Name;
}
else
{
var fname = fi.FullName.Replace(Path.DirectorySeparatorChar, '/').Replace(PlayerLoopHelper.ApplicationDataPath, "");
var withAssetsPath = "Assets/" + fname;
return "<a href=\"" + withAssetsPath + "\" line=\"" + line + "\">" + withAssetsPath + ":" + line + "</a>";
}
}
}
}

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,79 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.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.AggressiveInlining)]
public static Exception ArgumentOutOfRange(string paramName)
{
return new ArgumentOutOfRangeException(paramName);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Exception NoElements()
{
return new InvalidOperationException("Source sequence doesn't contain any elements.");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Exception MoreThanOneElement()
{
return new InvalidOperationException("Source sequence contains more than one element.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowArgumentException(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();
}
}
}

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,112 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.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
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return size; }
}
public T Peek()
{
if (size == 0) ThrowForEmptyQueue();
return array[head];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Enqueue(T item)
{
if (size == array.Length)
{
Grow();
}
array[tail] = item;
MoveNext(ref tail);
size++;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
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;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
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,260 @@

using System;
using UnityEngine;
namespace Cysharp.Threading.Tasks.Internal
{
internal sealed class PlayerLoopRunner
{
const int InitialSize = 16;
readonly PlayerLoopTiming timing;
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(PlayerLoopTiming timing)
{
this.unhandledExceptionCallback = ex => Debug.LogException(ex);
this.timing = timing;
}
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 int Clear()
{
lock (arrayLock)
{
var rest = 0;
for (var index = 0; index < loopItems.Length; index++)
{
if (loopItems[index] != null)
{
rest++;
}
loopItems[index] = null;
}
tail = 0;
return rest;
}
}
// delegate entrypoint.
public void Run()
{
// for debugging, create named stacktrace.
#if DEBUG
switch (timing)
{
case PlayerLoopTiming.Initialization:
Initialization();
break;
case PlayerLoopTiming.LastInitialization:
LastInitialization();
break;
case PlayerLoopTiming.EarlyUpdate:
EarlyUpdate();
break;
case PlayerLoopTiming.LastEarlyUpdate:
LastEarlyUpdate();
break;
case PlayerLoopTiming.FixedUpdate:
FixedUpdate();
break;
case PlayerLoopTiming.LastFixedUpdate:
LastFixedUpdate();
break;
case PlayerLoopTiming.PreUpdate:
PreUpdate();
break;
case PlayerLoopTiming.LastPreUpdate:
LastPreUpdate();
break;
case PlayerLoopTiming.Update:
Update();
break;
case PlayerLoopTiming.LastUpdate:
LastUpdate();
break;
case PlayerLoopTiming.PreLateUpdate:
PreLateUpdate();
break;
case PlayerLoopTiming.LastPreLateUpdate:
LastPreLateUpdate();
break;
case PlayerLoopTiming.PostLateUpdate:
PostLateUpdate();
break;
case PlayerLoopTiming.LastPostLateUpdate:
LastPostLateUpdate();
break;
#if UNITY_2020_2_OR_NEWER
case PlayerLoopTiming.TimeUpdate:
TimeUpdate();
break;
case PlayerLoopTiming.LastTimeUpdate:
LastTimeUpdate();
break;
#endif
default:
break;
}
#else
RunCore();
#endif
}
void Initialization() => RunCore();
void LastInitialization() => RunCore();
void EarlyUpdate() => RunCore();
void LastEarlyUpdate() => RunCore();
void FixedUpdate() => RunCore();
void LastFixedUpdate() => RunCore();
void PreUpdate() => RunCore();
void LastPreUpdate() => RunCore();
void Update() => RunCore();
void LastUpdate() => RunCore();
void PreLateUpdate() => RunCore();
void LastPreLateUpdate() => RunCore();
void PostLateUpdate() => RunCore();
void LastPostLateUpdate() => RunCore();
#if UNITY_2020_2_OR_NEWER
void TimeUpdate() => RunCore();
void LastTimeUpdate() => RunCore();
#endif
[System.Diagnostics.DebuggerHidden]
void RunCore()
{
lock (runningAndQueueLock)
{
running = true;
}
lock (arrayLock)
{
var j = tail - 1;
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();
}
}
}
}
}
}

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,50 @@
using System;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.Internal
{
internal sealed class PooledDelegate<T> : ITaskPoolNode<PooledDelegate<T>>
{
static TaskPool<PooledDelegate<T>> pool;
PooledDelegate<T> nextNode;
public ref PooledDelegate<T> NextNode => ref nextNode;
static PooledDelegate()
{
TaskPool.RegisterSizeGetter(typeof(PooledDelegate<T>), () => pool.Size);
}
readonly Action<T> runDelegate;
Action continuation;
PooledDelegate()
{
runDelegate = Run;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Action<T> Create(Action continuation)
{
if (!pool.TryPop(out var item))
{
item = new PooledDelegate<T>();
}
item.continuation = continuation;
return item.runDelegate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run(T _)
{
var call = continuation;
continuation = null;
if (call != null)
{
pool.TryPush(this);
call.Invoke();
}
}
}
}

View File

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

View File

@@ -0,0 +1,64 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
#if UNITY_2018_3_OR_NEWER
using UnityEngine;
#endif
namespace Cysharp.Threading.Tasks.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]);
}
#if UNITY_2018_3_OR_NEWER
// 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;
#endif
return false;
}
static class WellKnownNoReferenceContainsType<T>
{
public static readonly bool IsWellKnownType;
static WellKnownNoReferenceContainsType()
{
IsWellKnownType = WellKnownNoReferenceContainsTypeInitialize(typeof(T));
}
}
}
}

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,153 @@
using System;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.Internal
{
internal static class StateTuple
{
public static StateTuple<T1> Create<T1>(T1 item1)
{
return StatePool<T1>.Create(item1);
}
public static StateTuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2)
{
return StatePool<T1, T2>.Create(item1, item2);
}
public static StateTuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)
{
return StatePool<T1, T2, T3>.Create(item1, item2, item3);
}
}
internal class StateTuple<T1> : IDisposable
{
public T1 Item1;
public void Deconstruct(out T1 item1)
{
item1 = this.Item1;
}
public void Dispose()
{
StatePool<T1>.Return(this);
}
}
internal static class StatePool<T1>
{
static readonly ConcurrentQueue<StateTuple<T1>> queue = new ConcurrentQueue<StateTuple<T1>>();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static StateTuple<T1> Create(T1 item1)
{
if (queue.TryDequeue(out var value))
{
value.Item1 = item1;
return value;
}
return new StateTuple<T1> { Item1 = item1 };
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Return(StateTuple<T1> tuple)
{
tuple.Item1 = default;
queue.Enqueue(tuple);
}
}
internal class StateTuple<T1, T2> : IDisposable
{
public T1 Item1;
public T2 Item2;
public void Deconstruct(out T1 item1, out T2 item2)
{
item1 = this.Item1;
item2 = this.Item2;
}
public void Dispose()
{
StatePool<T1, T2>.Return(this);
}
}
internal static class StatePool<T1, T2>
{
static readonly ConcurrentQueue<StateTuple<T1, T2>> queue = new ConcurrentQueue<StateTuple<T1, T2>>();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static StateTuple<T1, T2> Create(T1 item1, T2 item2)
{
if (queue.TryDequeue(out var value))
{
value.Item1 = item1;
value.Item2 = item2;
return value;
}
return new StateTuple<T1, T2> { Item1 = item1, Item2 = item2 };
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Return(StateTuple<T1, T2> tuple)
{
tuple.Item1 = default;
tuple.Item2 = default;
queue.Enqueue(tuple);
}
}
internal class StateTuple<T1, T2, T3> : IDisposable
{
public T1 Item1;
public T2 Item2;
public T3 Item3;
public void Deconstruct(out T1 item1, out T2 item2, out T3 item3)
{
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
}
public void Dispose()
{
StatePool<T1, T2, T3>.Return(this);
}
}
internal static class StatePool<T1, T2, T3>
{
static readonly ConcurrentQueue<StateTuple<T1, T2, T3>> queue = new ConcurrentQueue<StateTuple<T1, T2, T3>>();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static StateTuple<T1, T2, T3> Create(T1 item1, T2 item2, T3 item3)
{
if (queue.TryDequeue(out var value))
{
value.Item1 = item1;
value.Item2 = item2;
value.Item3 = item3;
return value;
}
return new StateTuple<T1, T2, T3> { Item1 = item1, Item2 = item2, Item3 = item3 };
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Return(StateTuple<T1, T2, T3> tuple)
{
tuple.Item1 = default;
tuple.Item2 = default;
tuple.Item3 = default;
queue.Enqueue(tuple);
}
}
}

View File

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

View File

@@ -0,0 +1,178 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using Cysharp.Threading.Tasks.Internal;
namespace Cysharp.Threading.Tasks
{
// 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<IUniTaskSource, (string formattedType, int trackingId, DateTime addTime, string stackTrace)>> listPool = new List<KeyValuePair<IUniTaskSource, (string formattedType, int trackingId, DateTime addTime, string stackTrace)>>();
static readonly WeakDictionary<IUniTaskSource, (string formattedType, int trackingId, DateTime addTime, string stackTrace)> tracking = new WeakDictionary<IUniTaskSource, (string formattedType, int trackingId, DateTime addTime, string stackTrace)>();
[Conditional("UNITY_EDITOR")]
public static void TrackActiveTask(IUniTaskSource task, int skipFrame)
{
#if UNITY_EDITOR
dirty = true;
if (!EditorEnableState.EnableTracking) return;
var stackTrace = EditorEnableState.EnableStackTrace ? new StackTrace(skipFrame, true).CleanupAsyncStackTrace() : "";
string typeName;
if (EditorEnableState.EnableStackTrace)
{
var sb = new StringBuilder();
TypeBeautify(task.GetType(), sb);
typeName = sb.ToString();
}
else
{
typeName = task.GetType().Name;
}
tracking.TryAdd(task, (typeName, Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace));
#endif
}
[Conditional("UNITY_EDITOR")]
public static void RemoveTracking(IUniTaskSource 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, UniTaskStatus, DateTime, string> action)
{
lock (listPool)
{
var count = tracking.ToList(ref listPool, clear: false);
try
{
for (int i = 0; i < count; i++)
{
action(listPool[i].Value.trackingId, listPool[i].Value.formattedType, listPool[i].Key.UnsafeGetStatus(), listPool[i].Value.addTime, listPool[i].Value.stackTrace);
listPool[i] = default;
}
}
catch
{
listPool.Clear();
throw;
}
}
}
static void TypeBeautify(Type type, StringBuilder sb)
{
if (type.IsNested)
{
// TypeBeautify(type.DeclaringType, sb);
sb.Append(type.DeclaringType.Name.ToString());
sb.Append(".");
}
if (type.IsGenericType)
{
var genericsStart = type.Name.IndexOf("`");
if (genericsStart != -1)
{
sb.Append(type.Name.Substring(0, genericsStart));
}
else
{
sb.Append(type.Name);
}
sb.Append("<");
var first = true;
foreach (var item in type.GetGenericArguments())
{
if (!first)
{
sb.Append(", ");
}
first = false;
TypeBeautify(item, sb);
}
sb.Append(">");
}
else
{
sb.Append(type.Name);
}
}
//static string RemoveUniTaskNamespace(string str)
//{
// return str.Replace("Cysharp.Threading.Tasks.CompilerServices", "")
// .Replace("Cysharp.Threading.Tasks.Linq", "")
// .Replace("Cysharp.Threading.Tasks", "");
//}
}
}

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,267 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Cysharp.Threading.Tasks.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,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine.Networking;
namespace Cysharp.Threading.Tasks.Internal
{
#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT)
internal static class UnityWebRequestResultExtensions
{
public static bool IsError(this UnityWebRequest unityWebRequest)
{
#if UNITY_2020_2_OR_NEWER
var result = unityWebRequest.result;
return (result == UnityWebRequest.Result.ConnectionError)
|| (result == UnityWebRequest.Result.DataProcessingError)
|| (result == UnityWebRequest.Result.ProtocolError);
#else
return unityWebRequest.isHttpError || unityWebRequest.isNetworkError;
#endif
}
}
#endif
}

View File

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

View File

@@ -0,0 +1,37 @@
using System;
using System.Diagnostics;
namespace Cysharp.Threading.Tasks.Internal
{
internal readonly struct ValueStopwatch
{
static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
readonly long startTimestamp;
public static ValueStopwatch StartNew() => new ValueStopwatch(Stopwatch.GetTimestamp());
ValueStopwatch(long startTimestamp)
{
this.startTimestamp = startTimestamp;
}
public TimeSpan Elapsed => TimeSpan.FromTicks(this.ElapsedTicks);
public bool IsInvalid => startTimestamp == 0;
public long ElapsedTicks
{
get
{
if (startTimestamp == 0)
{
throw new InvalidOperationException("Detected invalid initialization(use 'default'), only to create from StartNew().");
}
var delta = Stopwatch.GetTimestamp() - startTimestamp;
return (long)(delta * TimestampToTicks);
}
}
}
}

View File

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

View File

@@ -0,0 +1,334 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Threading;
namespace Cysharp.Threading.Tasks.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;
}
}
}
}

View File

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