From 17a3687159a1edc436f2acd4d59271fad967154c Mon Sep 17 00:00:00 2001 From: YangHua <1475658476@qq.com> Date: Tue, 25 Jun 2024 13:21:51 +0800 Subject: [PATCH] 2323 --- .../u3d-ShanDongVirtualPowerPlant/v17/.suo | Bin 1398272 -> 454656 bytes .../Assets/Adam/Scenes/Main.unity | 1703 +++ .../Assets/Adam/Scripts/AsyncWebReq.cs | 74 + .../Assets/Adam/Scripts/AsyncWebReq.cs.meta | 11 + .../Assets/Adam/Scripts/Bootstrap.cs | 32 +- .../Assets/Adam/Scripts/CityInfo.cs | 30 +- .../Assets/Adam/{ => Scripts}/Data.meta | 0 .../Adam/{ => Scripts}/Data/AreaData.cs | 31 +- .../Adam/{ => Scripts}/Data/AreaData.cs.meta | 0 .../Assets/Adam/Scripts/Data/CityExcelData.cs | 120 + .../Adam/Scripts/Data/CityExcelData.cs.meta | 11 + .../Assets/Adam/Scripts/TEst.cs | 29 + .../Assets/Adam/Scripts/TEst.cs.meta | 11 + .../Assets/Adam/Scripts/UniTask.meta | 8 + .../Assets/Adam/Scripts/UniTask/Editor.meta | 8 + .../UniTask/Editor/SplitterGUILayout.cs | 62 + .../UniTask/Editor/SplitterGUILayout.cs.meta | 11 + .../UniTask/Editor/UniTask.Editor.asmdef | 17 + .../UniTask/Editor/UniTask.Editor.asmdef.meta | 7 + .../UniTask/Editor/UniTaskTrackerTreeView.cs | 182 + .../Editor/UniTaskTrackerTreeView.cs.meta | 11 + .../UniTask/Editor/UniTaskTrackerWindow.cs | 209 + .../Editor/UniTaskTrackerWindow.cs.meta | 11 + .../Assets/Adam/Scripts/UniTask/Runtime.meta | 8 + .../Adam/Scripts/UniTask/Runtime/AsyncLazy.cs | 245 + .../Scripts/UniTask/Runtime/AsyncLazy.cs.meta | 11 + .../UniTask/Runtime/AsyncReactiveProperty.cs | 644 + .../Runtime/AsyncReactiveProperty.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/AsyncUnit.cs | 26 + .../Scripts/UniTask/Runtime/AsyncUnit.cs.meta | 11 + .../CancellationTokenEqualityComparer.cs | 23 + .../CancellationTokenEqualityComparer.cs.meta | 11 + .../Runtime/CancellationTokenExtensions.cs | 182 + .../CancellationTokenExtensions.cs.meta | 11 + .../CancellationTokenSourceExtensions.cs | 44 + .../CancellationTokenSourceExtensions.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Channel.cs | 450 + .../Scripts/UniTask/Runtime/Channel.cs.meta | 11 + .../UniTask/Runtime/CompilerServices.meta | 8 + .../AsyncMethodBuilderAttribute.cs | 17 + .../AsyncMethodBuilderAttribute.cs.meta | 11 + .../AsyncUniTaskMethodBuilder.cs | 269 + .../AsyncUniTaskMethodBuilder.cs.meta | 11 + .../AsyncUniTaskVoidMethodBuilder.cs | 137 + .../AsyncUniTaskVoidMethodBuilder.cs.meta | 11 + .../CompilerServices/StateMachineRunner.cs | 380 + .../StateMachineRunner.cs.meta | 11 + .../Runtime/EnumerableAsyncExtensions.cs | 34 + .../Runtime/EnumerableAsyncExtensions.cs.meta | 11 + .../Runtime/EnumeratorAsyncExtensions.cs | 287 + .../Runtime/EnumeratorAsyncExtensions.cs.meta | 11 + .../UniTask/Runtime/ExceptionExtensions.cs | 14 + .../Runtime/ExceptionExtensions.cs.meta | 11 + .../Scripts/UniTask/Runtime/External.meta | 8 + .../Runtime/External/Addressables.meta | 8 + .../AddressablesAsyncExtensions.cs | 401 + .../AddressablesAsyncExtensions.cs.meta | 11 + .../Addressables/UniTask.Addressables.asmdef | 27 + .../UniTask.Addressables.asmdef.meta | 7 + .../UniTask/Runtime/External/DOTween.meta | 8 + .../DOTween/DOTweenAsyncExtensions.cs | 470 + .../DOTween/DOTweenAsyncExtensions.cs.meta | 11 + .../External/DOTween/UniTask.DOTween.asmdef | 22 + .../DOTween/UniTask.DOTween.asmdef.meta | 7 + .../UniTask/Runtime/External/TextMeshPro.meta | 8 + .../TextMeshProAsyncExtensions.InputField.cs | 224 + ...tMeshProAsyncExtensions.InputField.cs.meta | 11 + .../TextMeshPro/TextMeshProAsyncExtensions.cs | 130 + .../TextMeshProAsyncExtensions.cs.meta | 11 + .../TextMeshPro/UniTask.TextMeshPro.asmdef | 22 + .../UniTask.TextMeshPro.asmdef.meta | 7 + .../Runtime/IUniTaskAsyncEnumerable.cs | 91 + .../Runtime/IUniTaskAsyncEnumerable.cs.meta | 11 + .../Scripts/UniTask/Runtime/IUniTaskSource.cs | 124 + .../UniTask/Runtime/IUniTaskSource.cs.meta | 11 + .../Scripts/UniTask/Runtime/Internal.meta | 8 + .../UniTask/Runtime/Internal/ArrayPool.cs | 150 + .../Runtime/Internal/ArrayPool.cs.meta | 12 + .../UniTask/Runtime/Internal/ArrayPoolUtil.cs | 115 + .../Runtime/Internal/ArrayPoolUtil.cs.meta | 12 + .../UniTask/Runtime/Internal/ArrayUtil.cs | 73 + .../Runtime/Internal/ArrayUtil.cs.meta | 12 + .../Runtime/Internal/ContinuationQueue.cs | 225 + .../Internal/ContinuationQueue.cs.meta | 11 + .../Runtime/Internal/DiagnosticsExtensions.cs | 249 + .../Internal/DiagnosticsExtensions.cs.meta | 11 + .../Scripts/UniTask/Runtime/Internal/Error.cs | 79 + .../UniTask/Runtime/Internal/Error.cs.meta | 12 + .../UniTask/Runtime/Internal/MinimumQueue.cs | 112 + .../Runtime/Internal/MinimumQueue.cs.meta | 11 + .../Runtime/Internal/PlayerLoopRunner.cs | 260 + .../Runtime/Internal/PlayerLoopRunner.cs.meta | 11 + .../Runtime/Internal/PooledDelegate.cs | 50 + .../Runtime/Internal/PooledDelegate.cs.meta | 11 + .../Internal/RuntimeHelpersAbstraction.cs | 64 + .../RuntimeHelpersAbstraction.cs.meta | 12 + .../UniTask/Runtime/Internal/StatePool.cs | 153 + .../Runtime/Internal/StatePool.cs.meta | 11 + .../UniTask/Runtime/Internal/TaskTracker.cs | 178 + .../Runtime/Internal/TaskTracker.cs.meta | 11 + .../Runtime/Internal/UnityEqualityComparer.cs | 267 + .../Internal/UnityEqualityComparer.cs.meta | 11 + .../Internal/UnityWebRequestExtensions.cs | 28 + .../UnityWebRequestExtensions.cs.meta | 11 + .../Runtime/Internal/ValueStopwatch.cs | 37 + .../Runtime/Internal/ValueStopwatch.cs.meta | 11 + .../Runtime/Internal/WeakDictionary.cs | 334 + .../Runtime/Internal/WeakDictionary.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq.meta | 8 + .../Scripts/UniTask/Runtime/Linq/Aggregate.cs | 318 + .../UniTask/Runtime/Linq/Aggregate.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/All.cs | 108 + .../Scripts/UniTask/Runtime/Linq/All.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Any.cs | 136 + .../Scripts/UniTask/Runtime/Linq/Any.cs.meta | 11 + .../UniTask/Runtime/Linq/AppendPrepend.cs | 151 + .../Runtime/Linq/AppendPrepend.cs.meta | 11 + .../Runtime/Linq/AsUniTaskAsyncEnumerable.cs | 10 + .../Linq/AsUniTaskAsyncEnumerable.cs.meta | 11 + .../Runtime/Linq/AsyncEnumeratorBase.cs | 356 + .../Runtime/Linq/AsyncEnumeratorBase.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Average.cs | 1524 +++ .../UniTask/Runtime/Linq/Average.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Buffer.cs | 345 + .../UniTask/Runtime/Linq/Buffer.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Cast.cs | 53 + .../Scripts/UniTask/Runtime/Linq/Cast.cs.meta | 11 + .../UniTask/Runtime/Linq/CombineLatest.cs | 11372 ++++++++++++++++ .../Runtime/Linq/CombineLatest.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Concat.cs | 164 + .../UniTask/Runtime/Linq/Concat.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Contains.cs | 50 + .../UniTask/Runtime/Linq/Contains.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Count.cs | 144 + .../UniTask/Runtime/Linq/Count.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Create.cs | 174 + .../UniTask/Runtime/Linq/Create.cs.meta | 11 + .../UniTask/Runtime/Linq/DefaultIfEmpty.cs | 142 + .../Runtime/Linq/DefaultIfEmpty.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Distinct.cs | 277 + .../UniTask/Runtime/Linq/Distinct.cs.meta | 11 + .../Runtime/Linq/DistinctUntilChanged.cs | 662 + .../Runtime/Linq/DistinctUntilChanged.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Do.cs | 258 + .../Scripts/UniTask/Runtime/Linq/Do.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/ElementAt.cs | 58 + .../UniTask/Runtime/Linq/ElementAt.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Empty.cs | 47 + .../UniTask/Runtime/Linq/Empty.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Except.cs | 116 + .../UniTask/Runtime/Linq/Except.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/First.cs | 200 + .../UniTask/Runtime/Linq/First.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/ForEach.cs | 193 + .../UniTask/Runtime/Linq/ForEach.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/GroupBy.cs | 923 ++ .../UniTask/Runtime/Linq/GroupBy.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/GroupJoin.cs | 612 + .../UniTask/Runtime/Linq/GroupJoin.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Intersect.cs | 117 + .../UniTask/Runtime/Linq/Intersect.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Join.cs | 728 + .../Scripts/UniTask/Runtime/Linq/Join.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Last.cs | 240 + .../Scripts/UniTask/Runtime/Linq/Last.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/LongCount.cs | 144 + .../UniTask/Runtime/Linq/LongCount.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Max.cs | 200 + .../Scripts/UniTask/Runtime/Linq/Max.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Min.cs | 200 + .../Scripts/UniTask/Runtime/Linq/Min.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/MinMax.cs | 3763 +++++ .../UniTask/Runtime/Linq/MinMax.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Never.cs | 56 + .../UniTask/Runtime/Linq/Never.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/OfType.cs | 61 + .../UniTask/Runtime/Linq/OfType.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/OrderBy.cs | 558 + .../UniTask/Runtime/Linq/OrderBy.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Pairwise.cs | 128 + .../UniTask/Runtime/Linq/Pairwise.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Publish.cs | 173 + .../UniTask/Runtime/Linq/Publish.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Queue.cs | 103 + .../UniTask/Runtime/Linq/Queue.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Range.cs | 75 + .../UniTask/Runtime/Linq/Range.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Repeat.cs | 68 + .../UniTask/Runtime/Linq/Repeat.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Return.cs | 63 + .../UniTask/Runtime/Linq/Return.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Reverse.cs | 78 + .../UniTask/Runtime/Linq/Reverse.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Select.cs | 760 ++ .../UniTask/Runtime/Linq/Select.cs.meta | 11 + .../UniTask/Runtime/Linq/SelectMany.cs | 892 ++ .../UniTask/Runtime/Linq/SelectMany.cs.meta | 11 + .../UniTask/Runtime/Linq/SequenceEqual.cs | 87 + .../Runtime/Linq/SequenceEqual.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Single.cs | 230 + .../UniTask/Runtime/Linq/Single.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Skip.cs | 69 + .../Scripts/UniTask/Runtime/Linq/Skip.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/SkipLast.cs | 159 + .../UniTask/Runtime/Linq/SkipLast.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/SkipUntil.cs | 187 + .../UniTask/Runtime/Linq/SkipUntil.cs.meta | 11 + .../UniTask/Runtime/Linq/SkipUntilCanceled.cs | 173 + .../Runtime/Linq/SkipUntilCanceled.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/SkipWhile.cs | 379 + .../UniTask/Runtime/Linq/SkipWhile.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Subscribe.cs | 536 + .../UniTask/Runtime/Linq/Subscribe.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Sum.cs | 1244 ++ .../Scripts/UniTask/Runtime/Linq/Sum.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Take.cs | 124 + .../Scripts/UniTask/Runtime/Linq/Take.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/TakeLast.cs | 175 + .../UniTask/Runtime/Linq/TakeLast.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/TakeUntil.cs | 190 + .../UniTask/Runtime/Linq/TakeUntil.cs.meta | 11 + .../UniTask/Runtime/Linq/TakeUntilCanceled.cs | 164 + .../Runtime/Linq/TakeUntilCanceled.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/TakeWhile.cs | 342 + .../UniTask/Runtime/Linq/TakeWhile.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Throw.cs | 54 + .../UniTask/Runtime/Linq/Throw.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/ToArray.cs | 60 + .../UniTask/Runtime/Linq/ToArray.cs.meta | 11 + .../UniTask/Runtime/Linq/ToDictionary.cs | 278 + .../UniTask/Runtime/Linq/ToDictionary.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/ToHashSet.cs | 50 + .../UniTask/Runtime/Linq/ToHashSet.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/ToList.cs | 42 + .../UniTask/Runtime/Linq/ToList.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/ToLookup.cs | 554 + .../UniTask/Runtime/Linq/ToLookup.cs.meta | 11 + .../UniTask/Runtime/Linq/ToObservable.cs | 97 + .../UniTask/Runtime/Linq/ToObservable.cs.meta | 11 + .../Runtime/Linq/ToUniTaskAsyncEnumerable.cs | 1115 ++ .../Linq/ToUniTaskAsyncEnumerable.cs.meta | 11 + .../UniTask/Runtime/Linq/UniTask.Linq.asmdef | 15 + .../Runtime/Linq/UniTask.Linq.asmdef.meta | 7 + .../Scripts/UniTask/Runtime/Linq/Union.cs | 26 + .../UniTask/Runtime/Linq/Union.cs.meta | 11 + .../UniTask/Runtime/Linq/UnityExtensions.meta | 8 + .../Linq/UnityExtensions/EveryUpdate.cs | 77 + .../Linq/UnityExtensions/EveryUpdate.cs.meta | 11 + .../Linq/UnityExtensions/EveryValueChanged.cs | 240 + .../UnityExtensions/EveryValueChanged.cs.meta | 11 + .../Runtime/Linq/UnityExtensions/Timer.cs | 312 + .../Linq/UnityExtensions/Timer.cs.meta | 11 + .../Scripts/UniTask/Runtime/Linq/Where.cs | 818 ++ .../UniTask/Runtime/Linq/Where.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Linq/Zip.cs | 541 + .../Scripts/UniTask/Runtime/Linq/Zip.cs.meta | 11 + .../Scripts/UniTask/Runtime/MoveNextSource.cs | 63 + .../UniTask/Runtime/MoveNextSource.cs.meta | 11 + .../UniTask/Runtime/PlayerLoopHelper.cs | 577 + .../UniTask/Runtime/PlayerLoopHelper.cs.meta | 11 + .../UniTask/Runtime/PlayerLoopTimer.cs | 262 + .../UniTask/Runtime/PlayerLoopTimer.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/Progress.cs | 87 + .../Scripts/UniTask/Runtime/Progress.cs.meta | 11 + .../Adam/Scripts/UniTask/Runtime/TaskPool.cs | 123 + .../Scripts/UniTask/Runtime/TaskPool.cs.meta | 11 + .../UniTask/Runtime/TimeoutController.cs | 129 + .../UniTask/Runtime/TimeoutController.cs.meta | 11 + .../Scripts/UniTask/Runtime/TriggerEvent.cs | 311 + .../UniTask/Runtime/TriggerEvent.cs.meta | 11 + .../Scripts/UniTask/Runtime/Triggers.meta | 8 + .../Runtime/Triggers/AsyncAwakeTrigger.cs | 32 + .../Triggers/AsyncAwakeTrigger.cs.meta | 11 + .../Runtime/Triggers/AsyncDestroyTrigger.cs | 97 + .../Triggers/AsyncDestroyTrigger.cs.meta | 11 + .../Runtime/Triggers/AsyncStartTrigger.cs | 38 + .../Triggers/AsyncStartTrigger.cs.meta | 11 + .../Runtime/Triggers/AsyncTriggerBase.cs | 310 + .../Runtime/Triggers/AsyncTriggerBase.cs.meta | 11 + .../Triggers/AsyncTriggerExtensions.cs | 102 + .../Triggers/AsyncTriggerExtensions.cs.meta | 11 + .../Triggers/MonoBehaviourMessagesTriggers.cs | 4457 ++++++ .../MonoBehaviourMessagesTriggers.cs.meta | 11 + .../Scripts/UniTask/Runtime/UniTask.Bridge.cs | 18 + .../UniTask/Runtime/UniTask.Bridge.cs.meta | 11 + .../Scripts/UniTask/Runtime/UniTask.Delay.cs | 965 ++ .../UniTask/Runtime/UniTask.Delay.cs.meta | 11 + .../UniTask/Runtime/UniTask.Factory.cs | 499 + .../UniTask/Runtime/UniTask.Factory.cs.meta | 11 + .../Scripts/UniTask/Runtime/UniTask.Run.cs | 289 + .../UniTask/Runtime/UniTask.Run.cs.meta | 11 + .../UniTask/Runtime/UniTask.Threading.cs | 412 + .../UniTask/Runtime/UniTask.Threading.cs.meta | 11 + .../UniTask/Runtime/UniTask.WaitUntil.cs | 582 + .../UniTask/Runtime/UniTask.WaitUntil.cs.meta | 11 + .../Runtime/UniTask.WhenAll.Generated.cs | 5011 +++++++ .../Runtime/UniTask.WhenAll.Generated.cs.meta | 11 + .../UniTask/Runtime/UniTask.WhenAll.cs | 237 + .../UniTask/Runtime/UniTask.WhenAll.cs.meta | 11 + .../Runtime/UniTask.WhenAny.Generated.cs | 5060 +++++++ .../Runtime/UniTask.WhenAny.Generated.cs.meta | 11 + .../UniTask/Runtime/UniTask.WhenAny.cs | 359 + .../UniTask/Runtime/UniTask.WhenAny.cs.meta | 11 + .../Scripts/UniTask/Runtime/UniTask.asmdef | 45 + .../UniTask/Runtime/UniTask.asmdef.meta | 7 + .../Adam/Scripts/UniTask/Runtime/UniTask.cs | 707 + .../Scripts/UniTask/Runtime/UniTask.cs.meta | 11 + .../Runtime/UniTaskCompletionSource.cs | 941 ++ .../Runtime/UniTaskCompletionSource.cs.meta | 11 + .../Runtime/UniTaskExtensions.Shorthand.cs | 187 + .../UniTaskExtensions.Shorthand.cs.meta | 11 + .../UniTask/Runtime/UniTaskExtensions.cs | 921 ++ .../UniTask/Runtime/UniTaskExtensions.cs.meta | 11 + .../Runtime/UniTaskObservableExtensions.cs | 750 + .../UniTaskObservableExtensions.cs.meta | 11 + .../UniTask/Runtime/UniTaskScheduler.cs | 103 + .../UniTask/Runtime/UniTaskScheduler.cs.meta | 11 + .../Runtime/UniTaskSynchronizationContext.cs | 158 + .../UniTaskSynchronizationContext.cs.meta | 11 + .../Scripts/UniTask/Runtime/UniTaskVoid.cs | 19 + .../UniTask/Runtime/UniTaskVoid.cs.meta | 11 + ...cExtensions.AssetBundleRequestAllAssets.cs | 198 + ...nsions.AssetBundleRequestAllAssets.cs.meta | 11 + .../UnityAsyncExtensions.AsyncGPUReadback.cs | 140 + ...tyAsyncExtensions.AsyncGPUReadback.cs.meta | 11 + .../Runtime/UnityAsyncExtensions.Jobs.cs | 102 + .../Runtime/UnityAsyncExtensions.Jobs.cs.meta | 11 + .../UnityAsyncExtensions.MonoBehaviour.cs | 14 + ...UnityAsyncExtensions.MonoBehaviour.cs.meta | 11 + .../UniTask/Runtime/UnityAsyncExtensions.cs | 932 ++ .../Runtime/UnityAsyncExtensions.cs.meta | 11 + .../Runtime/UnityAsyncExtensions.uGUI.cs | 858 ++ .../Runtime/UnityAsyncExtensions.uGUI.cs.meta | 11 + .../UniTask/Runtime/UnityBindingExtensions.cs | 245 + .../Runtime/UnityBindingExtensions.cs.meta | 11 + .../Runtime/UnityWebRequestException.cs | 67 + .../Runtime/UnityWebRequestException.cs.meta | 11 + .../UniTask/Runtime/_InternalVisibleTo.cs | 6 + .../Runtime/_InternalVisibleTo.cs.meta | 11 + .../Assets/Adam/Scripts/UniTask/package.json | 12 + .../Adam/Scripts/UniTask/package.json.meta | 7 + .../Assets/Adam/Scripts/Utility/FileUtil.cs | 86 + .../Adam/Scripts/Utility/FileUtil.cs.meta | 11 + .../Assets/Adam/Scripts/Utility/IOHelper.cs | 69 + .../Adam/Scripts/Utility/IOHelper.cs.meta | 11 + .../Assets/Adam/Scripts/Utility/JsonHelper.cs | 30 + .../Adam/Scripts/Utility/JsonHelper.cs.meta | 11 + .../Adam/Scripts/Utility/StringHelper.cs | 27 + .../Adam/Scripts/Utility/StringHelper.cs.meta | 11 + .../Adam/Scripts/Utility/ToolUtility.cs | 118 + .../Adam/Scripts/Utility/ToolUtility.cs.meta | 11 + .../Assets/Adam/Scripts/WebAdapter.cs | 12 + .../Assets/Excels.meta | 8 + .../Assets/Excels/山东行政区划数据.xlsx | Bin 0 -> 18052 bytes .../Assets/Excels/山东行政区划数据.xlsx.meta | 7 + .../Assets/Plugins/Excel.dll | Bin 0 -> 68608 bytes .../Assets/Plugins/Excel.dll.meta | 33 + .../Plugins/ICSharpCode.SharpZipLib.dll | Bin 0 -> 192512 bytes .../Plugins/ICSharpCode.SharpZipLib.dll.meta | 33 + .../Assets/Plugins/Newtonsoft.Json.dll | Bin 0 -> 690688 bytes .../Assets/Plugins/Newtonsoft.Json.dll.meta | 33 + .../Assets/Plugins/System.Data.dll | Bin 0 -> 856064 bytes .../Assets/Plugins/System.Data.dll.meta | 33 + .../Assets/StreamingAssets.meta | 8 + .../Assets/StreamingAssets/WebAddress.json | 1 + .../StreamingAssets/WebAddress.json.meta | 7 + .../ProjectSettings/ProjectSettings.asset | 2 +- ...gnTimeResolveAssemblyReferencesInput.cache | Bin 39536 -> 41351 bytes 368 files changed, 73059 insertions(+), 36 deletions(-) create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/AsyncWebReq.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/AsyncWebReq.cs.meta rename u3d-ShanDongVirtualPowerPlant/Assets/Adam/{ => Scripts}/Data.meta (100%) rename u3d-ShanDongVirtualPowerPlant/Assets/Adam/{ => Scripts}/Data/AreaData.cs (58%) rename u3d-ShanDongVirtualPowerPlant/Assets/Adam/{ => Scripts}/Data/AreaData.cs.meta (100%) create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/CityExcelData.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/CityExcelData.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/TEst.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/TEst.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/SplitterGUILayout.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/SplitterGUILayout.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTask.Editor.asmdef create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTask.Editor.asmdef.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerTreeView.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerTreeView.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerWindow.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerWindow.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncLazy.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncLazy.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncReactiveProperty.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncReactiveProperty.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncUnit.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncUnit.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenEqualityComparer.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenEqualityComparer.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenSourceExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenSourceExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Channel.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Channel.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/StateMachineRunner.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/StateMachineRunner.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumerableAsyncExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumerableAsyncExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumeratorAsyncExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumeratorAsyncExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/ExceptionExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/ExceptionExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskAsyncEnumerable.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskAsyncEnumerable.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskSource.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskSource.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPool.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPool.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPoolUtil.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPoolUtil.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayUtil.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayUtil.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ContinuationQueue.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ContinuationQueue.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/DiagnosticsExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/DiagnosticsExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/Error.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/Error.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/MinimumQueue.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/MinimumQueue.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PlayerLoopRunner.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PlayerLoopRunner.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PooledDelegate.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PooledDelegate.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/StatePool.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/StatePool.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/TaskTracker.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/TaskTracker.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityEqualityComparer.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityEqualityComparer.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ValueStopwatch.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ValueStopwatch.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/WeakDictionary.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/WeakDictionary.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Aggregate.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Aggregate.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/All.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/All.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Any.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Any.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AppendPrepend.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AppendPrepend.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Average.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Average.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Buffer.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Buffer.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Cast.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Cast.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/CombineLatest.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/CombineLatest.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Concat.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Concat.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Contains.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Contains.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Count.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Count.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Create.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Create.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DefaultIfEmpty.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DefaultIfEmpty.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Distinct.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Distinct.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DistinctUntilChanged.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DistinctUntilChanged.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Do.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Do.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ElementAt.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ElementAt.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Empty.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Empty.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Except.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Except.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/First.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/First.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ForEach.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ForEach.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupBy.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupBy.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupJoin.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupJoin.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Intersect.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Intersect.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Join.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Join.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Last.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Last.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/LongCount.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/LongCount.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Max.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Max.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Min.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Min.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/MinMax.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/MinMax.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Never.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Never.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OfType.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OfType.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OrderBy.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OrderBy.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Pairwise.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Pairwise.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Publish.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Publish.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Queue.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Queue.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Range.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Range.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Repeat.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Repeat.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Return.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Return.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Reverse.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Reverse.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Select.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Select.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SelectMany.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SelectMany.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SequenceEqual.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SequenceEqual.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Single.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Single.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Skip.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Skip.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipLast.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipLast.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntil.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntil.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntilCanceled.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntilCanceled.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipWhile.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipWhile.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Subscribe.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Subscribe.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Sum.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Sum.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Take.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Take.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeLast.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeLast.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntil.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntil.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntilCanceled.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntilCanceled.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeWhile.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeWhile.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Throw.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Throw.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToArray.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToArray.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToDictionary.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToDictionary.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToHashSet.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToHashSet.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToList.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToList.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToLookup.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToLookup.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToObservable.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToObservable.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UniTask.Linq.asmdef create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UniTask.Linq.asmdef.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Union.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Union.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/Timer.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/Timer.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Where.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Where.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Zip.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Zip.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/MoveNextSource.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/MoveNextSource.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopHelper.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopHelper.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopTimer.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopTimer.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Progress.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Progress.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TaskPool.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TaskPool.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TimeoutController.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TimeoutController.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TriggerEvent.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TriggerEvent.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncStartTrigger.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncStartTrigger.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerBase.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerBase.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Bridge.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Bridge.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Delay.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Delay.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Factory.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Factory.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Run.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Run.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Threading.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Threading.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WaitUntil.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WaitUntil.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.Generated.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.Generated.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.Generated.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.Generated.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.asmdef create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.asmdef.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskCompletionSource.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskCompletionSource.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.Shorthand.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.Shorthand.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskObservableExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskObservableExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskScheduler.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskScheduler.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskSynchronizationContext.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskSynchronizationContext.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskVoid.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskVoid.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityBindingExtensions.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityBindingExtensions.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityWebRequestException.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityWebRequestException.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/_InternalVisibleTo.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/_InternalVisibleTo.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/package.json create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/package.json.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/FileUtil.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/FileUtil.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/IOHelper.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/IOHelper.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/JsonHelper.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/JsonHelper.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/StringHelper.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/StringHelper.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/ToolUtility.cs create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/ToolUtility.cs.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Excels.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Excels/山东行政区划数据.xlsx create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Excels/山东行政区划数据.xlsx.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Excel.dll create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Excel.dll.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Plugins/ICSharpCode.SharpZipLib.dll create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Plugins/ICSharpCode.SharpZipLib.dll.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Newtonsoft.Json.dll create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Newtonsoft.Json.dll.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Plugins/System.Data.dll create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/Plugins/System.Data.dll.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets.meta create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets/WebAddress.json create mode 100644 u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets/WebAddress.json.meta diff --git a/u3d-ShanDongVirtualPowerPlant/.vs/u3d-ShanDongVirtualPowerPlant/v17/.suo b/u3d-ShanDongVirtualPowerPlant/.vs/u3d-ShanDongVirtualPowerPlant/v17/.suo index 373530bb6f323d086f74759d779a440eae5dc4bf..c08e79b01f57735d91a25318711056e4418c0682 100644 GIT binary patch delta 21794 zcmeHP34D~*wg0}^GMP-mB$x)#AJ|FGpMz$ z2)W9|U9_dGiV7%WTUtYa5(Gg5kUonbjDd&3Uz|F1isH0@ae!@rTL8BLZUe;c-F1Pu zy|1`eGgpjf&j-av9{$6h?t9{oBFYd-it&T5*F4)ug`uodEIcCFK#5TT+o;)S=!e%L zuusyeLIn|iy&qoBQ3TQe^aTSxrxN@=YTbCm+W=z$1_1RW3P5O--mds>fLjar9)K!I z0E7Y}095YvaAN==fLH+XCQuo^kC2j(KoQAs$ABi=_uike5dLr_z7B4W;wQXN;E=0+ zHQRTkrkv-8Knc-)VVB}JZQoU{+k${h*aXc)YiH%3za7e|jZ-O1RHIL&tQpPlrz}xS zrK}Eqf67umm9pd?OxZZ#6UwO?r4SWq2+GEP6=k>Y%}tpg7f8iO-*Chfx3JGs7Knf6 z^K{~a6R7zrJdP3$1Ae8n=t&lCjZAw+38`4mE8!R5z6f|p3G+I=m>W%4#}V^azzM+L zl+<_GuGC25drFA)o1DFq=KcpXBCDL0N6%m$M|r4-DJm@lA|I_z=8jHdx1}vJtU=0> zNVZYC(J&U?yAs$ZN%M^}fUctQk{**zG_#MBH|ePuBioQL$2=Xr5 zmLVUZxgy&bzES@Kye({lWsaHZC3fJ;^ArL)wxN0sJDlP$)1Vxay@D=$bh4|%Vr*hWnDQ`O4khs8jjvty{LSq}u)uB?U)MmBxpgRyq`=gF+ znqI{YYa9k*VvT0@NnW*?_#>?{6;~}Mcavc~qGtuMjak)ZTCeJKR|c-e9Er#*zpTs? zr(+*QZx++p+VKm_v^JCck`0p($OMTsb}^SFXrftPw2r7_AWRwtBos;sCDFNtHxM~n zWD8@enKR}fTM^@gTijbvP9v*{5ZH$`^UcXXng;N-o*2j}_HlwVRQhKT(z1`IfhO7T z=K5g<_aQ(-AYcuS3#PFn3L0re1{1Rm1B{_ik5x(QR$OBFL=2iv#KtKf%^8|nG;iVo z6qg8>2tbWYQQ}hJ(l#?0Fhz;8!_5F>0;Vc)L|1BZ4owDXcb<|!)1weTQ-pd>D}XAa zwLJ3P1y(5kT?HaA~h- z0bB@J37~lPeSNZxJZ?m+1zZeR2e^^_S)auE(xchfh*a&`oMsH-3_Xnu4d-;ejq7!+ zE~a=OYVQ4%2q41uzxBR-$%%*7)Fe5}Rz2W-J5rn3NdA+1E6@A%x8Iv~=|pGQ+{X5I z{t@Ddd@8|NHhtbd-$_TlF#sA4_FBDlMO{U=JF}@f1dGz$0FOp08mY=Rt8S}QQ2X@@ zZ(Das!Is_8&a$$sZEr07?o_F=70tK58h)ii@=v)bJbL9@zgcbu&dZlJTyYL1<0p4AhttO9O$hGI z@bqdYiFxwWkJ6cGe$YGs31xOfvcNg=I>`5}0}_R%f!#z^g^H!{(+pB`h-2BwsQIki zGJ{#I*0Ym%v?sB77We|qt6;$-FtKs{j#67BJ92)SIV;PaQ?$9Vp{?8XBX($JbkXAW zR`-T%M|M_y?Xq*7^|dP-+Sj+vY42Fq=4!ssRo2k$LPABGtI6Hf+SJfi)!y9+e``lO z+k1}9ve@0)hWz!Ft!*yyvy!HCW1ih1)zI6xA!0B>W)t(oJI%D(X)@49d|6M7+R8rG zWQav7i#3-cu1rBBB=d6!B-3)k*E@TX=ulB5Zv0!sHftqrT%abHiGMi(YDI?E5wK%g zMpuv8J}@}}W#%gFqKcL(6%s3^u=-uTeb=~9b^A1HAyjYQn`$BXPX)sCuGfiIiOiEc z+erHzMWOd;LBziCu~S7=Mv~-}gyfK4B5;I~1c4vw(AbzY%3-EdT7oK;p%sDE8jz=2 zN~6-$w4Npe%9IWeE6oH)eiY&468SizDHQ|{;``us!tKVe5a+aGh)7EPIov1Uz64UY zXawQXS#pbRoQ*yrKDrvL7v7mfjPxua3vz5c5PRTWi~^i>g0KOt_cAf|jg?MpT5dqSP%gB>w*mcGkG{BsHq2Z(P43$ZDYds67JTu) z6JNaYZQHU-SKQsRFURw&dx!oSPmj0$XC#VAO{M0_E6_El(prbzL8#ms zcqMOf<)`_t_Z6=c-h6TO?hW2IOY-aAeDle_)ql9<$I6x!E?!2YW%uTckAM946Zgbj z_=nGzJ@nJs3!D!oKT=nF``zbED|vJNgoxEIr|wm<1SJpdS98Of`r4+h)=qb~G&uTn~CRVm~*o2xrH*u;|fN4THRWAM^`H` z(3TEgxfRW=h^=4bYG_{Lk^@wQ3Bx4kzhA9EM}mRGUDY&j*WK5eL?azeGyrbY8IpbD zK(gQ08;7IkObIEn=j6x@*snCe$;zA3%tcwgzCWV2ETpu1Lwgelu*h{08fXW7a`WZP zdkKffAGgMq4yG=(P5ws4Rle?8XPvRuh@n?tuu4f6-}z}!{P^LgJm2+K>x3Yz;D5^; z*rQTfnghHf$(9jhmuFya<9eC{k;C(tZ$!7DnMgV4Hh4JCl!v4@48-nunKj!WKz-keB%?nl+?>lMD@c#W> z>t}lJR=cfB!Z4PER{3-E(V0UJ@T=3! z`;S>)^F|wO5r&DRa+8ldvv&kbQVcW5*12@PFX_wexTUQ@cbOUgGyN?1rK5NQtMJRn}dUo+a)hD%f0 zFFu)05AsC!i~UmU(10?$3;V51HUh5FA{`JNF1GFckMS- zjanPC9yV3XDn|<|0l8AAD$ynCTA9?%3heD=XgPJW3^-27R|;7p8-H2oYA%T6px?nA z9<5@f4v$u0QiqE$7`f^-o@WYWwkKzC`RDlk0@(fJJgmSXZ!7xU4{O8Dim&zF2OD~Lo{ z5^-qED+q7!IFDAbQnyE|Fsa*p51Nv-vntVWTFW$zOYuu%Ox>r^rWH(6oVs1E#5sUl zB$0(ybvXz|C7jmn(JEHz_GlF*O>bJK)B&2*G|6e43-Ffr)2AuP%*o7h)O2;Mf+D25zRuO{t}pHGcEPWn7b?3N*0`2- zbgizR?{e4Aadj^4YAajY+SVK>-FKnf=rmusQc*Q+YcFhV?^a6;6t4YF1`jGyp(Ah` zmn869dzNxSxtq>G{DElOGgk?ARPMyAkb(G)yha|aqlSBFb-Rc4!o?x4Zb9$D1()Bes zKoby>ooCOS%yz(5&ExcIF9p`)=)UD@5m!AiqJ-KZU@^ukG@G1N0>T`bhaCt5+62vuEcU z<5R-6J^Jka$(P(wVZP_8H)pUzVO7ifcNG<$-$l9-QMkKHjBowygZ>kj&xnY6`uv0g zdk&OEtYn)PUXYT0!`(NW_~_OJ?2?5;fsZKMFW;C?R{D7RK9cYtr^`PsZ&q7h#AqXS!f@!sTw)D&6(M= z88LLi2?o$rjC!-;e?_C-n$UHP|259e>z41{FfC8Ieeu7E`My1BZbpbxiub>Lx$^1< zQ#S2+R=SBnb@XX)Nmn{Gk}ZpINTWRHM;`R_SXyD?6%udE#pd4##bBfKmjfS#3m_u6 zAOg@Cha}!?C=x3{#x}$*#@Lci9^D_`^ozMaPTF|npX1Y>PIS*p9DC}%zqiE9`a$;e zdmfmx^XhA;RYY0($o~TX-Luh2`9ZST_#-^`fn;L<$8aXU3gO!^6PpnZ0m~u2b{H-( z@kWDe{8EBh8UfsTklBU!c#|A&27`-7d_Hc@=zel6bmc#XYlFU(@UyU&5dKBjb(SLh zg0%;VB1F6lop=-6%b@~?7Fn18CHH!`e}%gV?tUn?*T7wgZLAY+>UbINpyF0RLz#sJ z{{oj*m2j)#WTtDHCNU$ zlLhE11)&4iqO0NNrVGL)a8n?Xc;JrBpd|)%LZ%?loQs|+2){(Wi?Rjbd7U6!Rv;VQ zq!bDmFvP*7ax|4~@ht)kOoMQxOp?yPdI%M>fPza{ zADSKnm+q8hK?lR&TMxX%V~QgFbU{7Lf0p5r)rm<|iwn~RbbURh&>XlOxFe-W)r@g= zLE>z{xVa>}We~tAr3wA)0(KM9+Jq|P>BbPq@vX?;&iBUI()scxoh5(hDO!|#xc)JB z@r{rEvh0ytZd&GvTj2h9?Bx&D{kHg>8{UtxKA^Cbn4T}ha@-=M9;x5!Ax`H?B6R`6bciaz zdZUwPZV7&Ju-F<9q$SycWD3)nx&;Lm;+NcdNovo>Zxd4K?ACyS8-x~Knqs@Jm}=Yr zGBpWH5#1;(!tX`OYIVGK{CB?_d*03~Yj1e^TH)%)p4;4>7@z*(^>^$Mex0gk{X`0^ zF??5nJG_xI&|81iIceDk1MM3Wch+P;SOHQr02&pNG{YsX(*huFwh}<3`U;Z)Pr+5A;@RzA! zR^tp6^MN}9pkhddHn}jgsg@0x%ue$(B!i9kP(trO0ERXAg<+oeP?T+^_P|`*a*b%B zJGIoIC)0qSAYY4x0rxHDsE_i#nq*5BA+jJZUAkaTFned#+JZSjBHbL?oWX#{0r zD-bkP2Di`CMxhWRKb34d$&V%5jG^)#CY!fJ0qK2qv3-&^Ez_1JiU!Iw@yk{d*e^Ey zZtSXcy~&a#4(+$HT~>9d2v#c@p!i6L$|XxJ$sB9II4e}z3`>xxVw$ld__V|K^wnx0 zsVN3yv^rHZ{WAzi7FQCV{tZHsv}VS386e07&IAXpBw>X`!ksFuc|AX~_GwuBq91DR z*RwH|92dn-=_(r=qOZP?bqGWO@ZrK3QdCM-2<@{+q$t08Vr-|9)vDUkFS{oWX##Q? z^%&Pp;9&b{XkyvciaZ?Sa+pJ761RdGJ=V)?EFvO(L?$%m>?O4|RAfbYZ4JgK*PM$0 zqyWkMh?K-B0eb2oY+^`3FI(vBi?dB(Zx)T^=giSsn8m5K%eZe!iO5#emg*&D&)S#$ zge-!ZGR4nWSmk@H@7^%Y2`!lNk#TN_k!}c+BoC7`+zK(T zMd)Ci%U)!Eu8fyZj}iYK9`%me*GE*$--D=_ykTmD4B8C=liJaV7LlM#GCZ*zw2s;{ zY$YRXfLH>xtet1tgU7O)+wywCwFR-dt2ZR~qk&P;FqE zU(%$2O#HR)h|v~N7$SE6k+wRKEs1IO>BWx)g&W>|;qWunm(U?#(ul0GzKI=xW$fs6%iIyqC#AJ*8rA(*Pt(78A+cZQxPk1fH)m z#EsCF2=52djH*cC{fz0O#Ng|m=xL$%HdlJXZ`5l=Z~P8@rl?s_@2%nb598QN`(D*c zCReQV*OSF-+4K8eORvH;ihKa>!m=sHQfbCK%Jhp{E-fewG*5^(q`mSlb|Jl%o zybl=+x@_Jb4=MVkeSO@M861}sFhx*1op1*&6uvM-oXj733YN)gw$OlVyfhXFXw$1> z0^)^C{#u)E9Pj^*HkOsVG+cJ}^LM6l=K;fEsYQc|#-xqmedmjbUdN5b4|Lum)#9W$ z?_CFtm+8GV4TkmSQ%_?C%-J&0`ZoNLWGuzXtgee zZ~KekQSau*4D&U-zd|#3w6xG{^S!SHPvlQ-)mVASRhkdIeZMp`hx22nq>+&ajy>?4 zVaMX&%pK!`p73t_uCDV^?nxdqo;$v)=@hTR40>E5SLz^&4>f?q>3C_6K60YUFozsx z!Nq6VgU4})s2Lcl)5@30OM1?Lnt7=`*yii*&=Vm6JrB$U8V4{@xfIJgelv7>KsCsq zGCp;9=twsVj$GVVO)Wz>NjCvS@P&!`3B1xCZ1LU&dh5NfY}LdkdE0t|PBib%(2BvI zMcn){t@q75JVX1QvfK;T(Q>~u!n?anyId4gxHwOn9zExunYUwEyl|Yd^^Qvl+N|uqvvX`Fc6>kSMgv=^?xnH{h-#n=mK4=mOuHD z_yUwJWt?97M5I6dLS+Qm725MR?-;DjQ?NDZU3iPr|4`*ucq4I zkz1tRDA;@Gv`XjWuXDquoOA{M1(GZ$#<@m{&%kN^3F=H4wO4rVR(xhZ|EJS93wk+;onI02pv~|Hm(2bD89UogH{W4 zrt4lhdyo!0dyo#0^G5q1tvMmGqisjUUfyuX`bLtZ35K?z9@-K4-Hprl?nX&tw|Ae< zmd0Fg)~uMUX3v@xgGZhE%unj2m6_nv+8E^PSz&^PORn|29yB*6r%%hfdcF^neaP;R26}#jZqT+Z(btk{|e@s8MtX1B9x8U73`K4<4HuPrbq>ArqoYNfm+f?W*a^w``dbqk6rdl1t<>f^7Ms^6rb?q7Cu7 zYxs9x-dkU_-YRY5!M&TS{$F zr^lWFuJXQ*xSsqO`{Pyd*p<&@@}TOd9Snfw751NlRedmtgw8C6*f;PL@#e z7u82M+L`?Jd|S1TC&@26m(Np?gs8sr;3rJy|1+KwF~aztRUk@>b zwIRww2E=zhoZg}msy0K*h7r>PP?sP&=cha265;o&tw3seEpB5!bf&u z{v0OosWMT9u*eb$7pT&AU_rLNVtb4FRC&aEzTZ>jGv2cPW1cFHxVPW-Q)Q+LCtEi4 zi-*S{KU;Qa^u7lWXAQ4MXn0-rO%1PwNV0Z4PlJakl3{95>=^%l9|LPxE>5()<1-@k z+UMFb|C7vOxoNWPLsn9j$u%jqf1GX`8w*=ldRgZH)1iBIE7`_ojo{7^?3Dh2j{Kh( K&cvd&`2PTaWLMAt delta 122434 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 +/// 异步封装unityWebRequest请求 +/// +public static class AsyncWebReq +{ + + /// + /// Get + /// + /// + /// 地址 + /// 头文件,登录令牌 + /// token + /// + public static async UniTask Get(string url, string _hend = null, string _token = null) + { + UnityWebRequest getRequest = UnityWebRequest.Get(url); + if (_hend != null && _token != null) + { + getRequest.SetRequestHeader("AddHeader", _hend); + getRequest.SetRequestHeader("Hulk-Auth", _token); + await getRequest.SendWebRequest(); + } + else + await getRequest.SendWebRequest(); +#if UNITY_EDITOR + Debug.Log("async req : " + getRequest.downloadHandler.text); +#endif + + T result = JsonConvert.DeserializeObject(getRequest.downloadHandler.text); + getRequest.Dispose(); + return result; + } + /// + /// Post + /// + /// + /// 地址 + /// + /// + /// + /// + public static async UniTask Post(string url, Dictionary _dic, string _hend = null, string _token = null) + { + + WWWForm form = new WWWForm(); + foreach (var item in _dic) + { + form.AddField(item.Key, item.Value); + } + var postRequest = UnityWebRequest.Post(url, form); + if (_hend != null && _token != null) + { + postRequest.SetRequestHeader("AddHeader", _hend); + postRequest.SetRequestHeader("Hulk-Auth", _token); + await postRequest.SendWebRequest(); + } + else + await postRequest.SendWebRequest(); + +#if UNITY_EDITOR + Debug.Log("async req : " + postRequest.downloadHandler.text); +#endif + T result = JsonConvert.DeserializeObject(postRequest.downloadHandler.text); + postRequest.Dispose(); + return result; + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/AsyncWebReq.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/AsyncWebReq.cs.meta new file mode 100644 index 0000000..5966ee8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/AsyncWebReq.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ef12d44eecd52a4890e4906ca98ca18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Bootstrap.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Bootstrap.cs index 720a873..fe52df8 100644 --- a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Bootstrap.cs +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Bootstrap.cs @@ -3,7 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; - +using Adam; public class Bootstrap : MonoSingleton @@ -59,6 +59,19 @@ public class Bootstrap : MonoSingleton private Dictionary _fadeTweens = new Dictionary(); public WebAdapter webAdapter; + + public Dictionary urlDic = new Dictionary(); + + + private void Awake() + { + string[] data = FileUtil.ReadAllLineFromLocal("WebAddress.json"); + for (int i = 0; i < data.Length; i++) + { + string[] urlInfo = data[i].Split("="); + urlDic.Add(urlInfo[0], urlInfo[1]); + } + } void Start() { webAdapter = GetComponent(); @@ -67,14 +80,26 @@ public class Bootstrap : MonoSingleton cameraRt.OnLimitScroll += SwitchLand; } - + public bool isLoad = false; /// /// չʾر /// /// - public void ShowLandMark(GameObject land) + public async void ShowLandMark(GameObject land) { + if (isLoad) return; + landMarks.Clear(); + string distCode = land.GetComponent().distCode; + AreaData areaData = await AsyncWebReq.Get($"{urlDic["ͼ"]}{distCode}", webAdapter.head, webAdapter.token); + if (!bool.Parse(areaData.success)) return; + isLoad = true; + for (int i = 0; i < areaData.data.items.Count; i++) + { + string info = $"{areaData.data.items[i].label}:{areaData.data.items[i].value}{areaData.data.items[i].unit}"; + landMarks.Add(info); + } + currentLand = land; currentLand.GetComponent().materials = select; landMarkAndInfoCotroller.gameObject.SetActive(true); @@ -88,6 +113,7 @@ public class Bootstrap : MonoSingleton /// public void CloseLandMark() { + isLoad = false; landMarkAndInfoCotroller.gameObject.SetActive(false); if (currentLand != null) { diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/CityInfo.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/CityInfo.cs index f1059de..ff71309 100644 --- a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/CityInfo.cs +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/CityInfo.cs @@ -1,33 +1,9 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; -public enum CurrentLevel -{ - /// - /// ʡ - /// - ProvincialCapital, - /// - /// - /// - City, - /// - /// - /// - Area -} + public class CityInfo : MonoBehaviour { - - // Start is called before the first frame update - void Start() - { - - } - - // Update is called once per frame - void Update() - { - - } + public string distCode; + public string cityName; } diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Data.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data.meta similarity index 100% rename from u3d-ShanDongVirtualPowerPlant/Assets/Adam/Data.meta rename to u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data.meta diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Data/AreaData.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/AreaData.cs similarity index 58% rename from u3d-ShanDongVirtualPowerPlant/Assets/Adam/Data/AreaData.cs rename to u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/AreaData.cs index 7ea2b29..d6c8347 100644 --- a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Data/AreaData.cs +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/AreaData.cs @@ -1,25 +1,46 @@ -using System.Collections; +using System; using System.Collections.Generic; -using UnityEngine; /// /// Ϣ /// +[Serializable] public class AreaData { /// - /// + /// + /// + public int code; + /// + /// + /// + public string success; + /// + /// + /// + public Data data; + /// + /// ɹ + /// + public string msg; + +} +[Serializable] +public class Data +{ + /// + /// /// public string distCode; /// - /// ʹ + /// /// public string disName; /// /// /// public List items; - } +[Serializable] public class ItemsItem { /// diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Data/AreaData.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/AreaData.cs.meta similarity index 100% rename from u3d-ShanDongVirtualPowerPlant/Assets/Adam/Data/AreaData.cs.meta rename to u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/AreaData.cs.meta diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/CityExcelData.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/CityExcelData.cs new file mode 100644 index 0000000..db9cf95 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/CityExcelData.cs @@ -0,0 +1,120 @@ +using Excel; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.IO; +using UnityEditor; +using UnityEngine; +[Serializable] +public class CityExcelData +{ + public CityItem[] cityItems; +} +[Serializable] +public class CityItem +{ + /// + /// + /// + public string divisionNumber; + /// + /// + /// + public string districtName; + /// + /// ʡ + /// + public string provincialDivisionNumber; + /// + /// ʡ + /// + public string provinceName; + /// + /// м + /// + public string cityLevelZoningNumber; + /// + /// м + /// + public string cityLevelName; + /// + /// + /// + public string districtLevelDivisionNumber; + /// + /// + /// + public string districtLevelName; + /// + /// 㼶 + /// + public string level; +} + +public class ExcelConfig +{ + /// + /// excelļеĵ·xecel"Assets/Excels/" + /// + public static readonly string excelsFolderPath = Application.dataPath + "/Excels/"; + + /// + /// ExcelתCSļļ· + /// + public static readonly string assetPath = "Assets/Resources/"; +} + +public class ExcelTool +{ + + /// + /// ȡݣɶӦ + /// + /// excelļȫ· + /// Item + public static CityItem[] CreateItemArrayWithExcel(string filePath) + { + //ñ + int columnNum = 0, rowNum = 0; + DataRowCollection collect = ReadExcel(filePath, ref columnNum, ref rowNum); + + //excelĶ壬ڶпʼ + CityItem[] array = new CityItem[rowNum - 1]; + for (int i = 1; i < rowNum; i++) + { + CityItem item = new CityItem(); + //ÿе + item.divisionNumber = collect[i][0].ToString(); + item.districtName = collect[i][1].ToString(); + item.provincialDivisionNumber = collect[i][2].ToString(); + item.provinceName = collect[i][3].ToString(); + item.cityLevelZoningNumber = collect[i][4].ToString(); + item.cityLevelName = collect[i][5].ToString(); + item.districtLevelDivisionNumber = collect[i][6].ToString(); + item.districtLevelName = collect[i][7].ToString(); + item.level = collect[i][8].ToString(); + array[i - 1] = item; + } + return array; + } + + /// + /// ȡexcelļ + /// + /// ļ· + /// + /// + /// + static DataRowCollection ReadExcel(string filePath, ref int columnNum, ref int rowNum) + { + FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); + IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); + + DataSet result = excelReader.AsDataSet(); + //Tables[0] ±0ʾexcelļеһű + columnNum = result.Tables[0].Columns.Count; + rowNum = result.Tables[0].Rows.Count; + return result.Tables[0].Rows; + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/CityExcelData.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/CityExcelData.cs.meta new file mode 100644 index 0000000..f6910bf --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Data/CityExcelData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8096271945f5f2842aed418ba157a873 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/TEst.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/TEst.cs new file mode 100644 index 0000000..b159171 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/TEst.cs @@ -0,0 +1,29 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.Linq; + +public class TEst : MonoBehaviour +{ + + public CityExcelData manager = new CityExcelData(); + + [ContextMenu("GetInfo")] + public void CreateItemAsset() + { + manager.cityItems = null; + manager.cityItems = ExcelTool.CreateItemArrayWithExcel(ExcelConfig.excelsFolderPath + "ɽ.xlsx"); + + for (int i = 0; i < transform.childCount; i++) + { + CityInfo c = transform.GetChild(i).GetComponent(); + c.cityName = c.gameObject.name; + for (int l = 0; l < manager.cityItems.Length; l++) + { + if (c.cityName == manager.cityItems[l].districtName) + c.distCode = manager.cityItems[l].divisionNumber; + } + } + + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/TEst.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/TEst.cs.meta new file mode 100644 index 0000000..2ec0d9d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/TEst.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ed0e77789977cb4a9a95db4c9afecd0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask.meta new file mode 100644 index 0000000..a076464 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 43cf8a4655d4ac140858caddc92ba51d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor.meta new file mode 100644 index 0000000..71abaa3 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 073d6d818cce31e4a8a33cc5e9dd28ae +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/SplitterGUILayout.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/SplitterGUILayout.cs new file mode 100644 index 0000000..4189133 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/SplitterGUILayout.cs @@ -0,0 +1,62 @@ +#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 Cysharp.Threading.Tasks.Editor +{ + // reflection call of UnityEditor.SplitterGUILayout + internal static class SplitterGUILayout + { + static BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; + + static Lazy splitterStateType = new Lazy(() => + { + var type = typeof(EditorWindow).Assembly.GetTypes().First(x => x.FullName == "UnityEditor.SplitterState"); + return type; + }); + + static Lazy splitterStateCtor = new Lazy(() => + { + var type = splitterStateType.Value; + return type.GetConstructor(flags, null, new Type[] { typeof(float[]), typeof(int[]), typeof(int[]) }, null); + }); + + static Lazy splitterGUILayoutType = new Lazy(() => + { + var type = typeof(EditorWindow).Assembly.GetTypes().First(x => x.FullName == "UnityEditor.SplitterGUILayout"); + return type; + }); + + static Lazy beginVerticalSplit = new Lazy(() => + { + var type = splitterGUILayoutType.Value; + return type.GetMethod("BeginVerticalSplit", flags, null, new Type[] { splitterStateType.Value, typeof(GUILayoutOption[]) }, null); + }); + + static Lazy endVerticalSplit = new Lazy(() => + { + 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); + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/SplitterGUILayout.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/SplitterGUILayout.cs.meta new file mode 100644 index 0000000..4d718f4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/SplitterGUILayout.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40ef2e46f900131419e869398a8d3c9d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTask.Editor.asmdef b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTask.Editor.asmdef new file mode 100644 index 0000000..c618c6a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTask.Editor.asmdef @@ -0,0 +1,17 @@ +{ + "name": "UniTask.Editor", + "references": [ + "UniTask" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": false, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTask.Editor.asmdef.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTask.Editor.asmdef.meta new file mode 100644 index 0000000..821b87b --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTask.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4129704b5a1a13841ba16f230bf24a57 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerTreeView.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerTreeView.cs new file mode 100644 index 0000000..e7b6269 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerTreeView.cs @@ -0,0 +1,182 @@ +#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 Cysharp.Threading.Tasks.Internal; +using System.Text; +using System.Text.RegularExpressions; + +namespace Cysharp.Threading.Tasks.Editor +{ + public class UniTaskTrackerViewItem : TreeViewItem + { + static Regex removeHref = new Regex("(.+)", RegexOptions.Compiled); + + 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 removeHref.Replace(sb.ToString(), "$1"); + } + + public UniTaskTrackerViewItem(int id) : base(id) + { + + } + } + + public class UniTaskTrackerTreeView : TreeView + { + const string sortedColumnIndexStateKey = "UniTaskTrackerTreeView_sortedColumnIndex"; + + public IReadOnlyList 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(); + + IOrderedEnumerable 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().ToList(); + BuildRows(rootItem); + } + + protected override TreeViewItem BuildRoot() + { + var root = new TreeViewItem { depth = -1 }; + + var children = new List(); + + 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; + 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); + } + } + } + } + +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerTreeView.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerTreeView.cs.meta new file mode 100644 index 0000000..9b34d7b --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerTreeView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52e2d973a2156674e8c1c9433ed031f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerWindow.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerWindow.cs new file mode 100644 index 0000000..242ac6d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerWindow.cs @@ -0,0 +1,209 @@ +#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 Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks.Editor +{ + public class UniTaskTrackerWindow : EditorWindow + { + static int interval; + + static UniTaskTrackerWindow window; + + [MenuItem("Window/UniTask Tracker")] + public static void OpenWindow() + { + if (window != null) + { + window.Close(); + } + + // will called OnEnable(singleton instance will be set). + GetWindow("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("CN Message"); + 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 + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerWindow.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerWindow.cs.meta new file mode 100644 index 0000000..ba1b704 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Editor/UniTaskTrackerWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5bee3e3860e37484aa3b861bf76d129f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime.meta new file mode 100644 index 0000000..8e11ef4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 20afd5140b490ce4594b0464e01d30df +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncLazy.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncLazy.cs new file mode 100644 index 0000000..51bfadc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncLazy.cs @@ -0,0 +1,245 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public class AsyncLazy + { + static Action continuation = SetCompletionSource; + + Func taskFactory; + UniTaskCompletionSource completionSource; + UniTask.Awaiter awaiter; + + object syncLock; + bool initialized; + + public AsyncLazy(Func taskFactory) + { + this.taskFactory = taskFactory; + this.completionSource = new UniTaskCompletionSource(); + this.syncLock = new object(); + this.initialized = false; + } + + internal AsyncLazy(UniTask task) + { + this.taskFactory = null; + this.completionSource = new UniTaskCompletionSource(); + this.syncLock = null; + this.initialized = true; + + var awaiter = task.GetAwaiter(); + if (awaiter.IsCompleted) + { + SetCompletionSource(awaiter); + } + else + { + this.awaiter = awaiter; + awaiter.SourceOnCompleted(continuation, this); + } + } + + public UniTask Task + { + get + { + EnsureInitialized(); + return completionSource.Task; + } + } + + + public UniTask.Awaiter GetAwaiter() => Task.GetAwaiter(); + + void EnsureInitialized() + { + if (Volatile.Read(ref initialized)) + { + return; + } + + EnsureInitializedCore(); + } + + void EnsureInitializedCore() + { + lock (syncLock) + { + if (!Volatile.Read(ref initialized)) + { + var f = Interlocked.Exchange(ref taskFactory, null); + if (f != null) + { + var task = f(); + var awaiter = task.GetAwaiter(); + if (awaiter.IsCompleted) + { + SetCompletionSource(awaiter); + } + else + { + this.awaiter = awaiter; + awaiter.SourceOnCompleted(continuation, this); + } + + Volatile.Write(ref initialized, true); + } + } + } + } + + void SetCompletionSource(in UniTask.Awaiter awaiter) + { + try + { + awaiter.GetResult(); + completionSource.TrySetResult(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void SetCompletionSource(object state) + { + var self = (AsyncLazy)state; + try + { + self.awaiter.GetResult(); + self.completionSource.TrySetResult(); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + finally + { + self.awaiter = default; + } + } + } + + public class AsyncLazy + { + static Action continuation = SetCompletionSource; + + Func> taskFactory; + UniTaskCompletionSource completionSource; + UniTask.Awaiter awaiter; + + object syncLock; + bool initialized; + + public AsyncLazy(Func> taskFactory) + { + this.taskFactory = taskFactory; + this.completionSource = new UniTaskCompletionSource(); + this.syncLock = new object(); + this.initialized = false; + } + + internal AsyncLazy(UniTask task) + { + this.taskFactory = null; + this.completionSource = new UniTaskCompletionSource(); + this.syncLock = null; + this.initialized = true; + + var awaiter = task.GetAwaiter(); + if (awaiter.IsCompleted) + { + SetCompletionSource(awaiter); + } + else + { + this.awaiter = awaiter; + awaiter.SourceOnCompleted(continuation, this); + } + } + + public UniTask Task + { + get + { + EnsureInitialized(); + return completionSource.Task; + } + } + + + public UniTask.Awaiter GetAwaiter() => Task.GetAwaiter(); + + void EnsureInitialized() + { + if (Volatile.Read(ref initialized)) + { + return; + } + + EnsureInitializedCore(); + } + + void EnsureInitializedCore() + { + lock (syncLock) + { + if (!Volatile.Read(ref initialized)) + { + var f = Interlocked.Exchange(ref taskFactory, null); + if (f != null) + { + var task = f(); + var awaiter = task.GetAwaiter(); + if (awaiter.IsCompleted) + { + SetCompletionSource(awaiter); + } + else + { + this.awaiter = awaiter; + awaiter.SourceOnCompleted(continuation, this); + } + + Volatile.Write(ref initialized, true); + } + } + } + } + + void SetCompletionSource(in UniTask.Awaiter awaiter) + { + try + { + var result = awaiter.GetResult(); + completionSource.TrySetResult(result); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void SetCompletionSource(object state) + { + var self = (AsyncLazy)state; + try + { + var result = self.awaiter.GetResult(); + self.completionSource.TrySetResult(result); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + finally + { + self.awaiter = default; + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncLazy.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncLazy.cs.meta new file mode 100644 index 0000000..554d162 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncLazy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01d1404ca421466419a7db7340ff5e77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncReactiveProperty.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncReactiveProperty.cs new file mode 100644 index 0000000..a08844d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncReactiveProperty.cs @@ -0,0 +1,644 @@ +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public interface IReadOnlyAsyncReactiveProperty : IUniTaskAsyncEnumerable + { + T Value { get; } + IUniTaskAsyncEnumerable WithoutCurrent(); + UniTask WaitAsync(CancellationToken cancellationToken = default); + } + + public interface IAsyncReactiveProperty : IReadOnlyAsyncReactiveProperty + { + new T Value { get; set; } + } + + [Serializable] + public class AsyncReactiveProperty : IAsyncReactiveProperty, IDisposable + { + TriggerEvent triggerEvent; + +#if UNITY_2018_3_OR_NEWER + [UnityEngine.SerializeField] +#endif + T latestValue; + + public T Value + { + get + { + return latestValue; + } + set + { + this.latestValue = value; + triggerEvent.SetResult(value); + } + } + + public AsyncReactiveProperty(T value) + { + this.latestValue = value; + this.triggerEvent = default; + } + + public IUniTaskAsyncEnumerable WithoutCurrent() + { + return new WithoutCurrentEnumerable(this); + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken) + { + return new Enumerator(this, cancellationToken, true); + } + + public void Dispose() + { + triggerEvent.SetCompleted(); + } + + public static implicit operator T(AsyncReactiveProperty value) + { + return value.Value; + } + + public override string ToString() + { + if (isValueType) return latestValue.ToString(); + return latestValue?.ToString(); + } + + public UniTask WaitAsync(CancellationToken cancellationToken = default) + { + return new UniTask(WaitAsyncSource.Create(this, cancellationToken, out var token), token); + } + + static bool isValueType; + + static AsyncReactiveProperty() + { + isValueType = typeof(T).IsValueType; + } + + sealed class WaitAsyncSource : IUniTaskSource, ITriggerHandler, ITaskPoolNode + { + static Action cancellationCallback = CancellationCallback; + + static TaskPool pool; + WaitAsyncSource nextNode; + ref WaitAsyncSource ITaskPoolNode.NextNode => ref nextNode; + + static WaitAsyncSource() + { + TaskPool.RegisterSizeGetter(typeof(WaitAsyncSource), () => pool.Size); + } + + AsyncReactiveProperty parent; + CancellationToken cancellationToken; + CancellationTokenRegistration cancellationTokenRegistration; + UniTaskCompletionSourceCore core; + + WaitAsyncSource() + { + } + + public static IUniTaskSource Create(AsyncReactiveProperty parent, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new WaitAsyncSource(); + } + + result.parent = parent; + result.cancellationToken = cancellationToken; + + if (cancellationToken.CanBeCanceled) + { + result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, result); + } + + result.parent.triggerEvent.Add(result); + + TaskTracker.TrackActiveTask(result, 3); + + token = result.core.Version; + return result; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + cancellationTokenRegistration.Dispose(); + cancellationTokenRegistration = default; + parent.triggerEvent.Remove(this); + parent = null; + cancellationToken = default; + return pool.TryPush(this); + } + + static void CancellationCallback(object state) + { + var self = (WaitAsyncSource)state; + self.OnCanceled(self.cancellationToken); + } + + // IUniTaskSource + + public T GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + // ITriggerHandler + + ITriggerHandler ITriggerHandler.Prev { get; set; } + ITriggerHandler ITriggerHandler.Next { get; set; } + + public void OnCanceled(CancellationToken cancellationToken) + { + core.TrySetCanceled(cancellationToken); + } + + public void OnCompleted() + { + // Complete as Cancel. + core.TrySetCanceled(CancellationToken.None); + } + + public void OnError(Exception ex) + { + core.TrySetException(ex); + } + + public void OnNext(T value) + { + core.TrySetResult(value); + } + } + + sealed class WithoutCurrentEnumerable : IUniTaskAsyncEnumerable + { + readonly AsyncReactiveProperty parent; + + public WithoutCurrentEnumerable(AsyncReactiveProperty parent) + { + this.parent = parent; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new Enumerator(parent, cancellationToken, false); + } + } + + sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator, ITriggerHandler + { + static Action cancellationCallback = CancellationCallback; + + readonly AsyncReactiveProperty parent; + readonly CancellationToken cancellationToken; + readonly CancellationTokenRegistration cancellationTokenRegistration; + T value; + bool isDisposed; + bool firstCall; + + public Enumerator(AsyncReactiveProperty parent, CancellationToken cancellationToken, bool publishCurrentValue) + { + this.parent = parent; + this.cancellationToken = cancellationToken; + this.firstCall = publishCurrentValue; + + parent.triggerEvent.Add(this); + TaskTracker.TrackActiveTask(this, 3); + + if (cancellationToken.CanBeCanceled) + { + cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); + } + } + + public T Current => value; + + ITriggerHandler ITriggerHandler.Prev { get; set; } + ITriggerHandler ITriggerHandler.Next { get; set; } + + public UniTask MoveNextAsync() + { + // raise latest value on first call. + if (firstCall) + { + firstCall = false; + value = parent.Value; + return CompletedTasks.True; + } + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + + public UniTask DisposeAsync() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + completionSource.TrySetCanceled(cancellationToken); + parent.triggerEvent.Remove(this); + } + return default; + } + + public void OnNext(T value) + { + this.value = value; + completionSource.TrySetResult(true); + } + + public void OnCanceled(CancellationToken cancellationToken) + { + DisposeAsync().Forget(); + } + + public void OnCompleted() + { + completionSource.TrySetResult(false); + } + + public void OnError(Exception ex) + { + completionSource.TrySetException(ex); + } + + static void CancellationCallback(object state) + { + var self = (Enumerator)state; + self.DisposeAsync().Forget(); + } + } + } + + public class ReadOnlyAsyncReactiveProperty : IReadOnlyAsyncReactiveProperty, IDisposable + { + TriggerEvent triggerEvent; + + T latestValue; + IUniTaskAsyncEnumerator enumerator; + + public T Value + { + get + { + return latestValue; + } + } + + public ReadOnlyAsyncReactiveProperty(T initialValue, IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + latestValue = initialValue; + ConsumeEnumerator(source, cancellationToken).Forget(); + } + + public ReadOnlyAsyncReactiveProperty(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + ConsumeEnumerator(source, cancellationToken).Forget(); + } + + async UniTaskVoid ConsumeEnumerator(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await enumerator.MoveNextAsync()) + { + var value = enumerator.Current; + this.latestValue = value; + triggerEvent.SetResult(value); + } + } + finally + { + await enumerator.DisposeAsync(); + enumerator = null; + } + } + + public IUniTaskAsyncEnumerable WithoutCurrent() + { + return new WithoutCurrentEnumerable(this); + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken) + { + return new Enumerator(this, cancellationToken, true); + } + + public void Dispose() + { + if (enumerator != null) + { + enumerator.DisposeAsync().Forget(); + } + + triggerEvent.SetCompleted(); + } + + public static implicit operator T(ReadOnlyAsyncReactiveProperty value) + { + return value.Value; + } + + public override string ToString() + { + if (isValueType) return latestValue.ToString(); + return latestValue?.ToString(); + } + + public UniTask WaitAsync(CancellationToken cancellationToken = default) + { + return new UniTask(WaitAsyncSource.Create(this, cancellationToken, out var token), token); + } + + static bool isValueType; + + static ReadOnlyAsyncReactiveProperty() + { + isValueType = typeof(T).IsValueType; + } + + sealed class WaitAsyncSource : IUniTaskSource, ITriggerHandler, ITaskPoolNode + { + static Action cancellationCallback = CancellationCallback; + + static TaskPool pool; + WaitAsyncSource nextNode; + ref WaitAsyncSource ITaskPoolNode.NextNode => ref nextNode; + + static WaitAsyncSource() + { + TaskPool.RegisterSizeGetter(typeof(WaitAsyncSource), () => pool.Size); + } + + ReadOnlyAsyncReactiveProperty parent; + CancellationToken cancellationToken; + CancellationTokenRegistration cancellationTokenRegistration; + UniTaskCompletionSourceCore core; + + WaitAsyncSource() + { + } + + public static IUniTaskSource Create(ReadOnlyAsyncReactiveProperty parent, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new WaitAsyncSource(); + } + + result.parent = parent; + result.cancellationToken = cancellationToken; + + if (cancellationToken.CanBeCanceled) + { + result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, result); + } + + result.parent.triggerEvent.Add(result); + + TaskTracker.TrackActiveTask(result, 3); + + token = result.core.Version; + return result; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + cancellationTokenRegistration.Dispose(); + cancellationTokenRegistration = default; + parent.triggerEvent.Remove(this); + parent = null; + cancellationToken = default; + return pool.TryPush(this); + } + + static void CancellationCallback(object state) + { + var self = (WaitAsyncSource)state; + self.OnCanceled(self.cancellationToken); + } + + // IUniTaskSource + + public T GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + // ITriggerHandler + + ITriggerHandler ITriggerHandler.Prev { get; set; } + ITriggerHandler ITriggerHandler.Next { get; set; } + + public void OnCanceled(CancellationToken cancellationToken) + { + core.TrySetCanceled(cancellationToken); + } + + public void OnCompleted() + { + // Complete as Cancel. + core.TrySetCanceled(CancellationToken.None); + } + + public void OnError(Exception ex) + { + core.TrySetException(ex); + } + + public void OnNext(T value) + { + core.TrySetResult(value); + } + } + + sealed class WithoutCurrentEnumerable : IUniTaskAsyncEnumerable + { + readonly ReadOnlyAsyncReactiveProperty parent; + + public WithoutCurrentEnumerable(ReadOnlyAsyncReactiveProperty parent) + { + this.parent = parent; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new Enumerator(parent, cancellationToken, false); + } + } + + sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator, ITriggerHandler + { + static Action cancellationCallback = CancellationCallback; + + readonly ReadOnlyAsyncReactiveProperty parent; + readonly CancellationToken cancellationToken; + readonly CancellationTokenRegistration cancellationTokenRegistration; + T value; + bool isDisposed; + bool firstCall; + + public Enumerator(ReadOnlyAsyncReactiveProperty parent, CancellationToken cancellationToken, bool publishCurrentValue) + { + this.parent = parent; + this.cancellationToken = cancellationToken; + this.firstCall = publishCurrentValue; + + parent.triggerEvent.Add(this); + TaskTracker.TrackActiveTask(this, 3); + + if (cancellationToken.CanBeCanceled) + { + cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); + } + } + + public T Current => value; + ITriggerHandler ITriggerHandler.Prev { get; set; } + ITriggerHandler ITriggerHandler.Next { get; set; } + + public UniTask MoveNextAsync() + { + // raise latest value on first call. + if (firstCall) + { + firstCall = false; + value = parent.Value; + return CompletedTasks.True; + } + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + + public UniTask DisposeAsync() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + completionSource.TrySetCanceled(cancellationToken); + parent.triggerEvent.Remove(this); + } + return default; + } + + public void OnNext(T value) + { + this.value = value; + completionSource.TrySetResult(true); + } + + public void OnCanceled(CancellationToken cancellationToken) + { + DisposeAsync().Forget(); + } + + public void OnCompleted() + { + completionSource.TrySetResult(false); + } + + public void OnError(Exception ex) + { + completionSource.TrySetException(ex); + } + + static void CancellationCallback(object state) + { + var self = (Enumerator)state; + self.DisposeAsync().Forget(); + } + } + } + + public static class StateExtensions + { + public static ReadOnlyAsyncReactiveProperty ToReadOnlyAsyncReactiveProperty(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + return new ReadOnlyAsyncReactiveProperty(source, cancellationToken); + } + + public static ReadOnlyAsyncReactiveProperty ToReadOnlyAsyncReactiveProperty(this IUniTaskAsyncEnumerable source, T initialValue, CancellationToken cancellationToken) + { + return new ReadOnlyAsyncReactiveProperty(initialValue, source, cancellationToken); + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncReactiveProperty.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncReactiveProperty.cs.meta new file mode 100644 index 0000000..d64e3cf --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncReactiveProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ef320b87f537ee4fb2282e765dc6166 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncUnit.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncUnit.cs new file mode 100644 index 0000000..1d4bc74 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncUnit.cs @@ -0,0 +1,26 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or + +using System; + +namespace Cysharp.Threading.Tasks +{ + public readonly struct AsyncUnit : IEquatable + { + 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 "()"; + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncUnit.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncUnit.cs.meta new file mode 100644 index 0000000..e0ee132 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/AsyncUnit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f95ac245430d304bb5128d13b6becc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenEqualityComparer.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenEqualityComparer.cs new file mode 100644 index 0000000..42e9445 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenEqualityComparer.cs @@ -0,0 +1,23 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public class CancellationTokenEqualityComparer : IEqualityComparer + { + public static readonly IEqualityComparer Default = new CancellationTokenEqualityComparer(); + + public bool Equals(CancellationToken x, CancellationToken y) + { + return x.Equals(y); + } + + public int GetHashCode(CancellationToken obj) + { + return obj.GetHashCode(); + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenEqualityComparer.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenEqualityComparer.cs.meta new file mode 100644 index 0000000..a4fe3fd --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenEqualityComparer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d739f510b125b74fa7290ac4335e46e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenExtensions.cs new file mode 100644 index 0000000..3f3a532 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenExtensions.cs @@ -0,0 +1,182 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Runtime.CompilerServices; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public static class CancellationTokenExtensions + { + static readonly Action cancellationTokenCallback = Callback; + static readonly Action disposeCallback = DisposeCallback; + + public static CancellationToken ToCancellationToken(this UniTask task) + { + var cts = new CancellationTokenSource(); + ToCancellationTokenCore(task, cts).Forget(); + return cts.Token; + } + + public static CancellationToken ToCancellationToken(this UniTask task, CancellationToken linkToken) + { + if (linkToken.IsCancellationRequested) + { + return linkToken; + } + + if (!linkToken.CanBeCanceled) + { + return ToCancellationToken(task); + } + + var cts = CancellationTokenSource.CreateLinkedTokenSource(linkToken); + ToCancellationTokenCore(task, cts).Forget(); + + return cts.Token; + } + + public static CancellationToken ToCancellationToken(this UniTask task) + { + return ToCancellationToken(task.AsUniTask()); + } + + public static CancellationToken ToCancellationToken(this UniTask task, CancellationToken linkToken) + { + return ToCancellationToken(task.AsUniTask(), linkToken); + } + + static async UniTaskVoid ToCancellationTokenCore(UniTask task, CancellationTokenSource cts) + { + try + { + await task; + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + cts.Cancel(); + cts.Dispose(); + } + + public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return (UniTask.FromCanceled(cancellationToken), default(CancellationTokenRegistration)); + } + + var promise = new UniTaskCompletionSource(); + return (promise.Task, cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise)); + } + + static void Callback(object state) + { + var promise = (UniTaskCompletionSource)state; + promise.TrySetResult(); + } + + public static CancellationTokenAwaitable WaitUntilCanceled(this CancellationToken cancellationToken) + { + return new CancellationTokenAwaitable(cancellationToken); + } + + 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 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(); + } + } + } + + public static CancellationTokenRegistration AddTo(this IDisposable disposable, CancellationToken cancellationToken) + { + return cancellationToken.RegisterWithoutCaptureExecutionContext(disposeCallback, disposable); + } + + static void DisposeCallback(object state) + { + var d = (IDisposable)state; + d.Dispose(); + } + } + + public struct CancellationTokenAwaitable + { + CancellationToken cancellationToken; + + public CancellationTokenAwaitable(CancellationToken cancellationToken) + { + this.cancellationToken = cancellationToken; + } + + public Awaiter GetAwaiter() + { + return new Awaiter(cancellationToken); + } + + public struct Awaiter : ICriticalNotifyCompletion + { + CancellationToken cancellationToken; + + public Awaiter(CancellationToken cancellationToken) + { + this.cancellationToken = cancellationToken; + } + + public bool IsCompleted => !cancellationToken.CanBeCanceled || cancellationToken.IsCancellationRequested; + + public void GetResult() + { + } + + public void OnCompleted(Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + cancellationToken.RegisterWithoutCaptureExecutionContext(continuation); + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenExtensions.cs.meta new file mode 100644 index 0000000..28a6958 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4be7209f04146bd45ac5ee775a5f7c26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenSourceExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenSourceExtensions.cs new file mode 100644 index 0000000..c519944 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenSourceExtensions.cs @@ -0,0 +1,44 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System.Threading; +using UnityEngine; +using Cysharp.Threading.Tasks.Triggers; +using System; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + + public static partial class CancellationTokenSourceExtensions + { + readonly static Action CancelCancellationTokenSourceStateDelegate = new Action(CancelCancellationTokenSourceState); + + static void CancelCancellationTokenSourceState(object state) + { + var cts = (CancellationTokenSource)state; + cts.Cancel(); + } + + public static IDisposable CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update) + { + return CancelAfterSlim(cts, TimeSpan.FromMilliseconds(millisecondsDelay), delayType, delayTiming); + } + + public static IDisposable CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update) + { + return PlayerLoopTimer.StartNew(delayTimeSpan, false, delayType, delayTiming, cts.Token, CancelCancellationTokenSourceStateDelegate, cts); + } + + 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.CancellationToken.RegisterWithoutCaptureExecutionContext(CancelCancellationTokenSourceStateDelegate, cts); + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenSourceExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenSourceExtensions.cs.meta new file mode 100644 index 0000000..fd09fe4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CancellationTokenSourceExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22d85d07f1e70ab42a7a4c25bd65e661 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Channel.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Channel.cs new file mode 100644 index 0000000..5a484fd --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Channel.cs @@ -0,0 +1,450 @@ +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public static class Channel + { + public static Channel CreateSingleConsumerUnbounded() + { + return new SingleConsumerUnboundedChannel(); + } + } + + public abstract class Channel + { + public ChannelReader Reader { get; protected set; } + public ChannelWriter Writer { get; protected set; } + + public static implicit operator ChannelReader(Channel channel) => channel.Reader; + public static implicit operator ChannelWriter(Channel channel) => channel.Writer; + } + + public abstract class Channel : Channel + { + } + + public abstract class ChannelReader + { + public abstract bool TryRead(out T item); + public abstract UniTask WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken)); + + public abstract UniTask Completion { get; } + + public virtual UniTask ReadAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + if (this.TryRead(out var item)) + { + return UniTask.FromResult(item); + } + + return ReadAsyncCore(cancellationToken); + } + + async UniTask ReadAsyncCore(CancellationToken cancellationToken = default(CancellationToken)) + { + if (await WaitToReadAsync(cancellationToken)) + { + if (TryRead(out var item)) + { + return item; + } + } + + throw new ChannelClosedException(); + } + + public abstract IUniTaskAsyncEnumerable ReadAllAsync(CancellationToken cancellationToken = default(CancellationToken)); + } + + public abstract class ChannelWriter + { + public abstract bool TryWrite(T item); + public abstract bool TryComplete(Exception error = null); + + public void Complete(Exception error = null) + { + if (!TryComplete(error)) + { + throw new ChannelClosedException(); + } + } + } + + public partial class ChannelClosedException : InvalidOperationException + { + public ChannelClosedException() : + base("Channel is already closed.") + { } + + public ChannelClosedException(string message) : base(message) { } + + public ChannelClosedException(Exception innerException) : + base("Channel is already closed", innerException) + { } + + public ChannelClosedException(string message, Exception innerException) : base(message, innerException) { } + } + + internal class SingleConsumerUnboundedChannel : Channel + { + readonly Queue items; + readonly SingleConsumerUnboundedChannelReader readerSource; + UniTaskCompletionSource completedTaskSource; + UniTask completedTask; + + Exception completionError; + bool closed; + + public SingleConsumerUnboundedChannel() + { + items = new Queue(); + Writer = new SingleConsumerUnboundedChannelWriter(this); + readerSource = new SingleConsumerUnboundedChannelReader(this); + Reader = readerSource; + } + + sealed class SingleConsumerUnboundedChannelWriter : ChannelWriter + { + readonly SingleConsumerUnboundedChannel parent; + + public SingleConsumerUnboundedChannelWriter(SingleConsumerUnboundedChannel parent) + { + this.parent = parent; + } + + public override bool TryWrite(T item) + { + bool waiting; + lock (parent.items) + { + if (parent.closed) return false; + + parent.items.Enqueue(item); + waiting = parent.readerSource.isWaiting; + } + + if (waiting) + { + parent.readerSource.SingalContinuation(); + } + + return true; + } + + public override bool TryComplete(Exception error = null) + { + bool waiting; + lock (parent.items) + { + if (parent.closed) return false; + parent.closed = true; + waiting = parent.readerSource.isWaiting; + + if (parent.items.Count == 0) + { + if (error == null) + { + if (parent.completedTaskSource != null) + { + parent.completedTaskSource.TrySetResult(); + } + else + { + parent.completedTask = UniTask.CompletedTask; + } + } + else + { + if (parent.completedTaskSource != null) + { + parent.completedTaskSource.TrySetException(error); + } + else + { + parent.completedTask = UniTask.FromException(error); + } + } + + if (waiting) + { + parent.readerSource.SingalCompleted(error); + } + } + + parent.completionError = error; + } + + return true; + } + } + + sealed class SingleConsumerUnboundedChannelReader : ChannelReader, IUniTaskSource + { + readonly Action CancellationCallbackDelegate = CancellationCallback; + readonly SingleConsumerUnboundedChannel parent; + + CancellationToken cancellationToken; + CancellationTokenRegistration cancellationTokenRegistration; + UniTaskCompletionSourceCore core; + internal bool isWaiting; + + public SingleConsumerUnboundedChannelReader(SingleConsumerUnboundedChannel parent) + { + this.parent = parent; + + TaskTracker.TrackActiveTask(this, 4); + } + + public override UniTask Completion + { + get + { + if (parent.completedTaskSource != null) return parent.completedTaskSource.Task; + + if (parent.closed) + { + return parent.completedTask; + } + + parent.completedTaskSource = new UniTaskCompletionSource(); + return parent.completedTaskSource.Task; + } + } + + public override bool TryRead(out T item) + { + lock (parent.items) + { + if (parent.items.Count != 0) + { + item = parent.items.Dequeue(); + + // complete when all value was consumed. + if (parent.closed && parent.items.Count == 0) + { + if (parent.completionError != null) + { + if (parent.completedTaskSource != null) + { + parent.completedTaskSource.TrySetException(parent.completionError); + } + else + { + parent.completedTask = UniTask.FromException(parent.completionError); + } + } + else + { + if (parent.completedTaskSource != null) + { + parent.completedTaskSource.TrySetResult(); + } + else + { + parent.completedTask = UniTask.CompletedTask; + } + } + } + } + else + { + item = default; + return false; + } + } + + return true; + } + + public override UniTask WaitToReadAsync(CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return UniTask.FromCanceled(cancellationToken); + } + + lock (parent.items) + { + if (parent.items.Count != 0) + { + return CompletedTasks.True; + } + + if (parent.closed) + { + if (parent.completionError == null) + { + return CompletedTasks.False; + } + else + { + return UniTask.FromException(parent.completionError); + } + } + + cancellationTokenRegistration.Dispose(); + + core.Reset(); + isWaiting = true; + + this.cancellationToken = cancellationToken; + if (this.cancellationToken.CanBeCanceled) + { + cancellationTokenRegistration = this.cancellationToken.RegisterWithoutCaptureExecutionContext(CancellationCallbackDelegate, this); + } + + return new UniTask(this, core.Version); + } + } + + public void SingalContinuation() + { + core.TrySetResult(true); + } + + public void SingalCancellation(CancellationToken cancellationToken) + { + TaskTracker.RemoveTracking(this); + core.TrySetCanceled(cancellationToken); + } + + public void SingalCompleted(Exception error) + { + if (error != null) + { + TaskTracker.RemoveTracking(this); + core.TrySetException(error); + } + else + { + TaskTracker.RemoveTracking(this); + core.TrySetResult(false); + } + } + + public override IUniTaskAsyncEnumerable ReadAllAsync(CancellationToken cancellationToken = default) + { + return new ReadAllAsyncEnumerable(this, cancellationToken); + } + + bool IUniTaskSource.GetResult(short token) + { + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + core.GetResult(token); + } + + UniTaskStatus IUniTaskSource.GetStatus(short token) + { + return core.GetStatus(token); + } + + void IUniTaskSource.OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + UniTaskStatus IUniTaskSource.UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + static void CancellationCallback(object state) + { + var self = (SingleConsumerUnboundedChannelReader)state; + self.SingalCancellation(self.cancellationToken); + } + + sealed class ReadAllAsyncEnumerable : IUniTaskAsyncEnumerable, IUniTaskAsyncEnumerator + { + readonly Action CancellationCallback1Delegate = CancellationCallback1; + readonly Action CancellationCallback2Delegate = CancellationCallback2; + + readonly SingleConsumerUnboundedChannelReader parent; + CancellationToken cancellationToken1; + CancellationToken cancellationToken2; + CancellationTokenRegistration cancellationTokenRegistration1; + CancellationTokenRegistration cancellationTokenRegistration2; + + T current; + bool cacheValue; + bool running; + + public ReadAllAsyncEnumerable(SingleConsumerUnboundedChannelReader parent, CancellationToken cancellationToken) + { + this.parent = parent; + this.cancellationToken1 = cancellationToken; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + if (running) + { + throw new InvalidOperationException("Enumerator is already running, does not allow call GetAsyncEnumerator twice."); + } + + if (this.cancellationToken1 != cancellationToken) + { + this.cancellationToken2 = cancellationToken; + } + + if (this.cancellationToken1.CanBeCanceled) + { + this.cancellationTokenRegistration1 = this.cancellationToken1.RegisterWithoutCaptureExecutionContext(CancellationCallback1Delegate, this); + } + + if (this.cancellationToken2.CanBeCanceled) + { + this.cancellationTokenRegistration2 = this.cancellationToken2.RegisterWithoutCaptureExecutionContext(CancellationCallback2Delegate, this); + } + + running = true; + return this; + } + + public T Current + { + get + { + if (cacheValue) + { + return current; + } + parent.TryRead(out current); + return current; + } + } + + public UniTask MoveNextAsync() + { + cacheValue = false; + return parent.WaitToReadAsync(CancellationToken.None); // ok to use None, registered in ctor. + } + + public UniTask DisposeAsync() + { + cancellationTokenRegistration1.Dispose(); + cancellationTokenRegistration2.Dispose(); + return default; + } + + static void CancellationCallback1(object state) + { + var self = (ReadAllAsyncEnumerable)state; + self.parent.SingalCancellation(self.cancellationToken1); + } + + static void CancellationCallback2(object state) + { + var self = (ReadAllAsyncEnumerable)state; + self.parent.SingalCancellation(self.cancellationToken2); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Channel.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Channel.cs.meta new file mode 100644 index 0000000..32edb9c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Channel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ceb3107bbdd1f14eb39091273798360 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices.meta new file mode 100644 index 0000000..926f0ec --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 24c1de7e806b869449e576e50c38defe +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs new file mode 100644 index 0000000..700fc33 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs @@ -0,0 +1,17 @@ + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#pragma warning disable CS0436 + +namespace System.Runtime.CompilerServices +{ + internal sealed class AsyncMethodBuilderAttribute : Attribute + { + public Type BuilderType { get; } + + public AsyncMethodBuilderAttribute(Type builderType) + { + BuilderType = builderType; + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs.meta new file mode 100644 index 0000000..19961df --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02ce354d37b10454e8376062f7cbe57a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs new file mode 100644 index 0000000..1aa990d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs @@ -0,0 +1,269 @@ + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; + +namespace Cysharp.Threading.Tasks.CompilerServices +{ + [StructLayout(LayoutKind.Auto)] + public struct AsyncUniTaskMethodBuilder + { + IStateMachineRunnerPromise runnerPromise; + Exception ex; + + // 1. Static Create method. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static AsyncUniTaskMethodBuilder Create() + { + return default; + } + + // 2. TaskLike Task property. + public UniTask Task + { + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + if (runnerPromise != null) + { + return runnerPromise.Task; + } + else if (ex != null) + { + return UniTask.FromException(ex); + } + else + { + return UniTask.CompletedTask; + } + } + } + + // 3. SetException + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetException(Exception exception) + { + if (runnerPromise == null) + { + ex = exception; + } + else + { + runnerPromise.SetException(exception); + } + } + + // 4. SetResult + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetResult() + { + if (runnerPromise != null) + { + runnerPromise.SetResult(); + } + } + + // 5. AwaitOnCompleted + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : INotifyCompletion + where TStateMachine : IAsyncStateMachine + { + if (runnerPromise == null) + { + AsyncUniTask.SetStateMachine(ref stateMachine, ref runnerPromise); + } + + awaiter.OnCompleted(runnerPromise.MoveNext); + } + + // 6. AwaitUnsafeOnCompleted + [DebuggerHidden] + [SecuritySafeCritical] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : ICriticalNotifyCompletion + where TStateMachine : IAsyncStateMachine + { + if (runnerPromise == null) + { + AsyncUniTask.SetStateMachine(ref stateMachine, ref runnerPromise); + } + + awaiter.UnsafeOnCompleted(runnerPromise.MoveNext); + } + + // 7. Start + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Start(ref TStateMachine stateMachine) + where TStateMachine : IAsyncStateMachine + { + stateMachine.MoveNext(); + } + + // 8. SetStateMachine + [DebuggerHidden] + public void SetStateMachine(IAsyncStateMachine stateMachine) + { + // don't use boxed stateMachine. + } + +#if DEBUG || !UNITY_2018_3_OR_NEWER + // Important for IDE debugger. + object debuggingId; + private object ObjectIdForDebugger + { + get + { + if (debuggingId == null) + { + debuggingId = new object(); + } + return debuggingId; + } + } +#endif + } + + [StructLayout(LayoutKind.Auto)] + public struct AsyncUniTaskMethodBuilder + { + IStateMachineRunnerPromise runnerPromise; + Exception ex; + T result; + + // 1. Static Create method. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static AsyncUniTaskMethodBuilder Create() + { + return default; + } + + // 2. TaskLike Task property. + public UniTask Task + { + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + if (runnerPromise != null) + { + return runnerPromise.Task; + } + else if (ex != null) + { + return UniTask.FromException(ex); + } + else + { + return UniTask.FromResult(result); + } + } + } + + // 3. SetException + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetException(Exception exception) + { + if (runnerPromise == null) + { + ex = exception; + } + else + { + runnerPromise.SetException(exception); + } + } + + // 4. SetResult + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetResult(T result) + { + if (runnerPromise == null) + { + this.result = result; + } + else + { + runnerPromise.SetResult(result); + } + } + + // 5. AwaitOnCompleted + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : INotifyCompletion + where TStateMachine : IAsyncStateMachine + { + if (runnerPromise == null) + { + AsyncUniTask.SetStateMachine(ref stateMachine, ref runnerPromise); + } + + awaiter.OnCompleted(runnerPromise.MoveNext); + } + + // 6. AwaitUnsafeOnCompleted + [DebuggerHidden] + [SecuritySafeCritical] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : ICriticalNotifyCompletion + where TStateMachine : IAsyncStateMachine + { + if (runnerPromise == null) + { + AsyncUniTask.SetStateMachine(ref stateMachine, ref runnerPromise); + } + + awaiter.UnsafeOnCompleted(runnerPromise.MoveNext); + } + + // 7. Start + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Start(ref TStateMachine stateMachine) + where TStateMachine : IAsyncStateMachine + { + stateMachine.MoveNext(); + } + + // 8. SetStateMachine + [DebuggerHidden] + public void SetStateMachine(IAsyncStateMachine stateMachine) + { + // don't use boxed stateMachine. + } + +#if DEBUG || !UNITY_2018_3_OR_NEWER + // Important for IDE debugger. + object debuggingId; + private object ObjectIdForDebugger + { + get + { + if (debuggingId == null) + { + debuggingId = new object(); + } + return debuggingId; + } + } +#endif + + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs.meta new file mode 100644 index 0000000..ad43cfc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68d72a45afdec574ebc26e7de2c38330 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs new file mode 100644 index 0000000..82e91f3 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs @@ -0,0 +1,137 @@ + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; + +namespace Cysharp.Threading.Tasks.CompilerServices +{ + [StructLayout(LayoutKind.Auto)] + public struct AsyncUniTaskVoidMethodBuilder + { + IStateMachineRunner runner; + + // 1. Static Create method. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static AsyncUniTaskVoidMethodBuilder Create() + { + return default; + } + + // 2. TaskLike Task property(void) + public UniTaskVoid Task + { + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return default; + } + } + + // 3. SetException + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetException(Exception exception) + { + // runner is finished, return first. + if (runner != null) + { +#if ENABLE_IL2CPP + // workaround for IL2CPP bug. + PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction); +#else + runner.Return(); +#endif + runner = null; + } + + UniTaskScheduler.PublishUnobservedTaskException(exception); + } + + // 4. SetResult + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SetResult() + { + // runner is finished, return. + if (runner != null) + { +#if ENABLE_IL2CPP + // workaround for IL2CPP bug. + PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction); +#else + runner.Return(); +#endif + runner = null; + } + } + + // 5. AwaitOnCompleted + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : INotifyCompletion + where TStateMachine : IAsyncStateMachine + { + if (runner == null) + { + AsyncUniTaskVoid.SetStateMachine(ref stateMachine, ref runner); + } + + awaiter.OnCompleted(runner.MoveNext); + } + + // 6. AwaitUnsafeOnCompleted + [DebuggerHidden] + [SecuritySafeCritical] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : ICriticalNotifyCompletion + where TStateMachine : IAsyncStateMachine + { + if (runner == null) + { + AsyncUniTaskVoid.SetStateMachine(ref stateMachine, ref runner); + } + + awaiter.UnsafeOnCompleted(runner.MoveNext); + } + + // 7. Start + [DebuggerHidden] + public void Start(ref TStateMachine stateMachine) + where TStateMachine : IAsyncStateMachine + { + stateMachine.MoveNext(); + } + + // 8. SetStateMachine + [DebuggerHidden] + public void SetStateMachine(IAsyncStateMachine stateMachine) + { + // don't use boxed stateMachine. + } + +#if DEBUG || !UNITY_2018_3_OR_NEWER + // Important for IDE debugger. + object debuggingId; + private object ObjectIdForDebugger + { + get + { + if (debuggingId == null) + { + debuggingId = new object(); + } + return debuggingId; + } + } +#endif + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs.meta new file mode 100644 index 0000000..9bcc50e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e891aaac17b933a47a9d7fa3b8e1226f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/StateMachineRunner.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/StateMachineRunner.cs new file mode 100644 index 0000000..1cffece --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/StateMachineRunner.cs @@ -0,0 +1,380 @@ +#pragma warning disable CS1591 + +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Linq; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace Cysharp.Threading.Tasks.CompilerServices +{ + // #ENABLE_IL2CPP in this file is to avoid bug of IL2CPP VM. + // Issue is tracked on https://issuetracker.unity3d.com/issues/il2cpp-incorrect-results-when-calling-a-method-from-outside-class-in-a-struct + // but currently it is labeled `Won't Fix`. + + internal interface IStateMachineRunner + { + Action MoveNext { get; } + void Return(); + +#if ENABLE_IL2CPP + Action ReturnAction { get; } +#endif + } + + internal interface IStateMachineRunnerPromise : IUniTaskSource + { + Action MoveNext { get; } + UniTask Task { get; } + void SetResult(); + void SetException(Exception exception); + } + + internal interface IStateMachineRunnerPromise : IUniTaskSource + { + Action MoveNext { get; } + UniTask Task { get; } + void SetResult(T result); + void SetException(Exception exception); + } + + internal static class StateMachineUtility + { + // Get AsyncStateMachine internal state to check IL2CPP bug + public static int GetState(IAsyncStateMachine stateMachine) + { + var info = stateMachine.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) + .First(x => x.Name.EndsWith("__state")); + return (int)info.GetValue(stateMachine); + } + } + + internal sealed class AsyncUniTaskVoid : IStateMachineRunner, ITaskPoolNode>, IUniTaskSource + where TStateMachine : IAsyncStateMachine + { + static TaskPool> pool; + +#if ENABLE_IL2CPP + public Action ReturnAction { get; } +#endif + + TStateMachine stateMachine; + + public Action MoveNext { get; } + + public AsyncUniTaskVoid() + { + MoveNext = Run; +#if ENABLE_IL2CPP + ReturnAction = Return; +#endif + } + + public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunner runnerFieldRef) + { + if (!pool.TryPop(out var result)) + { + result = new AsyncUniTaskVoid(); + } + TaskTracker.TrackActiveTask(result, 3); + + runnerFieldRef = result; // set runner before copied. + result.stateMachine = stateMachine; // copy struct StateMachine(in release build). + } + + static AsyncUniTaskVoid() + { + TaskPool.RegisterSizeGetter(typeof(AsyncUniTaskVoid), () => pool.Size); + } + + AsyncUniTaskVoid nextNode; + public ref AsyncUniTaskVoid NextNode => ref nextNode; + + public void Return() + { + TaskTracker.RemoveTracking(this); + stateMachine = default; + pool.TryPush(this); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void Run() + { + stateMachine.MoveNext(); + } + + // dummy interface implementation for TaskTracker. + + UniTaskStatus IUniTaskSource.GetStatus(short token) + { + return UniTaskStatus.Pending; + } + + UniTaskStatus IUniTaskSource.UnsafeGetStatus() + { + return UniTaskStatus.Pending; + } + + void IUniTaskSource.OnCompleted(Action continuation, object state, short token) + { + } + + void IUniTaskSource.GetResult(short token) + { + } + } + + internal sealed class AsyncUniTask : IStateMachineRunnerPromise, IUniTaskSource, ITaskPoolNode> + where TStateMachine : IAsyncStateMachine + { + static TaskPool> pool; + +#if ENABLE_IL2CPP + readonly Action returnDelegate; +#endif + public Action MoveNext { get; } + + TStateMachine stateMachine; + UniTaskCompletionSourceCore core; + + AsyncUniTask() + { + MoveNext = Run; +#if ENABLE_IL2CPP + returnDelegate = Return; +#endif + } + + public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise runnerPromiseFieldRef) + { + if (!pool.TryPop(out var result)) + { + result = new AsyncUniTask(); + } + TaskTracker.TrackActiveTask(result, 3); + + runnerPromiseFieldRef = result; // set runner before copied. + result.stateMachine = stateMachine; // copy struct StateMachine(in release build). + } + + AsyncUniTask nextNode; + public ref AsyncUniTask NextNode => ref nextNode; + + static AsyncUniTask() + { + TaskPool.RegisterSizeGetter(typeof(AsyncUniTask), () => pool.Size); + } + + void Return() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + stateMachine = default; + pool.TryPush(this); + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + stateMachine = default; + return pool.TryPush(this); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void Run() + { + stateMachine.MoveNext(); + } + + public UniTask Task + { + [DebuggerHidden] + get + { + return new UniTask(this, core.Version); + } + } + + [DebuggerHidden] + public void SetResult() + { + core.TrySetResult(AsyncUnit.Default); + } + + [DebuggerHidden] + public void SetException(Exception exception) + { + core.TrySetException(exception); + } + + [DebuggerHidden] + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { +#if ENABLE_IL2CPP + // workaround for IL2CPP bug. + PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, returnDelegate); +#else + TryReturn(); +#endif + } + } + + [DebuggerHidden] + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + [DebuggerHidden] + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + [DebuggerHidden] + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + internal sealed class AsyncUniTask : IStateMachineRunnerPromise, IUniTaskSource, ITaskPoolNode> + where TStateMachine : IAsyncStateMachine + { + static TaskPool> pool; + +#if ENABLE_IL2CPP + readonly Action returnDelegate; +#endif + + public Action MoveNext { get; } + + TStateMachine stateMachine; + UniTaskCompletionSourceCore core; + + AsyncUniTask() + { + MoveNext = Run; +#if ENABLE_IL2CPP + returnDelegate = Return; +#endif + } + + public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise runnerPromiseFieldRef) + { + if (!pool.TryPop(out var result)) + { + result = new AsyncUniTask(); + } + TaskTracker.TrackActiveTask(result, 3); + + runnerPromiseFieldRef = result; // set runner before copied. + result.stateMachine = stateMachine; // copy struct StateMachine(in release build). + } + + AsyncUniTask nextNode; + public ref AsyncUniTask NextNode => ref nextNode; + + static AsyncUniTask() + { + TaskPool.RegisterSizeGetter(typeof(AsyncUniTask), () => pool.Size); + } + + void Return() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + stateMachine = default; + pool.TryPush(this); + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + stateMachine = default; + return pool.TryPush(this); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void Run() + { + // UnityEngine.Debug.Log($"MoveNext State:" + StateMachineUtility.GetState(stateMachine)); + stateMachine.MoveNext(); + } + + public UniTask Task + { + [DebuggerHidden] + get + { + return new UniTask(this, core.Version); + } + } + + [DebuggerHidden] + public void SetResult(T result) + { + core.TrySetResult(result); + } + + [DebuggerHidden] + public void SetException(Exception exception) + { + core.TrySetException(exception); + } + + [DebuggerHidden] + public T GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { +#if ENABLE_IL2CPP + // workaround for IL2CPP bug. + PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, returnDelegate); +#else + TryReturn(); +#endif + } + } + + [DebuggerHidden] + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + [DebuggerHidden] + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + [DebuggerHidden] + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + [DebuggerHidden] + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/StateMachineRunner.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/StateMachineRunner.cs.meta new file mode 100644 index 0000000..2cb82e0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/CompilerServices/StateMachineRunner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98649642833cabf44a9dc060ce4c84a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumerableAsyncExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumerableAsyncExtensions.cs new file mode 100644 index 0000000..004e763 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumerableAsyncExtensions.cs @@ -0,0 +1,34 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Collections.Generic; + +namespace Cysharp.Threading.Tasks +{ + public static class EnumerableAsyncExtensions + { + // overload resolver - .Select(async x => { }) : IEnumerable> + + public static IEnumerable Select(this IEnumerable source, Func selector) + { + return System.Linq.Enumerable.Select(source, selector); + } + + public static IEnumerable> Select(this IEnumerable source, Func> selector) + { + return System.Linq.Enumerable.Select(source, selector); + } + + public static IEnumerable Select(this IEnumerable source, Func selector) + { + return System.Linq.Enumerable.Select(source, selector); + } + + public static IEnumerable> Select(this IEnumerable source, Func> selector) + { + return System.Linq.Enumerable.Select(source, selector); + } + } +} + + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumerableAsyncExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumerableAsyncExtensions.cs.meta new file mode 100644 index 0000000..d2e4930 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumerableAsyncExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff50260d74bd54c4b92cf99895549445 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumeratorAsyncExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumeratorAsyncExtensions.cs new file mode 100644 index 0000000..785bbc2 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumeratorAsyncExtensions.cs @@ -0,0 +1,287 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Collections; +using System.Reflection; +using System.Runtime.ExceptionServices; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; +using UnityEngine; + +namespace Cysharp.Threading.Tasks +{ + public static class EnumeratorAsyncExtensions + { + public static UniTask.Awaiter GetAwaiter(this T enumerator) + where T : IEnumerator + { + var e = (IEnumerator)enumerator; + Error.ThrowArgumentNullException(e, nameof(enumerator)); + return new UniTask(EnumeratorPromise.Create(e, PlayerLoopTiming.Update, CancellationToken.None, out var token), token).GetAwaiter(); + } + + public static UniTask WithCancellation(this IEnumerator enumerator, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(enumerator, nameof(enumerator)); + return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, cancellationToken, out var token), token); + } + + public static UniTask ToUniTask(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + Error.ThrowArgumentNullException(enumerator, nameof(enumerator)); + return new UniTask(EnumeratorPromise.Create(enumerator, timing, cancellationToken, out var token), token); + } + + public static UniTask ToUniTask(this IEnumerator enumerator, MonoBehaviour coroutineRunner) + { + var source = AutoResetUniTaskCompletionSource.Create(); + coroutineRunner.StartCoroutine(Core(enumerator, coroutineRunner, source)); + return source.Task; + } + + static IEnumerator Core(IEnumerator inner, MonoBehaviour coroutineRunner, AutoResetUniTaskCompletionSource source) + { + yield return coroutineRunner.StartCoroutine(inner); + source.TrySetResult(); + } + + sealed class EnumeratorPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + EnumeratorPromise nextNode; + public ref EnumeratorPromise NextNode => ref nextNode; + + static EnumeratorPromise() + { + TaskPool.RegisterSizeGetter(typeof(EnumeratorPromise), () => pool.Size); + } + + IEnumerator innerEnumerator; + CancellationToken cancellationToken; + int initialFrame; + bool loopRunning; + bool calledGetResult; + + UniTaskCompletionSourceCore core; + + EnumeratorPromise() + { + } + + public static IUniTaskSource Create(IEnumerator innerEnumerator, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new EnumeratorPromise(); + } + TaskTracker.TrackActiveTask(result, 3); + + result.innerEnumerator = ConsumeEnumerator(innerEnumerator); + result.cancellationToken = cancellationToken; + result.loopRunning = true; + result.calledGetResult = false; + result.initialFrame = -1; + + token = result.core.Version; + + // run immediately. + if (result.MoveNext()) + { + PlayerLoopHelper.AddAction(timing, result); + } + + return result; + } + + public void GetResult(short token) + { + try + { + calledGetResult = true; + core.GetResult(token); + } + finally + { + if (!loopRunning) + { + TryReturn(); + } + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (calledGetResult) + { + loopRunning = false; + TryReturn(); + return false; + } + + if (innerEnumerator == null) // invalid status, returned but loop running? + { + return false; + } + + if (cancellationToken.IsCancellationRequested) + { + loopRunning = false; + core.TrySetCanceled(cancellationToken); + return false; + } + + if (initialFrame == -1) + { + // Time can not touch in threadpool. + if (PlayerLoopHelper.IsMainThread) + { + initialFrame = Time.frameCount; + } + } + else if (initialFrame == Time.frameCount) + { + return true; // already executed in first frame, skip. + } + + try + { + if (innerEnumerator.MoveNext()) + { + return true; + } + } + catch (Exception ex) + { + loopRunning = false; + core.TrySetException(ex); + return false; + } + + loopRunning = false; + core.TrySetResult(null); + return false; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + innerEnumerator = default; + cancellationToken = default; + + return pool.TryPush(this); + } + + // Unwrap YieldInstructions + + static IEnumerator ConsumeEnumerator(IEnumerator enumerator) + { + while (enumerator.MoveNext()) + { + var current = enumerator.Current; + if (current == null) + { + yield return null; + } + else if (current is CustomYieldInstruction cyi) + { + // WWW, WaitForSecondsRealtime + while (cyi.keepWaiting) + { + yield return null; + } + } + else if (current is YieldInstruction) + { + IEnumerator innerCoroutine = null; + switch (current) + { + case AsyncOperation ao: + innerCoroutine = UnwrapWaitAsyncOperation(ao); + break; + case WaitForSeconds wfs: + innerCoroutine = UnwrapWaitForSeconds(wfs); + break; + } + if (innerCoroutine != null) + { + while (innerCoroutine.MoveNext()) + { + yield return null; + } + } + else + { + goto WARN; + } + } + else if (current is IEnumerator e3) + { + var e4 = ConsumeEnumerator(e3); + while (e4.MoveNext()) + { + yield return null; + } + } + else + { + goto WARN; + } + + continue; + + WARN: + // WaitForEndOfFrame, WaitForFixedUpdate, others. + UnityEngine.Debug.LogWarning($"yield {current.GetType().Name} is not supported on await IEnumerator or IEnumerator.ToUniTask(), please use ToUniTask(MonoBehaviour coroutineRunner) instead."); + yield return null; + } + } + + static readonly FieldInfo waitForSeconds_Seconds = typeof(WaitForSeconds).GetField("m_Seconds", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic); + + static IEnumerator UnwrapWaitForSeconds(WaitForSeconds waitForSeconds) + { + var second = (float)waitForSeconds_Seconds.GetValue(waitForSeconds); + var elapsed = 0.0f; + while (true) + { + yield return null; + + elapsed += Time.deltaTime; + if (elapsed >= second) + { + break; + } + }; + } + + static IEnumerator UnwrapWaitAsyncOperation(AsyncOperation asyncOperation) + { + while (!asyncOperation.isDone) + { + yield return null; + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumeratorAsyncExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumeratorAsyncExtensions.cs.meta new file mode 100644 index 0000000..a07b336 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/EnumeratorAsyncExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc661232f11e4a741af54ba1c175d5ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/ExceptionExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/ExceptionExtensions.cs new file mode 100644 index 0000000..e411898 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/ExceptionExtensions.cs @@ -0,0 +1,14 @@ + +using System; + +namespace Cysharp.Threading.Tasks +{ + public static class ExceptionExtensions + { + public static bool IsOperationCanceledException(this Exception exception) + { + return exception is OperationCanceledException; + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/ExceptionExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/ExceptionExtensions.cs.meta new file mode 100644 index 0000000..9833001 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/ExceptionExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 930800098504c0d46958ce23a0495202 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External.meta new file mode 100644 index 0000000..ac0ce6d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 49a3ffcde3d76d6448c5c89d0f28f48f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables.meta new file mode 100644 index 0000000..6c142e8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6d56d16a90e4f5c428c3310a41a87906 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs new file mode 100644 index 0000000..f321bdb --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs @@ -0,0 +1,401 @@ +// asmdef Version Defines, enabled when com.unity.addressables is imported. + +#if UNITASK_ADDRESSABLE_SUPPORT + +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Threading; +using UnityEngine.ResourceManagement.AsyncOperations; + +namespace Cysharp.Threading.Tasks +{ + public static class AddressablesAsyncExtensions + { +#region AsyncOperationHandle + + public static UniTask.Awaiter GetAwaiter(this AsyncOperationHandle handle) + { + return ToUniTask(handle).GetAwaiter(); + } + + public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken) + { + return ToUniTask(handle, cancellationToken: cancellationToken); + } + + public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); + + if (!handle.IsValid()) + { + // autoReleaseHandle:true handle is invalid(immediately internal handle == null) so return completed. + return UniTask.CompletedTask; + } + + if (handle.IsDone) + { + if (handle.Status == AsyncOperationStatus.Failed) + { + return UniTask.FromException(handle.OperationException); + } + return UniTask.CompletedTask; + } + + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, out var token), token); + } + + public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion + { + AsyncOperationHandle handle; + Action continuationAction; + + public AsyncOperationHandleAwaiter(AsyncOperationHandle handle) + { + this.handle = handle; + this.continuationAction = null; + } + + public bool IsCompleted => handle.IsDone; + + public void GetResult() + { + if (continuationAction != null) + { + handle.Completed -= continuationAction; + continuationAction = null; + } + + if (handle.Status == AsyncOperationStatus.Failed) + { + var e = handle.OperationException; + handle = default; + ExceptionDispatchInfo.Capture(e).Throw(); + } + + var result = handle.Result; + handle = default; + } + + public void OnCompleted(Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction); + continuationAction = PooledDelegate.Create(continuation); + handle.Completed += continuationAction; + } + } + + sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + AsyncOperationHandleConfiguredSource nextNode; + public ref AsyncOperationHandleConfiguredSource NextNode => ref nextNode; + + static AsyncOperationHandleConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource), () => pool.Size); + } + + readonly Action continuationAction; + AsyncOperationHandle handle; + CancellationToken cancellationToken; + IProgress progress; + bool completed; + + UniTaskCompletionSourceCore core; + + AsyncOperationHandleConfiguredSource() + { + continuationAction = Continuation; + } + + public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new AsyncOperationHandleConfiguredSource(); + } + + result.handle = handle; + result.progress = progress; + result.cancellationToken = cancellationToken; + result.completed = false; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + handle.Completed += result.continuationAction; + + token = result.core.Version; + return result; + } + + void Continuation(AsyncOperationHandle _) + { + handle.Completed -= continuationAction; + + if (completed) + { + TryReturn(); + } + else + { + completed = true; + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + } + else if (handle.Status == AsyncOperationStatus.Failed) + { + core.TrySetException(handle.OperationException); + } + else + { + core.TrySetResult(AsyncUnit.Default); + } + } + } + + public void GetResult(short token) + { + core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (completed) + { + TryReturn(); + return false; + } + + if (cancellationToken.IsCancellationRequested) + { + completed = true; + core.TrySetCanceled(cancellationToken); + return false; + } + + if (progress != null && handle.IsValid()) + { + progress.Report(handle.PercentComplete); + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + handle = default; + progress = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + +#endregion + +#region AsyncOperationHandle_T + + public static UniTask.Awaiter GetAwaiter(this AsyncOperationHandle handle) + { + return ToUniTask(handle).GetAwaiter(); + } + + public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken) + { + return ToUniTask(handle, cancellationToken: cancellationToken); + } + + public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); + + if (!handle.IsValid()) + { + throw new Exception("Attempting to use an invalid operation handle"); + } + + if (handle.IsDone) + { + if (handle.Status == AsyncOperationStatus.Failed) + { + return UniTask.FromException(handle.OperationException); + } + return UniTask.FromResult(handle.Result); + } + + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, out var token), token); + } + + sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode> + { + static TaskPool> pool; + AsyncOperationHandleConfiguredSource nextNode; + public ref AsyncOperationHandleConfiguredSource NextNode => ref nextNode; + + static AsyncOperationHandleConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource), () => pool.Size); + } + + readonly Action> continuationAction; + AsyncOperationHandle handle; + CancellationToken cancellationToken; + IProgress progress; + bool completed; + + UniTaskCompletionSourceCore core; + + AsyncOperationHandleConfiguredSource() + { + continuationAction = Continuation; + } + + public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new AsyncOperationHandleConfiguredSource(); + } + + result.handle = handle; + result.cancellationToken = cancellationToken; + result.completed = false; + result.progress = progress; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + handle.Completed += result.continuationAction; + + token = result.core.Version; + return result; + } + + void Continuation(AsyncOperationHandle argHandle) + { + handle.Completed -= continuationAction; + + if (completed) + { + TryReturn(); + } + else + { + completed = true; + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + } + else if (argHandle.Status == AsyncOperationStatus.Failed) + { + core.TrySetException(argHandle.OperationException); + } + else + { + core.TrySetResult(argHandle.Result); + } + } + } + + public T GetResult(short token) + { + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (completed) + { + TryReturn(); + return false; + } + + if (cancellationToken.IsCancellationRequested) + { + completed = true; + core.TrySetCanceled(cancellationToken); + return false; + } + + if (progress != null && handle.IsValid()) + { + progress.Report(handle.PercentComplete); + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + handle = default; + progress = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + +#endregion + } +} + +#endif \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta new file mode 100644 index 0000000..6927930 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3dc6441f9094f354b931dc3c79fb99e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef new file mode 100644 index 0000000..0439df7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef @@ -0,0 +1,27 @@ +{ + "name": "UniTask.Addressables", + "references": [ + "UniTask", + "Unity.ResourceManager" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.addressables", + "expression": "", + "define": "UNITASK_ADDRESSABLE_SUPPORT" + }, + { + "name": "com.unity.addressables.cn", + "expression": "", + "define": "UNITASK_ADDRESSABLE_SUPPORT" + } + ], + "noEngineReferences": false +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta new file mode 100644 index 0000000..b0178c4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 593a5b492d29ac6448b1ebf7f035ef33 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween.meta new file mode 100644 index 0000000..5b7c866 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ae13b754ddcd24e41912e4711f5a95c4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs new file mode 100644 index 0000000..80ae27c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs @@ -0,0 +1,470 @@ +// asmdef Version Defines, enabled when com.demigiant.dotween is imported. + +#if UNITASK_DOTWEEN_SUPPORT + +using Cysharp.Threading.Tasks.Internal; +using DG.Tweening; +using System; +using System.Collections.Concurrent; +using System.Runtime.CompilerServices; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public enum TweenCancelBehaviour + { + Kill, + KillWithCompleteCallback, + Complete, + CompleteWithSequenceCallback, + CancelAwait, + + // AndCancelAwait + KillAndCancelAwait, + KillWithCompleteCallbackAndCancelAwait, + CompleteAndCancelAwait, + CompleteWithSequenceCallbackAndCancelAwait + } + + public static class DOTweenAsyncExtensions + { + enum CallbackType + { + Kill, + Complete, + Pause, + Play, + Rewind, + StepComplete + } + + public static TweenAwaiter GetAwaiter(this Tween tween) + { + return new TweenAwaiter(tween); + } + + public static UniTask WithCancellation(this Tween tween, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; + return new UniTask(TweenConfiguredSource.Create(tween, TweenCancelBehaviour.Kill, cancellationToken, CallbackType.Kill, out var token), token); + } + + public static UniTask ToUniTask(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; + return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Kill, out var token), token); + } + + public static UniTask AwaitForComplete(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; + return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Complete, out var token), token); + } + + public static UniTask AwaitForPause(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; + return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Pause, out var token), token); + } + + public static UniTask AwaitForPlay(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; + return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Play, out var token), token); + } + + public static UniTask AwaitForRewind(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; + return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Rewind, out var token), token); + } + + public static UniTask AwaitForStepComplete(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; + return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.StepComplete, out var token), token); + } + + public struct TweenAwaiter : ICriticalNotifyCompletion + { + readonly Tween tween; + + // killed(non active) as completed. + public bool IsCompleted => !tween.IsActive(); + + public TweenAwaiter(Tween tween) + { + this.tween = tween; + } + + public TweenAwaiter GetAwaiter() + { + return this; + } + + public void GetResult() + { + } + + public void OnCompleted(System.Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(System.Action continuation) + { + // onKill is called after OnCompleted, both Complete(false/true) and Kill(false/true). + tween.onKill = PooledTweenCallback.Create(continuation); + } + } + + sealed class TweenConfiguredSource : IUniTaskSource, ITaskPoolNode + { + static TaskPool pool; + TweenConfiguredSource nextNode; + public ref TweenConfiguredSource NextNode => ref nextNode; + + static TweenConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(TweenConfiguredSource), () => pool.Size); + } + + readonly TweenCallback onCompleteCallbackDelegate; + readonly TweenCallback onUpdateDelegate; + + Tween tween; + TweenCancelBehaviour cancelBehaviour; + CancellationToken cancellationToken; + CallbackType callbackType; + bool canceled; + + TweenCallback originalUpdateAction; + TweenCallback originalCompleteAction; + UniTaskCompletionSourceCore core; + + TweenConfiguredSource() + { + onCompleteCallbackDelegate = OnCompleteCallbackDelegate; + onUpdateDelegate = OnUpdate; + } + + public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, CallbackType callbackType, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + DoCancelBeforeCreate(tween, cancelBehaviour); + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new TweenConfiguredSource(); + } + + result.tween = tween; + result.cancelBehaviour = cancelBehaviour; + result.cancellationToken = cancellationToken; + result.callbackType = callbackType; + + result.originalUpdateAction = tween.onUpdate; + result.canceled = false; + + if (result.originalUpdateAction == result.onUpdateDelegate) + { + result.originalUpdateAction = null; + } + + tween.onUpdate = result.onUpdateDelegate; + + switch (callbackType) + { + case CallbackType.Kill: + result.originalCompleteAction = tween.onKill; + tween.onKill = result.onCompleteCallbackDelegate; + break; + case CallbackType.Complete: + result.originalCompleteAction = tween.onComplete; + tween.onComplete = result.onCompleteCallbackDelegate; + break; + case CallbackType.Pause: + result.originalCompleteAction = tween.onPause; + tween.onPause = result.onCompleteCallbackDelegate; + break; + case CallbackType.Play: + result.originalCompleteAction = tween.onPlay; + tween.onPlay = result.onCompleteCallbackDelegate; + break; + case CallbackType.Rewind: + result.originalCompleteAction = tween.onRewind; + tween.onRewind = result.onCompleteCallbackDelegate; + break; + case CallbackType.StepComplete: + result.originalCompleteAction = tween.onStepComplete; + tween.onStepComplete = result.onCompleteCallbackDelegate; + break; + default: + break; + } + + if (result.originalCompleteAction == result.onCompleteCallbackDelegate) + { + result.originalCompleteAction = null; + } + + TaskTracker.TrackActiveTask(result, 3); + + token = result.core.Version; + return result; + } + + void OnCompleteCallbackDelegate() + { + if (cancellationToken.IsCancellationRequested) + { + if (this.cancelBehaviour == TweenCancelBehaviour.KillAndCancelAwait + || this.cancelBehaviour == TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait + || this.cancelBehaviour == TweenCancelBehaviour.CompleteAndCancelAwait + || this.cancelBehaviour == TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait + || this.cancelBehaviour == TweenCancelBehaviour.CancelAwait) + { + canceled = true; + } + } + if (canceled) + { + core.TrySetCanceled(cancellationToken); + } + else + { + originalCompleteAction?.Invoke(); + core.TrySetResult(AsyncUnit.Default); + } + } + + void OnUpdate() + { + originalUpdateAction?.Invoke(); + + if (!cancellationToken.IsCancellationRequested) + { + return; + } + + switch (this.cancelBehaviour) + { + case TweenCancelBehaviour.Kill: + default: + this.tween.Kill(false); + break; + case TweenCancelBehaviour.KillAndCancelAwait: + this.canceled = true; + this.tween.Kill(false); + break; + case TweenCancelBehaviour.KillWithCompleteCallback: + this.tween.Kill(true); + break; + case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait: + this.canceled = true; + this.tween.Kill(true); + break; + case TweenCancelBehaviour.Complete: + this.tween.Complete(false); + break; + case TweenCancelBehaviour.CompleteAndCancelAwait: + this.canceled = true; + this.tween.Complete(false); + break; + case TweenCancelBehaviour.CompleteWithSequenceCallback: + this.tween.Complete(true); + break; + case TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait: + this.canceled = true; + this.tween.Complete(true); + break; + case TweenCancelBehaviour.CancelAwait: + // restore to original callback + switch (callbackType) + { + case CallbackType.Kill: + tween.onKill = originalCompleteAction; + break; + case CallbackType.Complete: + tween.onComplete = originalCompleteAction; + break; + case CallbackType.Pause: + tween.onPause = originalCompleteAction; + break; + case CallbackType.Play: + tween.onPlay = originalCompleteAction; + break; + case CallbackType.Rewind: + tween.onRewind = originalCompleteAction; + break; + case CallbackType.StepComplete: + tween.onStepComplete = originalCompleteAction; + break; + default: + break; + } + + this.core.TrySetCanceled(this.cancellationToken); + break; + } + } + + static void DoCancelBeforeCreate(Tween tween, TweenCancelBehaviour tweenCancelBehaviour) + { + + switch (tweenCancelBehaviour) + { + case TweenCancelBehaviour.Kill: + default: + tween.Kill(false); + break; + case TweenCancelBehaviour.KillAndCancelAwait: + tween.Kill(false); + break; + case TweenCancelBehaviour.KillWithCompleteCallback: + tween.Kill(true); + break; + case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait: + tween.Kill(true); + break; + case TweenCancelBehaviour.Complete: + tween.Complete(false); + break; + case TweenCancelBehaviour.CompleteAndCancelAwait: + tween.Complete(false); + break; + case TweenCancelBehaviour.CompleteWithSequenceCallback: + tween.Complete(true); + break; + case TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait: + tween.Complete(true); + break; + case TweenCancelBehaviour.CancelAwait: + break; + } + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + tween.onUpdate = originalUpdateAction; + + switch (callbackType) + { + case CallbackType.Kill: + tween.onKill = originalCompleteAction; + break; + case CallbackType.Complete: + tween.onComplete = originalCompleteAction; + break; + case CallbackType.Pause: + tween.onPause = originalCompleteAction; + break; + case CallbackType.Play: + tween.onPlay = originalCompleteAction; + break; + case CallbackType.Rewind: + tween.onRewind = originalCompleteAction; + break; + case CallbackType.StepComplete: + tween.onStepComplete = originalCompleteAction; + break; + default: + break; + } + + tween = default; + cancellationToken = default; + originalUpdateAction = default; + originalCompleteAction = default; + return pool.TryPush(this); + } + } + } + + sealed class PooledTweenCallback + { + static readonly ConcurrentQueue pool = new ConcurrentQueue(); + + readonly TweenCallback runDelegate; + + Action continuation; + + + PooledTweenCallback() + { + runDelegate = Run; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TweenCallback Create(Action continuation) + { + if (!pool.TryDequeue(out var item)) + { + item = new PooledTweenCallback(); + } + + item.continuation = continuation; + return item.runDelegate; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void Run() + { + var call = continuation; + continuation = null; + if (call != null) + { + pool.Enqueue(this); + call.Invoke(); + } + } + } +} + +#endif diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta new file mode 100644 index 0000000..63131b0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f448d5bc5b232e4f98d89d5d1832e8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef new file mode 100644 index 0000000..7bdb2b6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef @@ -0,0 +1,22 @@ +{ + "name": "UniTask.DOTween", + "references": [ + "UniTask", + "DOTween.Modules" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.demigiant.dotween", + "expression": "", + "define": "UNITASK_DOTWEEN_SUPPORT" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta new file mode 100644 index 0000000..427fe29 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 029c1c1b674aaae47a6841a0b89ad80e +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro.meta new file mode 100644 index 0000000..07c8c80 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 428facb8d46ed804795d1f6e71438496 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs new file mode 100644 index 0000000..22f081c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs @@ -0,0 +1,224 @@ +#if UNITASK_TEXTMESHPRO_SUPPORT + +using System; +using System.Threading; +using TMPro; + +namespace Cysharp.Threading.Tasks +{ + public static partial class TextMeshProAsyncExtensions + { + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onValueChanged, cancellationToken, false); + } + + public static UniTask OnValueChangedAsync(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnValueChangedAsync(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onValueChanged, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this TMP_InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onValueChanged, cancellationToken); + } + + public static IAsyncEndEditEventHandler GetAsyncEndEditEventHandler(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncEndEditEventHandler GetAsyncEndEditEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onEndEdit, cancellationToken, false); + } + + public static UniTask OnEndEditAsync(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnEndEditAsync(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onEndEdit, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnEndEditAsAsyncEnumerable(this TMP_InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnEndEditAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onEndEdit, cancellationToken); + } + + public static IAsyncEndTextSelectionEventHandler<(string, int, int)> GetAsyncEndTextSelectionEventHandler(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncEndTextSelectionEventHandler<(string, int, int)> GetAsyncEndTextSelectionEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken, false); + } + + public static UniTask<(string, int, int)> OnEndTextSelectionAsync(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask<(string, int, int)> OnEndTextSelectionAsync(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable<(string, int, int)> OnEndTextSelectionAsAsyncEnumerable(this TMP_InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable<(string, int, int)> OnEndTextSelectionAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken); + } + + public static IAsyncTextSelectionEventHandler<(string, int, int)> GetAsyncTextSelectionEventHandler(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncTextSelectionEventHandler<(string, int, int)> GetAsyncTextSelectionEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken, false); + } + + public static UniTask<(string, int, int)> OnTextSelectionAsync(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask<(string, int, int)> OnTextSelectionAsync(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable<(string, int, int)> OnTextSelectionAsAsyncEnumerable(this TMP_InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable<(string, int, int)> OnTextSelectionAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken); + } + + public static IAsyncDeselectEventHandler GetAsyncDeselectEventHandler(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncDeselectEventHandler GetAsyncDeselectEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onDeselect, cancellationToken, false); + } + + public static UniTask OnDeselectAsync(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnDeselectAsync(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onDeselect, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnDeselectAsAsyncEnumerable(this TMP_InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnDeselectAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onDeselect, cancellationToken); + } + + public static IAsyncSelectEventHandler GetAsyncSelectEventHandler(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onSelect, inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncSelectEventHandler GetAsyncSelectEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onSelect, cancellationToken, false); + } + + public static UniTask OnSelectAsync(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onSelect, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnSelectAsync(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onSelect, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnSelectAsAsyncEnumerable(this TMP_InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onSelect, inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnSelectAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onSelect, cancellationToken); + } + + public static IAsyncSubmitEventHandler GetAsyncSubmitEventHandler(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncSubmitEventHandler GetAsyncSubmitEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onSubmit, cancellationToken, false); + } + + public static UniTask OnSubmitAsync(this TMP_InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnSubmitAsync(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onSubmit, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnSubmitAsAsyncEnumerable(this TMP_InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnSubmitAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onSubmit, cancellationToken); + } + + } +} + +#endif \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs.meta new file mode 100644 index 0000000..2e39d2e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 79f4f2475e0b2c44e97ed1dee760627b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs new file mode 100644 index 0000000..362aa83 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs @@ -0,0 +1,130 @@ +#if UNITASK_TEXTMESHPRO_SUPPORT + +using System; +using System.Threading; +using TMPro; +using UnityEngine.Events; + +namespace Cysharp.Threading.Tasks +{ + public static partial class TextMeshProAsyncExtensions + { + // -> Text + public static void BindTo(this IUniTaskAsyncEnumerable source, TMP_Text text, bool rebindOnError = true) + { + BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + public static void BindTo(this IUniTaskAsyncEnumerable source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError = true) + { + BindToCore(source, text, cancellationToken, rebindOnError).Forget(); + } + + static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError) + { + var repeat = false; + BIND_AGAIN: + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (true) + { + bool moveNext; + try + { + moveNext = await e.MoveNextAsync(); + repeat = false; + } + catch (Exception ex) + { + if (ex is OperationCanceledException) return; + + if (rebindOnError && !repeat) + { + repeat = true; + goto BIND_AGAIN; + } + else + { + throw; + } + } + + if (!moveNext) return; + + text.text = e.Current; + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + // -> Text + + public static void BindTo(this IUniTaskAsyncEnumerable source, TMP_Text text, bool rebindOnError = true) + { + BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + public static void BindTo(this IUniTaskAsyncEnumerable source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError = true) + { + BindToCore(source, text, cancellationToken, rebindOnError).Forget(); + } + + public static void BindTo(this AsyncReactiveProperty source, TMP_Text text, bool rebindOnError = true) + { + BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError) + { + var repeat = false; + BIND_AGAIN: + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (true) + { + bool moveNext; + try + { + moveNext = await e.MoveNextAsync(); + repeat = false; + } + catch (Exception ex) + { + if (ex is OperationCanceledException) return; + + if (rebindOnError && !repeat) + { + repeat = true; + goto BIND_AGAIN; + } + else + { + throw; + } + } + + if (!moveNext) return; + + text.text = e.Current.ToString(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} + +#endif \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs.meta new file mode 100644 index 0000000..752d125 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6ba480edafb67d4e91bb10feb64fae5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef new file mode 100644 index 0000000..6bb01d7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef @@ -0,0 +1,22 @@ +{ + "name": "UniTask.TextMeshPro", + "references": [ + "UniTask", + "Unity.TextMeshPro" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.textmeshpro", + "expression": "", + "define": "UNITASK_TEXTMESHPRO_SUPPORT" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef.meta new file mode 100644 index 0000000..4b59831 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dc47925d1a5fa2946bdd37746b2b5d48 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskAsyncEnumerable.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskAsyncEnumerable.cs new file mode 100644 index 0000000..847d430 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskAsyncEnumerable.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public interface IUniTaskAsyncEnumerable + { + IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); + } + + public interface IUniTaskAsyncEnumerator : IUniTaskAsyncDisposable + { + T Current { get; } + UniTask MoveNextAsync(); + } + + public interface IUniTaskAsyncDisposable + { + UniTask DisposeAsync(); + } + + public interface IUniTaskOrderedAsyncEnumerable : IUniTaskAsyncEnumerable + { + IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func keySelector, IComparer comparer, bool descending); + IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func> keySelector, IComparer comparer, bool descending); + IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func> keySelector, IComparer comparer, bool descending); + } + + public interface IConnectableUniTaskAsyncEnumerable : IUniTaskAsyncEnumerable + { + IDisposable Connect(); + } + + // don't use AsyncGrouping. + //public interface IUniTaskAsyncGrouping : IUniTaskAsyncEnumerable + //{ + // TKey Key { get; } + //} + + public static class UniTaskAsyncEnumerableExtensions + { + public static UniTaskCancelableAsyncEnumerable WithCancellation(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + return new UniTaskCancelableAsyncEnumerable(source, cancellationToken); + } + } + + [StructLayout(LayoutKind.Auto)] + public readonly struct UniTaskCancelableAsyncEnumerable + { + private readonly IUniTaskAsyncEnumerable enumerable; + private readonly CancellationToken cancellationToken; + + internal UniTaskCancelableAsyncEnumerable(IUniTaskAsyncEnumerable enumerable, CancellationToken cancellationToken) + { + this.enumerable = enumerable; + this.cancellationToken = cancellationToken; + } + + public Enumerator GetAsyncEnumerator() + { + return new Enumerator(enumerable.GetAsyncEnumerator(cancellationToken)); + } + + [StructLayout(LayoutKind.Auto)] + public readonly struct Enumerator + { + private readonly IUniTaskAsyncEnumerator enumerator; + + internal Enumerator(IUniTaskAsyncEnumerator enumerator) + { + this.enumerator = enumerator; + } + + public T Current => enumerator.Current; + + public UniTask MoveNextAsync() + { + return enumerator.MoveNextAsync(); + } + + + public UniTask DisposeAsync() + { + return enumerator.DisposeAsync(); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskAsyncEnumerable.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskAsyncEnumerable.cs.meta new file mode 100644 index 0000000..12f0fe5 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskAsyncEnumerable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b20cf9f02ac585948a4372fa4ee06504 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskSource.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskSource.cs new file mode 100644 index 0000000..8814781 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskSource.cs @@ -0,0 +1,124 @@ +#pragma warning disable CS1591 + +using System; +using System.Runtime.CompilerServices; + +namespace Cysharp.Threading.Tasks +{ + public enum UniTaskStatus + { + /// The operation has not yet completed. + Pending = 0, + /// The operation completed successfully. + Succeeded = 1, + /// The operation completed with an error. + Faulted = 2, + /// The operation completed due to cancellation. + Canceled = 3 + } + + // similar as IValueTaskSource + public interface IUniTaskSource +#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0 + : System.Threading.Tasks.Sources.IValueTaskSource +#pragma warning disable CS0108 +#endif + { + UniTaskStatus GetStatus(short token); + void OnCompleted(Action continuation, object state, short token); + void GetResult(short token); + + UniTaskStatus UnsafeGetStatus(); // only for debug use. + +#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0 +#pragma warning restore CS0108 + + System.Threading.Tasks.Sources.ValueTaskSourceStatus System.Threading.Tasks.Sources.IValueTaskSource.GetStatus(short token) + { + return (System.Threading.Tasks.Sources.ValueTaskSourceStatus)(int)((IUniTaskSource)this).GetStatus(token); + } + + void System.Threading.Tasks.Sources.IValueTaskSource.GetResult(short token) + { + ((IUniTaskSource)this).GetResult(token); + } + + void System.Threading.Tasks.Sources.IValueTaskSource.OnCompleted(Action continuation, object state, short token, System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags flags) + { + // ignore flags, always none. + ((IUniTaskSource)this).OnCompleted(continuation, state, token); + } + +#endif + } + + public interface IUniTaskSource : IUniTaskSource +#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0 + , System.Threading.Tasks.Sources.IValueTaskSource +#endif + { + new T GetResult(short token); + +#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0 + + new public UniTaskStatus GetStatus(short token) + { + return ((IUniTaskSource)this).GetStatus(token); + } + + new public void OnCompleted(Action continuation, object state, short token) + { + ((IUniTaskSource)this).OnCompleted(continuation, state, token); + } + + System.Threading.Tasks.Sources.ValueTaskSourceStatus System.Threading.Tasks.Sources.IValueTaskSource.GetStatus(short token) + { + return (System.Threading.Tasks.Sources.ValueTaskSourceStatus)(int)((IUniTaskSource)this).GetStatus(token); + } + + T System.Threading.Tasks.Sources.IValueTaskSource.GetResult(short token) + { + return ((IUniTaskSource)this).GetResult(token); + } + + void System.Threading.Tasks.Sources.IValueTaskSource.OnCompleted(Action continuation, object state, short token, System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags flags) + { + // ignore flags, always none. + ((IUniTaskSource)this).OnCompleted(continuation, state, token); + } + +#endif + } + + public static class UniTaskStatusExtensions + { + /// status != Pending. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsCompleted(this UniTaskStatus status) + { + return status != UniTaskStatus.Pending; + } + + /// status == Succeeded. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsCompletedSuccessfully(this UniTaskStatus status) + { + return status == UniTaskStatus.Succeeded; + } + + /// status == Canceled. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsCanceled(this UniTaskStatus status) + { + return status == UniTaskStatus.Canceled; + } + + /// status == Faulted. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsFaulted(this UniTaskStatus status) + { + return status == UniTaskStatus.Faulted; + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskSource.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskSource.cs.meta new file mode 100644 index 0000000..b225d1c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/IUniTaskSource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e4d023d8404ab742b5e808c98097c3c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal.meta new file mode 100644 index 0000000..f9ba183 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d299dcffc6ed4847800ef875ccbda59 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPool.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPool.cs new file mode 100644 index 0000000..e1d9d3b --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPool.cs @@ -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 but only provides Shared. + + internal sealed class ArrayPool + { + // Same size as System.Buffers.DefaultArrayPool + const int DefaultMaxNumberOfArraysPerBucket = 50; + + static readonly T[] EmptyArray = new T[0]; + + public static readonly ArrayPool Shared = new ArrayPool(); + + readonly MinimumQueue[] buckets; + readonly SpinLock[] locks; + + ArrayPool() + { + // see: GetQueueIndex + buckets = new MinimumQueue[18]; + locks = new SpinLock[18]; + for (int i = 0; i < buckets.Length; i++) + { + buckets[i] = new MinimumQueue(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; + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPool.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPool.cs.meta new file mode 100644 index 0000000..693816c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPool.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f83ebad81fb89fb4882331616ca6d248 +timeCreated: 1532361008 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPoolUtil.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPoolUtil.cs new file mode 100644 index 0000000..016901d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPoolUtil.cs @@ -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(ref T[] array, int index, ArrayPool pool) + { + if (array.Length <= index) + { + EnsureCapacityCore(ref array, index, pool); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void EnsureCapacityCore(ref T[] array, int index, ArrayPool 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()); + + array = newArray; + } + } + + public static RentArray Materialize(IEnumerable source) + { + if (source is T[] array) + { + return new RentArray(array, array.Length, null); + } + + var defaultCount = 32; + if (source is ICollection coll) + { + if (coll.Count == 0) + { + return new RentArray(Array.Empty(), 0, null); + } + + defaultCount = coll.Count; + var pool = ArrayPool.Shared; + var buffer = pool.Rent(defaultCount); + coll.CopyTo(buffer, 0); + return new RentArray(buffer, coll.Count, pool); + } + else if (source is IReadOnlyCollection rcoll) + { + defaultCount = rcoll.Count; + } + + if (defaultCount == 0) + { + return new RentArray(Array.Empty(), 0, null); + } + + { + var pool = ArrayPool.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(buffer, index, pool); + } + } + + public struct RentArray : IDisposable + { + public readonly T[] Array; + public readonly int Length; + ArrayPool pool; + + public RentArray(T[] array, int length, ArrayPool pool) + { + this.Array = array; + this.Length = length; + this.pool = pool; + } + + public void Dispose() + { + DisposeManually(!RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); + } + + public void DisposeManually(bool clearArray) + { + if (pool != null) + { + if (clearArray) + { + System.Array.Clear(Array, 0, Length); + } + + pool.Return(Array, clearArray: false); + pool = null; + } + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPoolUtil.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPoolUtil.cs.meta new file mode 100644 index 0000000..e06ec65 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayPoolUtil.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 424cc208fb61d4e448b08fcfa0eee25e +timeCreated: 1532361007 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayUtil.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayUtil.cs new file mode 100644 index 0000000..fc7a808 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayUtil.cs @@ -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(ref T[] array, int index) + { + if (array.Length <= index) + { + EnsureCore(ref array, index); + } + } + + // rare case, no inlining. + [MethodImpl(MethodImplOptions.NoInlining)] + static void EnsureCore(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; + } + + /// + /// Optimizing utility to avoid .ToArray() that creates buffer copy(cut to just size). + /// + public static (T[] array, int length) Materialize(IEnumerable source) + { + if (source is T[] array) + { + return (array, array.Length); + } + + var defaultCount = 4; + if (source is ICollection coll) + { + defaultCount = coll.Count; + var buffer = new T[defaultCount]; + coll.CopyTo(buffer, 0); + return (buffer, defaultCount); + } + else if (source is IReadOnlyCollection rcoll) + { + defaultCount = rcoll.Count; + } + + if (defaultCount == 0) + { + return (Array.Empty(), 0); + } + + { + var index = 0; + var buffer = new T[defaultCount]; + foreach (var item in source) + { + EnsureCapacity(ref buffer, index); + buffer[index++] = item; + } + + return (buffer, index); + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayUtil.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayUtil.cs.meta new file mode 100644 index 0000000..645fc4e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ArrayUtil.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 23146a82ec99f2542a87971c8d3d7988 +timeCreated: 1532361007 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ContinuationQueue.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ContinuationQueue.cs new file mode 100644 index 0000000..a311126 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ContinuationQueue.cs @@ -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); + } + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ContinuationQueue.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ContinuationQueue.cs.meta new file mode 100644 index 0000000..b04e541 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ContinuationQueue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f66c32454e50f2546b17deadc80a4c77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/DiagnosticsExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/DiagnosticsExtensions.cs new file mode 100644 index 0000000..77d998f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/DiagnosticsExtensions.cs @@ -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 builtInTypeNames = new Dictionary + { + { 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(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 "" + withAssetsPath + ":" + line + ""; + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/DiagnosticsExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/DiagnosticsExtensions.cs.meta new file mode 100644 index 0000000..6c1f06c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/DiagnosticsExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f80fb1c9ed4c99447be1b0a47a8d980b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/Error.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/Error.cs new file mode 100644 index 0000000..5c7bc93 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/Error.cs @@ -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 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() + { + throw new InvalidOperationException("Not yet completed."); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowWhenContinuationIsAlreadyRegistered(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(); + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/Error.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/Error.cs.meta new file mode 100644 index 0000000..2e5d219 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/Error.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5f39f495294d4604b8082202faf98554 +timeCreated: 1532361007 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/MinimumQueue.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/MinimumQueue.cs new file mode 100644 index 0000000..a6b567a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/MinimumQueue.cs @@ -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. + internal class MinimumQueue + { + 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"); + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/MinimumQueue.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/MinimumQueue.cs.meta new file mode 100644 index 0000000..dc06736 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/MinimumQueue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d63add489ccc99498114d79702b904d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PlayerLoopRunner.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PlayerLoopRunner.cs new file mode 100644 index 0000000..43625ab --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PlayerLoopRunner.cs @@ -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 unhandledExceptionCallback; + + int tail = 0; + bool running = false; + IPlayerLoopItem[] loopItems = new IPlayerLoopItem[InitialSize]; + MinimumQueue waitQueue = new MinimumQueue(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(); + } + } + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PlayerLoopRunner.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PlayerLoopRunner.cs.meta new file mode 100644 index 0000000..603dbc9 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PlayerLoopRunner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 340c6d420bb4f484aa8683415ea92571 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PooledDelegate.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PooledDelegate.cs new file mode 100644 index 0000000..518244f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PooledDelegate.cs @@ -0,0 +1,50 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Cysharp.Threading.Tasks.Internal +{ + internal sealed class PooledDelegate : ITaskPoolNode> + { + static TaskPool> pool; + + PooledDelegate nextNode; + public ref PooledDelegate NextNode => ref nextNode; + + static PooledDelegate() + { + TaskPool.RegisterSizeGetter(typeof(PooledDelegate), () => pool.Size); + } + + readonly Action runDelegate; + Action continuation; + + PooledDelegate() + { + runDelegate = Run; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Action Create(Action continuation) + { + if (!pool.TryPop(out var item)) + { + item = new PooledDelegate(); + } + + 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(); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PooledDelegate.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PooledDelegate.cs.meta new file mode 100644 index 0000000..7f92aff --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/PooledDelegate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8932579438742fa40b010edd412dbfba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs new file mode 100644 index 0000000..cbabdab --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs @@ -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() + { + return WellKnownNoReferenceContainsType.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 + { + public static readonly bool IsWellKnownType; + + static WellKnownNoReferenceContainsType() + { + IsWellKnownType = WellKnownNoReferenceContainsTypeInitialize(typeof(T)); + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs.meta new file mode 100644 index 0000000..4254391 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 94975e4d4e0c0ea4ba787d3872ce9bb4 +timeCreated: 1532361007 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/StatePool.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/StatePool.cs new file mode 100644 index 0000000..e1d40bd --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/StatePool.cs @@ -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 Create(T1 item1) + { + return StatePool.Create(item1); + } + + public static StateTuple Create(T1 item1, T2 item2) + { + return StatePool.Create(item1, item2); + } + + public static StateTuple Create(T1 item1, T2 item2, T3 item3) + { + return StatePool.Create(item1, item2, item3); + } + } + + internal class StateTuple : IDisposable + { + public T1 Item1; + + public void Deconstruct(out T1 item1) + { + item1 = this.Item1; + } + + public void Dispose() + { + StatePool.Return(this); + } + } + + internal static class StatePool + { + static readonly ConcurrentQueue> queue = new ConcurrentQueue>(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static StateTuple Create(T1 item1) + { + if (queue.TryDequeue(out var value)) + { + value.Item1 = item1; + return value; + } + + return new StateTuple { Item1 = item1 }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Return(StateTuple tuple) + { + tuple.Item1 = default; + queue.Enqueue(tuple); + } + } + + internal class StateTuple : 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.Return(this); + } + } + + internal static class StatePool + { + static readonly ConcurrentQueue> queue = new ConcurrentQueue>(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static StateTuple Create(T1 item1, T2 item2) + { + if (queue.TryDequeue(out var value)) + { + value.Item1 = item1; + value.Item2 = item2; + return value; + } + + return new StateTuple { Item1 = item1, Item2 = item2 }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Return(StateTuple tuple) + { + tuple.Item1 = default; + tuple.Item2 = default; + queue.Enqueue(tuple); + } + } + + internal class StateTuple : 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.Return(this); + } + } + + internal static class StatePool + { + static readonly ConcurrentQueue> queue = new ConcurrentQueue>(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static StateTuple 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 { Item1 = item1, Item2 = item2, Item3 = item3 }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Return(StateTuple tuple) + { + tuple.Item1 = default; + tuple.Item2 = default; + tuple.Item3 = default; + queue.Enqueue(tuple); + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/StatePool.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/StatePool.cs.meta new file mode 100644 index 0000000..6779aa1 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/StatePool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 60cdf0bcaea36b444a7ae7263ae7598f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/TaskTracker.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/TaskTracker.cs new file mode 100644 index 0000000..c163e22 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/TaskTracker.cs @@ -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> listPool = new List>(); + + static readonly WeakDictionary tracking = new WeakDictionary(); + + [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; + } + + /// (trackingId, awaiterType, awaiterStatus, createdTime, stackTrace) + public static void ForEachActiveTask(Action 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", ""); + //} + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/TaskTracker.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/TaskTracker.cs.meta new file mode 100644 index 0000000..5563bf7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/TaskTracker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a203c73eb4ccdbb44bddfd82d38fdda9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityEqualityComparer.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityEqualityComparer.cs new file mode 100644 index 0000000..906f3b6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityEqualityComparer.cs @@ -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 = new Vector2EqualityComparer(); + public static readonly IEqualityComparer Vector3 = new Vector3EqualityComparer(); + public static readonly IEqualityComparer Vector4 = new Vector4EqualityComparer(); + public static readonly IEqualityComparer Color = new ColorEqualityComparer(); + public static readonly IEqualityComparer Color32 = new Color32EqualityComparer(); + public static readonly IEqualityComparer Rect = new RectEqualityComparer(); + public static readonly IEqualityComparer Bounds = new BoundsEqualityComparer(); + public static readonly IEqualityComparer 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 = new Vector2IntEqualityComparer(); + public static readonly IEqualityComparer Vector3Int = new Vector3IntEqualityComparer(); + public static readonly IEqualityComparer RangeInt = new RangeIntEqualityComparer(); + public static readonly IEqualityComparer RectInt = new RectIntEqualityComparer(); + public static readonly IEqualityComparer 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 + { + public static readonly IEqualityComparer Comparer; + + static Cache() + { + var comparer = GetDefaultHelper(typeof(T)); + if (comparer == null) + { + Comparer = EqualityComparer.Default; + } + else + { + Comparer = (IEqualityComparer)comparer; + } + } + } + + public static IEqualityComparer GetDefault() + { + return Cache.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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + { + 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 + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityEqualityComparer.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityEqualityComparer.cs.meta new file mode 100644 index 0000000..79eb04f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityEqualityComparer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ebaaf14253c9cfb47b23283218ff9b67 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs new file mode 100644 index 0000000..0da9f5a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs @@ -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 +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs.meta new file mode 100644 index 0000000..54bd2eb --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 111ba0e639de1d7428af6c823ead4918 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ValueStopwatch.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ValueStopwatch.cs new file mode 100644 index 0000000..d55d1f6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ValueStopwatch.cs @@ -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); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ValueStopwatch.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ValueStopwatch.cs.meta new file mode 100644 index 0000000..b7c6b09 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/ValueStopwatch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f16fb466974ad034c8732c79c7fd67ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/WeakDictionary.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/WeakDictionary.cs new file mode 100644 index 0000000..3feaad8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/WeakDictionary.cs @@ -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 + where TKey : class + { + Entry[] buckets; + int size; + SpinLock gate; // mutable struct(not readonly) + + readonly float loadFactor; + readonly IEqualityComparer keyEqualityComparer; + + public WeakDictionary(int capacity = 4, float loadFactor = 0.75f, IEqualityComparer keyComparer = null) + { + var tableSize = CalculateCapacity(capacity, loadFactor); + this.buckets = new Entry[tableSize]; + this.loadFactor = loadFactor; + this.gate = new SpinLock(false); + this.keyEqualityComparer = keyComparer ?? EqualityComparer.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(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(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> ToList() + { + var list = new List>(size); + ToList(ref list, false); + return list; + } + + // avoid allocate everytime. + public int ToList(ref List> 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(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 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; + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/WeakDictionary.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/WeakDictionary.cs.meta new file mode 100644 index 0000000..9dc1672 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Internal/WeakDictionary.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c78563864409714593226af59bcb6f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq.meta new file mode 100644 index 0000000..740eed9 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5e1adb6ec08bdbf4583fc305f06307c0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Aggregate.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Aggregate.cs new file mode 100644 index 0000000..78647ff --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Aggregate.cs @@ -0,0 +1,318 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask AggregateAsync(this IUniTaskAsyncEnumerable source, Func accumulator, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + + return Aggregate.AggregateAsync(source, accumulator, cancellationToken); + } + + public static UniTask AggregateAsync(this IUniTaskAsyncEnumerable source, TAccumulate seed, Func accumulator, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + + return Aggregate.AggregateAsync(source, seed, accumulator, cancellationToken); + } + + public static UniTask AggregateAsync(this IUniTaskAsyncEnumerable source, TAccumulate seed, Func accumulator, Func resultSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + Error.ThrowArgumentNullException(accumulator, nameof(resultSelector)); + + return Aggregate.AggregateAsync(source, seed, accumulator, resultSelector, cancellationToken); + } + + public static UniTask AggregateAwaitAsync(this IUniTaskAsyncEnumerable source, Func> accumulator, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + + return Aggregate.AggregateAwaitAsync(source, accumulator, cancellationToken); + } + + public static UniTask AggregateAwaitAsync(this IUniTaskAsyncEnumerable source, TAccumulate seed, Func> accumulator, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + + return Aggregate.AggregateAwaitAsync(source, seed, accumulator, cancellationToken); + } + + public static UniTask AggregateAwaitAsync(this IUniTaskAsyncEnumerable source, TAccumulate seed, Func> accumulator, Func> resultSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + Error.ThrowArgumentNullException(accumulator, nameof(resultSelector)); + + return Aggregate.AggregateAwaitAsync(source, seed, accumulator, resultSelector, cancellationToken); + } + + public static UniTask AggregateAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> accumulator, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + + return Aggregate.AggregateAwaitWithCancellationAsync(source, accumulator, cancellationToken); + } + + public static UniTask AggregateAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, TAccumulate seed, Func> accumulator, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + + return Aggregate.AggregateAwaitWithCancellationAsync(source, seed, accumulator, cancellationToken); + } + + public static UniTask AggregateAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, TAccumulate seed, Func> accumulator, Func> resultSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(accumulator, nameof(accumulator)); + Error.ThrowArgumentNullException(accumulator, nameof(resultSelector)); + + return Aggregate.AggregateAwaitWithCancellationAsync(source, seed, accumulator, resultSelector, cancellationToken); + } + } + + internal static class Aggregate + { + internal static async UniTask AggregateAsync(IUniTaskAsyncEnumerable source, Func accumulator, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value; + if (await e.MoveNextAsync()) + { + value = e.Current; + } + else + { + throw Error.NoElements(); + } + + while (await e.MoveNextAsync()) + { + value = accumulator(value, e.Current); + } + return value; + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AggregateAsync(IUniTaskAsyncEnumerable source, TAccumulate seed, Func accumulator, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TAccumulate value = seed; + while (await e.MoveNextAsync()) + { + value = accumulator(value, e.Current); + } + return value; + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AggregateAsync(IUniTaskAsyncEnumerable source, TAccumulate seed, Func accumulator, Func resultSelector, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TAccumulate value = seed; + while (await e.MoveNextAsync()) + { + value = accumulator(value, e.Current); + } + return resultSelector(value); + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + // with async + + internal static async UniTask AggregateAwaitAsync(IUniTaskAsyncEnumerable source, Func> accumulator, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value; + if (await e.MoveNextAsync()) + { + value = e.Current; + } + else + { + throw Error.NoElements(); + } + + while (await e.MoveNextAsync()) + { + value = await accumulator(value, e.Current); + } + return value; + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AggregateAwaitAsync(IUniTaskAsyncEnumerable source, TAccumulate seed, Func> accumulator, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TAccumulate value = seed; + while (await e.MoveNextAsync()) + { + value = await accumulator(value, e.Current); + } + return value; + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AggregateAwaitAsync(IUniTaskAsyncEnumerable source, TAccumulate seed, Func> accumulator, Func> resultSelector, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TAccumulate value = seed; + while (await e.MoveNextAsync()) + { + value = await accumulator(value, e.Current); + } + return await resultSelector(value); + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + + // with cancellation + + internal static async UniTask AggregateAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> accumulator, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value; + if (await e.MoveNextAsync()) + { + value = e.Current; + } + else + { + throw Error.NoElements(); + } + + while (await e.MoveNextAsync()) + { + value = await accumulator(value, e.Current, cancellationToken); + } + return value; + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AggregateAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, TAccumulate seed, Func> accumulator, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TAccumulate value = seed; + while (await e.MoveNextAsync()) + { + value = await accumulator(value, e.Current, cancellationToken); + } + return value; + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AggregateAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, TAccumulate seed, Func> accumulator, Func> resultSelector, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TAccumulate value = seed; + while (await e.MoveNextAsync()) + { + value = await accumulator(value, e.Current, cancellationToken); + } + return await resultSelector(value, cancellationToken); + + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Aggregate.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Aggregate.cs.meta new file mode 100644 index 0000000..837df4a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Aggregate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5dc68c05a4228c643937f6ebd185bcca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/All.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/All.cs new file mode 100644 index 0000000..5d6d5f0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/All.cs @@ -0,0 +1,108 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask AllAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return All.AllAsync(source, predicate, cancellationToken); + } + + public static UniTask AllAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return All.AllAwaitAsync(source, predicate, cancellationToken); + } + + public static UniTask AllAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return All.AllAwaitWithCancellationAsync(source, predicate, cancellationToken); + } + } + + internal static class All + { + internal static async UniTask AllAsync(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (!predicate(e.Current)) + { + return false; + } + } + + return true; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AllAwaitAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (!await predicate(e.Current)) + { + return false; + } + } + + return true; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AllAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (!await predicate(e.Current, cancellationToken)) + { + return false; + } + } + + return true; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/All.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/All.cs.meta new file mode 100644 index 0000000..d378ff0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/All.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7271437e0033af2448b600ee248924dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Any.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Any.cs new file mode 100644 index 0000000..2d43167 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Any.cs @@ -0,0 +1,136 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask AnyAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Any.AnyAsync(source, cancellationToken); + } + + public static UniTask AnyAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Any.AnyAsync(source, predicate, cancellationToken); + } + + public static UniTask AnyAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Any.AnyAwaitAsync(source, predicate, cancellationToken); + } + + public static UniTask AnyAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Any.AnyAwaitWithCancellationAsync(source, predicate, cancellationToken); + } + } + + internal static class Any + { + internal static async UniTask AnyAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + if (await e.MoveNextAsync()) + { + return true; + } + + return false; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AnyAsync(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (predicate(e.Current)) + { + return true; + } + } + + return false; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AnyAwaitAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (await predicate(e.Current)) + { + return true; + } + } + + return false; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask AnyAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (await predicate(e.Current, cancellationToken)) + { + return true; + } + } + + return false; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Any.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Any.cs.meta new file mode 100644 index 0000000..1070bcc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Any.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e2b2e65745263994fbe34f3e0ec8eb12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AppendPrepend.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AppendPrepend.cs new file mode 100644 index 0000000..3935afd --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AppendPrepend.cs @@ -0,0 +1,151 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Append(this IUniTaskAsyncEnumerable source, TSource element) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new AppendPrepend(source, element, true); + } + + public static IUniTaskAsyncEnumerable Prepend(this IUniTaskAsyncEnumerable source, TSource element) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new AppendPrepend(source, element, false); + } + } + + internal sealed class AppendPrepend : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly TSource element; + readonly bool append; // or prepend + + public AppendPrepend(IUniTaskAsyncEnumerable source, TSource element, bool append) + { + this.source = source; + this.element = element; + this.append = append; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _AppendPrepend(source, element, append, cancellationToken); + } + + sealed class _AppendPrepend : MoveNextSource, IUniTaskAsyncEnumerator + { + enum State : byte + { + None, + RequirePrepend, + RequireAppend, + Completed + } + + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + readonly TSource element; + CancellationToken cancellationToken; + + State state; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + + public _AppendPrepend(IUniTaskAsyncEnumerable source, TSource element, bool append, CancellationToken cancellationToken) + { + this.source = source; + this.element = element; + this.state = append ? State.RequireAppend : State.RequirePrepend; + this.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (enumerator == null) + { + if (state == State.RequirePrepend) + { + Current = element; + state = State.None; + return CompletedTasks.True; + } + + enumerator = source.GetAsyncEnumerator(cancellationToken); + } + + if (state == State.Completed) + { + return CompletedTasks.False; + } + + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + + if (awaiter.IsCompleted) + { + MoveNextCoreDelegate(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + + return new UniTask(this, completionSource.Version); + } + + static void MoveNextCore(object state) + { + var self = (_AppendPrepend)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.Current = self.enumerator.Current; + self.completionSource.TrySetResult(true); + } + else + { + if (self.state == State.RequireAppend) + { + self.state = State.Completed; + self.Current = self.element; + self.completionSource.TrySetResult(true); + } + else + { + self.state = State.Completed; + self.completionSource.TrySetResult(false); + } + } + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } + +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AppendPrepend.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AppendPrepend.cs.meta new file mode 100644 index 0000000..6d2ee04 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AppendPrepend.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3268ec424b8055f45aa2a26d17c80468 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs new file mode 100644 index 0000000..c00452e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs @@ -0,0 +1,10 @@ +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable AsUniTaskAsyncEnumerable(this IUniTaskAsyncEnumerable source) + { + return source; + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs.meta new file mode 100644 index 0000000..90f6207 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69866e262589ea643bbc62a1d696077a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs new file mode 100644 index 0000000..e7f9968 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs @@ -0,0 +1,356 @@ +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + // note: refactor all inherit class and should remove this. + // see Select and Where. + internal abstract class AsyncEnumeratorBase : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action moveNextCallbackDelegate = MoveNextCallBack; + + readonly IUniTaskAsyncEnumerable source; + protected CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter sourceMoveNext; + + public AsyncEnumeratorBase(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 4); + } + + // abstract + + /// + /// If return value is false, continue source.MoveNext. + /// + protected abstract bool TryMoveNextCore(bool sourceHasCurrent, out bool result); + + // Util + protected TSource SourceCurrent => enumerator.Current; + + // IUniTaskAsyncEnumerator + + public TResult Current { get; protected set; } + + public UniTask MoveNextAsync() + { + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + if (!OnFirstIteration()) + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + protected virtual bool OnFirstIteration() + { + return false; + } + + protected void SourceMoveNext() + { + CONTINUE: + sourceMoveNext = enumerator.MoveNextAsync().GetAwaiter(); + if (sourceMoveNext.IsCompleted) + { + bool result = false; + try + { + if (!TryMoveNextCore(sourceMoveNext.GetResult(), out result)) + { + goto CONTINUE; + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + if (cancellationToken.IsCancellationRequested) + { + completionSource.TrySetCanceled(cancellationToken); + } + else + { + completionSource.TrySetResult(result); + } + } + else + { + sourceMoveNext.SourceOnCompleted(moveNextCallbackDelegate, this); + } + } + + static void MoveNextCallBack(object state) + { + var self = (AsyncEnumeratorBase)state; + bool result; + try + { + if (!self.TryMoveNextCore(self.sourceMoveNext.GetResult(), out result)) + { + self.SourceMoveNext(); + return; + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + + if (self.cancellationToken.IsCancellationRequested) + { + self.completionSource.TrySetCanceled(self.cancellationToken); + } + else + { + self.completionSource.TrySetResult(result); + } + } + + // if require additional resource to dispose, override and call base.DisposeAsync. + public virtual UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + + internal abstract class AsyncEnumeratorAwaitSelectorBase : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action moveNextCallbackDelegate = MoveNextCallBack; + static readonly Action setCurrentCallbackDelegate = SetCurrentCallBack; + + + readonly IUniTaskAsyncEnumerable source; + protected CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter sourceMoveNext; + + UniTask.Awaiter resultAwaiter; + + public AsyncEnumeratorAwaitSelectorBase(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 4); + } + + // abstract + + protected abstract UniTask TransformAsync(TSource sourceCurrent); + protected abstract bool TrySetCurrentCore(TAwait awaitResult, out bool terminateIteration); + + // Util + protected TSource SourceCurrent { get; private set; } + + protected (bool waitCallback, bool requireNextIteration) ActionCompleted(bool trySetCurrentResult, out bool moveNextResult) + { + if (trySetCurrentResult) + { + moveNextResult = true; + return (false, false); + } + else + { + moveNextResult = default; + return (false, true); + } + } + protected (bool waitCallback, bool requireNextIteration) WaitAwaitCallback(out bool moveNextResult) { moveNextResult = default; return (true, false); } + protected (bool waitCallback, bool requireNextIteration) IterateFinished(out bool moveNextResult) { moveNextResult = false; return (false, false); } + + // IUniTaskAsyncEnumerator + + public TResult Current { get; protected set; } + + public UniTask MoveNextAsync() + { + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + protected void SourceMoveNext() + { + CONTINUE: + sourceMoveNext = enumerator.MoveNextAsync().GetAwaiter(); + if (sourceMoveNext.IsCompleted) + { + bool result = false; + try + { + (bool waitCallback, bool requireNextIteration) = TryMoveNextCore(sourceMoveNext.GetResult(), out result); + + if (waitCallback) + { + return; + } + + if (requireNextIteration) + { + goto CONTINUE; + } + else + { + completionSource.TrySetResult(result); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + } + else + { + sourceMoveNext.SourceOnCompleted(moveNextCallbackDelegate, this); + } + } + + (bool waitCallback, bool requireNextIteration) TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + SourceCurrent = enumerator.Current; + var task = TransformAsync(SourceCurrent); + if (UnwarapTask(task, out var taskResult)) + { + var currentResult = TrySetCurrentCore(taskResult, out var terminateIteration); + if (terminateIteration) + { + return IterateFinished(out result); + } + + return ActionCompleted(currentResult, out result); + } + else + { + return WaitAwaitCallback(out result); + } + } + + return IterateFinished(out result); + } + + protected bool UnwarapTask(UniTask taskResult, out TAwait result) + { + resultAwaiter = taskResult.GetAwaiter(); + + if (resultAwaiter.IsCompleted) + { + result = resultAwaiter.GetResult(); + return true; + } + else + { + resultAwaiter.SourceOnCompleted(setCurrentCallbackDelegate, this); + result = default; + return false; + } + } + + static void MoveNextCallBack(object state) + { + var self = (AsyncEnumeratorAwaitSelectorBase)state; + bool result = false; + try + { + (bool waitCallback, bool requireNextIteration) = self.TryMoveNextCore(self.sourceMoveNext.GetResult(), out result); + + if (waitCallback) + { + return; + } + + if (requireNextIteration) + { + self.SourceMoveNext(); + return; + } + else + { + self.completionSource.TrySetResult(result); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + } + + static void SetCurrentCallBack(object state) + { + var self = (AsyncEnumeratorAwaitSelectorBase)state; + + bool doneSetCurrent; + bool terminateIteration; + try + { + var result = self.resultAwaiter.GetResult(); + doneSetCurrent = self.TrySetCurrentCore(result, out terminateIteration); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + + if (self.cancellationToken.IsCancellationRequested) + { + self.completionSource.TrySetCanceled(self.cancellationToken); + } + else + { + if (doneSetCurrent) + { + self.completionSource.TrySetResult(true); + } + else + { + if (terminateIteration) + { + self.completionSource.TrySetResult(false); + } + else + { + self.SourceMoveNext(); + } + } + } + } + + // if require additional resource to dispose, override and call base.DisposeAsync. + public virtual UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs.meta new file mode 100644 index 0000000..a4e96dc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01ba1d3b17e13fb4c95740131c7e6e19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Average.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Average.cs new file mode 100644 index 0000000..b2ce42c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Average.cs @@ -0,0 +1,1524 @@ +using System; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Average.AverageAsync(source, cancellationToken); + } + + public static UniTask AverageAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask AverageAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + } + + internal static class Average + { + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Int32 sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += e.Current; + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Int32 sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Int32 sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Int32 sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current, cancellationToken); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Int64 sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += e.Current; + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Int64 sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Int64 sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Int64 sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current, cancellationToken); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Single sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += e.Current; + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (float)(sum / count); + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Single sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (float)(sum / count); + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Single sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (float)(sum / count); + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Single sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current, cancellationToken); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (float)(sum / count); + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Double sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += e.Current; + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Double sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Double sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Double sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current, cancellationToken); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Decimal sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += e.Current; + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Decimal sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Decimal sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Decimal sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked + { + sum += await selector(e.Current, cancellationToken); + count++; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Int32? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Int32? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Int32? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Int32? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current, cancellationToken); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Int64? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Int64? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Int64? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Int64? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current, cancellationToken); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (double)sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Single? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (float)(sum / count); + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Single? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (float)(sum / count); + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Single? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (float)(sum / count); + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Single? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current, cancellationToken); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return (float)(sum / count); + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Double? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Double? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Double? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Double? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current, cancellationToken); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + Decimal? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + long count = 0; + Decimal? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Decimal? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + public static async UniTask AverageAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + long count = 0; + Decimal? sum = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = await selector(e.Current, cancellationToken); + if (v.HasValue) + { + checked + { + sum += v.Value; + count++; + } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum / count; + } + + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Average.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Average.cs.meta new file mode 100644 index 0000000..8f60dfc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Average.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58499f95012fb3c47bb7bcbc5862e562 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Buffer.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Buffer.cs new file mode 100644 index 0000000..be395b6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Buffer.cs @@ -0,0 +1,345 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable> Buffer(this IUniTaskAsyncEnumerable source, Int32 count) + { + Error.ThrowArgumentNullException(source, nameof(source)); + if (count <= 0) throw Error.ArgumentOutOfRange(nameof(count)); + + return new Buffer(source, count); + } + + public static IUniTaskAsyncEnumerable> Buffer(this IUniTaskAsyncEnumerable source, Int32 count, Int32 skip) + { + Error.ThrowArgumentNullException(source, nameof(source)); + if (count <= 0) throw Error.ArgumentOutOfRange(nameof(count)); + if (skip <= 0) throw Error.ArgumentOutOfRange(nameof(skip)); + + return new BufferSkip(source, count, skip); + } + } + + internal sealed class Buffer : IUniTaskAsyncEnumerable> + { + readonly IUniTaskAsyncEnumerable source; + readonly int count; + + public Buffer(IUniTaskAsyncEnumerable source, int count) + { + this.source = source; + this.count = count; + } + + public IUniTaskAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Buffer(source, count, cancellationToken); + } + + sealed class _Buffer : MoveNextSource, IUniTaskAsyncEnumerator> + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + readonly int count; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + bool continueNext; + + bool completed; + List buffer; + + public _Buffer(IUniTaskAsyncEnumerable source, int count, CancellationToken cancellationToken) + { + this.source = source; + this.count = count; + this.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(this, 3); + } + + public IList Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + buffer = new List(count); + } + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + if (completed) + { + if (buffer != null && buffer.Count > 0) + { + var ret = buffer; + buffer = null; + Current = ret; + completionSource.TrySetResult(true); + return; + } + else + { + completionSource.TrySetResult(false); + return; + } + } + + try + { + + LOOP: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; // avoid recursive + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + + static void MoveNextCore(object state) + { + var self = (_Buffer)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.buffer.Add(self.enumerator.Current); + + if (self.buffer.Count == self.count) + { + self.Current = self.buffer; + self.buffer = new List(self.count); + self.continueNext = false; + self.completionSource.TrySetResult(true); + return; + } + else + { + if (!self.continueNext) + { + self.SourceMoveNext(); + } + } + } + else + { + self.continueNext = false; + self.completed = true; + self.SourceMoveNext(); + } + } + else + { + self.continueNext = false; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } + + internal sealed class BufferSkip : IUniTaskAsyncEnumerable> + { + readonly IUniTaskAsyncEnumerable source; + readonly int count; + readonly int skip; + + public BufferSkip(IUniTaskAsyncEnumerable source, int count, int skip) + { + this.source = source; + this.count = count; + this.skip = skip; + } + + public IUniTaskAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _BufferSkip(source, count, skip, cancellationToken); + } + + sealed class _BufferSkip : MoveNextSource, IUniTaskAsyncEnumerator> + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + readonly int count; + readonly int skip; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + bool continueNext; + + bool completed; + Queue> buffers; + int index = 0; + + public _BufferSkip(IUniTaskAsyncEnumerable source, int count, int skip, CancellationToken cancellationToken) + { + this.source = source; + this.count = count; + this.skip = skip; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public IList Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + buffers = new Queue>(); + } + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + if (completed) + { + if (buffers.Count > 0) + { + Current = buffers.Dequeue(); + completionSource.TrySetResult(true); + return; + } + else + { + completionSource.TrySetResult(false); + return; + } + } + + try + { + + LOOP: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; // avoid recursive + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + + static void MoveNextCore(object state) + { + var self = (_BufferSkip)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + if (self.index++ % self.skip == 0) + { + self.buffers.Enqueue(new List(self.count)); + } + + var item = self.enumerator.Current; + foreach (var buffer in self.buffers) + { + buffer.Add(item); + } + + if (self.buffers.Count > 0 && self.buffers.Peek().Count == self.count) + { + self.Current = self.buffers.Dequeue(); + self.continueNext = false; + self.completionSource.TrySetResult(true); + return; + } + else + { + if (!self.continueNext) + { + self.SourceMoveNext(); + } + } + } + else + { + self.continueNext = false; + self.completed = true; + self.SourceMoveNext(); + } + } + else + { + self.continueNext = false; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Buffer.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Buffer.cs.meta new file mode 100644 index 0000000..e7154e4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Buffer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 951310243334a3148a7872977cb31c5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Cast.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Cast.cs new file mode 100644 index 0000000..0a0c0f8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Cast.cs @@ -0,0 +1,53 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Cast(this IUniTaskAsyncEnumerable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new Cast(source); + } + } + + internal sealed class Cast : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + + public Cast(IUniTaskAsyncEnumerable source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Cast(source, cancellationToken); + } + + class _Cast : AsyncEnumeratorBase + { + public _Cast(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + Current = (TResult)SourceCurrent; + result = true; + return true; + } + + result = false; + return true; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Cast.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Cast.cs.meta new file mode 100644 index 0000000..913b043 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Cast.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: edebeae8b61352b428abe9ce8f3fc71a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/CombineLatest.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/CombineLatest.cs new file mode 100644 index 0000000..92fb1da --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/CombineLatest.cs @@ -0,0 +1,11372 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(source8, nameof(source8)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(source8, nameof(source8)); + Error.ThrowArgumentNullException(source9, nameof(source9)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(source8, nameof(source8)); + Error.ThrowArgumentNullException(source9, nameof(source9)); + Error.ThrowArgumentNullException(source10, nameof(source10)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(source8, nameof(source8)); + Error.ThrowArgumentNullException(source9, nameof(source9)); + Error.ThrowArgumentNullException(source10, nameof(source10)); + Error.ThrowArgumentNullException(source11, nameof(source11)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(source8, nameof(source8)); + Error.ThrowArgumentNullException(source9, nameof(source9)); + Error.ThrowArgumentNullException(source10, nameof(source10)); + Error.ThrowArgumentNullException(source11, nameof(source11)); + Error.ThrowArgumentNullException(source12, nameof(source12)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(source8, nameof(source8)); + Error.ThrowArgumentNullException(source9, nameof(source9)); + Error.ThrowArgumentNullException(source10, nameof(source10)); + Error.ThrowArgumentNullException(source11, nameof(source11)); + Error.ThrowArgumentNullException(source12, nameof(source12)); + Error.ThrowArgumentNullException(source13, nameof(source13)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, IUniTaskAsyncEnumerable source14, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(source8, nameof(source8)); + Error.ThrowArgumentNullException(source9, nameof(source9)); + Error.ThrowArgumentNullException(source10, nameof(source10)); + Error.ThrowArgumentNullException(source11, nameof(source11)); + Error.ThrowArgumentNullException(source12, nameof(source12)); + Error.ThrowArgumentNullException(source13, nameof(source13)); + Error.ThrowArgumentNullException(source14, nameof(source14)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector); + } + + public static IUniTaskAsyncEnumerable CombineLatest(this IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, IUniTaskAsyncEnumerable source14, IUniTaskAsyncEnumerable source15, Func resultSelector) + { + Error.ThrowArgumentNullException(source1, nameof(source1)); + Error.ThrowArgumentNullException(source2, nameof(source2)); + Error.ThrowArgumentNullException(source3, nameof(source3)); + Error.ThrowArgumentNullException(source4, nameof(source4)); + Error.ThrowArgumentNullException(source5, nameof(source5)); + Error.ThrowArgumentNullException(source6, nameof(source6)); + Error.ThrowArgumentNullException(source7, nameof(source7)); + Error.ThrowArgumentNullException(source8, nameof(source8)); + Error.ThrowArgumentNullException(source9, nameof(source9)); + Error.ThrowArgumentNullException(source10, nameof(source10)); + Error.ThrowArgumentNullException(source11, nameof(source11)); + Error.ThrowArgumentNullException(source12, nameof(source12)); + Error.ThrowArgumentNullException(source13, nameof(source13)); + Error.ThrowArgumentNullException(source14, nameof(source14)); + Error.ThrowArgumentNullException(source15, nameof(source15)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector); + } + + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + const int CompleteCount = 2; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + + if (!running1 || !running2) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2) + { + result = resultSelector(current1, current2); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + const int CompleteCount = 3; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + + if (!running1 || !running2 || !running3) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3) + { + result = resultSelector(current1, current2, current3); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + const int CompleteCount = 4; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4) + { + result = resultSelector(current1, current2, current3, current4); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + const int CompleteCount = 5; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5) + { + result = resultSelector(current1, current2, current3, current4, current5); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + const int CompleteCount = 6; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6) + { + result = resultSelector(current1, current2, current3, current4, current5, current6); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + const int CompleteCount = 7; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + static readonly Action Completed8Delegate = Completed8; + const int CompleteCount = 8; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + IUniTaskAsyncEnumerator enumerator8; + UniTask.Awaiter awaiter8; + bool hasCurrent8; + bool running8; + T8 current8; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + enumerator8 = source8.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + if (!running8) + { + running8 = true; + awaiter8 = enumerator8.MoveNextAsync().GetAwaiter(); + if (awaiter8.IsCompleted) + { + Completed8(this); + } + else + { + awaiter8.SourceOnCompleted(Completed8Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed8(object state) + { + var self = (_CombineLatest)state; + self.running8 = false; + + try + { + if (self.awaiter8.GetResult()) + { + self.hasCurrent8 = true; + self.current8 = self.enumerator8.Current; + goto SUCCESS; + } + else + { + self.running8 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running8 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running8 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter8.SourceOnCompleted(Completed8Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + if (enumerator8 != null) + { + await enumerator8.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + static readonly Action Completed8Delegate = Completed8; + static readonly Action Completed9Delegate = Completed9; + const int CompleteCount = 9; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + IUniTaskAsyncEnumerator enumerator8; + UniTask.Awaiter awaiter8; + bool hasCurrent8; + bool running8; + T8 current8; + + IUniTaskAsyncEnumerator enumerator9; + UniTask.Awaiter awaiter9; + bool hasCurrent9; + bool running9; + T9 current9; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + enumerator8 = source8.GetAsyncEnumerator(cancellationToken); + enumerator9 = source9.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + if (!running8) + { + running8 = true; + awaiter8 = enumerator8.MoveNextAsync().GetAwaiter(); + if (awaiter8.IsCompleted) + { + Completed8(this); + } + else + { + awaiter8.SourceOnCompleted(Completed8Delegate, this); + } + } + if (!running9) + { + running9 = true; + awaiter9 = enumerator9.MoveNextAsync().GetAwaiter(); + if (awaiter9.IsCompleted) + { + Completed9(this); + } + else + { + awaiter9.SourceOnCompleted(Completed9Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed8(object state) + { + var self = (_CombineLatest)state; + self.running8 = false; + + try + { + if (self.awaiter8.GetResult()) + { + self.hasCurrent8 = true; + self.current8 = self.enumerator8.Current; + goto SUCCESS; + } + else + { + self.running8 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running8 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running8 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter8.SourceOnCompleted(Completed8Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed9(object state) + { + var self = (_CombineLatest)state; + self.running9 = false; + + try + { + if (self.awaiter9.GetResult()) + { + self.hasCurrent9 = true; + self.current9 = self.enumerator9.Current; + goto SUCCESS; + } + else + { + self.running9 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running9 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running9 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter9.SourceOnCompleted(Completed9Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + if (enumerator8 != null) + { + await enumerator8.DisposeAsync(); + } + if (enumerator9 != null) + { + await enumerator9.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + static readonly Action Completed8Delegate = Completed8; + static readonly Action Completed9Delegate = Completed9; + static readonly Action Completed10Delegate = Completed10; + const int CompleteCount = 10; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + IUniTaskAsyncEnumerator enumerator8; + UniTask.Awaiter awaiter8; + bool hasCurrent8; + bool running8; + T8 current8; + + IUniTaskAsyncEnumerator enumerator9; + UniTask.Awaiter awaiter9; + bool hasCurrent9; + bool running9; + T9 current9; + + IUniTaskAsyncEnumerator enumerator10; + UniTask.Awaiter awaiter10; + bool hasCurrent10; + bool running10; + T10 current10; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + enumerator8 = source8.GetAsyncEnumerator(cancellationToken); + enumerator9 = source9.GetAsyncEnumerator(cancellationToken); + enumerator10 = source10.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + if (!running8) + { + running8 = true; + awaiter8 = enumerator8.MoveNextAsync().GetAwaiter(); + if (awaiter8.IsCompleted) + { + Completed8(this); + } + else + { + awaiter8.SourceOnCompleted(Completed8Delegate, this); + } + } + if (!running9) + { + running9 = true; + awaiter9 = enumerator9.MoveNextAsync().GetAwaiter(); + if (awaiter9.IsCompleted) + { + Completed9(this); + } + else + { + awaiter9.SourceOnCompleted(Completed9Delegate, this); + } + } + if (!running10) + { + running10 = true; + awaiter10 = enumerator10.MoveNextAsync().GetAwaiter(); + if (awaiter10.IsCompleted) + { + Completed10(this); + } + else + { + awaiter10.SourceOnCompleted(Completed10Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed8(object state) + { + var self = (_CombineLatest)state; + self.running8 = false; + + try + { + if (self.awaiter8.GetResult()) + { + self.hasCurrent8 = true; + self.current8 = self.enumerator8.Current; + goto SUCCESS; + } + else + { + self.running8 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running8 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running8 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter8.SourceOnCompleted(Completed8Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed9(object state) + { + var self = (_CombineLatest)state; + self.running9 = false; + + try + { + if (self.awaiter9.GetResult()) + { + self.hasCurrent9 = true; + self.current9 = self.enumerator9.Current; + goto SUCCESS; + } + else + { + self.running9 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running9 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running9 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter9.SourceOnCompleted(Completed9Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed10(object state) + { + var self = (_CombineLatest)state; + self.running10 = false; + + try + { + if (self.awaiter10.GetResult()) + { + self.hasCurrent10 = true; + self.current10 = self.enumerator10.Current; + goto SUCCESS; + } + else + { + self.running10 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running10 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running10 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter10.SourceOnCompleted(Completed10Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + if (enumerator8 != null) + { + await enumerator8.DisposeAsync(); + } + if (enumerator9 != null) + { + await enumerator9.DisposeAsync(); + } + if (enumerator10 != null) + { + await enumerator10.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + static readonly Action Completed8Delegate = Completed8; + static readonly Action Completed9Delegate = Completed9; + static readonly Action Completed10Delegate = Completed10; + static readonly Action Completed11Delegate = Completed11; + const int CompleteCount = 11; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + IUniTaskAsyncEnumerator enumerator8; + UniTask.Awaiter awaiter8; + bool hasCurrent8; + bool running8; + T8 current8; + + IUniTaskAsyncEnumerator enumerator9; + UniTask.Awaiter awaiter9; + bool hasCurrent9; + bool running9; + T9 current9; + + IUniTaskAsyncEnumerator enumerator10; + UniTask.Awaiter awaiter10; + bool hasCurrent10; + bool running10; + T10 current10; + + IUniTaskAsyncEnumerator enumerator11; + UniTask.Awaiter awaiter11; + bool hasCurrent11; + bool running11; + T11 current11; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + enumerator8 = source8.GetAsyncEnumerator(cancellationToken); + enumerator9 = source9.GetAsyncEnumerator(cancellationToken); + enumerator10 = source10.GetAsyncEnumerator(cancellationToken); + enumerator11 = source11.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + if (!running8) + { + running8 = true; + awaiter8 = enumerator8.MoveNextAsync().GetAwaiter(); + if (awaiter8.IsCompleted) + { + Completed8(this); + } + else + { + awaiter8.SourceOnCompleted(Completed8Delegate, this); + } + } + if (!running9) + { + running9 = true; + awaiter9 = enumerator9.MoveNextAsync().GetAwaiter(); + if (awaiter9.IsCompleted) + { + Completed9(this); + } + else + { + awaiter9.SourceOnCompleted(Completed9Delegate, this); + } + } + if (!running10) + { + running10 = true; + awaiter10 = enumerator10.MoveNextAsync().GetAwaiter(); + if (awaiter10.IsCompleted) + { + Completed10(this); + } + else + { + awaiter10.SourceOnCompleted(Completed10Delegate, this); + } + } + if (!running11) + { + running11 = true; + awaiter11 = enumerator11.MoveNextAsync().GetAwaiter(); + if (awaiter11.IsCompleted) + { + Completed11(this); + } + else + { + awaiter11.SourceOnCompleted(Completed11Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed8(object state) + { + var self = (_CombineLatest)state; + self.running8 = false; + + try + { + if (self.awaiter8.GetResult()) + { + self.hasCurrent8 = true; + self.current8 = self.enumerator8.Current; + goto SUCCESS; + } + else + { + self.running8 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running8 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running8 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter8.SourceOnCompleted(Completed8Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed9(object state) + { + var self = (_CombineLatest)state; + self.running9 = false; + + try + { + if (self.awaiter9.GetResult()) + { + self.hasCurrent9 = true; + self.current9 = self.enumerator9.Current; + goto SUCCESS; + } + else + { + self.running9 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running9 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running9 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter9.SourceOnCompleted(Completed9Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed10(object state) + { + var self = (_CombineLatest)state; + self.running10 = false; + + try + { + if (self.awaiter10.GetResult()) + { + self.hasCurrent10 = true; + self.current10 = self.enumerator10.Current; + goto SUCCESS; + } + else + { + self.running10 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running10 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running10 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter10.SourceOnCompleted(Completed10Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed11(object state) + { + var self = (_CombineLatest)state; + self.running11 = false; + + try + { + if (self.awaiter11.GetResult()) + { + self.hasCurrent11 = true; + self.current11 = self.enumerator11.Current; + goto SUCCESS; + } + else + { + self.running11 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running11 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running11 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter11.SourceOnCompleted(Completed11Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + if (enumerator8 != null) + { + await enumerator8.DisposeAsync(); + } + if (enumerator9 != null) + { + await enumerator9.DisposeAsync(); + } + if (enumerator10 != null) + { + await enumerator10.DisposeAsync(); + } + if (enumerator11 != null) + { + await enumerator11.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + readonly IUniTaskAsyncEnumerable source12; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + this.source12 = source12; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + static readonly Action Completed8Delegate = Completed8; + static readonly Action Completed9Delegate = Completed9; + static readonly Action Completed10Delegate = Completed10; + static readonly Action Completed11Delegate = Completed11; + static readonly Action Completed12Delegate = Completed12; + const int CompleteCount = 12; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + readonly IUniTaskAsyncEnumerable source12; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + IUniTaskAsyncEnumerator enumerator8; + UniTask.Awaiter awaiter8; + bool hasCurrent8; + bool running8; + T8 current8; + + IUniTaskAsyncEnumerator enumerator9; + UniTask.Awaiter awaiter9; + bool hasCurrent9; + bool running9; + T9 current9; + + IUniTaskAsyncEnumerator enumerator10; + UniTask.Awaiter awaiter10; + bool hasCurrent10; + bool running10; + T10 current10; + + IUniTaskAsyncEnumerator enumerator11; + UniTask.Awaiter awaiter11; + bool hasCurrent11; + bool running11; + T11 current11; + + IUniTaskAsyncEnumerator enumerator12; + UniTask.Awaiter awaiter12; + bool hasCurrent12; + bool running12; + T12 current12; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + this.source12 = source12; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + enumerator8 = source8.GetAsyncEnumerator(cancellationToken); + enumerator9 = source9.GetAsyncEnumerator(cancellationToken); + enumerator10 = source10.GetAsyncEnumerator(cancellationToken); + enumerator11 = source11.GetAsyncEnumerator(cancellationToken); + enumerator12 = source12.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + if (!running8) + { + running8 = true; + awaiter8 = enumerator8.MoveNextAsync().GetAwaiter(); + if (awaiter8.IsCompleted) + { + Completed8(this); + } + else + { + awaiter8.SourceOnCompleted(Completed8Delegate, this); + } + } + if (!running9) + { + running9 = true; + awaiter9 = enumerator9.MoveNextAsync().GetAwaiter(); + if (awaiter9.IsCompleted) + { + Completed9(this); + } + else + { + awaiter9.SourceOnCompleted(Completed9Delegate, this); + } + } + if (!running10) + { + running10 = true; + awaiter10 = enumerator10.MoveNextAsync().GetAwaiter(); + if (awaiter10.IsCompleted) + { + Completed10(this); + } + else + { + awaiter10.SourceOnCompleted(Completed10Delegate, this); + } + } + if (!running11) + { + running11 = true; + awaiter11 = enumerator11.MoveNextAsync().GetAwaiter(); + if (awaiter11.IsCompleted) + { + Completed11(this); + } + else + { + awaiter11.SourceOnCompleted(Completed11Delegate, this); + } + } + if (!running12) + { + running12 = true; + awaiter12 = enumerator12.MoveNextAsync().GetAwaiter(); + if (awaiter12.IsCompleted) + { + Completed12(this); + } + else + { + awaiter12.SourceOnCompleted(Completed12Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11 || !running12) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed8(object state) + { + var self = (_CombineLatest)state; + self.running8 = false; + + try + { + if (self.awaiter8.GetResult()) + { + self.hasCurrent8 = true; + self.current8 = self.enumerator8.Current; + goto SUCCESS; + } + else + { + self.running8 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running8 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running8 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter8.SourceOnCompleted(Completed8Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed9(object state) + { + var self = (_CombineLatest)state; + self.running9 = false; + + try + { + if (self.awaiter9.GetResult()) + { + self.hasCurrent9 = true; + self.current9 = self.enumerator9.Current; + goto SUCCESS; + } + else + { + self.running9 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running9 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running9 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter9.SourceOnCompleted(Completed9Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed10(object state) + { + var self = (_CombineLatest)state; + self.running10 = false; + + try + { + if (self.awaiter10.GetResult()) + { + self.hasCurrent10 = true; + self.current10 = self.enumerator10.Current; + goto SUCCESS; + } + else + { + self.running10 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running10 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running10 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter10.SourceOnCompleted(Completed10Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed11(object state) + { + var self = (_CombineLatest)state; + self.running11 = false; + + try + { + if (self.awaiter11.GetResult()) + { + self.hasCurrent11 = true; + self.current11 = self.enumerator11.Current; + goto SUCCESS; + } + else + { + self.running11 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running11 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running11 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter11.SourceOnCompleted(Completed11Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed12(object state) + { + var self = (_CombineLatest)state; + self.running12 = false; + + try + { + if (self.awaiter12.GetResult()) + { + self.hasCurrent12 = true; + self.current12 = self.enumerator12.Current; + goto SUCCESS; + } + else + { + self.running12 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running12 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running12 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter12 = self.enumerator12.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter12.SourceOnCompleted(Completed12Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11 && hasCurrent12) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11, current12); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + if (enumerator8 != null) + { + await enumerator8.DisposeAsync(); + } + if (enumerator9 != null) + { + await enumerator9.DisposeAsync(); + } + if (enumerator10 != null) + { + await enumerator10.DisposeAsync(); + } + if (enumerator11 != null) + { + await enumerator11.DisposeAsync(); + } + if (enumerator12 != null) + { + await enumerator12.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + readonly IUniTaskAsyncEnumerable source12; + readonly IUniTaskAsyncEnumerable source13; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + this.source12 = source12; + this.source13 = source13; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + static readonly Action Completed8Delegate = Completed8; + static readonly Action Completed9Delegate = Completed9; + static readonly Action Completed10Delegate = Completed10; + static readonly Action Completed11Delegate = Completed11; + static readonly Action Completed12Delegate = Completed12; + static readonly Action Completed13Delegate = Completed13; + const int CompleteCount = 13; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + readonly IUniTaskAsyncEnumerable source12; + readonly IUniTaskAsyncEnumerable source13; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + IUniTaskAsyncEnumerator enumerator8; + UniTask.Awaiter awaiter8; + bool hasCurrent8; + bool running8; + T8 current8; + + IUniTaskAsyncEnumerator enumerator9; + UniTask.Awaiter awaiter9; + bool hasCurrent9; + bool running9; + T9 current9; + + IUniTaskAsyncEnumerator enumerator10; + UniTask.Awaiter awaiter10; + bool hasCurrent10; + bool running10; + T10 current10; + + IUniTaskAsyncEnumerator enumerator11; + UniTask.Awaiter awaiter11; + bool hasCurrent11; + bool running11; + T11 current11; + + IUniTaskAsyncEnumerator enumerator12; + UniTask.Awaiter awaiter12; + bool hasCurrent12; + bool running12; + T12 current12; + + IUniTaskAsyncEnumerator enumerator13; + UniTask.Awaiter awaiter13; + bool hasCurrent13; + bool running13; + T13 current13; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + this.source12 = source12; + this.source13 = source13; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + enumerator8 = source8.GetAsyncEnumerator(cancellationToken); + enumerator9 = source9.GetAsyncEnumerator(cancellationToken); + enumerator10 = source10.GetAsyncEnumerator(cancellationToken); + enumerator11 = source11.GetAsyncEnumerator(cancellationToken); + enumerator12 = source12.GetAsyncEnumerator(cancellationToken); + enumerator13 = source13.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + if (!running8) + { + running8 = true; + awaiter8 = enumerator8.MoveNextAsync().GetAwaiter(); + if (awaiter8.IsCompleted) + { + Completed8(this); + } + else + { + awaiter8.SourceOnCompleted(Completed8Delegate, this); + } + } + if (!running9) + { + running9 = true; + awaiter9 = enumerator9.MoveNextAsync().GetAwaiter(); + if (awaiter9.IsCompleted) + { + Completed9(this); + } + else + { + awaiter9.SourceOnCompleted(Completed9Delegate, this); + } + } + if (!running10) + { + running10 = true; + awaiter10 = enumerator10.MoveNextAsync().GetAwaiter(); + if (awaiter10.IsCompleted) + { + Completed10(this); + } + else + { + awaiter10.SourceOnCompleted(Completed10Delegate, this); + } + } + if (!running11) + { + running11 = true; + awaiter11 = enumerator11.MoveNextAsync().GetAwaiter(); + if (awaiter11.IsCompleted) + { + Completed11(this); + } + else + { + awaiter11.SourceOnCompleted(Completed11Delegate, this); + } + } + if (!running12) + { + running12 = true; + awaiter12 = enumerator12.MoveNextAsync().GetAwaiter(); + if (awaiter12.IsCompleted) + { + Completed12(this); + } + else + { + awaiter12.SourceOnCompleted(Completed12Delegate, this); + } + } + if (!running13) + { + running13 = true; + awaiter13 = enumerator13.MoveNextAsync().GetAwaiter(); + if (awaiter13.IsCompleted) + { + Completed13(this); + } + else + { + awaiter13.SourceOnCompleted(Completed13Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11 || !running12 || !running13) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed8(object state) + { + var self = (_CombineLatest)state; + self.running8 = false; + + try + { + if (self.awaiter8.GetResult()) + { + self.hasCurrent8 = true; + self.current8 = self.enumerator8.Current; + goto SUCCESS; + } + else + { + self.running8 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running8 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running8 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter8.SourceOnCompleted(Completed8Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed9(object state) + { + var self = (_CombineLatest)state; + self.running9 = false; + + try + { + if (self.awaiter9.GetResult()) + { + self.hasCurrent9 = true; + self.current9 = self.enumerator9.Current; + goto SUCCESS; + } + else + { + self.running9 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running9 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running9 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter9.SourceOnCompleted(Completed9Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed10(object state) + { + var self = (_CombineLatest)state; + self.running10 = false; + + try + { + if (self.awaiter10.GetResult()) + { + self.hasCurrent10 = true; + self.current10 = self.enumerator10.Current; + goto SUCCESS; + } + else + { + self.running10 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running10 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running10 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter10.SourceOnCompleted(Completed10Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed11(object state) + { + var self = (_CombineLatest)state; + self.running11 = false; + + try + { + if (self.awaiter11.GetResult()) + { + self.hasCurrent11 = true; + self.current11 = self.enumerator11.Current; + goto SUCCESS; + } + else + { + self.running11 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running11 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running11 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter11.SourceOnCompleted(Completed11Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed12(object state) + { + var self = (_CombineLatest)state; + self.running12 = false; + + try + { + if (self.awaiter12.GetResult()) + { + self.hasCurrent12 = true; + self.current12 = self.enumerator12.Current; + goto SUCCESS; + } + else + { + self.running12 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running12 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running12 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter12 = self.enumerator12.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter12.SourceOnCompleted(Completed12Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed13(object state) + { + var self = (_CombineLatest)state; + self.running13 = false; + + try + { + if (self.awaiter13.GetResult()) + { + self.hasCurrent13 = true; + self.current13 = self.enumerator13.Current; + goto SUCCESS; + } + else + { + self.running13 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running13 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running13 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter13 = self.enumerator13.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter13.SourceOnCompleted(Completed13Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11 && hasCurrent12 && hasCurrent13) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11, current12, current13); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + if (enumerator8 != null) + { + await enumerator8.DisposeAsync(); + } + if (enumerator9 != null) + { + await enumerator9.DisposeAsync(); + } + if (enumerator10 != null) + { + await enumerator10.DisposeAsync(); + } + if (enumerator11 != null) + { + await enumerator11.DisposeAsync(); + } + if (enumerator12 != null) + { + await enumerator12.DisposeAsync(); + } + if (enumerator13 != null) + { + await enumerator13.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + readonly IUniTaskAsyncEnumerable source12; + readonly IUniTaskAsyncEnumerable source13; + readonly IUniTaskAsyncEnumerable source14; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, IUniTaskAsyncEnumerable source14, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + this.source12 = source12; + this.source13 = source13; + this.source14 = source14; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + static readonly Action Completed8Delegate = Completed8; + static readonly Action Completed9Delegate = Completed9; + static readonly Action Completed10Delegate = Completed10; + static readonly Action Completed11Delegate = Completed11; + static readonly Action Completed12Delegate = Completed12; + static readonly Action Completed13Delegate = Completed13; + static readonly Action Completed14Delegate = Completed14; + const int CompleteCount = 14; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + readonly IUniTaskAsyncEnumerable source12; + readonly IUniTaskAsyncEnumerable source13; + readonly IUniTaskAsyncEnumerable source14; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + IUniTaskAsyncEnumerator enumerator8; + UniTask.Awaiter awaiter8; + bool hasCurrent8; + bool running8; + T8 current8; + + IUniTaskAsyncEnumerator enumerator9; + UniTask.Awaiter awaiter9; + bool hasCurrent9; + bool running9; + T9 current9; + + IUniTaskAsyncEnumerator enumerator10; + UniTask.Awaiter awaiter10; + bool hasCurrent10; + bool running10; + T10 current10; + + IUniTaskAsyncEnumerator enumerator11; + UniTask.Awaiter awaiter11; + bool hasCurrent11; + bool running11; + T11 current11; + + IUniTaskAsyncEnumerator enumerator12; + UniTask.Awaiter awaiter12; + bool hasCurrent12; + bool running12; + T12 current12; + + IUniTaskAsyncEnumerator enumerator13; + UniTask.Awaiter awaiter13; + bool hasCurrent13; + bool running13; + T13 current13; + + IUniTaskAsyncEnumerator enumerator14; + UniTask.Awaiter awaiter14; + bool hasCurrent14; + bool running14; + T14 current14; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, IUniTaskAsyncEnumerable source14, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + this.source12 = source12; + this.source13 = source13; + this.source14 = source14; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + enumerator8 = source8.GetAsyncEnumerator(cancellationToken); + enumerator9 = source9.GetAsyncEnumerator(cancellationToken); + enumerator10 = source10.GetAsyncEnumerator(cancellationToken); + enumerator11 = source11.GetAsyncEnumerator(cancellationToken); + enumerator12 = source12.GetAsyncEnumerator(cancellationToken); + enumerator13 = source13.GetAsyncEnumerator(cancellationToken); + enumerator14 = source14.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + if (!running8) + { + running8 = true; + awaiter8 = enumerator8.MoveNextAsync().GetAwaiter(); + if (awaiter8.IsCompleted) + { + Completed8(this); + } + else + { + awaiter8.SourceOnCompleted(Completed8Delegate, this); + } + } + if (!running9) + { + running9 = true; + awaiter9 = enumerator9.MoveNextAsync().GetAwaiter(); + if (awaiter9.IsCompleted) + { + Completed9(this); + } + else + { + awaiter9.SourceOnCompleted(Completed9Delegate, this); + } + } + if (!running10) + { + running10 = true; + awaiter10 = enumerator10.MoveNextAsync().GetAwaiter(); + if (awaiter10.IsCompleted) + { + Completed10(this); + } + else + { + awaiter10.SourceOnCompleted(Completed10Delegate, this); + } + } + if (!running11) + { + running11 = true; + awaiter11 = enumerator11.MoveNextAsync().GetAwaiter(); + if (awaiter11.IsCompleted) + { + Completed11(this); + } + else + { + awaiter11.SourceOnCompleted(Completed11Delegate, this); + } + } + if (!running12) + { + running12 = true; + awaiter12 = enumerator12.MoveNextAsync().GetAwaiter(); + if (awaiter12.IsCompleted) + { + Completed12(this); + } + else + { + awaiter12.SourceOnCompleted(Completed12Delegate, this); + } + } + if (!running13) + { + running13 = true; + awaiter13 = enumerator13.MoveNextAsync().GetAwaiter(); + if (awaiter13.IsCompleted) + { + Completed13(this); + } + else + { + awaiter13.SourceOnCompleted(Completed13Delegate, this); + } + } + if (!running14) + { + running14 = true; + awaiter14 = enumerator14.MoveNextAsync().GetAwaiter(); + if (awaiter14.IsCompleted) + { + Completed14(this); + } + else + { + awaiter14.SourceOnCompleted(Completed14Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11 || !running12 || !running13 || !running14) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed8(object state) + { + var self = (_CombineLatest)state; + self.running8 = false; + + try + { + if (self.awaiter8.GetResult()) + { + self.hasCurrent8 = true; + self.current8 = self.enumerator8.Current; + goto SUCCESS; + } + else + { + self.running8 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running8 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running8 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter8.SourceOnCompleted(Completed8Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed9(object state) + { + var self = (_CombineLatest)state; + self.running9 = false; + + try + { + if (self.awaiter9.GetResult()) + { + self.hasCurrent9 = true; + self.current9 = self.enumerator9.Current; + goto SUCCESS; + } + else + { + self.running9 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running9 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running9 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter9.SourceOnCompleted(Completed9Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed10(object state) + { + var self = (_CombineLatest)state; + self.running10 = false; + + try + { + if (self.awaiter10.GetResult()) + { + self.hasCurrent10 = true; + self.current10 = self.enumerator10.Current; + goto SUCCESS; + } + else + { + self.running10 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running10 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running10 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter10.SourceOnCompleted(Completed10Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed11(object state) + { + var self = (_CombineLatest)state; + self.running11 = false; + + try + { + if (self.awaiter11.GetResult()) + { + self.hasCurrent11 = true; + self.current11 = self.enumerator11.Current; + goto SUCCESS; + } + else + { + self.running11 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running11 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running11 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter11.SourceOnCompleted(Completed11Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed12(object state) + { + var self = (_CombineLatest)state; + self.running12 = false; + + try + { + if (self.awaiter12.GetResult()) + { + self.hasCurrent12 = true; + self.current12 = self.enumerator12.Current; + goto SUCCESS; + } + else + { + self.running12 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running12 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running12 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter12 = self.enumerator12.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter12.SourceOnCompleted(Completed12Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed13(object state) + { + var self = (_CombineLatest)state; + self.running13 = false; + + try + { + if (self.awaiter13.GetResult()) + { + self.hasCurrent13 = true; + self.current13 = self.enumerator13.Current; + goto SUCCESS; + } + else + { + self.running13 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running13 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running13 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter13 = self.enumerator13.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter13.SourceOnCompleted(Completed13Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed14(object state) + { + var self = (_CombineLatest)state; + self.running14 = false; + + try + { + if (self.awaiter14.GetResult()) + { + self.hasCurrent14 = true; + self.current14 = self.enumerator14.Current; + goto SUCCESS; + } + else + { + self.running14 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running14 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running14 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter14 = self.enumerator14.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter14.SourceOnCompleted(Completed14Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11 && hasCurrent12 && hasCurrent13 && hasCurrent14) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11, current12, current13, current14); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + if (enumerator8 != null) + { + await enumerator8.DisposeAsync(); + } + if (enumerator9 != null) + { + await enumerator9.DisposeAsync(); + } + if (enumerator10 != null) + { + await enumerator10.DisposeAsync(); + } + if (enumerator11 != null) + { + await enumerator11.DisposeAsync(); + } + if (enumerator12 != null) + { + await enumerator12.DisposeAsync(); + } + if (enumerator13 != null) + { + await enumerator13.DisposeAsync(); + } + if (enumerator14 != null) + { + await enumerator14.DisposeAsync(); + } + } + } + } + + internal class CombineLatest : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + readonly IUniTaskAsyncEnumerable source12; + readonly IUniTaskAsyncEnumerable source13; + readonly IUniTaskAsyncEnumerable source14; + readonly IUniTaskAsyncEnumerable source15; + + readonly Func resultSelector; + + public CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, IUniTaskAsyncEnumerable source14, IUniTaskAsyncEnumerable source15, Func resultSelector) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + this.source12 = source12; + this.source13 = source13; + this.source14 = source14; + this.source15 = source15; + + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector, cancellationToken); + } + + class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action Completed1Delegate = Completed1; + static readonly Action Completed2Delegate = Completed2; + static readonly Action Completed3Delegate = Completed3; + static readonly Action Completed4Delegate = Completed4; + static readonly Action Completed5Delegate = Completed5; + static readonly Action Completed6Delegate = Completed6; + static readonly Action Completed7Delegate = Completed7; + static readonly Action Completed8Delegate = Completed8; + static readonly Action Completed9Delegate = Completed9; + static readonly Action Completed10Delegate = Completed10; + static readonly Action Completed11Delegate = Completed11; + static readonly Action Completed12Delegate = Completed12; + static readonly Action Completed13Delegate = Completed13; + static readonly Action Completed14Delegate = Completed14; + static readonly Action Completed15Delegate = Completed15; + const int CompleteCount = 15; + + readonly IUniTaskAsyncEnumerable source1; + readonly IUniTaskAsyncEnumerable source2; + readonly IUniTaskAsyncEnumerable source3; + readonly IUniTaskAsyncEnumerable source4; + readonly IUniTaskAsyncEnumerable source5; + readonly IUniTaskAsyncEnumerable source6; + readonly IUniTaskAsyncEnumerable source7; + readonly IUniTaskAsyncEnumerable source8; + readonly IUniTaskAsyncEnumerable source9; + readonly IUniTaskAsyncEnumerable source10; + readonly IUniTaskAsyncEnumerable source11; + readonly IUniTaskAsyncEnumerable source12; + readonly IUniTaskAsyncEnumerable source13; + readonly IUniTaskAsyncEnumerable source14; + readonly IUniTaskAsyncEnumerable source15; + + readonly Func resultSelector; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator1; + UniTask.Awaiter awaiter1; + bool hasCurrent1; + bool running1; + T1 current1; + + IUniTaskAsyncEnumerator enumerator2; + UniTask.Awaiter awaiter2; + bool hasCurrent2; + bool running2; + T2 current2; + + IUniTaskAsyncEnumerator enumerator3; + UniTask.Awaiter awaiter3; + bool hasCurrent3; + bool running3; + T3 current3; + + IUniTaskAsyncEnumerator enumerator4; + UniTask.Awaiter awaiter4; + bool hasCurrent4; + bool running4; + T4 current4; + + IUniTaskAsyncEnumerator enumerator5; + UniTask.Awaiter awaiter5; + bool hasCurrent5; + bool running5; + T5 current5; + + IUniTaskAsyncEnumerator enumerator6; + UniTask.Awaiter awaiter6; + bool hasCurrent6; + bool running6; + T6 current6; + + IUniTaskAsyncEnumerator enumerator7; + UniTask.Awaiter awaiter7; + bool hasCurrent7; + bool running7; + T7 current7; + + IUniTaskAsyncEnumerator enumerator8; + UniTask.Awaiter awaiter8; + bool hasCurrent8; + bool running8; + T8 current8; + + IUniTaskAsyncEnumerator enumerator9; + UniTask.Awaiter awaiter9; + bool hasCurrent9; + bool running9; + T9 current9; + + IUniTaskAsyncEnumerator enumerator10; + UniTask.Awaiter awaiter10; + bool hasCurrent10; + bool running10; + T10 current10; + + IUniTaskAsyncEnumerator enumerator11; + UniTask.Awaiter awaiter11; + bool hasCurrent11; + bool running11; + T11 current11; + + IUniTaskAsyncEnumerator enumerator12; + UniTask.Awaiter awaiter12; + bool hasCurrent12; + bool running12; + T12 current12; + + IUniTaskAsyncEnumerator enumerator13; + UniTask.Awaiter awaiter13; + bool hasCurrent13; + bool running13; + T13 current13; + + IUniTaskAsyncEnumerator enumerator14; + UniTask.Awaiter awaiter14; + bool hasCurrent14; + bool running14; + T14 current14; + + IUniTaskAsyncEnumerator enumerator15; + UniTask.Awaiter awaiter15; + bool hasCurrent15; + bool running15; + T15 current15; + + int completedCount; + bool syncRunning; + TResult result; + + public _CombineLatest(IUniTaskAsyncEnumerable source1, IUniTaskAsyncEnumerable source2, IUniTaskAsyncEnumerable source3, IUniTaskAsyncEnumerable source4, IUniTaskAsyncEnumerable source5, IUniTaskAsyncEnumerable source6, IUniTaskAsyncEnumerable source7, IUniTaskAsyncEnumerable source8, IUniTaskAsyncEnumerable source9, IUniTaskAsyncEnumerable source10, IUniTaskAsyncEnumerable source11, IUniTaskAsyncEnumerable source12, IUniTaskAsyncEnumerable source13, IUniTaskAsyncEnumerable source14, IUniTaskAsyncEnumerable source15, Func resultSelector, CancellationToken cancellationToken) + { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.source5 = source5; + this.source6 = source6; + this.source7 = source7; + this.source8 = source8; + this.source9 = source9; + this.source10 = source10; + this.source11 = source11; + this.source12 = source12; + this.source13 = source13; + this.source14 = source14; + this.source15 = source15; + + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current => result; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + if (completedCount == CompleteCount) return CompletedTasks.False; + + if (enumerator1 == null) + { + enumerator1 = source1.GetAsyncEnumerator(cancellationToken); + enumerator2 = source2.GetAsyncEnumerator(cancellationToken); + enumerator3 = source3.GetAsyncEnumerator(cancellationToken); + enumerator4 = source4.GetAsyncEnumerator(cancellationToken); + enumerator5 = source5.GetAsyncEnumerator(cancellationToken); + enumerator6 = source6.GetAsyncEnumerator(cancellationToken); + enumerator7 = source7.GetAsyncEnumerator(cancellationToken); + enumerator8 = source8.GetAsyncEnumerator(cancellationToken); + enumerator9 = source9.GetAsyncEnumerator(cancellationToken); + enumerator10 = source10.GetAsyncEnumerator(cancellationToken); + enumerator11 = source11.GetAsyncEnumerator(cancellationToken); + enumerator12 = source12.GetAsyncEnumerator(cancellationToken); + enumerator13 = source13.GetAsyncEnumerator(cancellationToken); + enumerator14 = source14.GetAsyncEnumerator(cancellationToken); + enumerator15 = source15.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + + AGAIN: + syncRunning = true; + if (!running1) + { + running1 = true; + awaiter1 = enumerator1.MoveNextAsync().GetAwaiter(); + if (awaiter1.IsCompleted) + { + Completed1(this); + } + else + { + awaiter1.SourceOnCompleted(Completed1Delegate, this); + } + } + if (!running2) + { + running2 = true; + awaiter2 = enumerator2.MoveNextAsync().GetAwaiter(); + if (awaiter2.IsCompleted) + { + Completed2(this); + } + else + { + awaiter2.SourceOnCompleted(Completed2Delegate, this); + } + } + if (!running3) + { + running3 = true; + awaiter3 = enumerator3.MoveNextAsync().GetAwaiter(); + if (awaiter3.IsCompleted) + { + Completed3(this); + } + else + { + awaiter3.SourceOnCompleted(Completed3Delegate, this); + } + } + if (!running4) + { + running4 = true; + awaiter4 = enumerator4.MoveNextAsync().GetAwaiter(); + if (awaiter4.IsCompleted) + { + Completed4(this); + } + else + { + awaiter4.SourceOnCompleted(Completed4Delegate, this); + } + } + if (!running5) + { + running5 = true; + awaiter5 = enumerator5.MoveNextAsync().GetAwaiter(); + if (awaiter5.IsCompleted) + { + Completed5(this); + } + else + { + awaiter5.SourceOnCompleted(Completed5Delegate, this); + } + } + if (!running6) + { + running6 = true; + awaiter6 = enumerator6.MoveNextAsync().GetAwaiter(); + if (awaiter6.IsCompleted) + { + Completed6(this); + } + else + { + awaiter6.SourceOnCompleted(Completed6Delegate, this); + } + } + if (!running7) + { + running7 = true; + awaiter7 = enumerator7.MoveNextAsync().GetAwaiter(); + if (awaiter7.IsCompleted) + { + Completed7(this); + } + else + { + awaiter7.SourceOnCompleted(Completed7Delegate, this); + } + } + if (!running8) + { + running8 = true; + awaiter8 = enumerator8.MoveNextAsync().GetAwaiter(); + if (awaiter8.IsCompleted) + { + Completed8(this); + } + else + { + awaiter8.SourceOnCompleted(Completed8Delegate, this); + } + } + if (!running9) + { + running9 = true; + awaiter9 = enumerator9.MoveNextAsync().GetAwaiter(); + if (awaiter9.IsCompleted) + { + Completed9(this); + } + else + { + awaiter9.SourceOnCompleted(Completed9Delegate, this); + } + } + if (!running10) + { + running10 = true; + awaiter10 = enumerator10.MoveNextAsync().GetAwaiter(); + if (awaiter10.IsCompleted) + { + Completed10(this); + } + else + { + awaiter10.SourceOnCompleted(Completed10Delegate, this); + } + } + if (!running11) + { + running11 = true; + awaiter11 = enumerator11.MoveNextAsync().GetAwaiter(); + if (awaiter11.IsCompleted) + { + Completed11(this); + } + else + { + awaiter11.SourceOnCompleted(Completed11Delegate, this); + } + } + if (!running12) + { + running12 = true; + awaiter12 = enumerator12.MoveNextAsync().GetAwaiter(); + if (awaiter12.IsCompleted) + { + Completed12(this); + } + else + { + awaiter12.SourceOnCompleted(Completed12Delegate, this); + } + } + if (!running13) + { + running13 = true; + awaiter13 = enumerator13.MoveNextAsync().GetAwaiter(); + if (awaiter13.IsCompleted) + { + Completed13(this); + } + else + { + awaiter13.SourceOnCompleted(Completed13Delegate, this); + } + } + if (!running14) + { + running14 = true; + awaiter14 = enumerator14.MoveNextAsync().GetAwaiter(); + if (awaiter14.IsCompleted) + { + Completed14(this); + } + else + { + awaiter14.SourceOnCompleted(Completed14Delegate, this); + } + } + if (!running15) + { + running15 = true; + awaiter15 = enumerator15.MoveNextAsync().GetAwaiter(); + if (awaiter15.IsCompleted) + { + Completed15(this); + } + else + { + awaiter15.SourceOnCompleted(Completed15Delegate, this); + } + } + + if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11 || !running12 || !running13 || !running14 || !running15) + { + goto AGAIN; + } + syncRunning = false; + + return new UniTask(this, completionSource.Version); + } + + static void Completed1(object state) + { + var self = (_CombineLatest)state; + self.running1 = false; + + try + { + if (self.awaiter1.GetResult()) + { + self.hasCurrent1 = true; + self.current1 = self.enumerator1.Current; + goto SUCCESS; + } + else + { + self.running1 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running1 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running1 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter1.SourceOnCompleted(Completed1Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed2(object state) + { + var self = (_CombineLatest)state; + self.running2 = false; + + try + { + if (self.awaiter2.GetResult()) + { + self.hasCurrent2 = true; + self.current2 = self.enumerator2.Current; + goto SUCCESS; + } + else + { + self.running2 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running2 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running2 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter2.SourceOnCompleted(Completed2Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed3(object state) + { + var self = (_CombineLatest)state; + self.running3 = false; + + try + { + if (self.awaiter3.GetResult()) + { + self.hasCurrent3 = true; + self.current3 = self.enumerator3.Current; + goto SUCCESS; + } + else + { + self.running3 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running3 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running3 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter3.SourceOnCompleted(Completed3Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed4(object state) + { + var self = (_CombineLatest)state; + self.running4 = false; + + try + { + if (self.awaiter4.GetResult()) + { + self.hasCurrent4 = true; + self.current4 = self.enumerator4.Current; + goto SUCCESS; + } + else + { + self.running4 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running4 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running4 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter4.SourceOnCompleted(Completed4Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed5(object state) + { + var self = (_CombineLatest)state; + self.running5 = false; + + try + { + if (self.awaiter5.GetResult()) + { + self.hasCurrent5 = true; + self.current5 = self.enumerator5.Current; + goto SUCCESS; + } + else + { + self.running5 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running5 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running5 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter5.SourceOnCompleted(Completed5Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed6(object state) + { + var self = (_CombineLatest)state; + self.running6 = false; + + try + { + if (self.awaiter6.GetResult()) + { + self.hasCurrent6 = true; + self.current6 = self.enumerator6.Current; + goto SUCCESS; + } + else + { + self.running6 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running6 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running6 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter6.SourceOnCompleted(Completed6Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed7(object state) + { + var self = (_CombineLatest)state; + self.running7 = false; + + try + { + if (self.awaiter7.GetResult()) + { + self.hasCurrent7 = true; + self.current7 = self.enumerator7.Current; + goto SUCCESS; + } + else + { + self.running7 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running7 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running7 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter7.SourceOnCompleted(Completed7Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed8(object state) + { + var self = (_CombineLatest)state; + self.running8 = false; + + try + { + if (self.awaiter8.GetResult()) + { + self.hasCurrent8 = true; + self.current8 = self.enumerator8.Current; + goto SUCCESS; + } + else + { + self.running8 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running8 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running8 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter8.SourceOnCompleted(Completed8Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed9(object state) + { + var self = (_CombineLatest)state; + self.running9 = false; + + try + { + if (self.awaiter9.GetResult()) + { + self.hasCurrent9 = true; + self.current9 = self.enumerator9.Current; + goto SUCCESS; + } + else + { + self.running9 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running9 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running9 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter9.SourceOnCompleted(Completed9Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed10(object state) + { + var self = (_CombineLatest)state; + self.running10 = false; + + try + { + if (self.awaiter10.GetResult()) + { + self.hasCurrent10 = true; + self.current10 = self.enumerator10.Current; + goto SUCCESS; + } + else + { + self.running10 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running10 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running10 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter10.SourceOnCompleted(Completed10Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed11(object state) + { + var self = (_CombineLatest)state; + self.running11 = false; + + try + { + if (self.awaiter11.GetResult()) + { + self.hasCurrent11 = true; + self.current11 = self.enumerator11.Current; + goto SUCCESS; + } + else + { + self.running11 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running11 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running11 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter11.SourceOnCompleted(Completed11Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed12(object state) + { + var self = (_CombineLatest)state; + self.running12 = false; + + try + { + if (self.awaiter12.GetResult()) + { + self.hasCurrent12 = true; + self.current12 = self.enumerator12.Current; + goto SUCCESS; + } + else + { + self.running12 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running12 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running12 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter12 = self.enumerator12.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter12.SourceOnCompleted(Completed12Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed13(object state) + { + var self = (_CombineLatest)state; + self.running13 = false; + + try + { + if (self.awaiter13.GetResult()) + { + self.hasCurrent13 = true; + self.current13 = self.enumerator13.Current; + goto SUCCESS; + } + else + { + self.running13 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running13 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running13 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter13 = self.enumerator13.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter13.SourceOnCompleted(Completed13Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed14(object state) + { + var self = (_CombineLatest)state; + self.running14 = false; + + try + { + if (self.awaiter14.GetResult()) + { + self.hasCurrent14 = true; + self.current14 = self.enumerator14.Current; + goto SUCCESS; + } + else + { + self.running14 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running14 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running14 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter14 = self.enumerator14.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter14.SourceOnCompleted(Completed14Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + static void Completed15(object state) + { + var self = (_CombineLatest)state; + self.running15 = false; + + try + { + if (self.awaiter15.GetResult()) + { + self.hasCurrent15 = true; + self.current15 = self.enumerator15.Current; + goto SUCCESS; + } + else + { + self.running15 = true; // as complete, no more call MoveNextAsync. + if (Interlocked.Increment(ref self.completedCount) == CompleteCount) + { + goto COMPLETE; + } + return; + } + } + catch (Exception ex) + { + self.running15 = true; // as complete, no more call MoveNextAsync. + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + SUCCESS: + if (!self.TrySetResult()) + { + if (self.syncRunning) return; + self.running15 = true; // as complete, no more call MoveNextAsync. + try + { + self.awaiter15 = self.enumerator15.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completedCount = CompleteCount; + self.completionSource.TrySetException(ex); + return; + } + + self.awaiter15.SourceOnCompleted(Completed15Delegate, self); + } + return; + COMPLETE: + self.completionSource.TrySetResult(false); + return; + } + + bool TrySetResult() + { + if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11 && hasCurrent12 && hasCurrent13 && hasCurrent14 && hasCurrent15) + { + result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11, current12, current13, current14, current15); + completionSource.TrySetResult(true); + return true; + } + else + { + return false; + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator1 != null) + { + await enumerator1.DisposeAsync(); + } + if (enumerator2 != null) + { + await enumerator2.DisposeAsync(); + } + if (enumerator3 != null) + { + await enumerator3.DisposeAsync(); + } + if (enumerator4 != null) + { + await enumerator4.DisposeAsync(); + } + if (enumerator5 != null) + { + await enumerator5.DisposeAsync(); + } + if (enumerator6 != null) + { + await enumerator6.DisposeAsync(); + } + if (enumerator7 != null) + { + await enumerator7.DisposeAsync(); + } + if (enumerator8 != null) + { + await enumerator8.DisposeAsync(); + } + if (enumerator9 != null) + { + await enumerator9.DisposeAsync(); + } + if (enumerator10 != null) + { + await enumerator10.DisposeAsync(); + } + if (enumerator11 != null) + { + await enumerator11.DisposeAsync(); + } + if (enumerator12 != null) + { + await enumerator12.DisposeAsync(); + } + if (enumerator13 != null) + { + await enumerator13.DisposeAsync(); + } + if (enumerator14 != null) + { + await enumerator14.DisposeAsync(); + } + if (enumerator15 != null) + { + await enumerator15.DisposeAsync(); + } + } + } + } + +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/CombineLatest.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/CombineLatest.cs.meta new file mode 100644 index 0000000..4e8b1c3 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/CombineLatest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6cb07f6e88287e34d9b9301a572284a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Concat.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Concat.cs new file mode 100644 index 0000000..715795e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Concat.cs @@ -0,0 +1,164 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Concat(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + + return new Concat(first, second); + } + } + + internal sealed class Concat : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + + public Concat(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second) + { + this.first = first; + this.second = second; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Concat(first, second, cancellationToken); + } + + sealed class _Concat : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + enum IteratingState + { + IteratingFirst, + IteratingSecond, + Complete + } + + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + CancellationToken cancellationToken; + + IteratingState iteratingState; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + + public _Concat(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, CancellationToken cancellationToken) + { + this.first = first; + this.second = second; + this.cancellationToken = cancellationToken; + this.iteratingState = IteratingState.IteratingFirst; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (iteratingState == IteratingState.Complete) return CompletedTasks.False; + + completionSource.Reset(); + StartIterate(); + return new UniTask(this, completionSource.Version); + } + + void StartIterate() + { + if (enumerator == null) + { + if (iteratingState == IteratingState.IteratingFirst) + { + enumerator = first.GetAsyncEnumerator(cancellationToken); + } + else if (iteratingState == IteratingState.IteratingSecond) + { + enumerator = second.GetAsyncEnumerator(cancellationToken); + } + } + + try + { + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + if (awaiter.IsCompleted) + { + MoveNextCoreDelegate(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + + static void MoveNextCore(object state) + { + var self = (_Concat)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.Current = self.enumerator.Current; + self.completionSource.TrySetResult(true); + } + else + { + if (self.iteratingState == IteratingState.IteratingFirst) + { + self.RunSecondAfterDisposeAsync().Forget(); + return; + } + + self.iteratingState = IteratingState.Complete; + self.completionSource.TrySetResult(false); + } + } + } + + async UniTaskVoid RunSecondAfterDisposeAsync() + { + try + { + await enumerator.DisposeAsync(); + enumerator = null; + awaiter = default; + iteratingState = IteratingState.IteratingSecond; + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + + StartIterate(); + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Concat.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Concat.cs.meta new file mode 100644 index 0000000..6bfcf31 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Concat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7cb9e19c449127a459851a135ce7d527 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Contains.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Contains.cs new file mode 100644 index 0000000..a93f566 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Contains.cs @@ -0,0 +1,50 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask ContainsAsync(this IUniTaskAsyncEnumerable source, TSource value, CancellationToken cancellationToken = default) + { + return ContainsAsync(source, value, EqualityComparer.Default, cancellationToken); + } + + public static UniTask ContainsAsync(this IUniTaskAsyncEnumerable source, TSource value, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return Contains.ContainsAsync(source, value, comparer, cancellationToken); + } + } + + internal static class Contains + { + internal static async UniTask ContainsAsync(IUniTaskAsyncEnumerable source, TSource value, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (comparer.Equals(value, e.Current)) + { + return true; + } + } + + return false; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Contains.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Contains.cs.meta new file mode 100644 index 0000000..9bd414b --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Contains.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36ab06d30f3223048b4f676e05431a7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Count.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Count.cs new file mode 100644 index 0000000..807b529 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Count.cs @@ -0,0 +1,144 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask CountAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Count.CountAsync(source, cancellationToken); + } + + public static UniTask CountAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Count.CountAsync(source, predicate, cancellationToken); + } + + public static UniTask CountAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Count.CountAwaitAsync(source, predicate, cancellationToken); + } + + public static UniTask CountAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Count.CountAwaitWithCancellationAsync(source, predicate, cancellationToken); + } + } + + internal static class Count + { + internal static async UniTask CountAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + var count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked { count++; } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask CountAsync(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + { + var count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (predicate(e.Current)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask CountAwaitAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + var count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (await predicate(e.Current)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask CountAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + var count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (await predicate(e.Current, cancellationToken)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Count.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Count.cs.meta new file mode 100644 index 0000000..35db332 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Count.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e606d38eed688574bb2ba89d983cc9bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Create.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Create.cs new file mode 100644 index 0000000..61b7afd --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Create.cs @@ -0,0 +1,174 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Create(Func, CancellationToken, UniTask> create) + { + Error.ThrowArgumentNullException(create, nameof(create)); + return new Create(create); + } + } + + public interface IAsyncWriter + { + UniTask YieldAsync(T value); + } + + internal sealed class Create : IUniTaskAsyncEnumerable + { + readonly Func, CancellationToken, UniTask> create; + + public Create(Func, CancellationToken, UniTask> create) + { + this.create = create; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Create(create, cancellationToken); + } + + sealed class _Create : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly Func, CancellationToken, UniTask> create; + readonly CancellationToken cancellationToken; + + int state = -1; + AsyncWriter writer; + + public _Create(Func, CancellationToken, UniTask> create, CancellationToken cancellationToken) + { + this.create = create; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public T Current { get; private set; } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return default; + } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + try + { + switch (state) + { + case -1: // init + { + writer = new AsyncWriter(this); + RunWriterTask(create(writer, cancellationToken)).Forget(); + if (Volatile.Read(ref state) == -2) + { + return; // complete synchronously + } + state = 0; // wait YieldAsync, it set TrySetResult(true) + return; + } + case 0: + writer.SignalWriter(); + return; + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + } + + async UniTaskVoid RunWriterTask(UniTask task) + { + try + { + await task; + goto DONE; + } + catch (Exception ex) + { + Volatile.Write(ref state, -2); + completionSource.TrySetException(ex); + return; + } + + DONE: + Volatile.Write(ref state, -2); + completionSource.TrySetResult(false); + } + + public void SetResult(T value) + { + Current = value; + completionSource.TrySetResult(true); + } + } + + sealed class AsyncWriter : IUniTaskSource, IAsyncWriter + { + readonly _Create enumerator; + + UniTaskCompletionSourceCore core; + + public AsyncWriter(_Create enumerator) + { + this.enumerator = enumerator; + } + + public void GetResult(short token) + { + core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTask YieldAsync(T value) + { + core.Reset(); + enumerator.SetResult(value); + return new UniTask(this, core.Version); + } + + public void SignalWriter() + { + core.TrySetResult(AsyncUnit.Default); + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Create.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Create.cs.meta new file mode 100644 index 0000000..5aba456 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Create.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0202f723469f93945afa063bfb440d15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DefaultIfEmpty.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DefaultIfEmpty.cs new file mode 100644 index 0000000..3d21bd7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DefaultIfEmpty.cs @@ -0,0 +1,142 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable DefaultIfEmpty(this IUniTaskAsyncEnumerable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new DefaultIfEmpty(source, default); + } + + public static IUniTaskAsyncEnumerable DefaultIfEmpty(this IUniTaskAsyncEnumerable source, TSource defaultValue) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new DefaultIfEmpty(source, defaultValue); + } + } + + internal sealed class DefaultIfEmpty : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly TSource defaultValue; + + public DefaultIfEmpty(IUniTaskAsyncEnumerable source, TSource defaultValue) + { + this.source = source; + this.defaultValue = defaultValue; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _DefaultIfEmpty(source, defaultValue, cancellationToken); + } + + sealed class _DefaultIfEmpty : MoveNextSource, IUniTaskAsyncEnumerator + { + enum IteratingState : byte + { + Empty, + Iterating, + Completed + } + + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + readonly TSource defaultValue; + CancellationToken cancellationToken; + + IteratingState iteratingState; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + + public _DefaultIfEmpty(IUniTaskAsyncEnumerable source, TSource defaultValue, CancellationToken cancellationToken) + { + this.source = source; + this.defaultValue = defaultValue; + this.cancellationToken = cancellationToken; + + this.iteratingState = IteratingState.Empty; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (iteratingState == IteratingState.Completed) + { + return CompletedTasks.False; + } + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + } + + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + + if (awaiter.IsCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + + return new UniTask(this, completionSource.Version); + } + + static void MoveNextCore(object state) + { + var self = (_DefaultIfEmpty)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.iteratingState = IteratingState.Iterating; + self.Current = self.enumerator.Current; + self.completionSource.TrySetResult(true); + } + else + { + if (self.iteratingState == IteratingState.Empty) + { + self.iteratingState = IteratingState.Completed; + + self.Current = self.defaultValue; + self.completionSource.TrySetResult(true); + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } + +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DefaultIfEmpty.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DefaultIfEmpty.cs.meta new file mode 100644 index 0000000..5aa5993 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DefaultIfEmpty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19e437c039ad7e1478dbce1779ef8660 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Distinct.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Distinct.cs new file mode 100644 index 0000000..85bf795 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Distinct.cs @@ -0,0 +1,277 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Distinct(this IUniTaskAsyncEnumerable source) + { + return Distinct(source, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable Distinct(this IUniTaskAsyncEnumerable source, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new Distinct(source, comparer); + } + + public static IUniTaskAsyncEnumerable Distinct(this IUniTaskAsyncEnumerable source, Func keySelector) + { + return Distinct(source, keySelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable Distinct(this IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new Distinct(source, keySelector, comparer); + } + + public static IUniTaskAsyncEnumerable DistinctAwait(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + return DistinctAwait(source, keySelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable DistinctAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new DistinctAwait(source, keySelector, comparer); + } + + public static IUniTaskAsyncEnumerable DistinctAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + return DistinctAwaitWithCancellation(source, keySelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable DistinctAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new DistinctAwaitWithCancellation(source, keySelector, comparer); + } + } + + internal sealed class Distinct : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly IEqualityComparer comparer; + + public Distinct(IUniTaskAsyncEnumerable source, IEqualityComparer comparer) + { + this.source = source; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Distinct(source, comparer, cancellationToken); + } + + class _Distinct : AsyncEnumeratorBase + { + readonly HashSet set; + + public _Distinct(IUniTaskAsyncEnumerable source, IEqualityComparer comparer, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.set = new HashSet(comparer); + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + var v = SourceCurrent; + if (set.Add(v)) + { + Current = v; + result = true; + return true; + } + else + { + result = default; + return false; + } + } + + result = false; + return true; + } + } + } + + internal sealed class Distinct : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func keySelector; + readonly IEqualityComparer comparer; + + public Distinct(IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Distinct(source, keySelector, comparer, cancellationToken); + } + + class _Distinct : AsyncEnumeratorBase + { + readonly HashSet set; + readonly Func keySelector; + + public _Distinct(IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.set = new HashSet(comparer); + this.keySelector = keySelector; + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + var v = SourceCurrent; + if (set.Add(keySelector(v))) + { + Current = v; + result = true; + return true; + } + else + { + result = default; + return false; + } + } + + result = false; + return true; + } + } + } + + internal sealed class DistinctAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly IEqualityComparer comparer; + + public DistinctAwait(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _DistinctAwait(source, keySelector, comparer, cancellationToken); + } + + class _DistinctAwait : AsyncEnumeratorAwaitSelectorBase + { + readonly HashSet set; + readonly Func> keySelector; + + public _DistinctAwait(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.set = new HashSet(comparer); + this.keySelector = keySelector; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + return keySelector(sourceCurrent); + } + + protected override bool TrySetCurrentCore(TKey awaitResult, out bool terminateIteration) + { + if (set.Add(awaitResult)) + { + Current = SourceCurrent; + terminateIteration = false; + return true; + } + else + { + terminateIteration = false; + return false; + } + } + } + } + + internal sealed class DistinctAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly IEqualityComparer comparer; + + public DistinctAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _DistinctAwaitWithCancellation(source, keySelector, comparer, cancellationToken); + } + + class _DistinctAwaitWithCancellation : AsyncEnumeratorAwaitSelectorBase + { + readonly HashSet set; + readonly Func> keySelector; + + public _DistinctAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.set = new HashSet(comparer); + this.keySelector = keySelector; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + return keySelector(sourceCurrent, cancellationToken); + } + + protected override bool TrySetCurrentCore(TKey awaitResult, out bool terminateIteration) + { + if (set.Add(awaitResult)) + { + Current = SourceCurrent; + terminateIteration = false; + return true; + } + else + { + terminateIteration = false; + return false; + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Distinct.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Distinct.cs.meta new file mode 100644 index 0000000..61804b7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Distinct.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f09903be66e5d943b243d7c19cb3811 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DistinctUntilChanged.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DistinctUntilChanged.cs new file mode 100644 index 0000000..d91bef9 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DistinctUntilChanged.cs @@ -0,0 +1,662 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable DistinctUntilChanged(this IUniTaskAsyncEnumerable source) + { + return DistinctUntilChanged(source, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable DistinctUntilChanged(this IUniTaskAsyncEnumerable source, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new DistinctUntilChanged(source, comparer); + } + + public static IUniTaskAsyncEnumerable DistinctUntilChanged(this IUniTaskAsyncEnumerable source, Func keySelector) + { + return DistinctUntilChanged(source, keySelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable DistinctUntilChanged(this IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new DistinctUntilChanged(source, keySelector, comparer); + } + + public static IUniTaskAsyncEnumerable DistinctUntilChangedAwait(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + return DistinctUntilChangedAwait(source, keySelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable DistinctUntilChangedAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new DistinctUntilChangedAwait(source, keySelector, comparer); + } + + public static IUniTaskAsyncEnumerable DistinctUntilChangedAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + return DistinctUntilChangedAwaitWithCancellation(source, keySelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable DistinctUntilChangedAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new DistinctUntilChangedAwaitWithCancellation(source, keySelector, comparer); + } + } + + internal sealed class DistinctUntilChanged : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly IEqualityComparer comparer; + + public DistinctUntilChanged(IUniTaskAsyncEnumerable source, IEqualityComparer comparer) + { + this.source = source; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _DistinctUntilChanged(source, comparer, cancellationToken); + } + + sealed class _DistinctUntilChanged : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly IEqualityComparer comparer; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + Action moveNextAction; + + public _DistinctUntilChanged(IUniTaskAsyncEnumerable source, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case -3; + } + else + { + state = -3; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case -3: // first + if (awaiter.GetResult()) + { + Current = enumerator.Current; + goto CONTINUE; + } + else + { + goto DONE; + } + case 0: // normal + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + var v = enumerator.Current; + if (!comparer.Equals(Current, v)) + { + Current = v; + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + } + else + { + goto DONE; + } + case -2: + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class DistinctUntilChanged : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func keySelector; + readonly IEqualityComparer comparer; + + public DistinctUntilChanged(IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _DistinctUntilChanged(source, keySelector, comparer, cancellationToken); + } + + sealed class _DistinctUntilChanged : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func keySelector; + readonly IEqualityComparer comparer; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + Action moveNextAction; + TKey prev; + + public _DistinctUntilChanged(IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case -3; + } + else + { + state = -3; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case -3: // first + if (awaiter.GetResult()) + { + Current = enumerator.Current; + goto CONTINUE; + } + else + { + goto DONE; + } + case 0: // normal + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + var v = enumerator.Current; + var key = keySelector(v); + if (!comparer.Equals(prev, key)) + { + prev = key; + Current = v; + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + } + else + { + goto DONE; + } + case -2: + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class DistinctUntilChangedAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly IEqualityComparer comparer; + + public DistinctUntilChangedAwait(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _DistinctUntilChangedAwait(source, keySelector, comparer, cancellationToken); + } + + sealed class _DistinctUntilChangedAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly IEqualityComparer comparer; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + TSource enumeratorCurrent; + TKey prev; + + public _DistinctUntilChangedAwait(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case -3; + } + else + { + state = -3; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case -3: // first + if (awaiter.GetResult()) + { + Current = enumerator.Current; + goto CONTINUE; + } + else + { + goto DONE; + } + case 0: // normal + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + enumeratorCurrent = enumerator.Current; + awaiter2 = keySelector(enumeratorCurrent).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + var key = awaiter2.GetResult(); + if (!comparer.Equals(prev, key)) + { + prev = key; + Current = enumeratorCurrent; + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + case -2: + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class DistinctUntilChangedAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly IEqualityComparer comparer; + + public DistinctUntilChangedAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _DistinctUntilChangedAwaitWithCancellation(source, keySelector, comparer, cancellationToken); + } + + sealed class _DistinctUntilChangedAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly IEqualityComparer comparer; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + TSource enumeratorCurrent; + TKey prev; + + public _DistinctUntilChangedAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case -3; + } + else + { + state = -3; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case -3: // first + if (awaiter.GetResult()) + { + Current = enumerator.Current; + goto CONTINUE; + } + else + { + goto DONE; + } + case 0: // normal + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + enumeratorCurrent = enumerator.Current; + awaiter2 = keySelector(enumeratorCurrent, cancellationToken).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + var key = awaiter2.GetResult(); + if (!comparer.Equals(prev, key)) + { + prev = key; + Current = enumeratorCurrent; + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + case -2: + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + return enumerator.DisposeAsync(); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DistinctUntilChanged.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DistinctUntilChanged.cs.meta new file mode 100644 index 0000000..84cddf8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/DistinctUntilChanged.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0351f6767df7e644b935d4d599968162 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Do.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Do.cs new file mode 100644 index 0000000..f6df368 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Do.cs @@ -0,0 +1,258 @@ +using Cysharp.Threading.Tasks; +using Cysharp.Threading.Tasks.Internal; +using Cysharp.Threading.Tasks.Linq; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Do(this IUniTaskAsyncEnumerable source, Action onNext) + { + Error.ThrowArgumentNullException(source, nameof(source)); + return source.Do(onNext, null, null); + } + + public static IUniTaskAsyncEnumerable Do(this IUniTaskAsyncEnumerable source, Action onNext, Action onError) + { + Error.ThrowArgumentNullException(source, nameof(source)); + return source.Do(onNext, onError, null); + } + + public static IUniTaskAsyncEnumerable Do(this IUniTaskAsyncEnumerable source, Action onNext, Action onCompleted) + { + Error.ThrowArgumentNullException(source, nameof(source)); + return source.Do(onNext, null, onCompleted); + } + + public static IUniTaskAsyncEnumerable Do(this IUniTaskAsyncEnumerable source, Action onNext, Action onError, Action onCompleted) + { + Error.ThrowArgumentNullException(source, nameof(source)); + return new Do(source, onNext, onError, onCompleted); + } + + public static IUniTaskAsyncEnumerable Do(this IUniTaskAsyncEnumerable source, IObserver observer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(observer, nameof(observer)); + + return source.Do(observer.OnNext, observer.OnError, observer.OnCompleted); // alloc delegate. + } + + // not yet impl. + + //public static IUniTaskAsyncEnumerable DoAwait(this IUniTaskAsyncEnumerable source, Func onNext) + //{ + // throw new NotImplementedException(); + //} + + //public static IUniTaskAsyncEnumerable DoAwait(this IUniTaskAsyncEnumerable source, Func onNext, Func onError) + //{ + // throw new NotImplementedException(); + //} + + //public static IUniTaskAsyncEnumerable DoAwait(this IUniTaskAsyncEnumerable source, Func onNext, Func onCompleted) + //{ + // throw new NotImplementedException(); + //} + + //public static IUniTaskAsyncEnumerable DoAwait(this IUniTaskAsyncEnumerable source, Func onNext, Func onError, Func onCompleted) + //{ + // throw new NotImplementedException(); + //} + + //public static IUniTaskAsyncEnumerable DoAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func onNext) + //{ + // throw new NotImplementedException(); + //} + + //public static IUniTaskAsyncEnumerable DoAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func onNext, Func onError) + //{ + // throw new NotImplementedException(); + //} + + //public static IUniTaskAsyncEnumerable DoAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func onNext, Func onCompleted) + //{ + // throw new NotImplementedException(); + //} + + //public static IUniTaskAsyncEnumerable DoAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func onNext, Func onError, Func onCompleted) + //{ + // throw new NotImplementedException(); + //} + } + + internal sealed class Do : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Action onNext; + readonly Action onError; + readonly Action onCompleted; + + public Do(IUniTaskAsyncEnumerable source, Action onNext, Action onError, Action onCompleted) + { + this.source = source; + this.onNext = onNext; + this.onError = onError; + this.onCompleted = onCompleted; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Do(source, onNext, onError, onCompleted, cancellationToken); + } + + sealed class _Do : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + readonly Action onNext; + readonly Action onError; + readonly Action onCompleted; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + + public _Do(IUniTaskAsyncEnumerable source, Action onNext, Action onError, Action onCompleted, CancellationToken cancellationToken) + { + this.source = source; + this.onNext = onNext; + this.onError = onError; + this.onCompleted = onCompleted; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + bool isCompleted = false; + try + { + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + } + + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + isCompleted = awaiter.IsCompleted; + } + catch (Exception ex) + { + CallTrySetExceptionAfterNotification(ex); + return new UniTask(this, completionSource.Version); + } + + if (isCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + + return new UniTask(this, completionSource.Version); + } + + void CallTrySetExceptionAfterNotification(Exception ex) + { + if (onError != null) + { + try + { + onError(ex); + } + catch (Exception ex2) + { + completionSource.TrySetException(ex2); + return; + } + } + + completionSource.TrySetException(ex); + } + + bool TryGetResultWithNotification(UniTask.Awaiter awaiter, out T result) + { + try + { + result = awaiter.GetResult(); + return true; + } + catch (Exception ex) + { + CallTrySetExceptionAfterNotification(ex); + result = default; + return false; + } + } + + + static void MoveNextCore(object state) + { + var self = (_Do)state; + + if (self.TryGetResultWithNotification(self.awaiter, out var result)) + { + if (result) + { + var v = self.enumerator.Current; + + if (self.onNext != null) + { + try + { + self.onNext(v); + } + catch (Exception ex) + { + self.CallTrySetExceptionAfterNotification(ex); + } + } + + self.Current = v; + self.completionSource.TrySetResult(true); + } + else + { + if (self.onCompleted != null) + { + try + { + self.onCompleted(); + } + catch (Exception ex) + { + self.CallTrySetExceptionAfterNotification(ex); + return; + } + } + + self.completionSource.TrySetResult(false); + } + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } + +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Do.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Do.cs.meta new file mode 100644 index 0000000..766bbb5 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Do.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd83c8e12dedf75409b829b93146d130 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ElementAt.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ElementAt.cs new file mode 100644 index 0000000..930675e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ElementAt.cs @@ -0,0 +1,58 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask ElementAtAsync(this IUniTaskAsyncEnumerable source, int index, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return ElementAt.ElementAtAsync(source, index, cancellationToken, false); + } + + public static UniTask ElementAtOrDefaultAsync(this IUniTaskAsyncEnumerable source, int index, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return ElementAt.ElementAtAsync(source, index, cancellationToken, true); + } + } + + internal static class ElementAt + { + public static async UniTask ElementAtAsync(IUniTaskAsyncEnumerable source, int index, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + int i = 0; + while (await e.MoveNextAsync()) + { + if (i++ == index) + { + return e.Current; + } + } + + if (defaultIfEmpty) + { + return default; + } + else + { + throw Error.ArgumentOutOfRange(nameof(index)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ElementAt.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ElementAt.cs.meta new file mode 100644 index 0000000..fb0850b --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ElementAt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c835bd2dd8555234c8919c7b8ef3b69a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Empty.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Empty.cs new file mode 100644 index 0000000..2f5b3a4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Empty.cs @@ -0,0 +1,47 @@ +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Empty() + { + return Cysharp.Threading.Tasks.Linq.Empty.Instance; + } + } + + internal class Empty : IUniTaskAsyncEnumerable + { + public static readonly IUniTaskAsyncEnumerable Instance = new Empty(); + + Empty() + { + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return _Empty.Instance; + } + + class _Empty : IUniTaskAsyncEnumerator + { + public static readonly IUniTaskAsyncEnumerator Instance = new _Empty(); + + _Empty() + { + } + + public T Current => default; + + public UniTask MoveNextAsync() + { + return CompletedTasks.False; + } + + public UniTask DisposeAsync() + { + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Empty.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Empty.cs.meta new file mode 100644 index 0000000..bfa577a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Empty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fa123ad6258abb4184721b719a13810 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Except.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Except.cs new file mode 100644 index 0000000..c405482 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Except.cs @@ -0,0 +1,116 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Except(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + + return new Except(first, second, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable Except(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new Except(first, second, comparer); + } + } + + internal sealed class Except : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + readonly IEqualityComparer comparer; + + public Except(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer) + { + this.first = first; + this.second = second; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Except(first, second, comparer, cancellationToken); + } + + class _Except : AsyncEnumeratorBase + { + static Action HashSetAsyncCoreDelegate = HashSetAsyncCore; + + readonly IEqualityComparer comparer; + readonly IUniTaskAsyncEnumerable second; + + HashSet set; + UniTask>.Awaiter awaiter; + + public _Except(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer, CancellationToken cancellationToken) + + : base(first, cancellationToken) + { + this.second = second; + this.comparer = comparer; + } + + protected override bool OnFirstIteration() + { + if (set != null) return false; + + awaiter = second.ToHashSetAsync(cancellationToken).GetAwaiter(); + if (awaiter.IsCompleted) + { + set = awaiter.GetResult(); + SourceMoveNext(); + } + else + { + awaiter.SourceOnCompleted(HashSetAsyncCoreDelegate, this); + } + + return true; + } + + static void HashSetAsyncCore(object state) + { + var self = (_Except)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + self.set = result; + self.SourceMoveNext(); + } + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + var v = SourceCurrent; + if (set.Add(v)) + { + Current = v; + result = true; + return true; + } + else + { + result = default; + return false; + } + } + + result = false; + return true; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Except.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Except.cs.meta new file mode 100644 index 0000000..f61a1aa --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Except.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38c1c4129f59dcb49a5b864eaf4ec63c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/First.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/First.cs new file mode 100644 index 0000000..da5688b --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/First.cs @@ -0,0 +1,200 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask FirstAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return First.FirstAsync(source, cancellationToken, false); + } + + public static UniTask FirstAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return First.FirstAsync(source, predicate, cancellationToken, false); + } + + public static UniTask FirstAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return First.FirstAwaitAsync(source, predicate, cancellationToken, false); + } + + public static UniTask FirstAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return First.FirstAwaitWithCancellationAsync(source, predicate, cancellationToken, false); + } + + public static UniTask FirstOrDefaultAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return First.FirstAsync(source, cancellationToken, true); + } + + public static UniTask FirstOrDefaultAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return First.FirstAsync(source, predicate, cancellationToken, true); + } + + public static UniTask FirstOrDefaultAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return First.FirstAwaitAsync(source, predicate, cancellationToken, true); + } + + public static UniTask FirstOrDefaultAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return First.FirstAwaitWithCancellationAsync(source, predicate, cancellationToken, true); + } + } + + internal static class First + { + public static async UniTask FirstAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + if (await e.MoveNextAsync()) + { + return e.Current; + } + else + { + if (defaultIfEmpty) + { + return default; + } + else + { + throw Error.NoElements(); + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask FirstAsync(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (predicate(v)) + { + return v; + } + } + + if (defaultIfEmpty) + { + return default; + } + else + { + throw Error.NoElements(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask FirstAwaitAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (await predicate(v)) + { + return v; + } + } + + if (defaultIfEmpty) + { + return default; + } + else + { + throw Error.NoElements(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask FirstAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (await predicate(v, cancellationToken)) + { + return v; + } + } + + if (defaultIfEmpty) + { + return default; + } + else + { + throw Error.NoElements(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/First.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/First.cs.meta new file mode 100644 index 0000000..6924307 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/First.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 417946e97e9eed84db6f840f57037ca6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ForEach.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ForEach.cs new file mode 100644 index 0000000..60f246d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ForEach.cs @@ -0,0 +1,193 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask ForEachAsync(this IUniTaskAsyncEnumerable source, Action action, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAsync(source, action, cancellationToken); + } + + public static UniTask ForEachAsync(this IUniTaskAsyncEnumerable source, Action action, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAsync(source, action, cancellationToken); + } + + /// Obsolete(Error), Use Use ForEachAwaitAsync instead. + [Obsolete("Use ForEachAwaitAsync instead.", true)] + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public static UniTask ForEachAsync(this IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken = default) + { + throw new NotSupportedException("Use ForEachAwaitAsync instead."); + } + + /// Obsolete(Error), Use Use ForEachAwaitAsync instead. + [Obsolete("Use ForEachAwaitAsync instead.", true)] + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public static UniTask ForEachAsync(this IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken = default) + { + throw new NotSupportedException("Use ForEachAwaitAsync instead."); + } + + public static UniTask ForEachAwaitAsync(this IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAwaitAsync(source, action, cancellationToken); + } + + public static UniTask ForEachAwaitAsync(this IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAwaitAsync(source, action, cancellationToken); + } + + public static UniTask ForEachAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAwaitWithCancellationAsync(source, action, cancellationToken); + } + + public static UniTask ForEachAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAwaitWithCancellationAsync(source, action, cancellationToken); + } + } + + internal static class ForEach + { + public static async UniTask ForEachAsync(IUniTaskAsyncEnumerable source, Action action, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + action(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask ForEachAsync(IUniTaskAsyncEnumerable source, Action action, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + int index = 0; + while (await e.MoveNextAsync()) + { + action(e.Current, checked(index++)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask ForEachAwaitAsync(IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + await action(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask ForEachAwaitAsync(IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + int index = 0; + while (await e.MoveNextAsync()) + { + await action(e.Current, checked(index++)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask ForEachAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + await action(e.Current, cancellationToken); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask ForEachAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + int index = 0; + while (await e.MoveNextAsync()) + { + await action(e.Current, checked(index++), cancellationToken); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ForEach.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ForEach.cs.meta new file mode 100644 index 0000000..5317756 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ForEach.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca8d7f8177ba16140920af405aea3fd4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupBy.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupBy.cs new file mode 100644 index 0000000..b9460ae --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupBy.cs @@ -0,0 +1,923 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + // Ix-Async returns IGrouping but it is competely waste, use standard IGrouping. + + public static IUniTaskAsyncEnumerable> GroupBy(this IUniTaskAsyncEnumerable source, Func keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + return new GroupBy(source, keySelector, x => x, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable> GroupBy(this IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupBy(source, keySelector, x => x, comparer); + } + + public static IUniTaskAsyncEnumerable> GroupBy(this IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + return new GroupBy(source, keySelector, elementSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable> GroupBy(this IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupBy(source, keySelector, elementSelector, comparer); + } + + public static IUniTaskAsyncEnumerable GroupBy(this IUniTaskAsyncEnumerable source, Func keySelector, Func, TResult> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + return new GroupBy(source, keySelector, x => x, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable GroupBy(this IUniTaskAsyncEnumerable source, Func keySelector, Func, TResult> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupBy(source, keySelector, x => x, resultSelector, comparer); + } + + public static IUniTaskAsyncEnumerable GroupBy(this IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + return new GroupBy(source, keySelector, elementSelector, resultSelector, EqualityComparer.Default); + } + public static IUniTaskAsyncEnumerable GroupBy(this IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupBy(source, keySelector, elementSelector, resultSelector, comparer); + } + + // await + + public static IUniTaskAsyncEnumerable> GroupByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + return new GroupByAwait(source, keySelector, x => UniTask.FromResult(x), EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable> GroupByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupByAwait(source, keySelector, x => UniTask.FromResult(x), comparer); + } + + public static IUniTaskAsyncEnumerable> GroupByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + return new GroupByAwait(source, keySelector, elementSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable> GroupByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupByAwait(source, keySelector, elementSelector, comparer); + } + + public static IUniTaskAsyncEnumerable GroupByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, Func, UniTask> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + return new GroupByAwait(source, keySelector, x => UniTask.FromResult(x), resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable GroupByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, Func, UniTask> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + return new GroupByAwait(source, keySelector, elementSelector, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable GroupByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, Func, UniTask> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupByAwait(source, keySelector, x => UniTask.FromResult(x), resultSelector, comparer); + } + + public static IUniTaskAsyncEnumerable GroupByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, Func, UniTask> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupByAwait(source, keySelector, elementSelector, resultSelector, comparer); + } + + // with ct + + public static IUniTaskAsyncEnumerable> GroupByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + return new GroupByAwaitWithCancellation(source, keySelector, (x, _) => UniTask.FromResult(x), EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable> GroupByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupByAwaitWithCancellation(source, keySelector, (x, _) => UniTask.FromResult(x), comparer); + } + + public static IUniTaskAsyncEnumerable> GroupByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + return new GroupByAwaitWithCancellation(source, keySelector, elementSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable> GroupByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupByAwaitWithCancellation(source, keySelector, elementSelector, comparer); + } + + public static IUniTaskAsyncEnumerable GroupByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, Func, CancellationToken, UniTask> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + return new GroupByAwaitWithCancellation(source, keySelector, (x, _) => UniTask.FromResult(x), resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable GroupByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, Func, CancellationToken, UniTask> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + return new GroupByAwaitWithCancellation(source, keySelector, elementSelector, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable GroupByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, Func, CancellationToken, UniTask> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupByAwaitWithCancellation(source, keySelector, (x, _) => UniTask.FromResult(x), resultSelector, comparer); + } + + public static IUniTaskAsyncEnumerable GroupByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, Func, CancellationToken, UniTask> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + return new GroupByAwaitWithCancellation(source, keySelector, elementSelector, resultSelector, comparer); + } + } + + internal sealed class GroupBy : IUniTaskAsyncEnumerable> + { + readonly IUniTaskAsyncEnumerable source; + readonly Func keySelector; + readonly Func elementSelector; + readonly IEqualityComparer comparer; + + public GroupBy(IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupBy(source, keySelector, elementSelector, comparer, cancellationToken); + } + + sealed class _GroupBy : MoveNextSource, IUniTaskAsyncEnumerator> + { + readonly IUniTaskAsyncEnumerable source; + readonly Func keySelector; + readonly Func elementSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + IEnumerator> groupEnumerator; + + public _GroupBy(IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public IGrouping Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (groupEnumerator == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + var lookup = await source.ToLookupAsync(keySelector, elementSelector, comparer, cancellationToken); + groupEnumerator = lookup.GetEnumerator(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + if (groupEnumerator.MoveNext()) + { + Current = groupEnumerator.Current as IGrouping; + completionSource.TrySetResult(true); + } + else + { + completionSource.TrySetResult(false); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (groupEnumerator != null) + { + groupEnumerator.Dispose(); + } + + return default; + } + } + } + + internal sealed class GroupBy : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func keySelector; + readonly Func elementSelector; + readonly Func, TResult> resultSelector; + readonly IEqualityComparer comparer; + + public GroupBy(IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupBy(source, keySelector, elementSelector, resultSelector, comparer, cancellationToken); + } + + sealed class _GroupBy : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func keySelector; + readonly Func elementSelector; + readonly Func, TResult> resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + IEnumerator> groupEnumerator; + + public _GroupBy(IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (groupEnumerator == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + var lookup = await source.ToLookupAsync(keySelector, elementSelector, comparer, cancellationToken); + groupEnumerator = lookup.GetEnumerator(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + if (groupEnumerator.MoveNext()) + { + var current = groupEnumerator.Current; + Current = resultSelector(current.Key, current); + completionSource.TrySetResult(true); + } + else + { + completionSource.TrySetResult(false); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (groupEnumerator != null) + { + groupEnumerator.Dispose(); + } + + return default; + } + } + } + + internal sealed class GroupByAwait : IUniTaskAsyncEnumerable> + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly Func> elementSelector; + readonly IEqualityComparer comparer; + + public GroupByAwait(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupByAwait(source, keySelector, elementSelector, comparer, cancellationToken); + } + + sealed class _GroupByAwait : MoveNextSource, IUniTaskAsyncEnumerator> + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly Func> elementSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + IEnumerator> groupEnumerator; + + public _GroupByAwait(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public IGrouping Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (groupEnumerator == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + var lookup = await source.ToLookupAwaitAsync(keySelector, elementSelector, comparer, cancellationToken); + groupEnumerator = lookup.GetEnumerator(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + if (groupEnumerator.MoveNext()) + { + Current = groupEnumerator.Current as IGrouping; + completionSource.TrySetResult(true); + } + else + { + completionSource.TrySetResult(false); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (groupEnumerator != null) + { + groupEnumerator.Dispose(); + } + + return default; + } + } + } + + internal sealed class GroupByAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly Func> elementSelector; + readonly Func, UniTask> resultSelector; + readonly IEqualityComparer comparer; + + public GroupByAwait(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, Func, UniTask> resultSelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupByAwait(source, keySelector, elementSelector, resultSelector, comparer, cancellationToken); + } + + sealed class _GroupByAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly static Action ResultSelectCoreDelegate = ResultSelectCore; + + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly Func> elementSelector; + readonly Func, UniTask> resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + IEnumerator> groupEnumerator; + UniTask.Awaiter awaiter; + + public _GroupByAwait(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, Func, UniTask> resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (groupEnumerator == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + var lookup = await source.ToLookupAwaitAsync(keySelector, elementSelector, comparer, cancellationToken); + groupEnumerator = lookup.GetEnumerator(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + if (groupEnumerator.MoveNext()) + { + var current = groupEnumerator.Current; + + awaiter = resultSelector(current.Key, current).GetAwaiter(); + if (awaiter.IsCompleted) + { + ResultSelectCore(this); + } + else + { + awaiter.SourceOnCompleted(ResultSelectCoreDelegate, this); + } + return; + } + else + { + completionSource.TrySetResult(false); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + } + + static void ResultSelectCore(object state) + { + var self = (_GroupByAwait)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + self.Current = result; + self.completionSource.TrySetResult(true); + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (groupEnumerator != null) + { + groupEnumerator.Dispose(); + } + + return default; + } + } + } + + internal sealed class GroupByAwaitWithCancellation : IUniTaskAsyncEnumerable> + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly Func> elementSelector; + readonly IEqualityComparer comparer; + + public GroupByAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupByAwaitWithCancellation(source, keySelector, elementSelector, comparer, cancellationToken); + } + + sealed class _GroupByAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator> + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly Func> elementSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + IEnumerator> groupEnumerator; + + public _GroupByAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public IGrouping Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (groupEnumerator == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + var lookup = await source.ToLookupAwaitWithCancellationAsync(keySelector, elementSelector, comparer, cancellationToken); + groupEnumerator = lookup.GetEnumerator(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + if (groupEnumerator.MoveNext()) + { + Current = groupEnumerator.Current as IGrouping; + completionSource.TrySetResult(true); + } + else + { + completionSource.TrySetResult(false); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (groupEnumerator != null) + { + groupEnumerator.Dispose(); + } + + return default; + } + } + } + + internal sealed class GroupByAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly Func> elementSelector; + readonly Func, CancellationToken, UniTask> resultSelector; + readonly IEqualityComparer comparer; + + public GroupByAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, Func, CancellationToken, UniTask> resultSelector, IEqualityComparer comparer) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupByAwaitWithCancellation(source, keySelector, elementSelector, resultSelector, comparer, cancellationToken); + } + + sealed class _GroupByAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly static Action ResultSelectCoreDelegate = ResultSelectCore; + + readonly IUniTaskAsyncEnumerable source; + readonly Func> keySelector; + readonly Func> elementSelector; + readonly Func, CancellationToken, UniTask> resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + IEnumerator> groupEnumerator; + UniTask.Awaiter awaiter; + + public _GroupByAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, Func, CancellationToken, UniTask> resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.source = source; + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (groupEnumerator == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + var lookup = await source.ToLookupAwaitWithCancellationAsync(keySelector, elementSelector, comparer, cancellationToken); + groupEnumerator = lookup.GetEnumerator(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + if (groupEnumerator.MoveNext()) + { + var current = groupEnumerator.Current; + + awaiter = resultSelector(current.Key, current, cancellationToken).GetAwaiter(); + if (awaiter.IsCompleted) + { + ResultSelectCore(this); + } + else + { + awaiter.SourceOnCompleted(ResultSelectCoreDelegate, this); + } + return; + } + else + { + completionSource.TrySetResult(false); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + } + + static void ResultSelectCore(object state) + { + var self = (_GroupByAwaitWithCancellation)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + self.Current = result; + self.completionSource.TrySetResult(true); + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (groupEnumerator != null) + { + groupEnumerator.Dispose(); + } + + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupBy.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupBy.cs.meta new file mode 100644 index 0000000..1489701 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupBy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2de80df1cc8a1240ab0ee7badd334d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupJoin.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupJoin.cs new file mode 100644 index 0000000..607b221 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupJoin.cs @@ -0,0 +1,612 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable GroupJoin(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func, TResult> resultSelector) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new GroupJoin(outer, inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable GroupJoin(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func, TResult> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new GroupJoin(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer); + } + + public static IUniTaskAsyncEnumerable GroupJoinAwait(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func, UniTask> resultSelector) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new GroupJoinAwait(outer, inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable GroupJoinAwait(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func, UniTask> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new GroupJoinAwait(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer); + } + + public static IUniTaskAsyncEnumerable GroupJoinAwaitWithCancellation(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func, CancellationToken, UniTask> resultSelector) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new GroupJoinAwaitWithCancellation(outer, inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable GroupJoinAwaitWithCancellation(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func, CancellationToken, UniTask> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new GroupJoinAwaitWithCancellation(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer); + } + + } + + internal sealed class GroupJoin : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func outerKeySelector; + readonly Func innerKeySelector; + readonly Func, TResult> resultSelector; + readonly IEqualityComparer comparer; + + public GroupJoin(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func, TResult> resultSelector, IEqualityComparer comparer) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupJoin(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer, cancellationToken); + } + + sealed class _GroupJoin : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func outerKeySelector; + readonly Func innerKeySelector; + readonly Func, TResult> resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + ILookup lookup; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + + + public _GroupJoin(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func, TResult> resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (lookup == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + lookup = await inner.ToLookupAsync(innerKeySelector, comparer, cancellationToken); + enumerator = outer.GetAsyncEnumerator(cancellationToken); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_GroupJoin)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + var outer = self.enumerator.Current; + var key = self.outerKeySelector(outer); + var values = self.lookup[key]; + + self.Current = self.resultSelector(outer, values); + self.completionSource.TrySetResult(true); + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + + return default; + } + } + } + + internal sealed class GroupJoinAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func> outerKeySelector; + readonly Func> innerKeySelector; + readonly Func, UniTask> resultSelector; + readonly IEqualityComparer comparer; + + public GroupJoinAwait(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func, UniTask> resultSelector, IEqualityComparer comparer) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupJoinAwait(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer, cancellationToken); + } + + sealed class _GroupJoinAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + readonly static Action ResultSelectCoreDelegate = ResultSelectCore; + readonly static Action OuterKeySelectCoreDelegate = OuterKeySelectCore; + + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func> outerKeySelector; + readonly Func> innerKeySelector; + readonly Func, UniTask> resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + ILookup lookup; + IUniTaskAsyncEnumerator enumerator; + TOuter outerValue; + UniTask.Awaiter awaiter; + UniTask.Awaiter outerKeyAwaiter; + UniTask.Awaiter resultAwaiter; + + + public _GroupJoinAwait(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func, UniTask> resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (lookup == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + lookup = await inner.ToLookupAwaitAsync(innerKeySelector, comparer, cancellationToken); + enumerator = outer.GetAsyncEnumerator(cancellationToken); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_GroupJoinAwait)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + try + { + + self.outerValue = self.enumerator.Current; + self.outerKeyAwaiter = self.outerKeySelector(self.outerValue).GetAwaiter(); + if (self.outerKeyAwaiter.IsCompleted) + { + OuterKeySelectCore(self); + } + else + { + self.outerKeyAwaiter.SourceOnCompleted(OuterKeySelectCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void OuterKeySelectCore(object state) + { + var self = (_GroupJoinAwait)state; + + if (self.TryGetResult(self.outerKeyAwaiter, out var result)) + { + try + { + var values = self.lookup[result]; + self.resultAwaiter = self.resultSelector(self.outerValue, values).GetAwaiter(); + if (self.resultAwaiter.IsCompleted) + { + ResultSelectCore(self); + } + else + { + self.resultAwaiter.SourceOnCompleted(ResultSelectCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + } + } + + static void ResultSelectCore(object state) + { + var self = (_GroupJoinAwait)state; + + if (self.TryGetResult(self.resultAwaiter, out var result)) + { + self.Current = result; + self.completionSource.TrySetResult(true); + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + + return default; + } + } + } + + internal sealed class GroupJoinAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func> outerKeySelector; + readonly Func> innerKeySelector; + readonly Func, CancellationToken, UniTask> resultSelector; + readonly IEqualityComparer comparer; + + public GroupJoinAwaitWithCancellation(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func, CancellationToken, UniTask> resultSelector, IEqualityComparer comparer) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _GroupJoinAwaitWithCancellation(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer, cancellationToken); + } + + sealed class _GroupJoinAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + readonly static Action ResultSelectCoreDelegate = ResultSelectCore; + readonly static Action OuterKeySelectCoreDelegate = OuterKeySelectCore; + + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func> outerKeySelector; + readonly Func> innerKeySelector; + readonly Func, CancellationToken, UniTask> resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + ILookup lookup; + IUniTaskAsyncEnumerator enumerator; + TOuter outerValue; + UniTask.Awaiter awaiter; + UniTask.Awaiter outerKeyAwaiter; + UniTask.Awaiter resultAwaiter; + + + public _GroupJoinAwaitWithCancellation(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func, CancellationToken, UniTask> resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (lookup == null) + { + CreateLookup().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateLookup() + { + try + { + lookup = await inner.ToLookupAwaitWithCancellationAsync(innerKeySelector, comparer, cancellationToken); + enumerator = outer.GetAsyncEnumerator(cancellationToken); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_GroupJoinAwaitWithCancellation)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + try + { + + self.outerValue = self.enumerator.Current; + self.outerKeyAwaiter = self.outerKeySelector(self.outerValue, self.cancellationToken).GetAwaiter(); + if (self.outerKeyAwaiter.IsCompleted) + { + OuterKeySelectCore(self); + } + else + { + self.outerKeyAwaiter.SourceOnCompleted(OuterKeySelectCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void OuterKeySelectCore(object state) + { + var self = (_GroupJoinAwaitWithCancellation)state; + + if (self.TryGetResult(self.outerKeyAwaiter, out var result)) + { + try + { + var values = self.lookup[result]; + self.resultAwaiter = self.resultSelector(self.outerValue, values, self.cancellationToken).GetAwaiter(); + if (self.resultAwaiter.IsCompleted) + { + ResultSelectCore(self); + } + else + { + self.resultAwaiter.SourceOnCompleted(ResultSelectCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + } + } + + static void ResultSelectCore(object state) + { + var self = (_GroupJoinAwaitWithCancellation)state; + + if (self.TryGetResult(self.resultAwaiter, out var result)) + { + self.Current = result; + self.completionSource.TrySetResult(true); + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupJoin.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupJoin.cs.meta new file mode 100644 index 0000000..f171ed1 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/GroupJoin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7bf7759d03bf3f64190d3ae83b182c2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Intersect.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Intersect.cs new file mode 100644 index 0000000..3faf645 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Intersect.cs @@ -0,0 +1,117 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Intersect(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + + return new Intersect(first, second, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable Intersect(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new Intersect(first, second, comparer); + } + } + + internal sealed class Intersect : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + readonly IEqualityComparer comparer; + + public Intersect(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer) + { + this.first = first; + this.second = second; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Intersect(first, second, comparer, cancellationToken); + } + + class _Intersect : AsyncEnumeratorBase + { + static Action HashSetAsyncCoreDelegate = HashSetAsyncCore; + + readonly IEqualityComparer comparer; + readonly IUniTaskAsyncEnumerable second; + + HashSet set; + UniTask>.Awaiter awaiter; + + public _Intersect(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer, CancellationToken cancellationToken) + + : base(first, cancellationToken) + { + this.second = second; + this.comparer = comparer; + } + + protected override bool OnFirstIteration() + { + if (set != null) return false; + + awaiter = second.ToHashSetAsync(cancellationToken).GetAwaiter(); + if (awaiter.IsCompleted) + { + set = awaiter.GetResult(); + SourceMoveNext(); + } + else + { + awaiter.SourceOnCompleted(HashSetAsyncCoreDelegate, this); + } + + return true; + } + + static void HashSetAsyncCore(object state) + { + var self = (_Intersect)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + self.set = result; + self.SourceMoveNext(); + } + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + var v = SourceCurrent; + + if (set.Remove(v)) + { + Current = v; + result = true; + return true; + } + else + { + result = default; + return false; + } + } + + result = false; + return true; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Intersect.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Intersect.cs.meta new file mode 100644 index 0000000..28cf8e3 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Intersect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93999a70f5d57134bbe971f3e988c4f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Join.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Join.cs new file mode 100644 index 0000000..2d80889 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Join.cs @@ -0,0 +1,728 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Join(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new Join(outer, inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable Join(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new Join(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer); + } + + public static IUniTaskAsyncEnumerable JoinAwait(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func> resultSelector) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new JoinAwait(outer, inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable JoinAwait(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new JoinAwait(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer); + } + + public static IUniTaskAsyncEnumerable JoinAwaitWithCancellation(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func> resultSelector) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new JoinAwaitWithCancellation(outer, inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable JoinAwaitWithCancellation(this IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func> resultSelector, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(outer, nameof(outer)); + Error.ThrowArgumentNullException(inner, nameof(inner)); + Error.ThrowArgumentNullException(outerKeySelector, nameof(outerKeySelector)); + Error.ThrowArgumentNullException(innerKeySelector, nameof(innerKeySelector)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new JoinAwaitWithCancellation(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer); + } + } + + internal sealed class Join : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func outerKeySelector; + readonly Func innerKeySelector; + readonly Func resultSelector; + readonly IEqualityComparer comparer; + + public Join(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector, IEqualityComparer comparer) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Join(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer, cancellationToken); + } + + sealed class _Join : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func outerKeySelector; + readonly Func innerKeySelector; + readonly Func resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + ILookup lookup; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + TOuter currentOuterValue; + IEnumerator valueEnumerator; + + bool continueNext; + + public _Join(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (lookup == null) + { + CreateInnerHashSet().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateInnerHashSet() + { + try + { + lookup = await inner.ToLookupAsync(innerKeySelector, comparer, cancellationToken); + enumerator = outer.GetAsyncEnumerator(cancellationToken); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + LOOP: + if (valueEnumerator != null) + { + if (valueEnumerator.MoveNext()) + { + Current = resultSelector(currentOuterValue, valueEnumerator.Current); + goto TRY_SET_RESULT_TRUE; + } + else + { + valueEnumerator.Dispose(); + valueEnumerator = null; + } + } + + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; // avoid recursive + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + + return; + + TRY_SET_RESULT_TRUE: + completionSource.TrySetResult(true); + } + + + static void MoveNextCore(object state) + { + var self = (_Join)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.currentOuterValue = self.enumerator.Current; + var key = self.outerKeySelector(self.currentOuterValue); + self.valueEnumerator = self.lookup[key].GetEnumerator(); + + if (self.continueNext) + { + return; + } + else + { + self.SourceMoveNext(); + } + } + else + { + self.continueNext = false; + self.completionSource.TrySetResult(false); + } + } + else + { + self.continueNext = false; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (valueEnumerator != null) + { + valueEnumerator.Dispose(); + } + + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + + return default; + } + } + } + + internal sealed class JoinAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func> outerKeySelector; + readonly Func> innerKeySelector; + readonly Func> resultSelector; + readonly IEqualityComparer comparer; + + public JoinAwait(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func> resultSelector, IEqualityComparer comparer) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _JoinAwait(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer, cancellationToken); + } + + sealed class _JoinAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + static readonly Action OuterSelectCoreDelegate = OuterSelectCore; + static readonly Action ResultSelectCoreDelegate = ResultSelectCore; + + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func> outerKeySelector; + readonly Func> innerKeySelector; + readonly Func> resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + ILookup lookup; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + TOuter currentOuterValue; + IEnumerator valueEnumerator; + + UniTask.Awaiter resultAwaiter; + UniTask.Awaiter outerKeyAwaiter; + + bool continueNext; + + public _JoinAwait(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func> resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (lookup == null) + { + CreateInnerHashSet().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateInnerHashSet() + { + try + { + lookup = await inner.ToLookupAwaitAsync(innerKeySelector, comparer, cancellationToken); + enumerator = outer.GetAsyncEnumerator(cancellationToken); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + LOOP: + if (valueEnumerator != null) + { + if (valueEnumerator.MoveNext()) + { + resultAwaiter = resultSelector(currentOuterValue, valueEnumerator.Current).GetAwaiter(); + if (resultAwaiter.IsCompleted) + { + ResultSelectCore(this); + } + else + { + resultAwaiter.SourceOnCompleted(ResultSelectCoreDelegate, this); + } + return; + } + else + { + valueEnumerator.Dispose(); + valueEnumerator = null; + } + } + + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; // avoid recursive + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + + static void MoveNextCore(object state) + { + var self = (_JoinAwait)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.currentOuterValue = self.enumerator.Current; + + self.outerKeyAwaiter = self.outerKeySelector(self.currentOuterValue).GetAwaiter(); + + if (self.outerKeyAwaiter.IsCompleted) + { + OuterSelectCore(self); + } + else + { + self.continueNext = false; + self.outerKeyAwaiter.SourceOnCompleted(OuterSelectCoreDelegate, self); + } + } + else + { + self.continueNext = false; + self.completionSource.TrySetResult(false); + } + } + else + { + self.continueNext = false; + } + } + + static void OuterSelectCore(object state) + { + var self = (_JoinAwait)state; + + if (self.TryGetResult(self.outerKeyAwaiter, out var key)) + { + self.valueEnumerator = self.lookup[key].GetEnumerator(); + + if (self.continueNext) + { + return; + } + else + { + self.SourceMoveNext(); + } + } + else + { + self.continueNext = false; + } + } + + static void ResultSelectCore(object state) + { + var self = (_JoinAwait)state; + + if (self.TryGetResult(self.resultAwaiter, out var result)) + { + self.Current = result; + self.completionSource.TrySetResult(true); + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (valueEnumerator != null) + { + valueEnumerator.Dispose(); + } + + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + + return default; + } + } + } + + internal sealed class JoinAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func> outerKeySelector; + readonly Func> innerKeySelector; + readonly Func> resultSelector; + readonly IEqualityComparer comparer; + + public JoinAwaitWithCancellation(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func> resultSelector, IEqualityComparer comparer) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _JoinAwaitWithCancellation(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer, cancellationToken); + } + + sealed class _JoinAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + static readonly Action OuterSelectCoreDelegate = OuterSelectCore; + static readonly Action ResultSelectCoreDelegate = ResultSelectCore; + + readonly IUniTaskAsyncEnumerable outer; + readonly IUniTaskAsyncEnumerable inner; + readonly Func> outerKeySelector; + readonly Func> innerKeySelector; + readonly Func> resultSelector; + readonly IEqualityComparer comparer; + CancellationToken cancellationToken; + + ILookup lookup; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + TOuter currentOuterValue; + IEnumerator valueEnumerator; + + UniTask.Awaiter resultAwaiter; + UniTask.Awaiter outerKeyAwaiter; + + bool continueNext; + + public _JoinAwaitWithCancellation(IUniTaskAsyncEnumerable outer, IUniTaskAsyncEnumerable inner, Func> outerKeySelector, Func> innerKeySelector, Func> resultSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + this.outer = outer; + this.inner = inner; + this.outerKeySelector = outerKeySelector; + this.innerKeySelector = innerKeySelector; + this.resultSelector = resultSelector; + this.comparer = comparer; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (lookup == null) + { + CreateInnerHashSet().Forget(); + } + else + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + async UniTaskVoid CreateInnerHashSet() + { + try + { + lookup = await inner.ToLookupAwaitWithCancellationAsync(innerKeySelector, comparer, cancellationToken: cancellationToken); + enumerator = outer.GetAsyncEnumerator(cancellationToken); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + SourceMoveNext(); + } + + void SourceMoveNext() + { + try + { + LOOP: + if (valueEnumerator != null) + { + if (valueEnumerator.MoveNext()) + { + resultAwaiter = resultSelector(currentOuterValue, valueEnumerator.Current, cancellationToken).GetAwaiter(); + if (resultAwaiter.IsCompleted) + { + ResultSelectCore(this); + } + else + { + resultAwaiter.SourceOnCompleted(ResultSelectCoreDelegate, this); + } + return; + } + else + { + valueEnumerator.Dispose(); + valueEnumerator = null; + } + } + + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; // avoid recursive + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + + static void MoveNextCore(object state) + { + var self = (_JoinAwaitWithCancellation)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.currentOuterValue = self.enumerator.Current; + + self.outerKeyAwaiter = self.outerKeySelector(self.currentOuterValue, self.cancellationToken).GetAwaiter(); + + if (self.outerKeyAwaiter.IsCompleted) + { + OuterSelectCore(self); + } + else + { + self.continueNext = false; + self.outerKeyAwaiter.SourceOnCompleted(OuterSelectCoreDelegate, self); + } + } + else + { + self.continueNext = false; + self.completionSource.TrySetResult(false); + } + } + else + { + self.continueNext = false; + } + } + + static void OuterSelectCore(object state) + { + var self = (_JoinAwaitWithCancellation)state; + + if (self.TryGetResult(self.outerKeyAwaiter, out var key)) + { + self.valueEnumerator = self.lookup[key].GetEnumerator(); + + if (self.continueNext) + { + return; + } + else + { + self.SourceMoveNext(); + } + } + else + { + self.continueNext = false; + } + } + + static void ResultSelectCore(object state) + { + var self = (_JoinAwaitWithCancellation)state; + + if (self.TryGetResult(self.resultAwaiter, out var result)) + { + self.Current = result; + self.completionSource.TrySetResult(true); + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (valueEnumerator != null) + { + valueEnumerator.Dispose(); + } + + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + + return default; + } + } + } + +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Join.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Join.cs.meta new file mode 100644 index 0000000..3ab1015 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Join.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc4ff8cb6d7c9a64896f2f082124d6b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Last.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Last.cs new file mode 100644 index 0000000..664bb27 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Last.cs @@ -0,0 +1,240 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask LastAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Last.LastAsync(source, cancellationToken, false); + } + + public static UniTask LastAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Last.LastAsync(source, predicate, cancellationToken, false); + } + + public static UniTask LastAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Last.LastAwaitAsync(source, predicate, cancellationToken, false); + } + + public static UniTask LastAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Last.LastAwaitWithCancellationAsync(source, predicate, cancellationToken, false); + } + + public static UniTask LastOrDefaultAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Last.LastAsync(source, cancellationToken, true); + } + + public static UniTask LastOrDefaultAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Last.LastAsync(source, predicate, cancellationToken, true); + } + + public static UniTask LastOrDefaultAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Last.LastAwaitAsync(source, predicate, cancellationToken, true); + } + + public static UniTask LastOrDefaultAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return Last.LastAwaitWithCancellationAsync(source, predicate, cancellationToken, true); + } + } + + internal static class Last + { + public static async UniTask LastAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value = default; + if (await e.MoveNextAsync()) + { + value = e.Current; + } + else + { + if (defaultIfEmpty) + { + return value; + } + else + { + throw Error.NoElements(); + } + } + + while (await e.MoveNextAsync()) + { + value = e.Current; + } + return value; + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask LastAsync(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value = default; + + bool found = false; + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (predicate(v)) + { + found = true; + value = v; + } + } + + if (defaultIfEmpty) + { + return value; + } + else + { + if (found) + { + return value; + } + else + { + throw Error.NoElements(); + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask LastAwaitAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value = default; + + bool found = false; + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (await predicate(v)) + { + found = true; + value = v; + } + } + + if (defaultIfEmpty) + { + return value; + } + else + { + if (found) + { + return value; + } + else + { + throw Error.NoElements(); + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask LastAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value = default; + + bool found = false; + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (await predicate(v, cancellationToken)) + { + found = true; + value = v; + } + } + + if (defaultIfEmpty) + { + return value; + } + else + { + if (found) + { + return value; + } + else + { + throw Error.NoElements(); + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Last.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Last.cs.meta new file mode 100644 index 0000000..edfa124 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Last.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0ccc93be1387fa4a975f06310127c11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/LongCount.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/LongCount.cs new file mode 100644 index 0000000..78ae805 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/LongCount.cs @@ -0,0 +1,144 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask LongCountAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return LongCount.LongCountAsync(source, cancellationToken); + } + + public static UniTask LongCountAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return LongCount.LongCountAsync(source, predicate, cancellationToken); + } + + public static UniTask LongCountAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return LongCount.LongCountAwaitAsync(source, predicate, cancellationToken); + } + + public static UniTask LongCountAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return LongCount.LongCountAwaitWithCancellationAsync(source, predicate, cancellationToken); + } + } + + internal static class LongCount + { + internal static async UniTask LongCountAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked { count++; } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask LongCountAsync(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + { + long count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (predicate(e.Current)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask LongCountAwaitAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + long count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (await predicate(e.Current)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask LongCountAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + long count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (await predicate(e.Current, cancellationToken)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/LongCount.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/LongCount.cs.meta new file mode 100644 index 0000000..862c2bc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/LongCount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 198b39e58ced3ab4f97ccbe0916787d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Max.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Max.cs new file mode 100644 index 0000000..d244a15 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Max.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + } + + internal static partial class Max + { + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + TSource value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (comparer.Compare(value, x) < 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (comparer.Compare(value, x) < 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (comparer.Compare(value, x) < 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (comparer.Compare(value, x) < 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Max.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Max.cs.meta new file mode 100644 index 0000000..2125edf --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Max.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c8a118a6b664c441820b8a87d7f6e28 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Min.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Min.cs new file mode 100644 index 0000000..8768a86 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Min.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + } + + internal static partial class Min + { + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + TSource value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (comparer.Compare(value, x) > 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (comparer.Compare(value, x) > 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (comparer.Compare(value, x) > 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (comparer.Compare(value, x) > 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Min.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Min.cs.meta new file mode 100644 index 0000000..91378dc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Min.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57ac9da21d3457849a8e45548290a508 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/MinMax.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/MinMax.cs new file mode 100644 index 0000000..aae3541 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/MinMax.cs @@ -0,0 +1,3763 @@ +using System; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.MinAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.MinAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + } + + internal static partial class Min + { + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int32 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int32 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int64 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int64 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Single value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Single value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Double value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Double value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Decimal value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Decimal value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int32? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int32? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int64? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int64? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Single? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Single? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Double? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Double? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Decimal? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Decimal? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MinAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value > x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + } + + public static partial class UniTaskAsyncEnumerable + { + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.MaxAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.MaxAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + } + + internal static partial class Max + { + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int32 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int32 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int64 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int64 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64 value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Single value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Single value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Double value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Double value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Decimal value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Decimal value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + throw Error.NoElements(); + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int32? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int32? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int64? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int64? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Single? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Single? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Double? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Double? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Decimal? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Decimal? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask MaxAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal? value = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + if(value == null) continue; + + goto NEXT_LOOP; + } + + return default; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if( x == null) continue; + if (value < x) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + } + +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/MinMax.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/MinMax.cs.meta new file mode 100644 index 0000000..3856b65 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/MinMax.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d6da02d9ab970e4999daf7147d98e36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Never.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Never.cs new file mode 100644 index 0000000..2dbce71 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Never.cs @@ -0,0 +1,56 @@ +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Never() + { + return Cysharp.Threading.Tasks.Linq.Never.Instance; + } + } + + internal class Never : IUniTaskAsyncEnumerable + { + public static readonly IUniTaskAsyncEnumerable Instance = new Never(); + + Never() + { + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Never(cancellationToken); + } + + class _Never : IUniTaskAsyncEnumerator + { + CancellationToken cancellationToken; + + public _Never(CancellationToken cancellationToken) + { + this.cancellationToken = cancellationToken; + } + + public T Current => default; + + public UniTask MoveNextAsync() + { + var tcs = new UniTaskCompletionSource(); + + cancellationToken.Register(state => + { + var task = (UniTaskCompletionSource)state; + task.TrySetCanceled(cancellationToken); + }, tcs); + + return tcs.Task; + } + + public UniTask DisposeAsync() + { + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Never.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Never.cs.meta new file mode 100644 index 0000000..ba9d358 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Never.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b307c3d3be71a94da251564bcdefa3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OfType.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OfType.cs new file mode 100644 index 0000000..fea8069 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OfType.cs @@ -0,0 +1,61 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable OfType(this IUniTaskAsyncEnumerable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new OfType(source); + } + } + + internal sealed class OfType : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + + public OfType(IUniTaskAsyncEnumerable source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _OfType(source, cancellationToken); + } + + class _OfType : AsyncEnumeratorBase + { + public _OfType(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + if (SourceCurrent is TResult castCurent) + { + Current = castCurent; + result = true; + return true; + } + else + { + result = default; + return false; + } + } + + result = false; + return true; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OfType.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OfType.cs.meta new file mode 100644 index 0000000..6ace53f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OfType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 111ffe87a7d700442a9ef5af554b252c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OrderBy.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OrderBy.cs new file mode 100644 index 0000000..d0c379f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OrderBy.cs @@ -0,0 +1,558 @@ +using Cysharp.Threading.Tasks; +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + #region OrderBy_OrderByDescending + + public static IUniTaskOrderedAsyncEnumerable OrderBy(this IUniTaskAsyncEnumerable source, Func keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return new OrderedAsyncEnumerable(source, keySelector, Comparer.Default, false, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderBy(this IUniTaskAsyncEnumerable source, Func keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new OrderedAsyncEnumerable(source, keySelector, comparer, false, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return new OrderedAsyncEnumerableAwait(source, keySelector, Comparer.Default, false, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new OrderedAsyncEnumerableAwait(source, keySelector, comparer, false, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return new OrderedAsyncEnumerableAwaitWithCancellation(source, keySelector, Comparer.Default, false, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new OrderedAsyncEnumerableAwaitWithCancellation(source, keySelector, comparer, false, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByDescending(this IUniTaskAsyncEnumerable source, Func keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return new OrderedAsyncEnumerable(source, keySelector, Comparer.Default, true, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByDescending(this IUniTaskAsyncEnumerable source, Func keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new OrderedAsyncEnumerable(source, keySelector, comparer, true, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByDescendingAwait(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return new OrderedAsyncEnumerableAwait(source, keySelector, Comparer.Default, true, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByDescendingAwait(this IUniTaskAsyncEnumerable source, Func> keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new OrderedAsyncEnumerableAwait(source, keySelector, comparer, true, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByDescendingAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return new OrderedAsyncEnumerableAwaitWithCancellation(source, keySelector, Comparer.Default, true, null); + } + + public static IUniTaskOrderedAsyncEnumerable OrderByDescendingAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return new OrderedAsyncEnumerableAwaitWithCancellation(source, keySelector, comparer, true, null); + } + + #endregion + + #region ThenBy_ThenByDescending + + public static IUniTaskOrderedAsyncEnumerable ThenBy(this IUniTaskOrderedAsyncEnumerable source, Func keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return source.CreateOrderedEnumerable(keySelector, Comparer.Default, false); + } + + public static IUniTaskOrderedAsyncEnumerable ThenBy(this IUniTaskOrderedAsyncEnumerable source, Func keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return source.CreateOrderedEnumerable(keySelector, comparer, false); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByAwait(this IUniTaskOrderedAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return source.CreateOrderedEnumerable(keySelector, Comparer.Default, false); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByAwait(this IUniTaskOrderedAsyncEnumerable source, Func> keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return source.CreateOrderedEnumerable(keySelector, comparer, false); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByAwaitWithCancellation(this IUniTaskOrderedAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return source.CreateOrderedEnumerable(keySelector, Comparer.Default, false); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByAwaitWithCancellation(this IUniTaskOrderedAsyncEnumerable source, Func> keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return source.CreateOrderedEnumerable(keySelector, comparer, false); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByDescending(this IUniTaskOrderedAsyncEnumerable source, Func keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return source.CreateOrderedEnumerable(keySelector, Comparer.Default, true); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByDescending(this IUniTaskOrderedAsyncEnumerable source, Func keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return source.CreateOrderedEnumerable(keySelector, comparer, true); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByDescendingAwait(this IUniTaskOrderedAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return source.CreateOrderedEnumerable(keySelector, Comparer.Default, true); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByDescendingAwait(this IUniTaskOrderedAsyncEnumerable source, Func> keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return source.CreateOrderedEnumerable(keySelector, comparer, true); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByDescendingAwaitWithCancellation(this IUniTaskOrderedAsyncEnumerable source, Func> keySelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return source.CreateOrderedEnumerable(keySelector, Comparer.Default, true); + } + + public static IUniTaskOrderedAsyncEnumerable ThenByDescendingAwaitWithCancellation(this IUniTaskOrderedAsyncEnumerable source, Func> keySelector, IComparer comparer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return source.CreateOrderedEnumerable(keySelector, comparer, true); + } + + #endregion + } + + internal abstract class AsyncEnumerableSorter + { + internal abstract UniTask ComputeKeysAsync(TElement[] elements, int count); + + internal abstract int CompareKeys(int index1, int index2); + + internal async UniTask SortAsync(TElement[] elements, int count) + { + await ComputeKeysAsync(elements, count); + + int[] map = new int[count]; + for (int i = 0; i < count; i++) map[i] = i; + QuickSort(map, 0, count - 1); + return map; + } + + void QuickSort(int[] map, int left, int right) + { + do + { + int i = left; + int j = right; + int x = map[i + ((j - i) >> 1)]; + do + { + while (i < map.Length && CompareKeys(x, map[i]) > 0) i++; + while (j >= 0 && CompareKeys(x, map[j]) < 0) j--; + if (i > j) break; + if (i < j) + { + int temp = map[i]; + map[i] = map[j]; + map[j] = temp; + } + i++; + j--; + } while (i <= j); + if (j - left <= right - i) + { + if (left < j) QuickSort(map, left, j); + left = i; + } + else + { + if (i < right) QuickSort(map, i, right); + right = j; + } + } while (left < right); + } + } + + internal class SyncSelectorAsyncEnumerableSorter : AsyncEnumerableSorter + { + readonly Func keySelector; + readonly IComparer comparer; + readonly bool descending; + readonly AsyncEnumerableSorter next; + TKey[] keys; + + internal SyncSelectorAsyncEnumerableSorter(Func keySelector, IComparer comparer, bool descending, AsyncEnumerableSorter next) + { + this.keySelector = keySelector; + this.comparer = comparer; + this.descending = descending; + this.next = next; + } + + internal override async UniTask ComputeKeysAsync(TElement[] elements, int count) + { + keys = new TKey[count]; + for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]); + if (next != null) await next.ComputeKeysAsync(elements, count); + } + + internal override int CompareKeys(int index1, int index2) + { + int c = comparer.Compare(keys[index1], keys[index2]); + if (c == 0) + { + if (next == null) return index1 - index2; + return next.CompareKeys(index1, index2); + } + return descending ? -c : c; + } + } + + internal class AsyncSelectorEnumerableSorter : AsyncEnumerableSorter + { + readonly Func> keySelector; + readonly IComparer comparer; + readonly bool descending; + readonly AsyncEnumerableSorter next; + TKey[] keys; + + internal AsyncSelectorEnumerableSorter(Func> keySelector, IComparer comparer, bool descending, AsyncEnumerableSorter next) + { + this.keySelector = keySelector; + this.comparer = comparer; + this.descending = descending; + this.next = next; + } + + internal override async UniTask ComputeKeysAsync(TElement[] elements, int count) + { + keys = new TKey[count]; + for (int i = 0; i < count; i++) keys[i] = await keySelector(elements[i]); + if (next != null) await next.ComputeKeysAsync(elements, count); + } + + internal override int CompareKeys(int index1, int index2) + { + int c = comparer.Compare(keys[index1], keys[index2]); + if (c == 0) + { + if (next == null) return index1 - index2; + return next.CompareKeys(index1, index2); + } + return descending ? -c : c; + } + } + + internal class AsyncSelectorWithCancellationEnumerableSorter : AsyncEnumerableSorter + { + readonly Func> keySelector; + readonly IComparer comparer; + readonly bool descending; + readonly AsyncEnumerableSorter next; + CancellationToken cancellationToken; + TKey[] keys; + + internal AsyncSelectorWithCancellationEnumerableSorter(Func> keySelector, IComparer comparer, bool descending, AsyncEnumerableSorter next, CancellationToken cancellationToken) + { + this.keySelector = keySelector; + this.comparer = comparer; + this.descending = descending; + this.next = next; + this.cancellationToken = cancellationToken; + } + + internal override async UniTask ComputeKeysAsync(TElement[] elements, int count) + { + keys = new TKey[count]; + for (int i = 0; i < count; i++) keys[i] = await keySelector(elements[i], cancellationToken); + if (next != null) await next.ComputeKeysAsync(elements, count); + } + + internal override int CompareKeys(int index1, int index2) + { + int c = comparer.Compare(keys[index1], keys[index2]); + if (c == 0) + { + if (next == null) return index1 - index2; + return next.CompareKeys(index1, index2); + } + return descending ? -c : c; + } + } + + internal abstract class OrderedAsyncEnumerable : IUniTaskOrderedAsyncEnumerable + { + protected readonly IUniTaskAsyncEnumerable source; + + public OrderedAsyncEnumerable(IUniTaskAsyncEnumerable source) + { + this.source = source; + } + + public IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func keySelector, IComparer comparer, bool descending) + { + return new OrderedAsyncEnumerable(source, keySelector, comparer, descending, this); + } + + public IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func> keySelector, IComparer comparer, bool descending) + { + return new OrderedAsyncEnumerableAwait(source, keySelector, comparer, descending, this); + } + + public IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func> keySelector, IComparer comparer, bool descending) + { + return new OrderedAsyncEnumerableAwaitWithCancellation(source, keySelector, comparer, descending, this); + } + + internal abstract AsyncEnumerableSorter GetAsyncEnumerableSorter(AsyncEnumerableSorter next, CancellationToken cancellationToken); + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _OrderedAsyncEnumerator(this, cancellationToken); + } + + class _OrderedAsyncEnumerator : MoveNextSource, IUniTaskAsyncEnumerator + { + protected readonly OrderedAsyncEnumerable parent; + CancellationToken cancellationToken; + TElement[] buffer; + int[] map; + int index; + + public _OrderedAsyncEnumerator(OrderedAsyncEnumerable parent, CancellationToken cancellationToken) + { + this.parent = parent; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TElement Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (map == null) + { + completionSource.Reset(); + CreateSortSource().Forget(); + return new UniTask(this, completionSource.Version); + } + + if (index < buffer.Length) + { + Current = buffer[map[index++]]; + return CompletedTasks.True; + } + else + { + return CompletedTasks.False; + } + } + + async UniTaskVoid CreateSortSource() + { + try + { + buffer = await parent.source.ToArrayAsync(); + if (buffer.Length == 0) + { + completionSource.TrySetResult(false); + return; + } + + var sorter = parent.GetAsyncEnumerableSorter(null, cancellationToken); + map = await sorter.SortAsync(buffer, buffer.Length); + sorter = null; + + // set first value + Current = buffer[map[index++]]; + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + completionSource.TrySetResult(true); + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return default; + } + } + } + + internal class OrderedAsyncEnumerable : OrderedAsyncEnumerable + { + readonly Func keySelector; + readonly IComparer comparer; + readonly bool descending; + readonly OrderedAsyncEnumerable parent; + + public OrderedAsyncEnumerable(IUniTaskAsyncEnumerable source, Func keySelector, IComparer comparer, bool descending, OrderedAsyncEnumerable parent) + : base(source) + { + this.keySelector = keySelector; + this.comparer = comparer; + this.descending = descending; + this.parent = parent; + } + + internal override AsyncEnumerableSorter GetAsyncEnumerableSorter(AsyncEnumerableSorter next, CancellationToken cancellationToken) + { + AsyncEnumerableSorter sorter = new SyncSelectorAsyncEnumerableSorter(keySelector, comparer, descending, next); + if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken); + return sorter; + } + } + + internal class OrderedAsyncEnumerableAwait : OrderedAsyncEnumerable + { + readonly Func> keySelector; + readonly IComparer comparer; + readonly bool descending; + readonly OrderedAsyncEnumerable parent; + + public OrderedAsyncEnumerableAwait(IUniTaskAsyncEnumerable source, Func> keySelector, IComparer comparer, bool descending, OrderedAsyncEnumerable parent) + : base(source) + { + this.keySelector = keySelector; + this.comparer = comparer; + this.descending = descending; + this.parent = parent; + } + + internal override AsyncEnumerableSorter GetAsyncEnumerableSorter(AsyncEnumerableSorter next, CancellationToken cancellationToken) + { + AsyncEnumerableSorter sorter = new AsyncSelectorEnumerableSorter(keySelector, comparer, descending, next); + if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken); + return sorter; + } + } + + internal class OrderedAsyncEnumerableAwaitWithCancellation : OrderedAsyncEnumerable + { + readonly Func> keySelector; + readonly IComparer comparer; + readonly bool descending; + readonly OrderedAsyncEnumerable parent; + + public OrderedAsyncEnumerableAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> keySelector, IComparer comparer, bool descending, OrderedAsyncEnumerable parent) + : base(source) + { + this.keySelector = keySelector; + this.comparer = comparer; + this.descending = descending; + this.parent = parent; + } + + internal override AsyncEnumerableSorter GetAsyncEnumerableSorter(AsyncEnumerableSorter next, CancellationToken cancellationToken) + { + AsyncEnumerableSorter sorter = new AsyncSelectorWithCancellationEnumerableSorter(keySelector, comparer, descending, next, cancellationToken); + if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken); + return sorter; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OrderBy.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OrderBy.cs.meta new file mode 100644 index 0000000..5c6b3e4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/OrderBy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 413883ceff8546143bdf200aafa4b8f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Pairwise.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Pairwise.cs new file mode 100644 index 0000000..5d44a9e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Pairwise.cs @@ -0,0 +1,128 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable<(TSource, TSource)> Pairwise(this IUniTaskAsyncEnumerable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new Pairwise(source); + } + } + + internal sealed class Pairwise : IUniTaskAsyncEnumerable<(TSource, TSource)> + { + readonly IUniTaskAsyncEnumerable source; + + public Pairwise(IUniTaskAsyncEnumerable source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator<(TSource, TSource)> GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Pairwise(source, cancellationToken); + } + + sealed class _Pairwise : MoveNextSource, IUniTaskAsyncEnumerator<(TSource, TSource)> + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + + TSource prev; + bool isFirst; + + public _Pairwise(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public (TSource, TSource) Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (enumerator == null) + { + isFirst = true; + enumerator = source.GetAsyncEnumerator(cancellationToken); + } + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + try + { + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_Pairwise)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + if (self.isFirst) + { + self.isFirst = false; + self.prev = self.enumerator.Current; + self.SourceMoveNext(); // run again. okay to use recursive(only one more). + } + else + { + var p = self.prev; + self.prev = self.enumerator.Current; + self.Current = (p, self.prev); + self.completionSource.TrySetResult(true); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Pairwise.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Pairwise.cs.meta new file mode 100644 index 0000000..727b8cf --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Pairwise.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cddbf051d2a88f549986c468b23214af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Publish.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Publish.cs new file mode 100644 index 0000000..d218c0f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Publish.cs @@ -0,0 +1,173 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IConnectableUniTaskAsyncEnumerable Publish(this IUniTaskAsyncEnumerable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new Publish(source); + } + } + + internal sealed class Publish : IConnectableUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly CancellationTokenSource cancellationTokenSource; + + TriggerEvent trigger; + IUniTaskAsyncEnumerator enumerator; + IDisposable connectedDisposable; + bool isCompleted; + + public Publish(IUniTaskAsyncEnumerable source) + { + this.source = source; + this.cancellationTokenSource = new CancellationTokenSource(); + } + + public IDisposable Connect() + { + if (connectedDisposable != null) return connectedDisposable; + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationTokenSource.Token); + } + + ConsumeEnumerator().Forget(); + + connectedDisposable = new ConnectDisposable(cancellationTokenSource); + return connectedDisposable; + } + + async UniTaskVoid ConsumeEnumerator() + { + try + { + try + { + while (await enumerator.MoveNextAsync()) + { + trigger.SetResult(enumerator.Current); + } + trigger.SetCompleted(); + } + catch (Exception ex) + { + trigger.SetError(ex); + } + } + finally + { + isCompleted = true; + await enumerator.DisposeAsync(); + } + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Publish(this, cancellationToken); + } + + sealed class ConnectDisposable : IDisposable + { + readonly CancellationTokenSource cancellationTokenSource; + + public ConnectDisposable(CancellationTokenSource cancellationTokenSource) + { + this.cancellationTokenSource = cancellationTokenSource; + } + + public void Dispose() + { + this.cancellationTokenSource.Cancel(); + } + } + + sealed class _Publish : MoveNextSource, IUniTaskAsyncEnumerator, ITriggerHandler + { + static readonly Action CancelDelegate = OnCanceled; + + readonly Publish parent; + CancellationToken cancellationToken; + CancellationTokenRegistration cancellationTokenRegistration; + bool isDisposed; + + public _Publish(Publish parent, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) return; + + this.parent = parent; + this.cancellationToken = cancellationToken; + + if (cancellationToken.CanBeCanceled) + { + this.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(CancelDelegate, this); + } + + parent.trigger.Add(this); + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + ITriggerHandler ITriggerHandler.Prev { get; set; } + ITriggerHandler ITriggerHandler.Next { get; set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (parent.isCompleted) return CompletedTasks.False; + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + + static void OnCanceled(object state) + { + var self = (_Publish)state; + self.completionSource.TrySetCanceled(self.cancellationToken); + self.DisposeAsync().Forget(); + } + + public UniTask DisposeAsync() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + cancellationTokenRegistration.Dispose(); + parent.trigger.Remove(this); + } + + return default; + } + + public void OnNext(TSource value) + { + Current = value; + completionSource.TrySetResult(true); + } + + public void OnCanceled(CancellationToken cancellationToken) + { + completionSource.TrySetCanceled(cancellationToken); + } + + public void OnCompleted() + { + completionSource.TrySetResult(false); + } + + public void OnError(Exception ex) + { + completionSource.TrySetException(ex); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Publish.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Publish.cs.meta new file mode 100644 index 0000000..f3a81ba --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Publish.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93c684d1e88c09d4e89b79437d97b810 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Queue.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Queue.cs new file mode 100644 index 0000000..b5c221f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Queue.cs @@ -0,0 +1,103 @@ +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Queue(this IUniTaskAsyncEnumerable source) + { + return new QueueOperator(source); + } + } + + internal sealed class QueueOperator : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + + public QueueOperator(IUniTaskAsyncEnumerable source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Queue(source, cancellationToken); + } + + sealed class _Queue : IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + CancellationToken cancellationToken; + + Channel channel; + IUniTaskAsyncEnumerator channelEnumerator; + IUniTaskAsyncEnumerator sourceEnumerator; + bool channelClosed; + + public _Queue(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + } + + public TSource Current => channelEnumerator.Current; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (sourceEnumerator == null) + { + sourceEnumerator = source.GetAsyncEnumerator(cancellationToken); + channel = Channel.CreateSingleConsumerUnbounded(); + + channelEnumerator = channel.Reader.ReadAllAsync().GetAsyncEnumerator(cancellationToken); + + ConsumeAll(this, sourceEnumerator, channel).Forget(); + } + + return channelEnumerator.MoveNextAsync(); + } + + static async UniTaskVoid ConsumeAll(_Queue self, IUniTaskAsyncEnumerator enumerator, ChannelWriter writer) + { + try + { + while (await enumerator.MoveNextAsync()) + { + writer.TryWrite(enumerator.Current); + } + writer.TryComplete(); + } + catch (Exception ex) + { + writer.TryComplete(ex); + } + finally + { + self.channelClosed = true; + await enumerator.DisposeAsync(); + } + } + + public async UniTask DisposeAsync() + { + if (sourceEnumerator != null) + { + await sourceEnumerator.DisposeAsync(); + } + if (channelEnumerator != null) + { + await channelEnumerator.DisposeAsync(); + } + + if (!channelClosed) + { + channelClosed = true; + channel.Writer.TryComplete(new OperationCanceledException()); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Queue.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Queue.cs.meta new file mode 100644 index 0000000..35f3fab --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Queue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7ea1bcf9dbebb042bc99c7816249e02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Range.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Range.cs new file mode 100644 index 0000000..24a795d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Range.cs @@ -0,0 +1,75 @@ +using Cysharp.Threading.Tasks.Internal; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Range(int start, int count) + { + if (count < 0) throw Error.ArgumentOutOfRange(nameof(count)); + + var end = (long)start + count - 1L; + if (end > int.MaxValue) throw Error.ArgumentOutOfRange(nameof(count)); + + if (count == 0) UniTaskAsyncEnumerable.Empty(); + + return new Cysharp.Threading.Tasks.Linq.Range(start, count); + } + } + + internal class Range : IUniTaskAsyncEnumerable + { + readonly int start; + readonly int end; + + public Range(int start, int count) + { + this.start = start; + this.end = start + count; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Range(start, end, cancellationToken); + } + + class _Range : IUniTaskAsyncEnumerator + { + readonly int start; + readonly int end; + int current; + CancellationToken cancellationToken; + + public _Range(int start, int end, CancellationToken cancellationToken) + { + this.start = start; + this.end = end; + this.cancellationToken = cancellationToken; + + this.current = start - 1; + } + + public int Current => current; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + current++; + + if (current != end) + { + return CompletedTasks.True; + } + + return CompletedTasks.False; + } + + public UniTask DisposeAsync() + { + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Range.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Range.cs.meta new file mode 100644 index 0000000..36272fc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Range.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d826418a813498648b10542d0a5fb173 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Repeat.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Repeat.cs new file mode 100644 index 0000000..db90a1a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Repeat.cs @@ -0,0 +1,68 @@ +using Cysharp.Threading.Tasks.Internal; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Repeat(TElement element, int count) + { + if (count < 0) throw Error.ArgumentOutOfRange(nameof(count)); + + return new Repeat(element, count); + } + } + + internal class Repeat : IUniTaskAsyncEnumerable + { + readonly TElement element; + readonly int count; + + public Repeat(TElement element, int count) + { + this.element = element; + this.count = count; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Repeat(element, count, cancellationToken); + } + + class _Repeat : IUniTaskAsyncEnumerator + { + readonly TElement element; + readonly int count; + int remaining; + CancellationToken cancellationToken; + + public _Repeat(TElement element, int count, CancellationToken cancellationToken) + { + this.element = element; + this.count = count; + this.cancellationToken = cancellationToken; + + this.remaining = count; + } + + public TElement Current => element; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (remaining-- != 0) + { + return CompletedTasks.True; + } + + return CompletedTasks.False; + } + + public UniTask DisposeAsync() + { + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Repeat.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Repeat.cs.meta new file mode 100644 index 0000000..693d579 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Repeat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3819a3925165a674d80ee848c8600379 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Return.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Return.cs new file mode 100644 index 0000000..ba8fa8d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Return.cs @@ -0,0 +1,63 @@ +using Cysharp.Threading.Tasks.Internal; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Return(TValue value) + { + return new Return(value); + } + } + + internal class Return : IUniTaskAsyncEnumerable + { + readonly TValue value; + + public Return(TValue value) + { + this.value = value; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Return(value, cancellationToken); + } + + class _Return : IUniTaskAsyncEnumerator + { + readonly TValue value; + CancellationToken cancellationToken; + + bool called; + + public _Return(TValue value, CancellationToken cancellationToken) + { + this.value = value; + this.cancellationToken = cancellationToken; + this.called = false; + } + + public TValue Current => value; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (!called) + { + called = true; + return CompletedTasks.True; + } + + return CompletedTasks.False; + } + + public UniTask DisposeAsync() + { + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Return.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Return.cs.meta new file mode 100644 index 0000000..ad264d0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Return.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4313cd8ecf705e44f9064ce46e293c2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Reverse.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Reverse.cs new file mode 100644 index 0000000..48d4318 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Reverse.cs @@ -0,0 +1,78 @@ +using Cysharp.Threading.Tasks.Internal; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Reverse(this IUniTaskAsyncEnumerable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + return new Reverse(source); + } + } + + internal sealed class Reverse : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + + public Reverse(IUniTaskAsyncEnumerable source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Reverse(source, cancellationToken); + } + + sealed class _Reverse : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + CancellationToken cancellationToken; + + TSource[] array; + int index; + + public _Reverse(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + // after consumed array, don't use await so allow async(not require UniTaskCompletionSourceCore). + public async UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (array == null) + { + array = await source.ToArrayAsync(cancellationToken); + index = array.Length - 1; + } + + if (index != -1) + { + Current = array[index]; + --index; + return true; + } + else + { + return false; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Reverse.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Reverse.cs.meta new file mode 100644 index 0000000..4a28306 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Reverse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2769e65c729b4f4ca6af9826d9c7b90 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Select.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Select.cs new file mode 100644 index 0000000..50e9cec --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Select.cs @@ -0,0 +1,760 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Select(this IUniTaskAsyncEnumerable source, Func selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new Cysharp.Threading.Tasks.Linq.Select(source, selector); + } + + public static IUniTaskAsyncEnumerable Select(this IUniTaskAsyncEnumerable source, Func selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new Cysharp.Threading.Tasks.Linq.SelectInt(source, selector); + } + + public static IUniTaskAsyncEnumerable SelectAwait(this IUniTaskAsyncEnumerable source, Func> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new Cysharp.Threading.Tasks.Linq.SelectAwait(source, selector); + } + + public static IUniTaskAsyncEnumerable SelectAwait(this IUniTaskAsyncEnumerable source, Func> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new Cysharp.Threading.Tasks.Linq.SelectIntAwait(source, selector); + } + + public static IUniTaskAsyncEnumerable SelectAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new Cysharp.Threading.Tasks.Linq.SelectAwaitWithCancellation(source, selector); + } + + public static IUniTaskAsyncEnumerable SelectAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new Cysharp.Threading.Tasks.Linq.SelectIntAwaitWithCancellation(source, selector); + } + } + + internal sealed class Select : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func selector; + + public Select(IUniTaskAsyncEnumerable source, Func selector) + { + this.source = source; + this.selector = selector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Select(source, selector, cancellationToken); + } + + sealed class _Select : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func selector; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + Action moveNextAction; + + public _Select(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + this.source = source; + this.selector = selector; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + Current = selector(enumerator.Current); + goto CONTINUE; + } + else + { + goto DONE; + } + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class SelectInt : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func selector; + + public SelectInt(IUniTaskAsyncEnumerable source, Func selector) + { + this.source = source; + this.selector = selector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Select(source, selector, cancellationToken); + } + + sealed class _Select : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func selector; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + Action moveNextAction; + int index; + + public _Select(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + this.source = source; + this.selector = selector; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + Current = selector(enumerator.Current, checked(index++)); + goto CONTINUE; + } + else + { + goto DONE; + } + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class SelectAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector; + + public SelectAwait(IUniTaskAsyncEnumerable source, Func> selector) + { + this.source = source; + this.selector = selector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SelectAwait(source, selector, cancellationToken); + } + + sealed class _SelectAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + + public _SelectAwait(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + this.source = source; + this.selector = selector; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + awaiter2 = selector(enumerator.Current).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + Current = awaiter2.GetResult(); + goto CONTINUE; + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class SelectIntAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector; + + public SelectIntAwait(IUniTaskAsyncEnumerable source, Func> selector) + { + this.source = source; + this.selector = selector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SelectAwait(source, selector, cancellationToken); + } + + sealed class _SelectAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + int index; + + public _SelectAwait(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + this.source = source; + this.selector = selector; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + awaiter2 = selector(enumerator.Current, checked(index++)).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + Current = awaiter2.GetResult(); + goto CONTINUE; + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class SelectAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector; + + public SelectAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> selector) + { + this.source = source; + this.selector = selector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SelectAwaitWithCancellation(source, selector, cancellationToken); + } + + sealed class _SelectAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + + public _SelectAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + this.source = source; + this.selector = selector; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + awaiter2 = selector(enumerator.Current, cancellationToken).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + Current = awaiter2.GetResult(); + goto CONTINUE; + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class SelectIntAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector; + + public SelectIntAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> selector) + { + this.source = source; + this.selector = selector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SelectAwaitWithCancellation(source, selector, cancellationToken); + } + + sealed class _SelectAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + int index; + + public _SelectAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + this.source = source; + this.selector = selector; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + awaiter2 = selector(enumerator.Current, checked(index++), cancellationToken).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + Current = awaiter2.GetResult(); + goto CONTINUE; + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Select.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Select.cs.meta new file mode 100644 index 0000000..476e972 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Select.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc68e598ca44a134b988dfaf5e53bfba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SelectMany.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SelectMany.cs new file mode 100644 index 0000000..6cad2a5 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SelectMany.cs @@ -0,0 +1,892 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + + public static IUniTaskAsyncEnumerable SelectMany(this IUniTaskAsyncEnumerable source, Func> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new SelectMany(source, selector, (x, y) => y); + } + + public static IUniTaskAsyncEnumerable SelectMany(this IUniTaskAsyncEnumerable source, Func> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new SelectMany(source, selector, (x, y) => y); + } + + public static IUniTaskAsyncEnumerable SelectMany(this IUniTaskAsyncEnumerable source, Func> collectionSelector, Func resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(collectionSelector, nameof(collectionSelector)); + + return new SelectMany(source, collectionSelector, resultSelector); + } + + public static IUniTaskAsyncEnumerable SelectMany(this IUniTaskAsyncEnumerable source, Func> collectionSelector, Func resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(collectionSelector, nameof(collectionSelector)); + + return new SelectMany(source, collectionSelector, resultSelector); + } + + public static IUniTaskAsyncEnumerable SelectManyAwait(this IUniTaskAsyncEnumerable source, Func>> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new SelectManyAwait(source, selector, (x, y) => UniTask.FromResult(y)); + } + + public static IUniTaskAsyncEnumerable SelectManyAwait(this IUniTaskAsyncEnumerable source, Func>> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new SelectManyAwait(source, selector, (x, y) => UniTask.FromResult(y)); + } + + public static IUniTaskAsyncEnumerable SelectManyAwait(this IUniTaskAsyncEnumerable source, Func>> collectionSelector, Func> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(collectionSelector, nameof(collectionSelector)); + + return new SelectManyAwait(source, collectionSelector, resultSelector); + } + + public static IUniTaskAsyncEnumerable SelectManyAwait(this IUniTaskAsyncEnumerable source, Func>> collectionSelector, Func> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(collectionSelector, nameof(collectionSelector)); + + return new SelectManyAwait(source, collectionSelector, resultSelector); + } + + public static IUniTaskAsyncEnumerable SelectManyAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func>> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new SelectManyAwaitWithCancellation(source, selector, (x, y, c) => UniTask.FromResult(y)); + } + + public static IUniTaskAsyncEnumerable SelectManyAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func>> selector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new SelectManyAwaitWithCancellation(source, selector, (x, y, c) => UniTask.FromResult(y)); + } + + public static IUniTaskAsyncEnumerable SelectManyAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func>> collectionSelector, Func> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(collectionSelector, nameof(collectionSelector)); + + return new SelectManyAwaitWithCancellation(source, collectionSelector, resultSelector); + } + + public static IUniTaskAsyncEnumerable SelectManyAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func>> collectionSelector, Func> resultSelector) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(collectionSelector, nameof(collectionSelector)); + + return new SelectManyAwaitWithCancellation(source, collectionSelector, resultSelector); + } + } + + internal sealed class SelectMany : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> selector1; + readonly Func> selector2; + readonly Func resultSelector; + + public SelectMany(IUniTaskAsyncEnumerable source, Func> selector, Func resultSelector) + { + this.source = source; + this.selector1 = selector; + this.selector2 = null; + this.resultSelector = resultSelector; + } + + public SelectMany(IUniTaskAsyncEnumerable source, Func> selector, Func resultSelector) + { + this.source = source; + this.selector1 = null; + this.selector2 = selector; + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SelectMany(source, selector1, selector2, resultSelector, cancellationToken); + } + + sealed class _SelectMany : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action sourceMoveNextCoreDelegate = SourceMoveNextCore; + static readonly Action selectedSourceMoveNextCoreDelegate = SeletedSourceMoveNextCore; + static readonly Action selectedEnumeratorDisposeAsyncCoreDelegate = SelectedEnumeratorDisposeAsyncCore; + + readonly IUniTaskAsyncEnumerable source; + + readonly Func> selector1; + readonly Func> selector2; + readonly Func resultSelector; + CancellationToken cancellationToken; + + TSource sourceCurrent; + int sourceIndex; + IUniTaskAsyncEnumerator sourceEnumerator; + IUniTaskAsyncEnumerator selectedEnumerator; + UniTask.Awaiter sourceAwaiter; + UniTask.Awaiter selectedAwaiter; + UniTask.Awaiter selectedDisposeAsyncAwaiter; + + public _SelectMany(IUniTaskAsyncEnumerable source, Func> selector1, Func> selector2, Func resultSelector, CancellationToken cancellationToken) + { + this.source = source; + this.selector1 = selector1; + this.selector2 = selector2; + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + completionSource.Reset(); + + // iterate selected field + if (selectedEnumerator != null) + { + MoveNextSelected(); + } + else + { + // iterate source field + if (sourceEnumerator == null) + { + sourceEnumerator = source.GetAsyncEnumerator(cancellationToken); + } + MoveNextSource(); + } + + return new UniTask(this, completionSource.Version); + } + + void MoveNextSource() + { + try + { + sourceAwaiter = sourceEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + if (sourceAwaiter.IsCompleted) + { + SourceMoveNextCore(this); + } + else + { + sourceAwaiter.SourceOnCompleted(sourceMoveNextCoreDelegate, this); + } + } + + void MoveNextSelected() + { + try + { + selectedAwaiter = selectedEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + if (selectedAwaiter.IsCompleted) + { + SeletedSourceMoveNextCore(this); + } + else + { + selectedAwaiter.SourceOnCompleted(selectedSourceMoveNextCoreDelegate, this); + } + } + + static void SourceMoveNextCore(object state) + { + var self = (_SelectMany)state; + + if (self.TryGetResult(self.sourceAwaiter, out var result)) + { + if (result) + { + try + { + self.sourceCurrent = self.sourceEnumerator.Current; + if (self.selector1 != null) + { + self.selectedEnumerator = self.selector1(self.sourceCurrent).GetAsyncEnumerator(self.cancellationToken); + } + else + { + self.selectedEnumerator = self.selector2(self.sourceCurrent, checked(self.sourceIndex++)).GetAsyncEnumerator(self.cancellationToken); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + + self.MoveNextSelected(); // iterated selected source. + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void SeletedSourceMoveNextCore(object state) + { + var self = (_SelectMany)state; + + if (self.TryGetResult(self.selectedAwaiter, out var result)) + { + if (result) + { + try + { + self.Current = self.resultSelector(self.sourceCurrent, self.selectedEnumerator.Current); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + + self.completionSource.TrySetResult(true); + } + else + { + // dispose selected source and try iterate source. + try + { + self.selectedDisposeAsyncAwaiter = self.selectedEnumerator.DisposeAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + if (self.selectedDisposeAsyncAwaiter.IsCompleted) + { + SelectedEnumeratorDisposeAsyncCore(self); + } + else + { + self.selectedDisposeAsyncAwaiter.SourceOnCompleted(selectedEnumeratorDisposeAsyncCoreDelegate, self); + } + } + } + } + + static void SelectedEnumeratorDisposeAsyncCore(object state) + { + var self = (_SelectMany)state; + + if (self.TryGetResult(self.selectedDisposeAsyncAwaiter)) + { + self.selectedEnumerator = null; + self.selectedAwaiter = default; + + self.MoveNextSource(); // iterate next source + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (selectedEnumerator != null) + { + await selectedEnumerator.DisposeAsync(); + } + if (sourceEnumerator != null) + { + await sourceEnumerator.DisposeAsync(); + } + } + } + } + + internal sealed class SelectManyAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func>> selector1; + readonly Func>> selector2; + readonly Func> resultSelector; + + public SelectManyAwait(IUniTaskAsyncEnumerable source, Func>> selector, Func> resultSelector) + { + this.source = source; + this.selector1 = selector; + this.selector2 = null; + this.resultSelector = resultSelector; + } + + public SelectManyAwait(IUniTaskAsyncEnumerable source, Func>> selector, Func> resultSelector) + { + this.source = source; + this.selector1 = null; + this.selector2 = selector; + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SelectManyAwait(source, selector1, selector2, resultSelector, cancellationToken); + } + + sealed class _SelectManyAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action sourceMoveNextCoreDelegate = SourceMoveNextCore; + static readonly Action selectedSourceMoveNextCoreDelegate = SeletedSourceMoveNextCore; + static readonly Action selectedEnumeratorDisposeAsyncCoreDelegate = SelectedEnumeratorDisposeAsyncCore; + static readonly Action selectorAwaitCoreDelegate = SelectorAwaitCore; + static readonly Action resultSelectorAwaitCoreDelegate = ResultSelectorAwaitCore; + + readonly IUniTaskAsyncEnumerable source; + + readonly Func>> selector1; + readonly Func>> selector2; + readonly Func> resultSelector; + CancellationToken cancellationToken; + + TSource sourceCurrent; + int sourceIndex; + IUniTaskAsyncEnumerator sourceEnumerator; + IUniTaskAsyncEnumerator selectedEnumerator; + UniTask.Awaiter sourceAwaiter; + UniTask.Awaiter selectedAwaiter; + UniTask.Awaiter selectedDisposeAsyncAwaiter; + + // await additional + UniTask>.Awaiter collectionSelectorAwaiter; + UniTask.Awaiter resultSelectorAwaiter; + + public _SelectManyAwait(IUniTaskAsyncEnumerable source, Func>> selector1, Func>> selector2, Func> resultSelector, CancellationToken cancellationToken) + { + this.source = source; + this.selector1 = selector1; + this.selector2 = selector2; + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + completionSource.Reset(); + + // iterate selected field + if (selectedEnumerator != null) + { + MoveNextSelected(); + } + else + { + // iterate source field + if (sourceEnumerator == null) + { + sourceEnumerator = source.GetAsyncEnumerator(cancellationToken); + } + MoveNextSource(); + } + + return new UniTask(this, completionSource.Version); + } + + void MoveNextSource() + { + try + { + sourceAwaiter = sourceEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + if (sourceAwaiter.IsCompleted) + { + SourceMoveNextCore(this); + } + else + { + sourceAwaiter.SourceOnCompleted(sourceMoveNextCoreDelegate, this); + } + } + + void MoveNextSelected() + { + try + { + selectedAwaiter = selectedEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + if (selectedAwaiter.IsCompleted) + { + SeletedSourceMoveNextCore(this); + } + else + { + selectedAwaiter.SourceOnCompleted(selectedSourceMoveNextCoreDelegate, this); + } + } + + static void SourceMoveNextCore(object state) + { + var self = (_SelectManyAwait)state; + + if (self.TryGetResult(self.sourceAwaiter, out var result)) + { + if (result) + { + try + { + self.sourceCurrent = self.sourceEnumerator.Current; + + if (self.selector1 != null) + { + self.collectionSelectorAwaiter = self.selector1(self.sourceCurrent).GetAwaiter(); + } + else + { + self.collectionSelectorAwaiter = self.selector2(self.sourceCurrent, checked(self.sourceIndex++)).GetAwaiter(); + } + + if (self.collectionSelectorAwaiter.IsCompleted) + { + SelectorAwaitCore(self); + } + else + { + self.collectionSelectorAwaiter.SourceOnCompleted(selectorAwaitCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void SeletedSourceMoveNextCore(object state) + { + var self = (_SelectManyAwait)state; + + if (self.TryGetResult(self.selectedAwaiter, out var result)) + { + if (result) + { + try + { + self.resultSelectorAwaiter = self.resultSelector(self.sourceCurrent, self.selectedEnumerator.Current).GetAwaiter(); + if (self.resultSelectorAwaiter.IsCompleted) + { + ResultSelectorAwaitCore(self); + } + else + { + self.resultSelectorAwaiter.SourceOnCompleted(resultSelectorAwaitCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + } + else + { + // dispose selected source and try iterate source. + try + { + self.selectedDisposeAsyncAwaiter = self.selectedEnumerator.DisposeAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + if (self.selectedDisposeAsyncAwaiter.IsCompleted) + { + SelectedEnumeratorDisposeAsyncCore(self); + } + else + { + self.selectedDisposeAsyncAwaiter.SourceOnCompleted(selectedEnumeratorDisposeAsyncCoreDelegate, self); + } + } + } + } + + static void SelectedEnumeratorDisposeAsyncCore(object state) + { + var self = (_SelectManyAwait)state; + + if (self.TryGetResult(self.selectedDisposeAsyncAwaiter)) + { + self.selectedEnumerator = null; + self.selectedAwaiter = default; + + self.MoveNextSource(); // iterate next source + } + } + + static void SelectorAwaitCore(object state) + { + var self = (_SelectManyAwait)state; + + if (self.TryGetResult(self.collectionSelectorAwaiter, out var result)) + { + self.selectedEnumerator = result.GetAsyncEnumerator(self.cancellationToken); + self.MoveNextSelected(); // iterated selected source. + } + } + + static void ResultSelectorAwaitCore(object state) + { + var self = (_SelectManyAwait)state; + + if (self.TryGetResult(self.resultSelectorAwaiter, out var result)) + { + self.Current = result; + self.completionSource.TrySetResult(true); + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (selectedEnumerator != null) + { + await selectedEnumerator.DisposeAsync(); + } + if (sourceEnumerator != null) + { + await sourceEnumerator.DisposeAsync(); + } + } + } + } + + internal sealed class SelectManyAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func>> selector1; + readonly Func>> selector2; + readonly Func> resultSelector; + + public SelectManyAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func>> selector, Func> resultSelector) + { + this.source = source; + this.selector1 = selector; + this.selector2 = null; + this.resultSelector = resultSelector; + } + + public SelectManyAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func>> selector, Func> resultSelector) + { + this.source = source; + this.selector1 = null; + this.selector2 = selector; + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SelectManyAwaitWithCancellation(source, selector1, selector2, resultSelector, cancellationToken); + } + + sealed class _SelectManyAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action sourceMoveNextCoreDelegate = SourceMoveNextCore; + static readonly Action selectedSourceMoveNextCoreDelegate = SeletedSourceMoveNextCore; + static readonly Action selectedEnumeratorDisposeAsyncCoreDelegate = SelectedEnumeratorDisposeAsyncCore; + static readonly Action selectorAwaitCoreDelegate = SelectorAwaitCore; + static readonly Action resultSelectorAwaitCoreDelegate = ResultSelectorAwaitCore; + + readonly IUniTaskAsyncEnumerable source; + + readonly Func>> selector1; + readonly Func>> selector2; + readonly Func> resultSelector; + CancellationToken cancellationToken; + + TSource sourceCurrent; + int sourceIndex; + IUniTaskAsyncEnumerator sourceEnumerator; + IUniTaskAsyncEnumerator selectedEnumerator; + UniTask.Awaiter sourceAwaiter; + UniTask.Awaiter selectedAwaiter; + UniTask.Awaiter selectedDisposeAsyncAwaiter; + + // await additional + UniTask>.Awaiter collectionSelectorAwaiter; + UniTask.Awaiter resultSelectorAwaiter; + + public _SelectManyAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func>> selector1, Func>> selector2, Func> resultSelector, CancellationToken cancellationToken) + { + this.source = source; + this.selector1 = selector1; + this.selector2 = selector2; + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + completionSource.Reset(); + + // iterate selected field + if (selectedEnumerator != null) + { + MoveNextSelected(); + } + else + { + // iterate source field + if (sourceEnumerator == null) + { + sourceEnumerator = source.GetAsyncEnumerator(cancellationToken); + } + MoveNextSource(); + } + + return new UniTask(this, completionSource.Version); + } + + void MoveNextSource() + { + try + { + sourceAwaiter = sourceEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + if (sourceAwaiter.IsCompleted) + { + SourceMoveNextCore(this); + } + else + { + sourceAwaiter.SourceOnCompleted(sourceMoveNextCoreDelegate, this); + } + } + + void MoveNextSelected() + { + try + { + selectedAwaiter = selectedEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return; + } + + if (selectedAwaiter.IsCompleted) + { + SeletedSourceMoveNextCore(this); + } + else + { + selectedAwaiter.SourceOnCompleted(selectedSourceMoveNextCoreDelegate, this); + } + } + + static void SourceMoveNextCore(object state) + { + var self = (_SelectManyAwaitWithCancellation)state; + + if (self.TryGetResult(self.sourceAwaiter, out var result)) + { + if (result) + { + try + { + self.sourceCurrent = self.sourceEnumerator.Current; + + if (self.selector1 != null) + { + self.collectionSelectorAwaiter = self.selector1(self.sourceCurrent, self.cancellationToken).GetAwaiter(); + } + else + { + self.collectionSelectorAwaiter = self.selector2(self.sourceCurrent, checked(self.sourceIndex++), self.cancellationToken).GetAwaiter(); + } + + if (self.collectionSelectorAwaiter.IsCompleted) + { + SelectorAwaitCore(self); + } + else + { + self.collectionSelectorAwaiter.SourceOnCompleted(selectorAwaitCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void SeletedSourceMoveNextCore(object state) + { + var self = (_SelectManyAwaitWithCancellation)state; + + if (self.TryGetResult(self.selectedAwaiter, out var result)) + { + if (result) + { + try + { + self.resultSelectorAwaiter = self.resultSelector(self.sourceCurrent, self.selectedEnumerator.Current, self.cancellationToken).GetAwaiter(); + if (self.resultSelectorAwaiter.IsCompleted) + { + ResultSelectorAwaitCore(self); + } + else + { + self.resultSelectorAwaiter.SourceOnCompleted(resultSelectorAwaitCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + } + else + { + // dispose selected source and try iterate source. + try + { + self.selectedDisposeAsyncAwaiter = self.selectedEnumerator.DisposeAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + if (self.selectedDisposeAsyncAwaiter.IsCompleted) + { + SelectedEnumeratorDisposeAsyncCore(self); + } + else + { + self.selectedDisposeAsyncAwaiter.SourceOnCompleted(selectedEnumeratorDisposeAsyncCoreDelegate, self); + } + } + } + } + + static void SelectedEnumeratorDisposeAsyncCore(object state) + { + var self = (_SelectManyAwaitWithCancellation)state; + + if (self.TryGetResult(self.selectedDisposeAsyncAwaiter)) + { + self.selectedEnumerator = null; + self.selectedAwaiter = default; + + self.MoveNextSource(); // iterate next source + } + } + + static void SelectorAwaitCore(object state) + { + var self = (_SelectManyAwaitWithCancellation)state; + + if (self.TryGetResult(self.collectionSelectorAwaiter, out var result)) + { + self.selectedEnumerator = result.GetAsyncEnumerator(self.cancellationToken); + self.MoveNextSelected(); // iterated selected source. + } + } + + static void ResultSelectorAwaitCore(object state) + { + var self = (_SelectManyAwaitWithCancellation)state; + + if (self.TryGetResult(self.resultSelectorAwaiter, out var result)) + { + self.Current = result; + self.completionSource.TrySetResult(true); + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (selectedEnumerator != null) + { + await selectedEnumerator.DisposeAsync(); + } + if (sourceEnumerator != null) + { + await sourceEnumerator.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SelectMany.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SelectMany.cs.meta new file mode 100644 index 0000000..a8dbbaf --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SelectMany.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d81862f0eb12680479ccaaf2ac319d24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SequenceEqual.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SequenceEqual.cs new file mode 100644 index 0000000..9512ea7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SequenceEqual.cs @@ -0,0 +1,87 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask SequenceEqualAsync(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, CancellationToken cancellationToken = default) + { + return SequenceEqualAsync(first, second, EqualityComparer.Default, cancellationToken); + } + + public static UniTask SequenceEqualAsync(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return SequenceEqual.SequenceEqualAsync(first, second, comparer, cancellationToken); + } + } + + internal static class SequenceEqual + { + internal static async UniTask SequenceEqualAsync(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var e1 = first.GetAsyncEnumerator(cancellationToken); + try + { + var e2 = second.GetAsyncEnumerator(cancellationToken); + try + { + while (true) + { + if (await e1.MoveNextAsync()) + { + if (await e2.MoveNextAsync()) + { + if (comparer.Equals(e1.Current, e2.Current)) + { + continue; + } + else + { + return false; + } + } + else + { + // e2 is finished, but e1 has value + return false; + } + } + else + { + // e1 is finished, e2? + if (await e2.MoveNextAsync()) + { + return false; + } + else + { + return true; + } + } + } + } + finally + { + if (e2 != null) + { + await e2.DisposeAsync(); + } + } + } + finally + { + if (e1 != null) + { + await e1.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SequenceEqual.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SequenceEqual.cs.meta new file mode 100644 index 0000000..ee2b75c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SequenceEqual.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b382772aba6128842928cdb6b2e034b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Single.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Single.cs new file mode 100644 index 0000000..30df1b3 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Single.cs @@ -0,0 +1,230 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask SingleAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return SingleOperator.SingleAsync(source, cancellationToken, false); + } + + public static UniTask SingleAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return SingleOperator.SingleAsync(source, predicate, cancellationToken, false); + } + + public static UniTask SingleAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return SingleOperator.SingleAwaitAsync(source, predicate, cancellationToken, false); + } + + public static UniTask SingleAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return SingleOperator.SingleAwaitWithCancellationAsync(source, predicate, cancellationToken, false); + } + + public static UniTask SingleOrDefaultAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return SingleOperator.SingleAsync(source, cancellationToken, true); + } + + public static UniTask SingleOrDefaultAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return SingleOperator.SingleAsync(source, predicate, cancellationToken, true); + } + + public static UniTask SingleOrDefaultAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return SingleOperator.SingleAwaitAsync(source, predicate, cancellationToken, true); + } + + public static UniTask SingleOrDefaultAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return SingleOperator.SingleAwaitWithCancellationAsync(source, predicate, cancellationToken, true); + } + } + + internal static class SingleOperator + { + public static async UniTask SingleAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + if (await e.MoveNextAsync()) + { + var v = e.Current; + if (!await e.MoveNextAsync()) + { + return v; + } + + throw Error.MoreThanOneElement(); + } + else + { + if (defaultIfEmpty) + { + return default; + } + else + { + throw Error.NoElements(); + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask SingleAsync(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value = default; + bool found = false; + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (predicate(v)) + { + if (found) + { + throw Error.MoreThanOneElement(); + } + else + { + found = true; + value = v; + } + } + } + + if (found || defaultIfEmpty) + { + return value; + } + + throw Error.NoElements(); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask SingleAwaitAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value = default; + bool found = false; + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (await predicate(v)) + { + if (found) + { + throw Error.MoreThanOneElement(); + } + else + { + found = true; + value = v; + } + } + } + + if (found || defaultIfEmpty) + { + return value; + } + + throw Error.NoElements(); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTask SingleAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken, bool defaultIfEmpty) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + TSource value = default; + bool found = false; + while (await e.MoveNextAsync()) + { + var v = e.Current; + if (await predicate(v, cancellationToken)) + { + if (found) + { + throw Error.MoreThanOneElement(); + } + else + { + found = true; + value = v; + } + } + } + + if (found || defaultIfEmpty) + { + return value; + } + + throw Error.NoElements(); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Single.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Single.cs.meta new file mode 100644 index 0000000..c053dfd --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Single.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1bcd3928b90472e43a3a92c3ba708967 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Skip.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Skip.cs new file mode 100644 index 0000000..6f4831d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Skip.cs @@ -0,0 +1,69 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Skip(this IUniTaskAsyncEnumerable source, Int32 count) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new Skip(source, count); + } + } + + internal sealed class Skip : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly int count; + + public Skip(IUniTaskAsyncEnumerable source, int count) + { + this.source = source; + this.count = count; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Skip(source, count, cancellationToken); + } + + sealed class _Skip : AsyncEnumeratorBase + { + readonly int count; + + int index; + + public _Skip(IUniTaskAsyncEnumerable source, int count, CancellationToken cancellationToken) + : base(source, cancellationToken) + { + this.count = count; + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + if (count <= checked(index++)) + { + Current = SourceCurrent; + result = true; + return true; + } + else + { + result = default; + return false; + } + } + else + { + result = false; + return true; + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Skip.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Skip.cs.meta new file mode 100644 index 0000000..25ad847 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Skip.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c46b6c7dce0cb049a73c81084c75154 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipLast.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipLast.cs new file mode 100644 index 0000000..9d127b8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipLast.cs @@ -0,0 +1,159 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable SkipLast(this IUniTaskAsyncEnumerable source, Int32 count) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + // non skip. + if (count <= 0) + { + return source; + } + + return new SkipLast(source, count); + } + } + + internal sealed class SkipLast : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly int count; + + public SkipLast(IUniTaskAsyncEnumerable source, int count) + { + this.source = source; + this.count = count; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SkipLast(source, count, cancellationToken); + } + + sealed class _SkipLast : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + readonly int count; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + Queue queue; + + bool continueNext; + + public _SkipLast(IUniTaskAsyncEnumerable source, int count, CancellationToken cancellationToken) + { + this.source = source; + this.count = count; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + queue = new Queue(); + } + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + try + { + + LOOP: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; // avoid recursive + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + + static void MoveNextCore(object state) + { + var self = (_SkipLast)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + if (self.queue.Count == self.count) + { + self.continueNext = false; + + var deq = self.queue.Dequeue(); + self.Current = deq; + self.queue.Enqueue(self.enumerator.Current); + + self.completionSource.TrySetResult(true); + } + else + { + self.queue.Enqueue(self.enumerator.Current); + + if (!self.continueNext) + { + self.SourceMoveNext(); + } + } + } + else + { + self.continueNext = false; + self.completionSource.TrySetResult(false); + } + } + else + { + self.continueNext = false; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipLast.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipLast.cs.meta new file mode 100644 index 0000000..06b1ede --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipLast.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df1d7f44d4fe7754f972c9e0b6fa72d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntil.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntil.cs new file mode 100644 index 0000000..5a707bb --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntil.cs @@ -0,0 +1,187 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable SkipUntil(this IUniTaskAsyncEnumerable source, UniTask other) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new SkipUntil(source, other, null); + } + + public static IUniTaskAsyncEnumerable SkipUntil(this IUniTaskAsyncEnumerable source, Func other) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(other)); + + return new SkipUntil(source, default, other); + } + } + + internal sealed class SkipUntil : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly UniTask other; + readonly Func other2; + + public SkipUntil(IUniTaskAsyncEnumerable source, UniTask other, Func other2) + { + this.source = source; + this.other = other; + this.other2 = other2; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + if (other2 != null) + { + return new _SkipUntil(source, this.other2(cancellationToken), cancellationToken); + } + else + { + return new _SkipUntil(source, this.other, cancellationToken); + } + } + + sealed class _SkipUntil : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action CancelDelegate1 = OnCanceled1; + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + CancellationToken cancellationToken1; + + bool completed; + CancellationTokenRegistration cancellationTokenRegistration1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + bool continueNext; + Exception exception; + + public _SkipUntil(IUniTaskAsyncEnumerable source, UniTask other, CancellationToken cancellationToken1) + { + this.source = source; + this.cancellationToken1 = cancellationToken1; + if (cancellationToken1.CanBeCanceled) + { + this.cancellationTokenRegistration1 = cancellationToken1.RegisterWithoutCaptureExecutionContext(CancelDelegate1, this); + } + + TaskTracker.TrackActiveTask(this, 3); + RunOther(other).Forget(); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (exception != null) + { + return UniTask.FromException(exception); + } + + if (cancellationToken1.IsCancellationRequested) + { + return UniTask.FromCanceled(cancellationToken1); + } + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken1); + } + completionSource.Reset(); + + if (completed) + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + try + { + LOOP: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_SkipUntil)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.Current = self.enumerator.Current; + self.completionSource.TrySetResult(true); + if (self.continueNext) + { + self.SourceMoveNext(); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + async UniTaskVoid RunOther(UniTask other) + { + try + { + await other; + completed = true; + SourceMoveNext(); + } + catch (Exception ex) + { + exception = ex; + completionSource.TrySetException(ex); + } + } + + static void OnCanceled1(object state) + { + var self = (_SkipUntil)state; + self.completionSource.TrySetCanceled(self.cancellationToken1); + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + cancellationTokenRegistration1.Dispose(); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntil.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntil.cs.meta new file mode 100644 index 0000000..0772ed0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de932d79c8d9f3841a066d05ff29edc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntilCanceled.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntilCanceled.cs new file mode 100644 index 0000000..f4c9679 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntilCanceled.cs @@ -0,0 +1,173 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable SkipUntilCanceled(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new SkipUntilCanceled(source, cancellationToken); + } + } + + internal sealed class SkipUntilCanceled : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly CancellationToken cancellationToken; + + public SkipUntilCanceled(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SkipUntilCanceled(source, this.cancellationToken, cancellationToken); + } + + sealed class _SkipUntilCanceled : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action CancelDelegate1 = OnCanceled1; + static readonly Action CancelDelegate2 = OnCanceled2; + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + CancellationToken cancellationToken1; + CancellationToken cancellationToken2; + CancellationTokenRegistration cancellationTokenRegistration1; + CancellationTokenRegistration cancellationTokenRegistration2; + + int isCanceled; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + bool continueNext; + + public _SkipUntilCanceled(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken1, CancellationToken cancellationToken2) + { + this.source = source; + this.cancellationToken1 = cancellationToken1; + this.cancellationToken2 = cancellationToken2; + if (cancellationToken1.CanBeCanceled) + { + this.cancellationTokenRegistration1 = cancellationToken1.RegisterWithoutCaptureExecutionContext(CancelDelegate1, this); + } + if (cancellationToken1 != cancellationToken2 && cancellationToken2.CanBeCanceled) + { + this.cancellationTokenRegistration2 = cancellationToken2.RegisterWithoutCaptureExecutionContext(CancelDelegate2, this); + } + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (enumerator == null) + { + if (cancellationToken1.IsCancellationRequested) isCanceled = 1; + if (cancellationToken2.IsCancellationRequested) isCanceled = 1; + enumerator = source.GetAsyncEnumerator(cancellationToken2); // use only AsyncEnumerator provided token. + } + completionSource.Reset(); + + if (isCanceled != 0) + { + SourceMoveNext(); + } + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + try + { + LOOP: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_SkipUntilCanceled)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.Current = self.enumerator.Current; + self.completionSource.TrySetResult(true); + if (self.continueNext) + { + self.SourceMoveNext(); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void OnCanceled1(object state) + { + var self = (_SkipUntilCanceled)state; + if (self.isCanceled == 0) + { + if (Interlocked.Increment(ref self.isCanceled) == 1) + { + self.cancellationTokenRegistration2.Dispose(); + self.SourceMoveNext(); + } + } + } + + static void OnCanceled2(object state) + { + var self = (_SkipUntilCanceled)state; + if (self.isCanceled == 0) + { + if (Interlocked.Increment(ref self.isCanceled) == 1) + { + self.cancellationTokenRegistration2.Dispose(); + self.SourceMoveNext(); + } + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + cancellationTokenRegistration1.Dispose(); + cancellationTokenRegistration2.Dispose(); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntilCanceled.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntilCanceled.cs.meta new file mode 100644 index 0000000..9f67181 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipUntilCanceled.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b1a778aef7150d47b93a49aa1bc34ae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipWhile.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipWhile.cs new file mode 100644 index 0000000..771a2e2 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipWhile.cs @@ -0,0 +1,379 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable SkipWhile(this IUniTaskAsyncEnumerable source, Func predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new SkipWhile(source, predicate); + } + + public static IUniTaskAsyncEnumerable SkipWhile(this IUniTaskAsyncEnumerable source, Func predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new SkipWhileInt(source, predicate); + } + + public static IUniTaskAsyncEnumerable SkipWhileAwait(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new SkipWhileAwait(source, predicate); + } + + public static IUniTaskAsyncEnumerable SkipWhileAwait(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new SkipWhileIntAwait(source, predicate); + } + + public static IUniTaskAsyncEnumerable SkipWhileAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new SkipWhileAwaitWithCancellation(source, predicate); + } + + public static IUniTaskAsyncEnumerable SkipWhileAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new SkipWhileIntAwaitWithCancellation(source, predicate); + } + } + + internal sealed class SkipWhile : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func predicate; + + public SkipWhile(IUniTaskAsyncEnumerable source, Func predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SkipWhile(source, predicate, cancellationToken); + } + + class _SkipWhile : AsyncEnumeratorBase + { + Func predicate; + + public _SkipWhile(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + if (predicate == null || !predicate(SourceCurrent)) + { + predicate = null; + Current = SourceCurrent; + result = true; + return true; + } + else + { + result = default; + return false; + } + } + + result = false; + return true; + } + } + } + + internal sealed class SkipWhileInt : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func predicate; + + public SkipWhileInt(IUniTaskAsyncEnumerable source, Func predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SkipWhileInt(source, predicate, cancellationToken); + } + + class _SkipWhileInt : AsyncEnumeratorBase + { + Func predicate; + int index; + + public _SkipWhileInt(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + if (predicate == null || !predicate(SourceCurrent, checked(index++))) + { + predicate = null; + Current = SourceCurrent; + result = true; + return true; + } + else + { + result = default; + return false; + } + } + + result = false; + return true; + } + } + } + + internal sealed class SkipWhileAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public SkipWhileAwait(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SkipWhileAwait(source, predicate, cancellationToken); + } + + class _SkipWhileAwait : AsyncEnumeratorAwaitSelectorBase + { + Func> predicate; + + public _SkipWhileAwait(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + if (predicate == null) + { + return CompletedTasks.False; + } + + return predicate(sourceCurrent); + } + + protected override bool TrySetCurrentCore(bool awaitResult, out bool terminateIteration) + { + if (!awaitResult) + { + predicate = null; + Current = SourceCurrent; + terminateIteration= false; + return true; + } + else + { + terminateIteration= false; + return false; + } + } + } + } + + internal sealed class SkipWhileIntAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public SkipWhileIntAwait(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SkipWhileIntAwait(source, predicate, cancellationToken); + } + + class _SkipWhileIntAwait : AsyncEnumeratorAwaitSelectorBase + { + Func> predicate; + int index; + + public _SkipWhileIntAwait(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + if (predicate == null) + { + return CompletedTasks.False; + } + + return predicate(sourceCurrent, checked(index++)); + } + + protected override bool TrySetCurrentCore(bool awaitResult, out bool terminateIteration) + { + terminateIteration= false; + if (!awaitResult) + { + predicate = null; + Current = SourceCurrent; + return true; + } + else + { + return false; + } + } + } + } + + internal sealed class SkipWhileAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public SkipWhileAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SkipWhileAwaitWithCancellation(source, predicate, cancellationToken); + } + + class _SkipWhileAwaitWithCancellation : AsyncEnumeratorAwaitSelectorBase + { + Func> predicate; + + public _SkipWhileAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + if (predicate == null) + { + return CompletedTasks.False; + } + + return predicate(sourceCurrent, cancellationToken); + } + + protected override bool TrySetCurrentCore(bool awaitResult, out bool terminateIteration) + { + terminateIteration= false; + if (!awaitResult) + { + predicate = null; + Current = SourceCurrent; + return true; + } + else + { + return false; + } + } + } + } + + internal sealed class SkipWhileIntAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public SkipWhileIntAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _SkipWhileIntAwaitWithCancellation(source, predicate, cancellationToken); + } + + class _SkipWhileIntAwaitWithCancellation : AsyncEnumeratorAwaitSelectorBase + { + Func> predicate; + int index; + + public _SkipWhileIntAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + if (predicate == null) + { + return CompletedTasks.False; + } + + return predicate(sourceCurrent, checked(index++), cancellationToken); + } + + protected override bool TrySetCurrentCore(bool awaitResult, out bool terminateIteration) + { + terminateIteration= false; + if (!awaitResult) + { + predicate = null; + Current = SourceCurrent; + return true; + } + else + { + return false; + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipWhile.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipWhile.cs.meta new file mode 100644 index 0000000..f2b210a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/SkipWhile.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b74b9fe361bf7148b51a29c8b2561e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Subscribe.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Subscribe.cs new file mode 100644 index 0000000..0785bc2 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Subscribe.cs @@ -0,0 +1,536 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; +using Subscribes = Cysharp.Threading.Tasks.Linq.Subscribe; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + // OnNext + + public static IDisposable Subscribe(this IUniTaskAsyncEnumerable source, Action action) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeCore(source, action, Subscribes.NopError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static IDisposable Subscribe(this IUniTaskAsyncEnumerable source, Func action) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeCore(source, action, Subscribes.NopError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static IDisposable Subscribe(this IUniTaskAsyncEnumerable source, Func action) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeCore(source, action, Subscribes.NopError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static void Subscribe(this IUniTaskAsyncEnumerable source, Action action, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + Subscribes.SubscribeCore(source, action, Subscribes.NopError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + public static void Subscribe(this IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + Subscribes.SubscribeCore(source, action, Subscribes.NopError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + public static void Subscribe(this IUniTaskAsyncEnumerable source, Func action, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(action, nameof(action)); + + Subscribes.SubscribeCore(source, action, Subscribes.NopError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + public static IDisposable SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeAwaitCore(source, onNext, Subscribes.NopError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static void SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + + Subscribes.SubscribeAwaitCore(source, onNext, Subscribes.NopError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + public static IDisposable SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeAwaitCore(source, onNext, Subscribes.NopError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static void SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + + Subscribes.SubscribeAwaitCore(source, onNext, Subscribes.NopError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + // OnNext, OnError + + public static IDisposable Subscribe(this IUniTaskAsyncEnumerable source, Action onNext, Action onError) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onError, nameof(onError)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeCore(source, onNext, onError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static IDisposable Subscribe(this IUniTaskAsyncEnumerable source, Func onNext, Action onError) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onError, nameof(onError)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeCore(source, onNext, onError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static void Subscribe(this IUniTaskAsyncEnumerable source, Action onNext, Action onError, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onError, nameof(onError)); + + Subscribes.SubscribeCore(source, onNext, onError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + public static void Subscribe(this IUniTaskAsyncEnumerable source, Func onNext, Action onError, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onError, nameof(onError)); + + Subscribes.SubscribeCore(source, onNext, onError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + public static IDisposable SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, Action onError) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onError, nameof(onError)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeAwaitCore(source, onNext, onError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static void SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, Action onError, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onError, nameof(onError)); + + Subscribes.SubscribeAwaitCore(source, onNext, onError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + public static IDisposable SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, Action onError) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onError, nameof(onError)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeAwaitCore(source, onNext, onError, Subscribes.NopCompleted, cts.Token).Forget(); + return cts; + } + + public static void SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, Action onError, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onError, nameof(onError)); + + Subscribes.SubscribeAwaitCore(source, onNext, onError, Subscribes.NopCompleted, cancellationToken).Forget(); + } + + // OnNext, OnCompleted + + public static IDisposable Subscribe(this IUniTaskAsyncEnumerable source, Action onNext, Action onCompleted) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onCompleted, nameof(onCompleted)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeCore(source, onNext, Subscribes.NopError, onCompleted, cts.Token).Forget(); + return cts; + } + + public static IDisposable Subscribe(this IUniTaskAsyncEnumerable source, Func onNext, Action onCompleted) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onCompleted, nameof(onCompleted)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeCore(source, onNext, Subscribes.NopError, onCompleted, cts.Token).Forget(); + return cts; + } + + public static void Subscribe(this IUniTaskAsyncEnumerable source, Action onNext, Action onCompleted, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onCompleted, nameof(onCompleted)); + + Subscribes.SubscribeCore(source, onNext, Subscribes.NopError, onCompleted, cancellationToken).Forget(); + } + + public static void Subscribe(this IUniTaskAsyncEnumerable source, Func onNext, Action onCompleted, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onCompleted, nameof(onCompleted)); + + Subscribes.SubscribeCore(source, onNext, Subscribes.NopError, onCompleted, cancellationToken).Forget(); + } + + public static IDisposable SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, Action onCompleted) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onCompleted, nameof(onCompleted)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeAwaitCore(source, onNext, Subscribes.NopError, onCompleted, cts.Token).Forget(); + return cts; + } + + public static void SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, Action onCompleted, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onCompleted, nameof(onCompleted)); + + Subscribes.SubscribeAwaitCore(source, onNext, Subscribes.NopError, onCompleted, cancellationToken).Forget(); + } + + public static IDisposable SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, Action onCompleted) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onCompleted, nameof(onCompleted)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeAwaitCore(source, onNext, Subscribes.NopError, onCompleted, cts.Token).Forget(); + return cts; + } + + public static void SubscribeAwait(this IUniTaskAsyncEnumerable source, Func onNext, Action onCompleted, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(onNext, nameof(onNext)); + Error.ThrowArgumentNullException(onCompleted, nameof(onCompleted)); + + Subscribes.SubscribeAwaitCore(source, onNext, Subscribes.NopError, onCompleted, cancellationToken).Forget(); + } + + // IObserver + + public static IDisposable Subscribe(this IUniTaskAsyncEnumerable source, IObserver observer) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(observer, nameof(observer)); + + var cts = new CancellationTokenDisposable(); + Subscribes.SubscribeCore(source, observer, cts.Token).Forget(); + return cts; + } + + public static void Subscribe(this IUniTaskAsyncEnumerable source, IObserver observer, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(observer, nameof(observer)); + + Subscribes.SubscribeCore(source, observer, cancellationToken).Forget(); + } + } + + internal sealed class CancellationTokenDisposable : IDisposable + { + readonly CancellationTokenSource cts = new CancellationTokenSource(); + + public CancellationToken Token => cts.Token; + + public void Dispose() + { + if (!cts.IsCancellationRequested) + { + cts.Cancel(); + } + } + } + + internal static class Subscribe + { + public static readonly Action NopError = _ => { }; + public static readonly Action NopCompleted = () => { }; + + public static async UniTaskVoid SubscribeCore(IUniTaskAsyncEnumerable source, Action onNext, Action onError, Action onCompleted, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + try + { + onNext(e.Current); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + onCompleted(); + } + catch (Exception ex) + { + if (onError == NopError) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + return; + } + + if (ex is OperationCanceledException) return; + + onError(ex); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTaskVoid SubscribeCore(IUniTaskAsyncEnumerable source, Func onNext, Action onError, Action onCompleted, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + try + { + onNext(e.Current).Forget(); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + onCompleted(); + } + catch (Exception ex) + { + if (onError == NopError) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + return; + } + + if (ex is OperationCanceledException) return; + + onError(ex); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTaskVoid SubscribeCore(IUniTaskAsyncEnumerable source, Func onNext, Action onError, Action onCompleted, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + try + { + onNext(e.Current, cancellationToken).Forget(); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + onCompleted(); + } + catch (Exception ex) + { + if (onError == NopError) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + return; + } + + if (ex is OperationCanceledException) return; + + onError(ex); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTaskVoid SubscribeCore(IUniTaskAsyncEnumerable source, IObserver observer, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + try + { + observer.OnNext(e.Current); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + observer.OnCompleted(); + } + catch (Exception ex) + { + if (ex is OperationCanceledException) return; + + observer.OnError(ex); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTaskVoid SubscribeAwaitCore(IUniTaskAsyncEnumerable source, Func onNext, Action onError, Action onCompleted, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + try + { + await onNext(e.Current); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + onCompleted(); + } + catch (Exception ex) + { + if (onError == NopError) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + return; + } + + if (ex is OperationCanceledException) return; + + onError(ex); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + public static async UniTaskVoid SubscribeAwaitCore(IUniTaskAsyncEnumerable source, Func onNext, Action onError, Action onCompleted, CancellationToken cancellationToken) + { + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + try + { + await onNext(e.Current, cancellationToken); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + onCompleted(); + } + catch (Exception ex) + { + if (onError == NopError) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + return; + } + + if (ex is OperationCanceledException) return; + + onError(ex); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Subscribe.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Subscribe.cs.meta new file mode 100644 index 0000000..ea83567 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Subscribe.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 263479eb04c189741931fc0e2f615c2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Sum.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Sum.cs new file mode 100644 index 0000000..1101cd7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Sum.cs @@ -0,0 +1,1244 @@ +using System; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Sum.SumAsync(source, cancellationToken); + } + + public static UniTask SumAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitAsync(source, selector, cancellationToken); + } + + public static UniTask SumAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken); + } + + } + + internal static class Sum + { + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int32 sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current; + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int32 sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32 sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32 sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int64 sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current; + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int64 sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64 sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64 sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Single sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current; + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Single sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Double sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current; + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Double sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Decimal sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current; + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Decimal sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int32? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current.GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int32? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int32? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Int64? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current.GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Int64? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Int64? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Single? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current.GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Single? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Single? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Double? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current.GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Double? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Double? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Decimal? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += e.Current.GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + Decimal? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += selector(e.Current).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + public static async UniTask SumAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + Decimal? sum = default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + sum += (await selector(e.Current, cancellationToken)).GetValueOrDefault(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return sum; + } + + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Sum.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Sum.cs.meta new file mode 100644 index 0000000..5331e34 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Sum.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4149754066a21a341be58c04357061f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Take.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Take.cs new file mode 100644 index 0000000..6cd4eda --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Take.cs @@ -0,0 +1,124 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Take(this IUniTaskAsyncEnumerable source, Int32 count) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new Take(source, count); + } + } + + internal sealed class Take : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly int count; + + public Take(IUniTaskAsyncEnumerable source, int count) + { + this.source = source; + this.count = count; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Take(source, count, cancellationToken); + } + + sealed class _Take : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + readonly int count; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + int index; + + public _Take(IUniTaskAsyncEnumerable source, int count, CancellationToken cancellationToken) + { + this.source = source; + this.count = count; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + } + + if (checked(index) >= count) + { + return CompletedTasks.False; + } + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + try + { + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_Take)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + self.index++; + self.Current = self.enumerator.Current; + self.completionSource.TrySetResult(true); + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Take.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Take.cs.meta new file mode 100644 index 0000000..1cc91ab --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Take.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 42f02cb84e5875b488304755d0e1383d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeLast.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeLast.cs new file mode 100644 index 0000000..ca0084e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeLast.cs @@ -0,0 +1,175 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable TakeLast(this IUniTaskAsyncEnumerable source, Int32 count) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + // non take. + if (count <= 0) + { + return Empty(); + } + + return new TakeLast(source, count); + } + } + + internal sealed class TakeLast : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly int count; + + public TakeLast(IUniTaskAsyncEnumerable source, int count) + { + this.source = source; + this.count = count; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TakeLast(source, count, cancellationToken); + } + + sealed class _TakeLast : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + readonly int count; + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + Queue queue; + + bool iterateCompleted; + bool continueNext; + + public _TakeLast(IUniTaskAsyncEnumerable source, int count, CancellationToken cancellationToken) + { + this.source = source; + this.count = count; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken); + queue = new Queue(); + } + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + if (iterateCompleted) + { + if (queue.Count > 0) + { + Current = queue.Dequeue(); + completionSource.TrySetResult(true); + } + else + { + completionSource.TrySetResult(false); + } + + return; + } + + try + { + LOOP: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + continueNext = true; + MoveNextCore(this); + if (continueNext) + { + continueNext = false; + goto LOOP; // avoid recursive + } + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + + static void MoveNextCore(object state) + { + var self = (_TakeLast)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + if (self.queue.Count < self.count) + { + self.queue.Enqueue(self.enumerator.Current); + + if (!self.continueNext) + { + self.SourceMoveNext(); + } + } + else + { + self.queue.Dequeue(); + self.queue.Enqueue(self.enumerator.Current); + + if (!self.continueNext) + { + self.SourceMoveNext(); + } + } + } + else + { + self.continueNext = false; + self.iterateCompleted = true; + self.SourceMoveNext(); + } + } + else + { + self.continueNext = false; + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeLast.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeLast.cs.meta new file mode 100644 index 0000000..d80037f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeLast.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 510aa9fd35b45fc40bcdb7e59f01fd1b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntil.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntil.cs new file mode 100644 index 0000000..25371ad --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntil.cs @@ -0,0 +1,190 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable TakeUntil(this IUniTaskAsyncEnumerable source, UniTask other) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new TakeUntil(source, other, null); + } + + public static IUniTaskAsyncEnumerable TakeUntil(this IUniTaskAsyncEnumerable source, Func other) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(other)); + + return new TakeUntil(source, default, other); + } + } + + internal sealed class TakeUntil : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly UniTask other; + readonly Func other2; + + public TakeUntil(IUniTaskAsyncEnumerable source, UniTask other, Func other2) + { + this.source = source; + this.other = other; + this.other2 = other2; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + if (other2 != null) + { + return new _TakeUntil(source, this.other2(cancellationToken), cancellationToken); + } + else + { + return new _TakeUntil(source, this.other, cancellationToken); + } + } + + sealed class _TakeUntil : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action CancelDelegate1 = OnCanceled1; + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + CancellationToken cancellationToken1; + CancellationTokenRegistration cancellationTokenRegistration1; + + bool completed; + Exception exception; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + + public _TakeUntil(IUniTaskAsyncEnumerable source, UniTask other, CancellationToken cancellationToken1) + { + this.source = source; + this.cancellationToken1 = cancellationToken1; + + if (cancellationToken1.CanBeCanceled) + { + this.cancellationTokenRegistration1 = cancellationToken1.RegisterWithoutCaptureExecutionContext(CancelDelegate1, this); + } + + TaskTracker.TrackActiveTask(this, 3); + + RunOther(other).Forget(); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (completed) + { + return CompletedTasks.False; + } + + if (exception != null) + { + return UniTask.FromException(exception); + } + + if (cancellationToken1.IsCancellationRequested) + { + return UniTask.FromCanceled(cancellationToken1); + } + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken1); + } + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + try + { + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_TakeUntil)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + if (self.exception != null) + { + self.completionSource.TrySetException(self.exception); + } + else if (self.cancellationToken1.IsCancellationRequested) + { + self.completionSource.TrySetCanceled(self.cancellationToken1); + } + else + { + self.Current = self.enumerator.Current; + self.completionSource.TrySetResult(true); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + async UniTaskVoid RunOther(UniTask other) + { + try + { + await other; + completed = true; + completionSource.TrySetResult(false); + } + catch (Exception ex) + { + exception = ex; + completionSource.TrySetException(ex); + } + } + + static void OnCanceled1(object state) + { + var self = (_TakeUntil)state; + self.completionSource.TrySetCanceled(self.cancellationToken1); + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + cancellationTokenRegistration1.Dispose(); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntil.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntil.cs.meta new file mode 100644 index 0000000..44cf63e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 12bda324162f15349afefc2c152ac07f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntilCanceled.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntilCanceled.cs new file mode 100644 index 0000000..67ee3c8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntilCanceled.cs @@ -0,0 +1,164 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable TakeUntilCanceled(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new TakeUntilCanceled(source, cancellationToken); + } + } + + internal sealed class TakeUntilCanceled : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly CancellationToken cancellationToken; + + public TakeUntilCanceled(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TakeUntilCanceled(source, this.cancellationToken, cancellationToken); + } + + sealed class _TakeUntilCanceled : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action CancelDelegate1 = OnCanceled1; + static readonly Action CancelDelegate2 = OnCanceled2; + static readonly Action MoveNextCoreDelegate = MoveNextCore; + + readonly IUniTaskAsyncEnumerable source; + CancellationToken cancellationToken1; + CancellationToken cancellationToken2; + CancellationTokenRegistration cancellationTokenRegistration1; + CancellationTokenRegistration cancellationTokenRegistration2; + + bool isCanceled; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + + public _TakeUntilCanceled(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken1, CancellationToken cancellationToken2) + { + this.source = source; + this.cancellationToken1 = cancellationToken1; + this.cancellationToken2 = cancellationToken2; + + if (cancellationToken1.CanBeCanceled) + { + this.cancellationTokenRegistration1 = cancellationToken1.RegisterWithoutCaptureExecutionContext(CancelDelegate1, this); + } + + if (cancellationToken1 != cancellationToken2 && cancellationToken2.CanBeCanceled) + { + this.cancellationTokenRegistration2 = cancellationToken2.RegisterWithoutCaptureExecutionContext(CancelDelegate2, this); + } + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (cancellationToken1.IsCancellationRequested) isCanceled = true; + if (cancellationToken2.IsCancellationRequested) isCanceled = true; + + if (enumerator == null) + { + enumerator = source.GetAsyncEnumerator(cancellationToken2); // use only AsyncEnumerator provided token. + } + + if (isCanceled) return CompletedTasks.False; + + completionSource.Reset(); + SourceMoveNext(); + return new UniTask(this, completionSource.Version); + } + + void SourceMoveNext() + { + try + { + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + MoveNextCore(this); + } + else + { + awaiter.SourceOnCompleted(MoveNextCoreDelegate, this); + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + } + } + + static void MoveNextCore(object state) + { + var self = (_TakeUntilCanceled)state; + + if (self.TryGetResult(self.awaiter, out var result)) + { + if (result) + { + if (self.isCanceled) + { + self.completionSource.TrySetResult(false); + } + else + { + self.Current = self.enumerator.Current; + self.completionSource.TrySetResult(true); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void OnCanceled1(object state) + { + var self = (_TakeUntilCanceled)state; + if (!self.isCanceled) + { + self.cancellationTokenRegistration2.Dispose(); + self.completionSource.TrySetResult(false); + } + } + + static void OnCanceled2(object state) + { + var self = (_TakeUntilCanceled)state; + if (!self.isCanceled) + { + self.cancellationTokenRegistration1.Dispose(); + self.completionSource.TrySetResult(false); + } + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + cancellationTokenRegistration1.Dispose(); + cancellationTokenRegistration2.Dispose(); + if (enumerator != null) + { + return enumerator.DisposeAsync(); + } + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntilCanceled.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntilCanceled.cs.meta new file mode 100644 index 0000000..4a89be5 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeUntilCanceled.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e82f498cf3a1df04cbf646773fc11319 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeWhile.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeWhile.cs new file mode 100644 index 0000000..6239c77 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeWhile.cs @@ -0,0 +1,342 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable TakeWhile(this IUniTaskAsyncEnumerable source, Func predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new TakeWhile(source, predicate); + } + + public static IUniTaskAsyncEnumerable TakeWhile(this IUniTaskAsyncEnumerable source, Func predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new TakeWhileInt(source, predicate); + } + + public static IUniTaskAsyncEnumerable TakeWhileAwait(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new TakeWhileAwait(source, predicate); + } + + public static IUniTaskAsyncEnumerable TakeWhileAwait(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new TakeWhileIntAwait(source, predicate); + } + + public static IUniTaskAsyncEnumerable TakeWhileAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new TakeWhileAwaitWithCancellation(source, predicate); + } + + public static IUniTaskAsyncEnumerable TakeWhileAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new TakeWhileIntAwaitWithCancellation(source, predicate); + } + } + + internal sealed class TakeWhile : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func predicate; + + public TakeWhile(IUniTaskAsyncEnumerable source, Func predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TakeWhile(source, predicate, cancellationToken); + } + + class _TakeWhile : AsyncEnumeratorBase + { + Func predicate; + + public _TakeWhile(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + if (predicate(SourceCurrent)) + { + Current = SourceCurrent; + result = true; + return true; + } + } + + result = false; + return true; + } + } + } + + internal sealed class TakeWhileInt : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func predicate; + + public TakeWhileInt(IUniTaskAsyncEnumerable source, Func predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TakeWhileInt(source, predicate, cancellationToken); + } + + class _TakeWhileInt : AsyncEnumeratorBase + { + readonly Func predicate; + int index; + + public _TakeWhileInt(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) + { + if (sourceHasCurrent) + { + if (predicate(SourceCurrent, checked(index++))) + { + Current = SourceCurrent; + result = true; + return true; + } + } + + result = false; + return true; + } + } + } + + internal sealed class TakeWhileAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public TakeWhileAwait(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TakeWhileAwait(source, predicate, cancellationToken); + } + + class _TakeWhileAwait : AsyncEnumeratorAwaitSelectorBase + { + Func> predicate; + + public _TakeWhileAwait(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + return predicate(sourceCurrent); + } + + protected override bool TrySetCurrentCore(bool awaitResult, out bool terminateIteration) + { + if (awaitResult) + { + Current = SourceCurrent; + terminateIteration = false; + return true; + } + else + { + terminateIteration = true; + return false; + } + } + } + } + + internal sealed class TakeWhileIntAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public TakeWhileIntAwait(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TakeWhileIntAwait(source, predicate, cancellationToken); + } + + class _TakeWhileIntAwait : AsyncEnumeratorAwaitSelectorBase + { + readonly Func> predicate; + int index; + + public _TakeWhileIntAwait(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + return predicate(sourceCurrent, checked(index++)); + } + + protected override bool TrySetCurrentCore(bool awaitResult, out bool terminateIteration) + { + if (awaitResult) + { + Current = SourceCurrent; + terminateIteration = false; + return true; + } + else + { + terminateIteration = true; + return false; + } + } + } + } + + internal sealed class TakeWhileAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public TakeWhileAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TakeWhileAwaitWithCancellation(source, predicate, cancellationToken); + } + + class _TakeWhileAwaitWithCancellation : AsyncEnumeratorAwaitSelectorBase + { + Func> predicate; + + public _TakeWhileAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + return predicate(sourceCurrent, cancellationToken); + } + + protected override bool TrySetCurrentCore(bool awaitResult, out bool terminateIteration) + { + if (awaitResult) + { + Current = SourceCurrent; + terminateIteration = false; + return true; + } + else + { + terminateIteration = true; + return false; + } + } + } + } + + internal sealed class TakeWhileIntAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public TakeWhileIntAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TakeWhileIntAwaitWithCancellation(source, predicate, cancellationToken); + } + + class _TakeWhileIntAwaitWithCancellation : AsyncEnumeratorAwaitSelectorBase + { + readonly Func> predicate; + int index; + + public _TakeWhileIntAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + : base(source, cancellationToken) + { + this.predicate = predicate; + } + + protected override UniTask TransformAsync(TSource sourceCurrent) + { + return predicate(sourceCurrent, checked(index++), cancellationToken); + } + + protected override bool TrySetCurrentCore(bool awaitResult, out bool terminateIteration) + { + if (awaitResult) + { + Current = SourceCurrent; + terminateIteration = false; + return true; + } + else + { + terminateIteration = true; + return false; + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeWhile.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeWhile.cs.meta new file mode 100644 index 0000000..f2173d5 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/TakeWhile.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bca55adabcc4b3141b50b8b09634f764 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Throw.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Throw.cs new file mode 100644 index 0000000..b6994c4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Throw.cs @@ -0,0 +1,54 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Throw(Exception exception) + { + return new Throw(exception); + } + } + + internal class Throw : IUniTaskAsyncEnumerable + { + readonly Exception exception; + + public Throw(Exception exception) + { + this.exception = exception; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Throw(exception, cancellationToken); + } + + class _Throw : IUniTaskAsyncEnumerator + { + readonly Exception exception; + CancellationToken cancellationToken; + + public _Throw(Exception exception, CancellationToken cancellationToken) + { + this.exception = exception; + this.cancellationToken = cancellationToken; + } + + public TValue Current => default; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + return UniTask.FromException(exception); + } + + public UniTask DisposeAsync() + { + return default; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Throw.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Throw.cs.meta new file mode 100644 index 0000000..c768ef1 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Throw.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d05a7d4f4161e549b4789e1022baae8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToArray.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToArray.cs new file mode 100644 index 0000000..3554968 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToArray.cs @@ -0,0 +1,60 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask ToArrayAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Cysharp.Threading.Tasks.Linq.ToArray.ToArrayAsync(source, cancellationToken); + } + } + + internal static class ToArray + { + internal static async UniTask ToArrayAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + var pool = ArrayPool.Shared; + var array = pool.Rent(16); + + TSource[] result = default; + IUniTaskAsyncEnumerator e = default; + try + { + e = source.GetAsyncEnumerator(cancellationToken); + var i = 0; + while (await e.MoveNextAsync()) + { + ArrayPoolUtil.EnsureCapacity(ref array, i, pool); + array[i++] = e.Current; + } + + if (i == 0) + { + result = Array.Empty(); + } + else + { + result = new TSource[i]; + Array.Copy(array, result, i); + } + } + finally + { + pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); + + if (e != null) + { + await e.DisposeAsync(); + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToArray.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToArray.cs.meta new file mode 100644 index 0000000..679d61c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: debb010bbb1622e43b94fe70ec0133dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToDictionary.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToDictionary.cs new file mode 100644 index 0000000..083ace0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToDictionary.cs @@ -0,0 +1,278 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask> ToDictionaryAsync(this IUniTaskAsyncEnumerable source, Func keySelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return ToDictionary.ToDictionaryAsync(source, keySelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToDictionaryAsync(this IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToDictionary.ToDictionaryAsync(source, keySelector, comparer, cancellationToken); + } + + public static UniTask> ToDictionaryAsync(this IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + + return ToDictionary.ToDictionaryAsync(source, keySelector, elementSelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToDictionaryAsync(this IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToDictionary.ToDictionaryAsync(source, keySelector, elementSelector, comparer, cancellationToken); + } + + public static UniTask> ToDictionaryAwaitAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return ToDictionary.ToDictionaryAwaitAsync(source, keySelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToDictionaryAwaitAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToDictionary.ToDictionaryAwaitAsync(source, keySelector, comparer, cancellationToken); + } + + public static UniTask> ToDictionaryAwaitAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + + return ToDictionary.ToDictionaryAwaitAsync(source, keySelector, elementSelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToDictionaryAwaitAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToDictionary.ToDictionaryAwaitAsync(source, keySelector, elementSelector, comparer, cancellationToken); + } + + public static UniTask> ToDictionaryAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return ToDictionary.ToDictionaryAwaitWithCancellationAsync(source, keySelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToDictionaryAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToDictionary.ToDictionaryAwaitWithCancellationAsync(source, keySelector, comparer, cancellationToken); + } + + public static UniTask> ToDictionaryAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + + return ToDictionary.ToDictionaryAwaitWithCancellationAsync(source, keySelector, elementSelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToDictionaryAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToDictionary.ToDictionaryAwaitWithCancellationAsync(source, keySelector, elementSelector, comparer, cancellationToken); + } + } + + internal static class ToDictionary + { + internal static async UniTask> ToDictionaryAsync(IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var dict = new Dictionary(comparer); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + var key = keySelector(v); + dict.Add(key, v); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return dict; + } + + internal static async UniTask> ToDictionaryAsync(IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var dict = new Dictionary(comparer); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + var key = keySelector(v); + var value = elementSelector(v); + dict.Add(key, value); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return dict; + } + + // with await + + internal static async UniTask> ToDictionaryAwaitAsync(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var dict = new Dictionary(comparer); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + var key = await keySelector(v); + dict.Add(key, v); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return dict; + } + + internal static async UniTask> ToDictionaryAwaitAsync(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var dict = new Dictionary(comparer); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + var key = await keySelector(v); + var value = await elementSelector(v); + dict.Add(key, value); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return dict; + } + + // with cancellation + + internal static async UniTask> ToDictionaryAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var dict = new Dictionary(comparer); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + var key = await keySelector(v, cancellationToken); + dict.Add(key, v); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return dict; + } + + internal static async UniTask> ToDictionaryAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var dict = new Dictionary(comparer); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + var v = e.Current; + var key = await keySelector(v, cancellationToken); + var value = await elementSelector(v, cancellationToken); + dict.Add(key, value); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return dict; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToDictionary.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToDictionary.cs.meta new file mode 100644 index 0000000..4deed19 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToDictionary.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 03b109b1fe1f2df46aa56ffb26747654 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToHashSet.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToHashSet.cs new file mode 100644 index 0000000..d058cb1 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToHashSet.cs @@ -0,0 +1,50 @@ +using Cysharp.Threading.Tasks.Internal; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask> ToHashSetAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Cysharp.Threading.Tasks.Linq.ToHashSet.ToHashSetAsync(source, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToHashSetAsync(this IUniTaskAsyncEnumerable source, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return Cysharp.Threading.Tasks.Linq.ToHashSet.ToHashSetAsync(source, comparer, cancellationToken); + } + } + + internal static class ToHashSet + { + internal static async UniTask> ToHashSetAsync(IUniTaskAsyncEnumerable source, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var set = new HashSet(comparer); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + set.Add(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return set; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToHashSet.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToHashSet.cs.meta new file mode 100644 index 0000000..8d3c4af --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToHashSet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a3e552113af96e4986805ec3c4fc80a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToList.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToList.cs new file mode 100644 index 0000000..e6fa35e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToList.cs @@ -0,0 +1,42 @@ +using Cysharp.Threading.Tasks.Internal; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask> ToListAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Cysharp.Threading.Tasks.Linq.ToList.ToListAsync(source, cancellationToken); + } + } + + internal static class ToList + { + internal static async UniTask> ToListAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + var list = new List(); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + list.Add(e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return list; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToList.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToList.cs.meta new file mode 100644 index 0000000..4f09373 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3859c1b31e81d9b44b282e7d97e11635 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToLookup.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToLookup.cs new file mode 100644 index 0000000..015c1c0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToLookup.cs @@ -0,0 +1,554 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static UniTask> ToLookupAsync(this IUniTaskAsyncEnumerable source, Func keySelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return ToLookup.ToLookupAsync(source, keySelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToLookupAsync(this IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToLookup.ToLookupAsync(source, keySelector, comparer, cancellationToken); + } + + public static UniTask> ToLookupAsync(this IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + + return ToLookup.ToLookupAsync(source, keySelector, elementSelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToLookupAsync(this IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToLookup.ToLookupAsync(source, keySelector, elementSelector, comparer, cancellationToken); + } + + public static UniTask> ToLookupAwaitAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return ToLookup.ToLookupAwaitAsync(source, keySelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToLookupAwaitAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToLookup.ToLookupAwaitAsync(source, keySelector, comparer, cancellationToken); + } + + public static UniTask> ToLookupAwaitAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + + return ToLookup.ToLookupAwaitAsync(source, keySelector, elementSelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToLookupAwaitAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToLookup.ToLookupAwaitAsync(source, keySelector, elementSelector, comparer, cancellationToken); + } + + public static UniTask> ToLookupAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + + return ToLookup.ToLookupAwaitWithCancellationAsync(source, keySelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToLookupAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToLookup.ToLookupAwaitWithCancellationAsync(source, keySelector, comparer, cancellationToken); + } + + public static UniTask> ToLookupAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + + return ToLookup.ToLookupAwaitWithCancellationAsync(source, keySelector, elementSelector, EqualityComparer.Default, cancellationToken); + } + + public static UniTask> ToLookupAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); + Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + return ToLookup.ToLookupAwaitWithCancellationAsync(source, keySelector, elementSelector, comparer, cancellationToken); + } + } + + internal static class ToLookup + { + internal static async UniTask> ToLookupAsync(IUniTaskAsyncEnumerable source, Func keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var pool = ArrayPool.Shared; + var array = pool.Rent(16); + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + var i = 0; + while (await e.MoveNextAsync()) + { + ArrayPoolUtil.EnsureCapacity(ref array, i, pool); + array[i++] = e.Current; + } + + if (i == 0) + { + return Lookup.CreateEmpty(); + } + else + { + return Lookup.Create(new ArraySegment(array, 0, i), keySelector, comparer); + } + } + finally + { + pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); + + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask> ToLookupAsync(IUniTaskAsyncEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var pool = ArrayPool.Shared; + var array = pool.Rent(16); + + IUniTaskAsyncEnumerator e = default; + try + { + e = source.GetAsyncEnumerator(cancellationToken); + var i = 0; + while (await e.MoveNextAsync()) + { + ArrayPoolUtil.EnsureCapacity(ref array, i, pool); + array[i++] = e.Current; + } + + if (i == 0) + { + return Lookup.CreateEmpty(); + } + else + { + return Lookup.Create(new ArraySegment(array, 0, i), keySelector, elementSelector, comparer); + } + } + finally + { + pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); + + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + + // with await + + internal static async UniTask> ToLookupAwaitAsync(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var pool = ArrayPool.Shared; + var array = pool.Rent(16); + + IUniTaskAsyncEnumerator e = default; + try + { + e = source.GetAsyncEnumerator(cancellationToken); + var i = 0; + while (await e.MoveNextAsync()) + { + ArrayPoolUtil.EnsureCapacity(ref array, i, pool); + array[i++] = e.Current; + } + + if (i == 0) + { + return Lookup.CreateEmpty(); + } + else + { + return await Lookup.CreateAsync(new ArraySegment(array, 0, i), keySelector, comparer); + } + } + finally + { + pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); + + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask> ToLookupAwaitAsync(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var pool = ArrayPool.Shared; + var array = pool.Rent(16); + + IUniTaskAsyncEnumerator e = default; + try + { + e = source.GetAsyncEnumerator(cancellationToken); + var i = 0; + while (await e.MoveNextAsync()) + { + ArrayPoolUtil.EnsureCapacity(ref array, i, pool); + array[i++] = e.Current; + } + + if (i == 0) + { + return Lookup.CreateEmpty(); + } + else + { + return await Lookup.CreateAsync(new ArraySegment(array, 0, i), keySelector, elementSelector, comparer); + } + } + finally + { + pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); + + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + // with cancellation + + internal static async UniTask> ToLookupAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var pool = ArrayPool.Shared; + var array = pool.Rent(16); + + IUniTaskAsyncEnumerator e = default; + try + { + e = source.GetAsyncEnumerator(cancellationToken); + var i = 0; + while (await e.MoveNextAsync()) + { + ArrayPoolUtil.EnsureCapacity(ref array, i, pool); + array[i++] = e.Current; + } + + if (i == 0) + { + return Lookup.CreateEmpty(); + } + else + { + return await Lookup.CreateAsync(new ArraySegment(array, 0, i), keySelector, comparer, cancellationToken); + } + } + finally + { + pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); + + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal static async UniTask> ToLookupAwaitWithCancellationAsync(IUniTaskAsyncEnumerable source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var pool = ArrayPool.Shared; + var array = pool.Rent(16); + + IUniTaskAsyncEnumerator e = default; + try + { + e = source.GetAsyncEnumerator(cancellationToken); + var i = 0; + while (await e.MoveNextAsync()) + { + ArrayPoolUtil.EnsureCapacity(ref array, i, pool); + array[i++] = e.Current; + } + + if (i == 0) + { + return Lookup.CreateEmpty(); + } + else + { + return await Lookup.CreateAsync(new ArraySegment(array, 0, i), keySelector, elementSelector, comparer, cancellationToken); + } + } + finally + { + pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType()); + + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + // Lookup + + class Lookup : ILookup + { + static readonly Lookup empty = new Lookup(new Dictionary>()); + + // original lookup keeps order but this impl does not(dictionary not guarantee) + readonly Dictionary> dict; + + Lookup(Dictionary> dict) + { + this.dict = dict; + } + + public static Lookup CreateEmpty() + { + return empty; + } + + public static Lookup Create(ArraySegment source, Func keySelector, IEqualityComparer comparer) + { + var dict = new Dictionary>(comparer); + + var arr = source.Array; + var c = source.Count; + for (int i = source.Offset; i < c; i++) + { + var key = keySelector(arr[i]); + + if (!dict.TryGetValue(key, out var list)) + { + list = new Grouping(key); + dict[key] = list; + } + + list.Add(arr[i]); + } + + return new Lookup(dict); + } + + public static Lookup Create(ArraySegment source, Func keySelector, Func elementSelector, IEqualityComparer comparer) + { + var dict = new Dictionary>(comparer); + + var arr = source.Array; + var c = source.Count; + for (int i = source.Offset; i < c; i++) + { + var key = keySelector(arr[i]); + var elem = elementSelector(arr[i]); + + if (!dict.TryGetValue(key, out var list)) + { + list = new Grouping(key); + dict[key] = list; + } + + list.Add(elem); + } + + return new Lookup(dict); + } + + public static async UniTask> CreateAsync(ArraySegment source, Func> keySelector, IEqualityComparer comparer) + { + var dict = new Dictionary>(comparer); + + var arr = source.Array; + var c = source.Count; + for (int i = source.Offset; i < c; i++) + { + var key = await keySelector(arr[i]); + + if (!dict.TryGetValue(key, out var list)) + { + list = new Grouping(key); + dict[key] = list; + } + + list.Add(arr[i]); + } + + return new Lookup(dict); + } + + public static async UniTask> CreateAsync(ArraySegment source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer) + { + var dict = new Dictionary>(comparer); + + var arr = source.Array; + var c = source.Count; + for (int i = source.Offset; i < c; i++) + { + var key = await keySelector(arr[i]); + var elem = await elementSelector(arr[i]); + + if (!dict.TryGetValue(key, out var list)) + { + list = new Grouping(key); + dict[key] = list; + } + + list.Add(elem); + } + + return new Lookup(dict); + } + + public static async UniTask> CreateAsync(ArraySegment source, Func> keySelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var dict = new Dictionary>(comparer); + + var arr = source.Array; + var c = source.Count; + for (int i = source.Offset; i < c; i++) + { + var key = await keySelector(arr[i], cancellationToken); + + if (!dict.TryGetValue(key, out var list)) + { + list = new Grouping(key); + dict[key] = list; + } + + list.Add(arr[i]); + } + + return new Lookup(dict); + } + + public static async UniTask> CreateAsync(ArraySegment source, Func> keySelector, Func> elementSelector, IEqualityComparer comparer, CancellationToken cancellationToken) + { + var dict = new Dictionary>(comparer); + + var arr = source.Array; + var c = source.Count; + for (int i = source.Offset; i < c; i++) + { + var key = await keySelector(arr[i], cancellationToken); + var elem = await elementSelector(arr[i], cancellationToken); + + if (!dict.TryGetValue(key, out var list)) + { + list = new Grouping(key); + dict[key] = list; + } + + list.Add(elem); + } + + return new Lookup(dict); + } + + public IEnumerable this[TKey key] => dict.TryGetValue(key, out var g) ? g : Enumerable.Empty(); + + public int Count => dict.Count; + + public bool Contains(TKey key) + { + return dict.ContainsKey(key); + } + + public IEnumerator> GetEnumerator() + { + return dict.Values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return dict.Values.GetEnumerator(); + } + } + + class Grouping : IGrouping // , IUniTaskAsyncGrouping + { + readonly List elements; + + public TKey Key { get; private set; } + + public Grouping(TKey key) + { + this.Key = key; + this.elements = new List(); + } + + public void Add(TElement value) + { + elements.Add(value); + } + public IEnumerator GetEnumerator() + { + return elements.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return elements.GetEnumerator(); + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return this.ToUniTaskAsyncEnumerable().GetAsyncEnumerator(cancellationToken); + } + + public override string ToString() + { + return "Key: " + Key + ", Count: " + elements.Count; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToLookup.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToLookup.cs.meta new file mode 100644 index 0000000..7dd8ecd --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToLookup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57da22563bcd6ca4aaf256d941de5cb0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToObservable.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToObservable.cs new file mode 100644 index 0000000..4f48388 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToObservable.cs @@ -0,0 +1,97 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IObservable ToObservable(this IUniTaskAsyncEnumerable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new ToObservable(source); + } + } + + internal sealed class ToObservable : IObservable + { + readonly IUniTaskAsyncEnumerable source; + + public ToObservable(IUniTaskAsyncEnumerable source) + { + this.source = source; + } + + public IDisposable Subscribe(IObserver observer) + { + var ctd = new CancellationTokenDisposable(); + + RunAsync(source, observer, ctd.Token).Forget(); + + return ctd; + } + + static async UniTaskVoid RunAsync(IUniTaskAsyncEnumerable src, IObserver observer, CancellationToken cancellationToken) + { + // cancellationToken.IsCancellationRequested is called when Rx's Disposed. + // when disposed, finish silently. + + var e = src.GetAsyncEnumerator(cancellationToken); + try + { + bool hasNext; + + do + { + try + { + hasNext = await e.MoveNextAsync(); + } + catch (Exception ex) + { + if (cancellationToken.IsCancellationRequested) + { + return; + } + + observer.OnError(ex); + return; + } + + if (hasNext) + { + observer.OnNext(e.Current); + } + else + { + observer.OnCompleted(); + return; + } + } while (!cancellationToken.IsCancellationRequested); + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + internal sealed class CancellationTokenDisposable : IDisposable + { + readonly CancellationTokenSource cts = new CancellationTokenSource(); + + public CancellationToken Token => cts.Token; + + public void Dispose() + { + if (!cts.IsCancellationRequested) + { + cts.Cancel(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToObservable.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToObservable.cs.meta new file mode 100644 index 0000000..44d917e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToObservable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4f6f48a532188e4c80b7ebe69aea3a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs new file mode 100644 index 0000000..02523c6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs @@ -0,0 +1,1115 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Runtime.ExceptionServices; +using System.Threading; +using System.Threading.Tasks; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable ToUniTaskAsyncEnumerable(this IEnumerable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new ToUniTaskAsyncEnumerable(source); + } + + public static IUniTaskAsyncEnumerable ToUniTaskAsyncEnumerable(this Task source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new ToUniTaskAsyncEnumerableTask(source); + } + + public static IUniTaskAsyncEnumerable ToUniTaskAsyncEnumerable(this UniTask source) + { + return new ToUniTaskAsyncEnumerableUniTask(source); + } + + public static IUniTaskAsyncEnumerable ToUniTaskAsyncEnumerable(this IObservable source) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return new ToUniTaskAsyncEnumerableObservable(source); + } + } + + internal class ToUniTaskAsyncEnumerable : IUniTaskAsyncEnumerable + { + readonly IEnumerable source; + + public ToUniTaskAsyncEnumerable(IEnumerable source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _ToUniTaskAsyncEnumerable(source, cancellationToken); + } + + class _ToUniTaskAsyncEnumerable : IUniTaskAsyncEnumerator + { + readonly IEnumerable source; + CancellationToken cancellationToken; + + IEnumerator enumerator; + + public _ToUniTaskAsyncEnumerable(IEnumerable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + } + + public T Current => enumerator.Current; + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (enumerator == null) + { + enumerator = source.GetEnumerator(); + } + + if (enumerator.MoveNext()) + { + return CompletedTasks.True; + } + + return CompletedTasks.False; + } + + public UniTask DisposeAsync() + { + enumerator.Dispose(); + return default; + } + } + } + + internal class ToUniTaskAsyncEnumerableTask : IUniTaskAsyncEnumerable + { + readonly Task source; + + public ToUniTaskAsyncEnumerableTask(Task source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _ToUniTaskAsyncEnumerableTask(source, cancellationToken); + } + + class _ToUniTaskAsyncEnumerableTask : IUniTaskAsyncEnumerator + { + readonly Task source; + CancellationToken cancellationToken; + + T current; + bool called; + + public _ToUniTaskAsyncEnumerableTask(Task source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + + this.called = false; + } + + public T Current => current; + + public async UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (called) + { + return false; + } + called = true; + + current = await source; + return true; + } + + public UniTask DisposeAsync() + { + return default; + } + } + } + + internal class ToUniTaskAsyncEnumerableUniTask : IUniTaskAsyncEnumerable + { + readonly UniTask source; + + public ToUniTaskAsyncEnumerableUniTask(UniTask source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _ToUniTaskAsyncEnumerableUniTask(source, cancellationToken); + } + + class _ToUniTaskAsyncEnumerableUniTask : IUniTaskAsyncEnumerator + { + readonly UniTask source; + CancellationToken cancellationToken; + + T current; + bool called; + + public _ToUniTaskAsyncEnumerableUniTask(UniTask source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + + this.called = false; + } + + public T Current => current; + + public async UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + + if (called) + { + return false; + } + called = true; + + current = await source; + return true; + } + + public UniTask DisposeAsync() + { + return default; + } + } + } + + internal class ToUniTaskAsyncEnumerableObservable : IUniTaskAsyncEnumerable + { + readonly IObservable source; + + public ToUniTaskAsyncEnumerableObservable(IObservable source) + { + this.source = source; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _ToUniTaskAsyncEnumerableObservable(source, cancellationToken); + } + + class _ToUniTaskAsyncEnumerableObservable : MoveNextSource, IUniTaskAsyncEnumerator, IObserver + { + static readonly Action OnCanceledDelegate = OnCanceled; + + readonly IObservable source; + CancellationToken cancellationToken; + + + bool useCachedCurrent; + T current; + bool subscribeCompleted; + readonly Queue queuedResult; + Exception error; + IDisposable subscription; + CancellationTokenRegistration cancellationTokenRegistration; + + public _ToUniTaskAsyncEnumerableObservable(IObservable source, CancellationToken cancellationToken) + { + this.source = source; + this.cancellationToken = cancellationToken; + this.queuedResult = new Queue(); + + if (cancellationToken.CanBeCanceled) + { + cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(OnCanceledDelegate, this); + } + } + + public T Current + { + get + { + if (useCachedCurrent) + { + return current; + } + + lock (queuedResult) + { + if (queuedResult.Count != 0) + { + current = queuedResult.Dequeue(); + useCachedCurrent = true; + return current; + } + else + { + return default; // undefined. + } + } + } + } + + public UniTask MoveNextAsync() + { + lock (queuedResult) + { + useCachedCurrent = false; + + if (cancellationToken.IsCancellationRequested) + { + return UniTask.FromCanceled(cancellationToken); + } + + if (subscription == null) + { + subscription = source.Subscribe(this); + } + + if (error != null) + { + return UniTask.FromException(error); + } + + if (queuedResult.Count != 0) + { + return CompletedTasks.True; + } + + if (subscribeCompleted) + { + return CompletedTasks.False; + } + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + } + + public UniTask DisposeAsync() + { + subscription.Dispose(); + cancellationTokenRegistration.Dispose(); + completionSource.Reset(); + return default; + } + + public void OnCompleted() + { + lock (queuedResult) + { + subscribeCompleted = true; + completionSource.TrySetResult(false); + } + } + + public void OnError(Exception error) + { + lock (queuedResult) + { + this.error = error; + completionSource.TrySetException(error); + } + } + + public void OnNext(T value) + { + lock (queuedResult) + { + queuedResult.Enqueue(value); + completionSource.TrySetResult(true); // include callback execution, too long lock? + } + } + + static void OnCanceled(object state) + { + var self = (_ToUniTaskAsyncEnumerableObservable)state; + lock (self.queuedResult) + { + self.completionSource.TrySetCanceled(self.cancellationToken); + } + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs.meta new file mode 100644 index 0000000..45fd3b0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7192de2a0581ec4db62962cc1404af5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UniTask.Linq.asmdef b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UniTask.Linq.asmdef new file mode 100644 index 0000000..db84553 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UniTask.Linq.asmdef @@ -0,0 +1,15 @@ +{ + "name": "UniTask.Linq", + "references": [ + "UniTask" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UniTask.Linq.asmdef.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UniTask.Linq.asmdef.meta new file mode 100644 index 0000000..1c85d19 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UniTask.Linq.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5c01796d064528144a599661eaab93a6 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Union.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Union.cs new file mode 100644 index 0000000..2ceefab --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Union.cs @@ -0,0 +1,26 @@ +using Cysharp.Threading.Tasks.Internal; +using System.Collections.Generic; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Union(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + + return Union(first, second, EqualityComparer.Default); + } + + public static IUniTaskAsyncEnumerable Union(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, IEqualityComparer comparer) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + Error.ThrowArgumentNullException(comparer, nameof(comparer)); + + // improv without combinate? + return first.Concat(second).Distinct(comparer); + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Union.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Union.cs.meta new file mode 100644 index 0000000..1d9c7ad --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Union.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae57a55bdeba98b4f8ff234d98d7dd76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions.meta new file mode 100644 index 0000000..bb3fb5a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: baf5f0a1dc331064a8f292932a5388b5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs new file mode 100644 index 0000000..585fff9 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs @@ -0,0 +1,77 @@ +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable EveryUpdate(PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) + { + return new EveryUpdate(updateTiming); + } + } + + internal class EveryUpdate : IUniTaskAsyncEnumerable + { + readonly PlayerLoopTiming updateTiming; + + public EveryUpdate(PlayerLoopTiming updateTiming) + { + this.updateTiming = updateTiming; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _EveryUpdate(updateTiming, cancellationToken); + } + + class _EveryUpdate : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem + { + readonly PlayerLoopTiming updateTiming; + CancellationToken cancellationToken; + + bool disposed; + + public _EveryUpdate(PlayerLoopTiming updateTiming, CancellationToken cancellationToken) + { + this.updateTiming = updateTiming; + this.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(this, 2); + PlayerLoopHelper.AddAction(updateTiming, this); + } + + public AsyncUnit Current => default; + + public UniTask MoveNextAsync() + { + // return false instead of throw + if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False; + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + + public UniTask DisposeAsync() + { + if (!disposed) + { + disposed = true; + TaskTracker.RemoveTracking(this); + } + return default; + } + + public bool MoveNext() + { + if (disposed || cancellationToken.IsCancellationRequested) + { + completionSource.TrySetResult(false); + return false; + } + + completionSource.TrySetResult(true); + return true; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs.meta new file mode 100644 index 0000000..6336e0e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00520eb52e49b5b4e8d9870d6ff1aced +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs new file mode 100644 index 0000000..f678e7a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs @@ -0,0 +1,240 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable EveryValueChanged(TTarget target, Func propertySelector, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer equalityComparer = null) + where TTarget : class + { + var unityObject = target as UnityEngine.Object; + var isUnityObject = target is UnityEngine.Object; // don't use (unityObject == null) + + if (isUnityObject) + { + return new EveryValueChangedUnityObject(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault(), monitorTiming); + } + else + { + return new EveryValueChangedStandardObject(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault(), monitorTiming); + } + } + } + + internal sealed class EveryValueChangedUnityObject : IUniTaskAsyncEnumerable + { + readonly TTarget target; + readonly Func propertySelector; + readonly IEqualityComparer equalityComparer; + readonly PlayerLoopTiming monitorTiming; + + public EveryValueChangedUnityObject(TTarget target, Func propertySelector, IEqualityComparer equalityComparer, PlayerLoopTiming monitorTiming) + { + this.target = target; + this.propertySelector = propertySelector; + this.equalityComparer = equalityComparer; + this.monitorTiming = monitorTiming; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken); + } + + sealed class _EveryValueChanged : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem + { + readonly TTarget target; + readonly UnityEngine.Object targetAsUnityObject; + readonly IEqualityComparer equalityComparer; + readonly Func propertySelector; + CancellationToken cancellationToken; + + bool first; + TProperty currentValue; + bool disposed; + + public _EveryValueChanged(TTarget target, Func propertySelector, IEqualityComparer equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken) + { + this.target = target; + this.targetAsUnityObject = target as UnityEngine.Object; + this.propertySelector = propertySelector; + this.equalityComparer = equalityComparer; + this.cancellationToken = cancellationToken; + this.first = true; + TaskTracker.TrackActiveTask(this, 2); + PlayerLoopHelper.AddAction(monitorTiming, this); + } + + public TProperty Current => currentValue; + + public UniTask MoveNextAsync() + { + // return false instead of throw + if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False; + + if (first) + { + first = false; + if (targetAsUnityObject == null) + { + return CompletedTasks.False; + } + this.currentValue = propertySelector(target); + return CompletedTasks.True; + } + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + + public UniTask DisposeAsync() + { + if (!disposed) + { + disposed = true; + TaskTracker.RemoveTracking(this); + } + return default; + } + + public bool MoveNext() + { + if (disposed || cancellationToken.IsCancellationRequested || targetAsUnityObject == null) // destroyed = cancel. + { + completionSource.TrySetResult(false); + DisposeAsync().Forget(); + return false; + } + + TProperty nextValue = default(TProperty); + try + { + nextValue = propertySelector(target); + if (equalityComparer.Equals(currentValue, nextValue)) + { + return true; + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + DisposeAsync().Forget(); + return false; + } + + currentValue = nextValue; + completionSource.TrySetResult(true); + return true; + } + } + } + + internal sealed class EveryValueChangedStandardObject : IUniTaskAsyncEnumerable + where TTarget : class + { + readonly WeakReference target; + readonly Func propertySelector; + readonly IEqualityComparer equalityComparer; + readonly PlayerLoopTiming monitorTiming; + + public EveryValueChangedStandardObject(TTarget target, Func propertySelector, IEqualityComparer equalityComparer, PlayerLoopTiming monitorTiming) + { + this.target = new WeakReference(target, false); + this.propertySelector = propertySelector; + this.equalityComparer = equalityComparer; + this.monitorTiming = monitorTiming; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken); + } + + sealed class _EveryValueChanged : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem + { + readonly WeakReference target; + readonly IEqualityComparer equalityComparer; + readonly Func propertySelector; + CancellationToken cancellationToken; + + bool first; + TProperty currentValue; + bool disposed; + + public _EveryValueChanged(WeakReference target, Func propertySelector, IEqualityComparer equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken) + { + this.target = target; + this.propertySelector = propertySelector; + this.equalityComparer = equalityComparer; + this.cancellationToken = cancellationToken; + this.first = true; + TaskTracker.TrackActiveTask(this, 2); + PlayerLoopHelper.AddAction(monitorTiming, this); + } + + public TProperty Current => currentValue; + + public UniTask MoveNextAsync() + { + if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False; + + if (first) + { + first = false; + if (!target.TryGetTarget(out var t)) + { + return CompletedTasks.False; + } + this.currentValue = propertySelector(t); + return CompletedTasks.True; + } + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + + public UniTask DisposeAsync() + { + if (!disposed) + { + disposed = true; + TaskTracker.RemoveTracking(this); + } + return default; + } + + public bool MoveNext() + { + if (disposed || cancellationToken.IsCancellationRequested || !target.TryGetTarget(out var t)) + { + completionSource.TrySetResult(false); + DisposeAsync().Forget(); + return false; + } + + TProperty nextValue = default(TProperty); + try + { + nextValue = propertySelector(t); + if (equalityComparer.Equals(currentValue, nextValue)) + { + return true; + } + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + DisposeAsync().Forget(); + return false; + } + + currentValue = nextValue; + completionSource.TrySetResult(true); + return true; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs.meta new file mode 100644 index 0000000..9d2be70 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ec39f1c41c305344854782c935ad354 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/Timer.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/Timer.cs new file mode 100644 index 0000000..53ecfcd --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/Timer.cs @@ -0,0 +1,312 @@ +using System; +using System.Threading; +using UnityEngine; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Timer(TimeSpan dueTime, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) + { + return new Timer(dueTime, null, updateTiming, ignoreTimeScale); + } + + public static IUniTaskAsyncEnumerable Timer(TimeSpan dueTime, TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) + { + return new Timer(dueTime, period, updateTiming, ignoreTimeScale); + } + + public static IUniTaskAsyncEnumerable Interval(TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) + { + return new Timer(period, period, updateTiming, ignoreTimeScale); + } + + public static IUniTaskAsyncEnumerable TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) + { + if (dueTimeFrameCount < 0) + { + throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. dueTimeFrameCount:" + dueTimeFrameCount); + } + + return new TimerFrame(dueTimeFrameCount, null, updateTiming); + } + + public static IUniTaskAsyncEnumerable TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) + { + if (dueTimeFrameCount < 0) + { + throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. dueTimeFrameCount:" + dueTimeFrameCount); + } + if (periodFrameCount < 0) + { + throw new ArgumentOutOfRangeException("Delay does not allow minus periodFrameCount. periodFrameCount:" + dueTimeFrameCount); + } + + return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming); + } + + public static IUniTaskAsyncEnumerable IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) + { + if (intervalFrameCount < 0) + { + throw new ArgumentOutOfRangeException("Delay does not allow minus intervalFrameCount. intervalFrameCount:" + intervalFrameCount); + } + return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming); + } + } + + internal class Timer : IUniTaskAsyncEnumerable + { + readonly PlayerLoopTiming updateTiming; + readonly TimeSpan dueTime; + readonly TimeSpan? period; + readonly bool ignoreTimeScale; + + public Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale) + { + this.updateTiming = updateTiming; + this.dueTime = dueTime; + this.period = period; + this.ignoreTimeScale = ignoreTimeScale; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Timer(dueTime, period, updateTiming, ignoreTimeScale, cancellationToken); + } + + class _Timer : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem + { + readonly float dueTime; + readonly float? period; + readonly PlayerLoopTiming updateTiming; + readonly bool ignoreTimeScale; + CancellationToken cancellationToken; + + int initialFrame; + float elapsed; + bool dueTimePhase; + bool completed; + bool disposed; + + public _Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, CancellationToken cancellationToken) + { + this.dueTime = (float)dueTime.TotalSeconds; + this.period = (period == null) ? null : (float?)period.Value.TotalSeconds; + + if (this.dueTime <= 0) this.dueTime = 0; + if (this.period != null) + { + if (this.period <= 0) this.period = 1; + } + + this.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + this.dueTimePhase = true; + this.updateTiming = updateTiming; + this.ignoreTimeScale = ignoreTimeScale; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 2); + PlayerLoopHelper.AddAction(updateTiming, this); + } + + public AsyncUnit Current => default; + + public UniTask MoveNextAsync() + { + // return false instead of throw + if (disposed || cancellationToken.IsCancellationRequested || completed) return CompletedTasks.False; + + // reset value here. + this.elapsed = 0; + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + + public UniTask DisposeAsync() + { + if (!disposed) + { + disposed = true; + TaskTracker.RemoveTracking(this); + } + return default; + } + + public bool MoveNext() + { + if (disposed || cancellationToken.IsCancellationRequested) + { + completionSource.TrySetResult(false); + return false; + } + + if (dueTimePhase) + { + if (elapsed == 0) + { + // skip in initial frame. + if (initialFrame == Time.frameCount) + { + return true; + } + } + + elapsed += (ignoreTimeScale) ? UnityEngine.Time.unscaledDeltaTime : UnityEngine.Time.deltaTime; + + if (elapsed >= dueTime) + { + dueTimePhase = false; + completionSource.TrySetResult(true); + } + } + else + { + if (period == null) + { + completed = true; + completionSource.TrySetResult(false); + return false; + } + + elapsed += (ignoreTimeScale) ? UnityEngine.Time.unscaledDeltaTime : UnityEngine.Time.deltaTime; + + if (elapsed >= period) + { + completionSource.TrySetResult(true); + } + } + + return true; + } + } + } + + internal class TimerFrame : IUniTaskAsyncEnumerable + { + readonly PlayerLoopTiming updateTiming; + readonly int dueTimeFrameCount; + readonly int? periodFrameCount; + + public TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming) + { + this.updateTiming = updateTiming; + this.dueTimeFrameCount = dueTimeFrameCount; + this.periodFrameCount = periodFrameCount; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming, cancellationToken); + } + + class _TimerFrame : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem + { + readonly int dueTimeFrameCount; + readonly int? periodFrameCount; + CancellationToken cancellationToken; + + int initialFrame; + int currentFrame; + bool dueTimePhase; + bool completed; + bool disposed; + + public _TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, CancellationToken cancellationToken) + { + if (dueTimeFrameCount <= 0) dueTimeFrameCount = 0; + if (periodFrameCount != null) + { + if (periodFrameCount <= 0) periodFrameCount = 1; + } + + this.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + this.dueTimePhase = true; + this.dueTimeFrameCount = dueTimeFrameCount; + this.periodFrameCount = periodFrameCount; + this.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(this, 2); + PlayerLoopHelper.AddAction(updateTiming, this); + } + + public AsyncUnit Current => default; + + public UniTask MoveNextAsync() + { + // return false instead of throw + if (disposed || cancellationToken.IsCancellationRequested || completed) return CompletedTasks.False; + + + // reset value here. + this.currentFrame = 0; + + completionSource.Reset(); + return new UniTask(this, completionSource.Version); + } + + public UniTask DisposeAsync() + { + if (!disposed) + { + disposed = true; + TaskTracker.RemoveTracking(this); + } + return default; + } + + public bool MoveNext() + { + if (disposed || cancellationToken.IsCancellationRequested) + { + completionSource.TrySetResult(false); + return false; + } + + if (dueTimePhase) + { + if (currentFrame == 0) + { + if (dueTimeFrameCount == 0) + { + dueTimePhase = false; + completionSource.TrySetResult(true); + return true; + } + + // skip in initial frame. + if (initialFrame == Time.frameCount) + { + return true; + } + } + + if (++currentFrame >= dueTimeFrameCount) + { + dueTimePhase = false; + completionSource.TrySetResult(true); + } + else + { + } + } + else + { + if (periodFrameCount == null) + { + completed = true; + completionSource.TrySetResult(false); + return false; + } + + if (++currentFrame >= periodFrameCount) + { + completionSource.TrySetResult(true); + } + } + + return true; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/Timer.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/Timer.cs.meta new file mode 100644 index 0000000..aa790c5 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/UnityExtensions/Timer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 382caacde439855418709c641e4d7b04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Where.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Where.cs new file mode 100644 index 0000000..1b5ac47 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Where.cs @@ -0,0 +1,818 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Where(this IUniTaskAsyncEnumerable source, Func predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new Where(source, predicate); + } + + public static IUniTaskAsyncEnumerable Where(this IUniTaskAsyncEnumerable source, Func predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new WhereInt(source, predicate); + } + + public static IUniTaskAsyncEnumerable WhereAwait(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new WhereAwait(source, predicate); + } + + public static IUniTaskAsyncEnumerable WhereAwait(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new WhereIntAwait(source, predicate); + } + + public static IUniTaskAsyncEnumerable WhereAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new WhereAwaitWithCancellation(source, predicate); + } + + public static IUniTaskAsyncEnumerable WhereAwaitWithCancellation(this IUniTaskAsyncEnumerable source, Func> predicate) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return new WhereIntAwaitWithCancellation(source, predicate); + } + } + + internal sealed class Where : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func predicate; + + public Where(IUniTaskAsyncEnumerable source, Func predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Where(source, predicate, cancellationToken); + } + + sealed class _Where : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func predicate; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + Action moveNextAction; + + public _Where(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + { + this.source = source; + this.predicate = predicate; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + Current = enumerator.Current; + if (predicate(Current)) + { + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + } + else + { + goto DONE; + } + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class WhereInt : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func predicate; + + public WhereInt(IUniTaskAsyncEnumerable source, Func predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Where(source, predicate, cancellationToken); + } + + sealed class _Where : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func predicate; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + Action moveNextAction; + int index; + + public _Where(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + { + this.source = source; + this.predicate = predicate; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + Current = enumerator.Current; + if (predicate(Current, checked(index++))) + { + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + } + else + { + goto DONE; + } + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class WhereAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public WhereAwait(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _WhereAwait(source, predicate, cancellationToken); + } + + sealed class _WhereAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + + public _WhereAwait(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + this.source = source; + this.predicate = predicate; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + Current = enumerator.Current; + + awaiter2 = predicate(Current).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + if (awaiter2.GetResult()) + { + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class WhereIntAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public WhereIntAwait(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _WhereAwait(source, predicate, cancellationToken); + } + + sealed class _WhereAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + int index; + + public _WhereAwait(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + this.source = source; + this.predicate = predicate; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + Current = enumerator.Current; + + awaiter2 = predicate(Current, checked(index++)).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + if (awaiter2.GetResult()) + { + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class WhereAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public WhereAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _WhereAwaitWithCancellation(source, predicate, cancellationToken); + } + + sealed class _WhereAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + + public _WhereAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + this.source = source; + this.predicate = predicate; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + Current = enumerator.Current; + + awaiter2 = predicate(Current, cancellationToken).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + if (awaiter2.GetResult()) + { + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } + + internal sealed class WhereIntAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + + public WhereIntAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate) + { + this.source = source; + this.predicate = predicate; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _WhereAwaitWithCancellation(source, predicate, cancellationToken); + } + + sealed class _WhereAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + readonly IUniTaskAsyncEnumerable source; + readonly Func> predicate; + readonly CancellationToken cancellationToken; + + int state = -1; + IUniTaskAsyncEnumerator enumerator; + UniTask.Awaiter awaiter; + UniTask.Awaiter awaiter2; + Action moveNextAction; + int index; + + public _WhereAwaitWithCancellation(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + this.source = source; + this.predicate = predicate; + this.cancellationToken = cancellationToken; + this.moveNextAction = MoveNext; + TaskTracker.TrackActiveTask(this, 3); + } + + public TSource Current { get; private set; } + + public UniTask MoveNextAsync() + { + if (state == -2) return default; + + completionSource.Reset(); + MoveNext(); + return new UniTask(this, completionSource.Version); + } + + void MoveNext() + { + REPEAT: + try + { + switch (state) + { + case -1: // init + enumerator = source.GetAsyncEnumerator(cancellationToken); + goto case 0; + case 0: + awaiter = enumerator.MoveNextAsync().GetAwaiter(); + if (awaiter.IsCompleted) + { + goto case 1; + } + else + { + state = 1; + awaiter.UnsafeOnCompleted(moveNextAction); + return; + } + case 1: + if (awaiter.GetResult()) + { + Current = enumerator.Current; + + awaiter2 = predicate(Current, checked(index++), cancellationToken).GetAwaiter(); + if (awaiter2.IsCompleted) + { + goto case 2; + } + else + { + state = 2; + awaiter2.UnsafeOnCompleted(moveNextAction); + return; + } + } + else + { + goto DONE; + } + case 2: + if (awaiter2.GetResult()) + { + goto CONTINUE; + } + else + { + state = 0; + goto REPEAT; + } + default: + goto DONE; + } + } + catch (Exception ex) + { + state = -2; + completionSource.TrySetException(ex); + return; + } + + DONE: + state = -2; + completionSource.TrySetResult(false); + return; + + CONTINUE: + state = 0; + completionSource.TrySetResult(true); + return; + } + + public UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + return enumerator.DisposeAsync(); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Where.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Where.cs.meta new file mode 100644 index 0000000..7e50337 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Where.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d882a3238d9535e4e8ce1ad3291eb7fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Zip.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Zip.cs new file mode 100644 index 0000000..af6d5f1 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Zip.cs @@ -0,0 +1,541 @@ +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + + public static IUniTaskAsyncEnumerable<(TFirst First, TSecond Second)> Zip(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + + return Zip(first, second, (x, y) => (x, y)); + } + + public static IUniTaskAsyncEnumerable Zip(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func resultSelector) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector)); + + return new Zip(first, second, resultSelector); + } + + public static IUniTaskAsyncEnumerable ZipAwait(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func> selector) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new ZipAwait(first, second, selector); + } + + public static IUniTaskAsyncEnumerable ZipAwaitWithCancellation(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func> selector) + { + Error.ThrowArgumentNullException(first, nameof(first)); + Error.ThrowArgumentNullException(second, nameof(second)); + Error.ThrowArgumentNullException(selector, nameof(selector)); + + return new ZipAwaitWithCancellation(first, second, selector); + } + } + + internal sealed class Zip : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + readonly Func resultSelector; + + public Zip(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func resultSelector) + { + this.first = first; + this.second = second; + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _Zip(first, second, resultSelector, cancellationToken); + } + + sealed class _Zip : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action firstMoveNextCoreDelegate = FirstMoveNextCore; + static readonly Action secondMoveNextCoreDelegate = SecondMoveNextCore; + + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + readonly Func resultSelector; + + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator firstEnumerator; + IUniTaskAsyncEnumerator secondEnumerator; + + UniTask.Awaiter firstAwaiter; + UniTask.Awaiter secondAwaiter; + + public _Zip(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func resultSelector, CancellationToken cancellationToken) + { + this.first = first; + this.second = second; + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + completionSource.Reset(); + + if (firstEnumerator == null) + { + firstEnumerator = first.GetAsyncEnumerator(cancellationToken); + secondEnumerator = second.GetAsyncEnumerator(cancellationToken); + } + + firstAwaiter = firstEnumerator.MoveNextAsync().GetAwaiter(); + + if (firstAwaiter.IsCompleted) + { + FirstMoveNextCore(this); + } + else + { + firstAwaiter.SourceOnCompleted(firstMoveNextCoreDelegate, this); + } + + return new UniTask(this, completionSource.Version); + } + + static void FirstMoveNextCore(object state) + { + var self = (_Zip)state; + + if (self.TryGetResult(self.firstAwaiter, out var result)) + { + if (result) + { + try + { + self.secondAwaiter = self.secondEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + + if (self.secondAwaiter.IsCompleted) + { + SecondMoveNextCore(self); + } + else + { + self.secondAwaiter.SourceOnCompleted(secondMoveNextCoreDelegate, self); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void SecondMoveNextCore(object state) + { + var self = (_Zip)state; + + if (self.TryGetResult(self.secondAwaiter, out var result)) + { + if (result) + { + try + { + self.Current = self.resultSelector(self.firstEnumerator.Current, self.secondEnumerator.Current); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + + if (self.cancellationToken.IsCancellationRequested) + { + self.completionSource.TrySetCanceled(self.cancellationToken); + } + else + { + self.completionSource.TrySetResult(true); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (firstEnumerator != null) + { + await firstEnumerator.DisposeAsync(); + } + if (secondEnumerator != null) + { + await secondEnumerator.DisposeAsync(); + } + } + } + } + + internal sealed class ZipAwait : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + readonly Func> resultSelector; + + public ZipAwait(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func> resultSelector) + { + this.first = first; + this.second = second; + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _ZipAwait(first, second, resultSelector, cancellationToken); + } + + sealed class _ZipAwait : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action firstMoveNextCoreDelegate = FirstMoveNextCore; + static readonly Action secondMoveNextCoreDelegate = SecondMoveNextCore; + static readonly Action resultAwaitCoreDelegate = ResultAwaitCore; + + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + readonly Func> resultSelector; + + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator firstEnumerator; + IUniTaskAsyncEnumerator secondEnumerator; + + UniTask.Awaiter firstAwaiter; + UniTask.Awaiter secondAwaiter; + UniTask.Awaiter resultAwaiter; + + public _ZipAwait(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func> resultSelector, CancellationToken cancellationToken) + { + this.first = first; + this.second = second; + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + completionSource.Reset(); + + if (firstEnumerator == null) + { + firstEnumerator = first.GetAsyncEnumerator(cancellationToken); + secondEnumerator = second.GetAsyncEnumerator(cancellationToken); + } + + firstAwaiter = firstEnumerator.MoveNextAsync().GetAwaiter(); + + if (firstAwaiter.IsCompleted) + { + FirstMoveNextCore(this); + } + else + { + firstAwaiter.SourceOnCompleted(firstMoveNextCoreDelegate, this); + } + + return new UniTask(this, completionSource.Version); + } + + static void FirstMoveNextCore(object state) + { + var self = (_ZipAwait)state; + + if (self.TryGetResult(self.firstAwaiter, out var result)) + { + if (result) + { + try + { + self.secondAwaiter = self.secondEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + + if (self.secondAwaiter.IsCompleted) + { + SecondMoveNextCore(self); + } + else + { + self.secondAwaiter.SourceOnCompleted(secondMoveNextCoreDelegate, self); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void SecondMoveNextCore(object state) + { + var self = (_ZipAwait)state; + + if (self.TryGetResult(self.secondAwaiter, out var result)) + { + if (result) + { + try + { + self.resultAwaiter = self.resultSelector(self.firstEnumerator.Current, self.secondEnumerator.Current).GetAwaiter(); + if (self.resultAwaiter.IsCompleted) + { + ResultAwaitCore(self); + } + else + { + self.resultAwaiter.SourceOnCompleted(resultAwaitCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void ResultAwaitCore(object state) + { + var self = (_ZipAwait)state; + + if (self.TryGetResult(self.resultAwaiter, out var result)) + { + self.Current = result; + + if (self.cancellationToken.IsCancellationRequested) + { + self.completionSource.TrySetCanceled(self.cancellationToken); + } + else + { + self.completionSource.TrySetResult(true); + } + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (firstEnumerator != null) + { + await firstEnumerator.DisposeAsync(); + } + if (secondEnumerator != null) + { + await secondEnumerator.DisposeAsync(); + } + } + } + } + + internal sealed class ZipAwaitWithCancellation : IUniTaskAsyncEnumerable + { + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + readonly Func> resultSelector; + + public ZipAwaitWithCancellation(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func> resultSelector) + { + this.first = first; + this.second = second; + this.resultSelector = resultSelector; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new _ZipAwaitWithCancellation(first, second, resultSelector, cancellationToken); + } + + sealed class _ZipAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action firstMoveNextCoreDelegate = FirstMoveNextCore; + static readonly Action secondMoveNextCoreDelegate = SecondMoveNextCore; + static readonly Action resultAwaitCoreDelegate = ResultAwaitCore; + + readonly IUniTaskAsyncEnumerable first; + readonly IUniTaskAsyncEnumerable second; + readonly Func> resultSelector; + + CancellationToken cancellationToken; + + IUniTaskAsyncEnumerator firstEnumerator; + IUniTaskAsyncEnumerator secondEnumerator; + + UniTask.Awaiter firstAwaiter; + UniTask.Awaiter secondAwaiter; + UniTask.Awaiter resultAwaiter; + + public _ZipAwaitWithCancellation(IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second, Func> resultSelector, CancellationToken cancellationToken) + { + this.first = first; + this.second = second; + this.resultSelector = resultSelector; + this.cancellationToken = cancellationToken; + TaskTracker.TrackActiveTask(this, 3); + } + + public TResult Current { get; private set; } + + public UniTask MoveNextAsync() + { + completionSource.Reset(); + + if (firstEnumerator == null) + { + firstEnumerator = first.GetAsyncEnumerator(cancellationToken); + secondEnumerator = second.GetAsyncEnumerator(cancellationToken); + } + + firstAwaiter = firstEnumerator.MoveNextAsync().GetAwaiter(); + + if (firstAwaiter.IsCompleted) + { + FirstMoveNextCore(this); + } + else + { + firstAwaiter.SourceOnCompleted(firstMoveNextCoreDelegate, this); + } + + return new UniTask(this, completionSource.Version); + } + + static void FirstMoveNextCore(object state) + { + var self = (_ZipAwaitWithCancellation)state; + + if (self.TryGetResult(self.firstAwaiter, out var result)) + { + if (result) + { + try + { + self.secondAwaiter = self.secondEnumerator.MoveNextAsync().GetAwaiter(); + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + return; + } + + if (self.secondAwaiter.IsCompleted) + { + SecondMoveNextCore(self); + } + else + { + self.secondAwaiter.SourceOnCompleted(secondMoveNextCoreDelegate, self); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void SecondMoveNextCore(object state) + { + var self = (_ZipAwaitWithCancellation)state; + + if (self.TryGetResult(self.secondAwaiter, out var result)) + { + if (result) + { + try + { + self.resultAwaiter = self.resultSelector(self.firstEnumerator.Current, self.secondEnumerator.Current, self.cancellationToken).GetAwaiter(); + if (self.resultAwaiter.IsCompleted) + { + ResultAwaitCore(self); + } + else + { + self.resultAwaiter.SourceOnCompleted(resultAwaitCoreDelegate, self); + } + } + catch (Exception ex) + { + self.completionSource.TrySetException(ex); + } + } + else + { + self.completionSource.TrySetResult(false); + } + } + } + + static void ResultAwaitCore(object state) + { + var self = (_ZipAwaitWithCancellation)state; + + if (self.TryGetResult(self.resultAwaiter, out var result)) + { + self.Current = result; + + if (self.cancellationToken.IsCancellationRequested) + { + self.completionSource.TrySetCanceled(self.cancellationToken); + } + else + { + self.completionSource.TrySetResult(true); + } + } + } + + public async UniTask DisposeAsync() + { + TaskTracker.RemoveTracking(this); + if (firstEnumerator != null) + { + await firstEnumerator.DisposeAsync(); + } + if (secondEnumerator != null) + { + await secondEnumerator.DisposeAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Zip.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Zip.cs.meta new file mode 100644 index 0000000..bf12163 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Linq/Zip.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: acc1acff153e347418f0f30b1c535994 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/MoveNextSource.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/MoveNextSource.cs new file mode 100644 index 0000000..3e9ca23 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/MoveNextSource.cs @@ -0,0 +1,63 @@ +using System; + +namespace Cysharp.Threading.Tasks +{ + public abstract class MoveNextSource : IUniTaskSource + { + protected UniTaskCompletionSourceCore completionSource; + + public bool GetResult(short token) + { + return completionSource.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return completionSource.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + completionSource.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return completionSource.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + completionSource.GetResult(token); + } + + protected bool TryGetResult(UniTask.Awaiter awaiter, out T result) + { + try + { + result = awaiter.GetResult(); + return true; + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + result = default; + return false; + } + } + + protected bool TryGetResult(UniTask.Awaiter awaiter) + { + try + { + awaiter.GetResult(); + return true; + } + catch (Exception ex) + { + completionSource.TrySetException(ex); + return false; + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/MoveNextSource.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/MoveNextSource.cs.meta new file mode 100644 index 0000000..60a0908 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/MoveNextSource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc4c5dc2a5f246e4f8df44cab735826c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopHelper.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopHelper.cs new file mode 100644 index 0000000..538fc01 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopHelper.cs @@ -0,0 +1,577 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Linq; +using UnityEngine; +using Cysharp.Threading.Tasks.Internal; +using System.Threading; + +#if UNITY_2019_3_OR_NEWER +using UnityEngine.LowLevel; +using PlayerLoopType = UnityEngine.PlayerLoop; +#else +using UnityEngine.Experimental.LowLevel; +using PlayerLoopType = UnityEngine.Experimental.PlayerLoop; +#endif + +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace Cysharp.Threading.Tasks +{ + 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 { }; + + // Last + + public struct UniTaskLoopRunnerLastInitialization { }; + public struct UniTaskLoopRunnerLastEarlyUpdate { }; + public struct UniTaskLoopRunnerLastFixedUpdate { }; + public struct UniTaskLoopRunnerLastPreUpdate { }; + public struct UniTaskLoopRunnerLastUpdate { }; + public struct UniTaskLoopRunnerLastPreLateUpdate { }; + public struct UniTaskLoopRunnerLastPostLateUpdate { }; + + // Yield + + public struct UniTaskLoopRunnerYieldInitialization { }; + public struct UniTaskLoopRunnerYieldEarlyUpdate { }; + public struct UniTaskLoopRunnerYieldFixedUpdate { }; + public struct UniTaskLoopRunnerYieldPreUpdate { }; + public struct UniTaskLoopRunnerYieldUpdate { }; + public struct UniTaskLoopRunnerYieldPreLateUpdate { }; + public struct UniTaskLoopRunnerYieldPostLateUpdate { }; + + // Yield Last + + public struct UniTaskLoopRunnerLastYieldInitialization { }; + public struct UniTaskLoopRunnerLastYieldEarlyUpdate { }; + public struct UniTaskLoopRunnerLastYieldFixedUpdate { }; + public struct UniTaskLoopRunnerLastYieldPreUpdate { }; + public struct UniTaskLoopRunnerLastYieldUpdate { }; + public struct UniTaskLoopRunnerLastYieldPreLateUpdate { }; + public struct UniTaskLoopRunnerLastYieldPostLateUpdate { }; + +#if UNITY_2020_2_OR_NEWER + public struct UniTaskLoopRunnerTimeUpdate { }; + public struct UniTaskLoopRunnerLastTimeUpdate { }; + public struct UniTaskLoopRunnerYieldTimeUpdate { }; + public struct UniTaskLoopRunnerLastYieldTimeUpdate { }; +#endif + } + + public enum PlayerLoopTiming + { + Initialization = 0, + LastInitialization = 1, + + EarlyUpdate = 2, + LastEarlyUpdate = 3, + + FixedUpdate = 4, + LastFixedUpdate = 5, + + PreUpdate = 6, + LastPreUpdate = 7, + + Update = 8, + LastUpdate = 9, + + PreLateUpdate = 10, + LastPreLateUpdate = 11, + + PostLateUpdate = 12, + LastPostLateUpdate = 13, + +#if UNITY_2020_2_OR_NEWER + // Unity 2020.2 added TimeUpdate https://docs.unity3d.com/2020.2/Documentation/ScriptReference/PlayerLoop.TimeUpdate.html + TimeUpdate = 14, + LastTimeUpdate = 15, +#endif + } + + [Flags] + public enum InjectPlayerLoopTimings + { + /// + /// Preset: All loops(default). + /// + All = + Initialization | LastInitialization | + EarlyUpdate | LastEarlyUpdate | + FixedUpdate | LastFixedUpdate | + PreUpdate | LastPreUpdate | + Update | LastUpdate | + PreLateUpdate | LastPreLateUpdate | + PostLateUpdate | LastPostLateUpdate +#if UNITY_2020_2_OR_NEWER + | TimeUpdate | LastTimeUpdate, +#else + , +#endif + + /// + /// Preset: All without last except LastPostLateUpdate. + /// + Standard = + Initialization | + EarlyUpdate | + FixedUpdate | + PreUpdate | + Update | + PreLateUpdate | + PostLateUpdate | LastPostLateUpdate +#if UNITY_2020_2_OR_NEWER + | TimeUpdate +#endif + , + + /// + /// Preset: Minimum pattern, Update | FixedUpdate | LastPostLateUpdate + /// + Minimum = + Update | FixedUpdate | LastPostLateUpdate, + + // PlayerLoopTiming + + Initialization = 1, + LastInitialization = 2, + + EarlyUpdate = 4, + LastEarlyUpdate = 8, + + FixedUpdate = 16, + LastFixedUpdate = 32, + + PreUpdate = 64, + LastPreUpdate = 128, + + Update = 256, + LastUpdate = 512, + + PreLateUpdate = 1024, + LastPreLateUpdate = 2048, + + PostLateUpdate = 4096, + LastPostLateUpdate = 8192 + +#if UNITY_2020_2_OR_NEWER + , + // Unity 2020.2 added TimeUpdate https://docs.unity3d.com/2020.2/Documentation/ScriptReference/PlayerLoop.TimeUpdate.html + TimeUpdate = 16384, + LastTimeUpdate = 32768 +#endif + } + + public interface IPlayerLoopItem + { + bool MoveNext(); + } + + public static class PlayerLoopHelper + { + static readonly ContinuationQueue ThrowMarkerContinuationQueue = new ContinuationQueue(PlayerLoopTiming.Initialization); + static readonly PlayerLoopRunner ThrowMarkerPlayerLoopRunner = new PlayerLoopRunner(PlayerLoopTiming.Initialization); + + public static SynchronizationContext UnitySynchronizationContext => unitySynchronizationContext; + public static int MainThreadId => mainThreadId; + internal static string ApplicationDataPath => applicationDataPath; + + public static bool IsMainThread => Thread.CurrentThread.ManagedThreadId == mainThreadId; + + static int mainThreadId; + static string applicationDataPath; + static SynchronizationContext unitySynchronizationContext; + static ContinuationQueue[] yielders; + static PlayerLoopRunner[] runners; + internal static bool IsEditorApplicationQuitting { get; private set; } + static PlayerLoopSystem[] InsertRunner(PlayerLoopSystem loopSystem, + bool injectOnFirst, + Type loopRunnerYieldType, ContinuationQueue cq, + Type loopRunnerType, PlayerLoopRunner runner) + { + +#if UNITY_EDITOR + EditorApplication.playModeStateChanged += (state) => + { + if (state == PlayModeStateChange.EnteredEditMode || state == PlayModeStateChange.ExitingEditMode) + { + IsEditorApplicationQuitting = true; + // run rest action before clear. + if (runner != null) + { + runner.Run(); + runner.Clear(); + } + if (cq != null) + { + cq.Run(); + cq.Clear(); + } + IsEditorApplicationQuitting = false; + } + }; +#endif + + var yieldLoop = new PlayerLoopSystem + { + type = loopRunnerYieldType, + updateDelegate = cq.Run + }; + + var runnerLoop = new PlayerLoopSystem + { + type = loopRunnerType, + updateDelegate = runner.Run + }; + + // Remove items from previous initializations. + var source = RemoveRunner(loopSystem, loopRunnerYieldType, loopRunnerType); + var dest = new PlayerLoopSystem[source.Length + 2]; + + Array.Copy(source, 0, dest, injectOnFirst ? 2 : 0, source.Length); + if (injectOnFirst) + { + dest[0] = yieldLoop; + dest[1] = runnerLoop; + } + else + { + dest[dest.Length - 2] = yieldLoop; + dest[dest.Length - 1] = runnerLoop; + } + + return dest; + } + + static PlayerLoopSystem[] RemoveRunner(PlayerLoopSystem loopSystem, Type loopRunnerYieldType, Type loopRunnerType) + { + return loopSystem.subSystemList + .Where(ls => ls.type != loopRunnerYieldType && ls.type != loopRunnerType) + .ToArray(); + } + + static PlayerLoopSystem[] InsertUniTaskSynchronizationContext(PlayerLoopSystem loopSystem) + { + var loop = new PlayerLoopSystem + { + type = typeof(UniTaskSynchronizationContext), + updateDelegate = UniTaskSynchronizationContext.Run + }; + + // Remove items from previous initializations. + var source = loopSystem.subSystemList + .Where(ls => ls.type != typeof(UniTaskSynchronizationContext)) + .ToArray(); + + var dest = new System.Collections.Generic.List(source); + + var index = dest.FindIndex(x => x.type.Name == "ScriptRunDelayedTasks"); + if (index == -1) + { + index = dest.FindIndex(x => x.type.Name == "UniTaskLoopRunnerUpdate"); + } + + dest.Insert(index + 1, loop); + + return dest.ToArray(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + static void Init() + { + // capture default(unity) sync-context. + unitySynchronizationContext = SynchronizationContext.Current; + mainThreadId = Thread.CurrentThread.ManagedThreadId; + try + { + applicationDataPath = Application.dataPath; + } + catch { } + +#if UNITY_EDITOR && UNITY_2019_3_OR_NEWER + // When domain reload is disabled, re-initialization is required when entering play mode; + // otherwise, pending tasks will leak between play mode sessions. + var domainReloadDisabled = UnityEditor.EditorSettings.enterPlayModeOptionsEnabled && + UnityEditor.EditorSettings.enterPlayModeOptions.HasFlag(UnityEditor.EnterPlayModeOptions.DisableDomainReload); + if (!domainReloadDisabled && runners != null) return; +#else + if (runners != null) return; // already initialized +#endif + + var playerLoop = +#if UNITY_2019_3_OR_NEWER + PlayerLoop.GetCurrentPlayerLoop(); +#else + PlayerLoop.GetDefaultPlayerLoop(); +#endif + + Initialize(ref playerLoop); + } + + +#if UNITY_EDITOR + + [InitializeOnLoadMethod] + static void InitOnEditor() + { + // Execute the play mode init method + Init(); + + // register an Editor update delegate, used to forcing playerLoop update + EditorApplication.update += ForceEditorPlayerLoopUpdate; + } + + private static void ForceEditorPlayerLoopUpdate() + { + if (EditorApplication.isPlayingOrWillChangePlaymode || EditorApplication.isCompiling || EditorApplication.isUpdating) + { + // Not in Edit mode, don't interfere + return; + } + + // EditorApplication.QueuePlayerLoopUpdate causes performance issue, don't call directly. + // EditorApplication.QueuePlayerLoopUpdate(); + + if (yielders != null) + { + foreach (var item in yielders) + { + if (item != null) item.Run(); + } + } + + if (runners != null) + { + foreach (var item in runners) + { + if (item != null) item.Run(); + } + } + + UniTaskSynchronizationContext.Run(); + } + +#endif + + private static int FindLoopSystemIndex(PlayerLoopSystem[] playerLoopList, Type systemType) + { + for (int i = 0; i < playerLoopList.Length; i++) + { + if (playerLoopList[i].type == systemType) + { + return i; + } + } + + throw new Exception("Target PlayerLoopSystem does not found. Type:" + systemType.FullName); + } + + static void InsertLoop(PlayerLoopSystem[] copyList, InjectPlayerLoopTimings injectTimings, Type loopType, InjectPlayerLoopTimings targetTimings, + int index, bool injectOnFirst, Type loopRunnerYieldType, Type loopRunnerType, PlayerLoopTiming playerLoopTiming) + { + var i = FindLoopSystemIndex(copyList, loopType); + if ((injectTimings & targetTimings) == targetTimings) + { + copyList[i].subSystemList = InsertRunner(copyList[i], injectOnFirst, + loopRunnerYieldType, yielders[index] = new ContinuationQueue(playerLoopTiming), + loopRunnerType, runners[index] = new PlayerLoopRunner(playerLoopTiming)); + } + else + { + copyList[i].subSystemList = RemoveRunner(copyList[i], loopRunnerYieldType, loopRunnerType); + } + } + + public static void Initialize(ref PlayerLoopSystem playerLoop, InjectPlayerLoopTimings injectTimings = InjectPlayerLoopTimings.All) + { +#if UNITY_2020_2_OR_NEWER + yielders = new ContinuationQueue[16]; + runners = new PlayerLoopRunner[16]; +#else + yielders = new ContinuationQueue[14]; + runners = new PlayerLoopRunner[14]; +#endif + + var copyList = playerLoop.subSystemList.ToArray(); + + // Initialization + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.Initialization), + InjectPlayerLoopTimings.Initialization, 0, true, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldInitialization), typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization), PlayerLoopTiming.Initialization); + + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.Initialization), + InjectPlayerLoopTimings.LastInitialization, 1, false, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldInitialization), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastInitialization), PlayerLoopTiming.LastInitialization); + + // EarlyUpdate + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.EarlyUpdate), + InjectPlayerLoopTimings.EarlyUpdate, 2, true, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldEarlyUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerEarlyUpdate), PlayerLoopTiming.EarlyUpdate); + + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.EarlyUpdate), + InjectPlayerLoopTimings.LastEarlyUpdate, 3, false, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldEarlyUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastEarlyUpdate), PlayerLoopTiming.LastEarlyUpdate); + + // FixedUpdate + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.FixedUpdate), + InjectPlayerLoopTimings.FixedUpdate, 4, true, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldFixedUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerFixedUpdate), PlayerLoopTiming.FixedUpdate); + + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.FixedUpdate), + InjectPlayerLoopTimings.LastFixedUpdate, 5, false, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldFixedUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastFixedUpdate), PlayerLoopTiming.LastFixedUpdate); + + // PreUpdate + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PreUpdate), + InjectPlayerLoopTimings.PreUpdate, 6, true, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreUpdate), PlayerLoopTiming.PreUpdate); + + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PreUpdate), + InjectPlayerLoopTimings.LastPreUpdate, 7, false, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreUpdate), PlayerLoopTiming.LastPreUpdate); + + // Update + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.Update), + InjectPlayerLoopTimings.Update, 8, true, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerUpdate), PlayerLoopTiming.Update); + + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.Update), + InjectPlayerLoopTimings.LastUpdate, 9, false, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastUpdate), PlayerLoopTiming.LastUpdate); + + // PreLateUpdate + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PreLateUpdate), + InjectPlayerLoopTimings.PreLateUpdate, 10, true, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreLateUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreLateUpdate), PlayerLoopTiming.PreLateUpdate); + + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PreLateUpdate), + InjectPlayerLoopTimings.LastPreLateUpdate, 11, false, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreLateUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreLateUpdate), PlayerLoopTiming.LastPreLateUpdate); + + // PostLateUpdate + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PostLateUpdate), + InjectPlayerLoopTimings.PostLateUpdate, 12, true, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPostLateUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPostLateUpdate), PlayerLoopTiming.PostLateUpdate); + + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PostLateUpdate), + InjectPlayerLoopTimings.LastPostLateUpdate, 13, false, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPostLateUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPostLateUpdate), PlayerLoopTiming.LastPostLateUpdate); + +#if UNITY_2020_2_OR_NEWER + // TimeUpdate + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.TimeUpdate), + InjectPlayerLoopTimings.TimeUpdate, 14, true, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldTimeUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerTimeUpdate), PlayerLoopTiming.TimeUpdate); + + InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.TimeUpdate), + InjectPlayerLoopTimings.LastTimeUpdate, 15, false, + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldTimeUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastTimeUpdate), PlayerLoopTiming.LastTimeUpdate); +#endif + + // Insert UniTaskSynchronizationContext to Update loop + var i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.Update)); + copyList[i].subSystemList = InsertUniTaskSynchronizationContext(copyList[i]); + + playerLoop.subSystemList = copyList; + PlayerLoop.SetPlayerLoop(playerLoop); + } + + public static void AddAction(PlayerLoopTiming timing, IPlayerLoopItem action) + { + var runner = runners[(int)timing]; + if (runner == null) + { + ThrowInvalidLoopTiming(timing); + } + runner.AddAction(action); + } + + static void ThrowInvalidLoopTiming(PlayerLoopTiming playerLoopTiming) + { + throw new InvalidOperationException("Target playerLoopTiming is not injected. Please check PlayerLoopHelper.Initialize. PlayerLoopTiming:" + playerLoopTiming); + } + + public static void AddContinuation(PlayerLoopTiming timing, Action continuation) + { + var q = yielders[(int)timing]; + if (q == null) + { + ThrowInvalidLoopTiming(timing); + } + q.Enqueue(continuation); + } + + // Diagnostics helper + +#if UNITY_2019_3_OR_NEWER + + public static void DumpCurrentPlayerLoop() + { + var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetCurrentPlayerLoop(); + + var sb = new System.Text.StringBuilder(); + sb.AppendLine($"PlayerLoop List"); + foreach (var header in playerLoop.subSystemList) + { + sb.AppendFormat("------{0}------", header.type.Name); + sb.AppendLine(); + + if (header.subSystemList is null) + { + sb.AppendFormat("{0} has no subsystems!", header.ToString()); + sb.AppendLine(); + continue; + } + + foreach (var subSystem in header.subSystemList) + { + sb.AppendFormat("{0}", subSystem.type.Name); + sb.AppendLine(); + + if (subSystem.subSystemList != null) + { + UnityEngine.Debug.LogWarning("More Subsystem:" + subSystem.subSystemList.Length); + } + } + } + + UnityEngine.Debug.Log(sb.ToString()); + } + + public static bool IsInjectedUniTaskPlayerLoop() + { + var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetCurrentPlayerLoop(); + + foreach (var header in playerLoop.subSystemList) + { + if (header.subSystemList is null) + { + continue; + } + + foreach (var subSystem in header.subSystemList) + { + if (subSystem.type == typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization)) + { + return true; + } + } + } + + return false; + } + +#endif + + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopHelper.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopHelper.cs.meta new file mode 100644 index 0000000..2487ef7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15fb5b85042f19640b973ce651795aca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopTimer.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopTimer.cs new file mode 100644 index 0000000..f8a877a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopTimer.cs @@ -0,0 +1,262 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System.Threading; +using System; +using Cysharp.Threading.Tasks.Internal; +using UnityEngine; + +namespace Cysharp.Threading.Tasks +{ + public abstract class PlayerLoopTimer : IDisposable, IPlayerLoopItem + { + readonly CancellationToken cancellationToken; + readonly Action timerCallback; + readonly object state; + readonly PlayerLoopTiming playerLoopTiming; + readonly bool periodic; + + bool isRunning; + bool tryStop; + bool isDisposed; + + protected PlayerLoopTimer(bool periodic, PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken, Action timerCallback, object state) + { + this.periodic = periodic; + this.playerLoopTiming = playerLoopTiming; + this.cancellationToken = cancellationToken; + this.timerCallback = timerCallback; + this.state = state; + } + + public static PlayerLoopTimer Create(TimeSpan interval, bool periodic, DelayType delayType, PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken, Action timerCallback, object state) + { +#if UNITY_EDITOR + // force use Realtime. + if (PlayerLoopHelper.IsMainThread && !UnityEditor.EditorApplication.isPlaying) + { + delayType = DelayType.Realtime; + } +#endif + + switch (delayType) + { + case DelayType.UnscaledDeltaTime: + return new IgnoreTimeScalePlayerLoopTimer(interval, periodic, playerLoopTiming, cancellationToken, timerCallback, state); + case DelayType.Realtime: + return new RealtimePlayerLoopTimer(interval, periodic, playerLoopTiming, cancellationToken, timerCallback, state); + case DelayType.DeltaTime: + default: + return new DeltaTimePlayerLoopTimer(interval, periodic, playerLoopTiming, cancellationToken, timerCallback, state); + } + } + + public static PlayerLoopTimer StartNew(TimeSpan interval, bool periodic, DelayType delayType, PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken, Action timerCallback, object state) + { + var timer = Create(interval, periodic, delayType, playerLoopTiming, cancellationToken, timerCallback, state); + timer.Restart(); + return timer; + } + + /// + /// Restart(Reset and Start) timer. + /// + public void Restart() + { + if (isDisposed) throw new ObjectDisposedException(null); + + ResetCore(null); // init state + if (!isRunning) + { + isRunning = true; + PlayerLoopHelper.AddAction(playerLoopTiming, this); + } + tryStop = false; + } + + /// + /// Restart(Reset and Start) and change interval. + /// + public void Restart(TimeSpan interval) + { + if (isDisposed) throw new ObjectDisposedException(null); + + ResetCore(interval); // init state + if (!isRunning) + { + isRunning = true; + PlayerLoopHelper.AddAction(playerLoopTiming, this); + } + tryStop = false; + } + + /// + /// Stop timer. + /// + public void Stop() + { + tryStop = true; + } + + protected abstract void ResetCore(TimeSpan? newInterval); + + public void Dispose() + { + isDisposed = true; + } + + bool IPlayerLoopItem.MoveNext() + { + if (isDisposed) + { + isRunning = false; + return false; + } + if (tryStop) + { + isRunning = false; + return false; + } + if (cancellationToken.IsCancellationRequested) + { + isRunning = false; + return false; + } + + if (!MoveNextCore()) + { + timerCallback(state); + + if (periodic) + { + ResetCore(null); + return true; + } + else + { + isRunning = false; + return false; + } + } + + return true; + } + + protected abstract bool MoveNextCore(); + } + + sealed class DeltaTimePlayerLoopTimer : PlayerLoopTimer + { + int initialFrame; + float elapsed; + float interval; + + public DeltaTimePlayerLoopTimer(TimeSpan interval, bool periodic, PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken, Action timerCallback, object state) + : base(periodic, playerLoopTiming, cancellationToken, timerCallback, state) + { + ResetCore(interval); + } + + protected override bool MoveNextCore() + { + if (elapsed == 0.0f) + { + if (initialFrame == Time.frameCount) + { + return true; + } + } + + elapsed += Time.deltaTime; + if (elapsed >= interval) + { + return false; + } + + return true; + } + + protected override void ResetCore(TimeSpan? interval) + { + this.elapsed = 0.0f; + this.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + if (interval != null) + { + this.interval = (float)interval.Value.TotalSeconds; + } + } + } + + sealed class IgnoreTimeScalePlayerLoopTimer : PlayerLoopTimer + { + int initialFrame; + float elapsed; + float interval; + + public IgnoreTimeScalePlayerLoopTimer(TimeSpan interval, bool periodic, PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken, Action timerCallback, object state) + : base(periodic, playerLoopTiming, cancellationToken, timerCallback, state) + { + ResetCore(interval); + } + + protected override bool MoveNextCore() + { + if (elapsed == 0.0f) + { + if (initialFrame == Time.frameCount) + { + return true; + } + } + + elapsed += Time.unscaledDeltaTime; + if (elapsed >= interval) + { + return false; + } + + return true; + } + + protected override void ResetCore(TimeSpan? interval) + { + this.elapsed = 0.0f; + this.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + if (interval != null) + { + this.interval = (float)interval.Value.TotalSeconds; + } + } + } + + sealed class RealtimePlayerLoopTimer : PlayerLoopTimer + { + ValueStopwatch stopwatch; + long intervalTicks; + + public RealtimePlayerLoopTimer(TimeSpan interval, bool periodic, PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken, Action timerCallback, object state) + : base(periodic, playerLoopTiming, cancellationToken, timerCallback, state) + { + ResetCore(interval); + } + + protected override bool MoveNextCore() + { + if (stopwatch.ElapsedTicks >= intervalTicks) + { + return false; + } + + return true; + } + + protected override void ResetCore(TimeSpan? interval) + { + this.stopwatch = ValueStopwatch.StartNew(); + if (interval != null) + { + this.intervalTicks = interval.Value.Ticks; + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopTimer.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopTimer.cs.meta new file mode 100644 index 0000000..eb2b50a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/PlayerLoopTimer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57095a17fdca7ee4380450910afc7f26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Progress.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Progress.cs new file mode 100644 index 0000000..ed11290 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Progress.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + /// + /// Lightweight IProgress[T] factory. + /// + public static class Progress + { + public static IProgress Create(Action handler) + { + if (handler == null) return NullProgress.Instance; + return new AnonymousProgress(handler); + } + + public static IProgress CreateOnlyValueChanged(Action handler, IEqualityComparer comparer = null) + { + if (handler == null) return NullProgress.Instance; +#if UNITY_2018_3_OR_NEWER + return new OnlyValueChangedProgress(handler, comparer ?? UnityEqualityComparer.GetDefault()); +#else + return new OnlyValueChangedProgress(handler, comparer ?? EqualityComparer.Default); +#endif + } + + sealed class NullProgress : IProgress + { + public static readonly IProgress Instance = new NullProgress(); + + NullProgress() + { + + } + + public void Report(T value) + { + } + } + + sealed class AnonymousProgress : IProgress + { + readonly Action action; + + public AnonymousProgress(Action action) + { + this.action = action; + } + + public void Report(T value) + { + action(value); + } + } + + sealed class OnlyValueChangedProgress : IProgress + { + readonly Action action; + readonly IEqualityComparer comparer; + bool isFirstCall; + T latestValue; + + public OnlyValueChangedProgress(Action action, IEqualityComparer 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); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Progress.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Progress.cs.meta new file mode 100644 index 0000000..f0e1f19 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Progress.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3377e2ae934ed54fb8fd5388e2d9eb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TaskPool.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TaskPool.cs new file mode 100644 index 0000000..e103559 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TaskPool.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + // internally used but public, allow to user create custom operator with pooling. + + public static class TaskPool + { + internal static int MaxPoolSize; + + // avoid to use ConcurrentDictionary for safety of WebGL build. + static Dictionary> sizes = new Dictionary>(); + + static TaskPool() + { + try + { + var value = Environment.GetEnvironmentVariable("UNITASK_MAX_POOLSIZE"); + if (value != null) + { + if (int.TryParse(value, out var size)) + { + MaxPoolSize = size; + return; + } + } + } + catch { } + + MaxPoolSize = int.MaxValue; + } + + public static void SetMaxPoolSize(int maxPoolSize) + { + MaxPoolSize = maxPoolSize; + } + + public static IEnumerable<(Type, int)> GetCacheSizeInfo() + { + lock (sizes) + { + foreach (var item in sizes) + { + yield return (item.Key, item.Value()); + } + } + } + + public static void RegisterSizeGetter(Type type, Func getSize) + { + lock (sizes) + { + sizes[type] = getSize; + } + } + } + + public interface ITaskPoolNode + { + ref T NextNode { get; } + } + + // mutable struct, don't mark readonly. + [StructLayout(LayoutKind.Auto)] + public struct TaskPool + where T : class, ITaskPoolNode + { + int gate; + int size; + T root; + + public int Size => size; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPop(out T result) + { + if (Interlocked.CompareExchange(ref gate, 1, 0) == 0) + { + var v = root; + if (!(v is null)) + { + ref var nextNode = ref v.NextNode; + root = nextNode; + nextNode = null; + size--; + result = v; + Volatile.Write(ref gate, 0); + return true; + } + + Volatile.Write(ref gate, 0); + } + result = default; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPush(T item) + { + if (Interlocked.CompareExchange(ref gate, 1, 0) == 0) + { + if (size < TaskPool.MaxPoolSize) + { + item.NextNode = root; + root = item; + size++; + Volatile.Write(ref gate, 0); + return true; + } + else + { + Volatile.Write(ref gate, 0); + } + } + return false; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TaskPool.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TaskPool.cs.meta new file mode 100644 index 0000000..94c7805 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TaskPool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19f4e6575150765449cc99f25f06f25f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TimeoutController.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TimeoutController.cs new file mode 100644 index 0000000..faca347 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TimeoutController.cs @@ -0,0 +1,129 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + // CancellationTokenSource itself can not reuse but CancelAfter(Timeout.InfiniteTimeSpan) allows reuse if did not reach timeout. + // Similar discussion: + // https://github.com/dotnet/runtime/issues/4694 + // https://github.com/dotnet/runtime/issues/48492 + // This TimeoutController emulate similar implementation, using CancelAfterSlim; to achieve zero allocation timeout. + + public sealed class TimeoutController : IDisposable + { + readonly static Action CancelCancellationTokenSourceStateDelegate = new Action(CancelCancellationTokenSourceState); + + static void CancelCancellationTokenSourceState(object state) + { + var cts = (CancellationTokenSource)state; + cts.Cancel(); + } + + CancellationTokenSource timeoutSource; + CancellationTokenSource linkedSource; + PlayerLoopTimer timer; + bool isDisposed; + + readonly DelayType delayType; + readonly PlayerLoopTiming delayTiming; + readonly CancellationTokenSource originalLinkCancellationTokenSource; + + public TimeoutController(DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update) + { + this.timeoutSource = new CancellationTokenSource(); + this.originalLinkCancellationTokenSource = null; + this.linkedSource = null; + this.delayType = delayType; + this.delayTiming = delayTiming; + } + + public TimeoutController(CancellationTokenSource linkCancellationTokenSource, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update) + { + this.timeoutSource = new CancellationTokenSource(); + this.originalLinkCancellationTokenSource = linkCancellationTokenSource; + this.linkedSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutSource.Token, linkCancellationTokenSource.Token); + this.delayType = delayType; + this.delayTiming = delayTiming; + } + + public CancellationToken Timeout(int millisecondsTimeout) + { + return Timeout(TimeSpan.FromMilliseconds(millisecondsTimeout)); + } + + public CancellationToken Timeout(TimeSpan timeout) + { + if (originalLinkCancellationTokenSource != null && originalLinkCancellationTokenSource.IsCancellationRequested) + { + return originalLinkCancellationTokenSource.Token; + } + + // Timeouted, create new source and timer. + if (timeoutSource.IsCancellationRequested) + { + timeoutSource.Dispose(); + timeoutSource = new CancellationTokenSource(); + if (linkedSource != null) + { + this.linkedSource.Cancel(); + this.linkedSource.Dispose(); + this.linkedSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutSource.Token, originalLinkCancellationTokenSource.Token); + } + + timer?.Dispose(); + timer = null; + } + + var useSource = (linkedSource != null) ? linkedSource : timeoutSource; + var token = useSource.Token; + if (timer == null) + { + // Timer complete => timeoutSource.Cancel() -> linkedSource will be canceled. + // (linked)token is canceled => stop timer + timer = PlayerLoopTimer.StartNew(timeout, false, delayType, delayTiming, token, CancelCancellationTokenSourceStateDelegate, timeoutSource); + } + else + { + timer.Restart(timeout); + } + + return token; + } + + public bool IsTimeout() + { + return timeoutSource.IsCancellationRequested; + } + + public void Reset() + { + timer?.Stop(); + } + + public void Dispose() + { + if (isDisposed) return; + + try + { + // stop timer. + timer?.Dispose(); + + // cancel and dispose. + timeoutSource.Cancel(); + timeoutSource.Dispose(); + if (linkedSource != null) + { + linkedSource.Cancel(); + linkedSource.Dispose(); + } + } + finally + { + isDisposed = true; + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TimeoutController.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TimeoutController.cs.meta new file mode 100644 index 0000000..4f3d16d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TimeoutController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6347ab34d2db6d744a654e8d62d96b96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TriggerEvent.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TriggerEvent.cs new file mode 100644 index 0000000..503e9db --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TriggerEvent.cs @@ -0,0 +1,311 @@ +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public interface ITriggerHandler + { + void OnNext(T value); + void OnError(Exception ex); + void OnCompleted(); + void OnCanceled(CancellationToken cancellationToken); + + // set/get from TriggerEvent + ITriggerHandler Prev { get; set; } + ITriggerHandler Next { get; set; } + } + + // be careful to use, itself is struct. + public struct TriggerEvent + { + ITriggerHandler head; // head.prev is last + ITriggerHandler iteratingHead; + + bool preserveRemoveSelf; + ITriggerHandler iteratingNode; + + void LogError(Exception ex) + { +#if UNITY_2018_3_OR_NEWER + UnityEngine.Debug.LogException(ex); +#else + Console.WriteLine(ex); +#endif + } + + public void SetResult(T value) + { + if (iteratingNode != null) + { + throw new InvalidOperationException("Can not trigger itself in iterating."); + } + + var h = head; + while (h != null) + { + iteratingNode = h; + + try + { + h.OnNext(value); + } + catch (Exception ex) + { + LogError(ex); + Remove(h); + } + + if (preserveRemoveSelf) + { + preserveRemoveSelf = false; + iteratingNode = null; + var next = h.Next; + Remove(h); + h = next; + } + else + { + h = h.Next; + } + } + + iteratingNode = null; + if (iteratingHead != null) + { + Add(iteratingHead); + iteratingHead = null; + } + } + + public void SetCanceled(CancellationToken cancellationToken) + { + if (iteratingNode != null) + { + throw new InvalidOperationException("Can not trigger itself in iterating."); + } + + var h = head; + while (h != null) + { + iteratingNode = h; + try + { + h.OnCanceled(cancellationToken); + } + catch (Exception ex) + { + LogError(ex); + } + + preserveRemoveSelf = false; + iteratingNode = null; + var next = h.Next; + Remove(h); + h = next; + } + + iteratingNode = null; + if (iteratingHead != null) + { + Add(iteratingHead); + iteratingHead = null; + } + } + + public void SetCompleted() + { + if (iteratingNode != null) + { + throw new InvalidOperationException("Can not trigger itself in iterating."); + } + + var h = head; + while (h != null) + { + iteratingNode = h; + try + { + h.OnCompleted(); + } + catch (Exception ex) + { + LogError(ex); + } + + preserveRemoveSelf = false; + iteratingNode = null; + var next = h.Next; + Remove(h); + h = next; + } + + iteratingNode = null; + if (iteratingHead != null) + { + Add(iteratingHead); + iteratingHead = null; + } + } + + public void SetError(Exception exception) + { + if (iteratingNode != null) + { + throw new InvalidOperationException("Can not trigger itself in iterating."); + } + + var h = head; + while (h != null) + { + iteratingNode = h; + try + { + h.OnError(exception); + } + catch (Exception ex) + { + LogError(ex); + } + + preserveRemoveSelf = false; + iteratingNode = null; + var next = h.Next; + Remove(h); + h = next; + } + + iteratingNode = null; + if (iteratingHead != null) + { + Add(iteratingHead); + iteratingHead = null; + } + } + + public void Add(ITriggerHandler handler) + { + if (handler == null) throw new ArgumentNullException(nameof(handler)); + + // zero node. + if (head == null) + { + head = handler; + return; + } + + if (iteratingNode != null) + { + if (iteratingHead == null) + { + iteratingHead = handler; + return; + } + + var last = iteratingHead.Prev; + if (last == null) + { + // single node. + iteratingHead.Prev = handler; + iteratingHead.Next = handler; + handler.Prev = iteratingHead; + } + else + { + // multi node + iteratingHead.Prev = handler; + last.Next = handler; + handler.Prev = last; + } + } + else + { + var last = head.Prev; + if (last == null) + { + // single node. + head.Prev = handler; + head.Next = handler; + handler.Prev = head; + } + else + { + // multi node + head.Prev = handler; + last.Next = handler; + handler.Prev = last; + } + } + } + + public void Remove(ITriggerHandler handler) + { + if (handler == null) throw new ArgumentNullException(nameof(handler)); + + if (iteratingNode != null && iteratingNode == handler) + { + // if remove self, reserve remove self after invoke completed. + preserveRemoveSelf = true; + } + else + { + var prev = handler.Prev; + var next = handler.Next; + + if (next != null) + { + next.Prev = prev; + } + + if (handler == head) + { + head = next; + } + else if (handler == iteratingHead) + { + iteratingHead = next; + } + else + { + // when handler is head, prev indicate last so don't use it. + if (prev != null) + { + prev.Next = next; + } + } + + if (head != null) + { + if (head.Prev == handler) + { + if (prev != head) + { + head.Prev = prev; + } + else + { + head.Prev = null; + } + } + } + + if (iteratingHead != null) + { + if (iteratingHead.Prev == handler) + { + if (prev != iteratingHead.Prev) + { + iteratingHead.Prev = prev; + } + else + { + iteratingHead.Prev = null; + } + } + } + + handler.Prev = null; + handler.Next = null; + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TriggerEvent.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TriggerEvent.cs.meta new file mode 100644 index 0000000..bbd47af --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/TriggerEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f68b22bb8f66f5c4885f9bd3c4fc43ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers.meta new file mode 100644 index 0000000..31c855b --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 312f94adae2fe444aa6dcc6f0428dad8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs new file mode 100644 index 0000000..a734f29 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs @@ -0,0 +1,32 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System.Threading; +using UnityEngine; + +namespace Cysharp.Threading.Tasks.Triggers +{ + public static partial class AsyncTriggerExtensions + { + public static AsyncAwakeTrigger GetAsyncAwakeTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncAwakeTrigger GetAsyncAwakeTrigger(this Component component) + { + return component.gameObject.GetAsyncAwakeTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncAwakeTrigger : AsyncTriggerBase + { + public UniTask AwakeAsync() + { + if (calledAwake) return UniTask.CompletedTask; + + return ((IAsyncOneShotTrigger)new AsyncTriggerHandler(this, true)).OneShotAsync(); + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs.meta new file mode 100644 index 0000000..097fdb6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef2840a2586894741a0ae211b8fd669b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs new file mode 100644 index 0000000..811f977 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs @@ -0,0 +1,97 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System.Threading; +using UnityEngine; + +namespace Cysharp.Threading.Tasks.Triggers +{ + public static partial class AsyncTriggerExtensions + { + public static AsyncDestroyTrigger GetAsyncDestroyTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncDestroyTrigger GetAsyncDestroyTrigger(this Component component) + { + return component.gameObject.GetAsyncDestroyTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncDestroyTrigger : MonoBehaviour + { + bool awakeCalled = false; + bool called = false; + CancellationTokenSource cancellationTokenSource; + + public CancellationToken CancellationToken + { + get + { + if (cancellationTokenSource == null) + { + cancellationTokenSource = new CancellationTokenSource(); + } + + if (!awakeCalled) + { + PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, new AwakeMonitor(this)); + } + + return cancellationTokenSource.Token; + } + } + + void Awake() + { + awakeCalled = true; + } + + void OnDestroy() + { + called = true; + + cancellationTokenSource?.Cancel(); + cancellationTokenSource?.Dispose(); + } + + public UniTask OnDestroyAsync() + { + if (called) return UniTask.CompletedTask; + + var tcs = new UniTaskCompletionSource(); + + // OnDestroy = Called Cancel. + CancellationToken.RegisterWithoutCaptureExecutionContext(state => + { + var tcs2 = (UniTaskCompletionSource)state; + tcs2.TrySetResult(); + }, tcs); + + return tcs.Task; + } + + class AwakeMonitor : IPlayerLoopItem + { + readonly AsyncDestroyTrigger trigger; + + public AwakeMonitor(AsyncDestroyTrigger trigger) + { + this.trigger = trigger; + } + + public bool MoveNext() + { + if (trigger.called) return false; + if (trigger == null) + { + trigger.OnDestroy(); + return false; + } + return true; + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs.meta new file mode 100644 index 0000000..6450049 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4afdcb1cbadf954ba8b1cf465429e17 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncStartTrigger.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncStartTrigger.cs new file mode 100644 index 0000000..63da82a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncStartTrigger.cs @@ -0,0 +1,38 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using UnityEngine; + +namespace Cysharp.Threading.Tasks.Triggers +{ + public static partial class AsyncTriggerExtensions + { + public static AsyncStartTrigger GetAsyncStartTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncStartTrigger GetAsyncStartTrigger(this Component component) + { + return component.gameObject.GetAsyncStartTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncStartTrigger : AsyncTriggerBase + { + bool called; + + void Start() + { + called = true; + RaiseEvent(AsyncUnit.Default); + } + + public UniTask StartAsync() + { + if (called) return UniTask.CompletedTask; + + return ((IAsyncOneShotTrigger)new AsyncTriggerHandler(this, true)).OneShotAsync(); + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncStartTrigger.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncStartTrigger.cs.meta new file mode 100644 index 0000000..9ef06e8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncStartTrigger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4fd0f75e54ec3d4fbcb7fc65b11646b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerBase.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerBase.cs new file mode 100644 index 0000000..fb6ca6e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerBase.cs @@ -0,0 +1,310 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Threading; +using UnityEngine; + +namespace Cysharp.Threading.Tasks.Triggers +{ + public abstract class AsyncTriggerBase : MonoBehaviour, IUniTaskAsyncEnumerable + { + TriggerEvent triggerEvent; + + internal protected bool calledAwake; + internal protected bool calledDestroy; + + void Awake() + { + calledAwake = true; + } + + void OnDestroy() + { + if (calledDestroy) return; + calledDestroy = true; + + triggerEvent.SetCompleted(); + } + + internal void AddHandler(ITriggerHandler handler) + { + if (!calledAwake) + { + PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, new AwakeMonitor(this)); + } + + triggerEvent.Add(handler); + } + + internal void RemoveHandler(ITriggerHandler handler) + { + if (!calledAwake) + { + PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, new AwakeMonitor(this)); + } + + triggerEvent.Remove(handler); + } + + protected void RaiseEvent(T value) + { + triggerEvent.SetResult(value); + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new AsyncTriggerEnumerator(this, cancellationToken); + } + + sealed class AsyncTriggerEnumerator : MoveNextSource, IUniTaskAsyncEnumerator, ITriggerHandler + { + static Action cancellationCallback = CancellationCallback; + + readonly AsyncTriggerBase parent; + CancellationToken cancellationToken; + CancellationTokenRegistration registration; + bool called; + bool isDisposed; + + public AsyncTriggerEnumerator(AsyncTriggerBase parent, CancellationToken cancellationToken) + { + this.parent = parent; + this.cancellationToken = cancellationToken; + } + + public void OnCanceled(CancellationToken cancellationToken = default) + { + completionSource.TrySetCanceled(cancellationToken); + } + + public void OnNext(T value) + { + Current = value; + completionSource.TrySetResult(true); + } + + public void OnCompleted() + { + completionSource.TrySetResult(false); + } + + public void OnError(Exception ex) + { + completionSource.TrySetException(ex); + } + + static void CancellationCallback(object state) + { + var self = (AsyncTriggerEnumerator)state; + self.DisposeAsync().Forget(); // sync + + self.completionSource.TrySetCanceled(self.cancellationToken); + } + + public T Current { get; private set; } + ITriggerHandler ITriggerHandler.Prev { get; set; } + ITriggerHandler ITriggerHandler.Next { get; set; } + + public UniTask MoveNextAsync() + { + cancellationToken.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (!called) + { + called = true; + + TaskTracker.TrackActiveTask(this, 3); + parent.AddHandler(this); + if (cancellationToken.CanBeCanceled) + { + registration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); + } + } + + return new UniTask(this, completionSource.Version); + } + + public UniTask DisposeAsync() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + registration.Dispose(); + parent.RemoveHandler(this); + } + + return default; + } + } + + class AwakeMonitor : IPlayerLoopItem + { + readonly AsyncTriggerBase trigger; + + public AwakeMonitor(AsyncTriggerBase trigger) + { + this.trigger = trigger; + } + + public bool MoveNext() + { + if (trigger.calledAwake) return false; + if (trigger == null) + { + trigger.OnDestroy(); + return false; + } + return true; + } + } + } + + public interface IAsyncOneShotTrigger + { + UniTask OneShotAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOneShotTrigger + { + UniTask IAsyncOneShotTrigger.OneShotAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)this, core.Version); + } + } + + public sealed partial class AsyncTriggerHandler : IUniTaskSource, ITriggerHandler, IDisposable + { + static Action cancellationCallback = CancellationCallback; + + readonly AsyncTriggerBase trigger; + + CancellationToken cancellationToken; + CancellationTokenRegistration registration; + bool isDisposed; + bool callOnce; + + UniTaskCompletionSourceCore core; + + internal CancellationToken CancellationToken => cancellationToken; + + ITriggerHandler ITriggerHandler.Prev { get; set; } + ITriggerHandler ITriggerHandler.Next { get; set; } + + internal AsyncTriggerHandler(AsyncTriggerBase trigger, bool callOnce) + { + if (cancellationToken.IsCancellationRequested) + { + isDisposed = true; + return; + } + + this.trigger = trigger; + this.cancellationToken = default; + this.registration = default; + this.callOnce = callOnce; + + trigger.AddHandler(this); + + TaskTracker.TrackActiveTask(this, 3); + } + + internal AsyncTriggerHandler(AsyncTriggerBase trigger, CancellationToken cancellationToken, bool callOnce) + { + if (cancellationToken.IsCancellationRequested) + { + isDisposed = true; + return; + } + + this.trigger = trigger; + this.cancellationToken = cancellationToken; + this.callOnce = callOnce; + + trigger.AddHandler(this); + + if (cancellationToken.CanBeCanceled) + { + registration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); + } + + TaskTracker.TrackActiveTask(this, 3); + } + + static void CancellationCallback(object state) + { + var self = (AsyncTriggerHandler)state; + self.Dispose(); + + self.core.TrySetCanceled(self.cancellationToken); + } + + public void Dispose() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + registration.Dispose(); + trigger.RemoveHandler(this); + } + } + + T IUniTaskSource.GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + if (callOnce) + { + Dispose(); + } + } + } + + void ITriggerHandler.OnNext(T value) + { + core.TrySetResult(value); + } + + void ITriggerHandler.OnCanceled(CancellationToken cancellationToken) + { + core.TrySetCanceled(cancellationToken); + } + + void ITriggerHandler.OnCompleted() + { + core.TrySetCanceled(CancellationToken.None); + } + + void ITriggerHandler.OnError(Exception ex) + { + core.TrySetException(ex); + } + + void IUniTaskSource.GetResult(short token) + { + ((IUniTaskSource)this).GetResult(token); + } + + UniTaskStatus IUniTaskSource.GetStatus(short token) + { + return core.GetStatus(token); + } + + UniTaskStatus IUniTaskSource.UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerBase.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerBase.cs.meta new file mode 100644 index 0000000..e101ea2 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c0c2bcee832c6641b25949c412f020f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs new file mode 100644 index 0000000..bad5a04 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs @@ -0,0 +1,102 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System.Threading; +using UnityEngine; +using Cysharp.Threading.Tasks.Triggers; + +namespace Cysharp.Threading.Tasks +{ + public static class UniTaskCancellationExtensions + { +#if UNITY_2022_2_OR_NEWER + + /// This CancellationToken is canceled when the MonoBehaviour will be destroyed. + public static CancellationToken GetCancellationTokenOnDestroy(this MonoBehaviour monoBehaviour) + { + return monoBehaviour.destroyCancellationToken; + } + +#endif + + /// This CancellationToken is canceled when the MonoBehaviour will be destroyed. + public static CancellationToken GetCancellationTokenOnDestroy(this GameObject gameObject) + { + return gameObject.GetAsyncDestroyTrigger().CancellationToken; + } + + /// This CancellationToken is canceled when the MonoBehaviour will be destroyed. + public static CancellationToken GetCancellationTokenOnDestroy(this Component component) + { +#if UNITY_2022_2_OR_NEWER + if (component is MonoBehaviour mb) + { + return mb.destroyCancellationToken; + } +#endif + + return component.GetAsyncDestroyTrigger().CancellationToken; + } + } +} + +namespace Cysharp.Threading.Tasks.Triggers +{ + public static partial class AsyncTriggerExtensions + { + // Util. + + static T GetOrAddComponent(GameObject gameObject) + where T : Component + { +#if UNITY_2019_2_OR_NEWER + if (!gameObject.TryGetComponent(out var component)) + { + component = gameObject.AddComponent(); + } +#else + var component = gameObject.GetComponent(); + if (component == null) + { + component = gameObject.AddComponent(); + } +#endif + + return component; + } + + // Special for single operation. + + /// This function is called when the MonoBehaviour will be destroyed. + public static UniTask OnDestroyAsync(this GameObject gameObject) + { + return gameObject.GetAsyncDestroyTrigger().OnDestroyAsync(); + } + + /// This function is called when the MonoBehaviour will be destroyed. + public static UniTask OnDestroyAsync(this Component component) + { + return component.GetAsyncDestroyTrigger().OnDestroyAsync(); + } + + public static UniTask StartAsync(this GameObject gameObject) + { + return gameObject.GetAsyncStartTrigger().StartAsync(); + } + + public static UniTask StartAsync(this Component component) + { + return component.GetAsyncStartTrigger().StartAsync(); + } + + public static UniTask AwakeAsync(this GameObject gameObject) + { + return gameObject.GetAsyncAwakeTrigger().AwakeAsync(); + } + + public static UniTask AwakeAsync(this Component component) + { + return component.GetAsyncAwakeTrigger().AwakeAsync(); + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs.meta new file mode 100644 index 0000000..348783d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59b61dbea1562a84fb7a38ae0a0a0f88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs new file mode 100644 index 0000000..6ef5014 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs @@ -0,0 +1,4457 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System.Threading; +using UnityEngine; +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT +using UnityEngine.EventSystems; +#endif + +namespace Cysharp.Threading.Tasks.Triggers +{ +#region FixedUpdate + + public interface IAsyncFixedUpdateHandler + { + UniTask FixedUpdateAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncFixedUpdateHandler + { + UniTask IAsyncFixedUpdateHandler.FixedUpdateAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncFixedUpdateTrigger GetAsyncFixedUpdateTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncFixedUpdateTrigger GetAsyncFixedUpdateTrigger(this Component component) + { + return component.gameObject.GetAsyncFixedUpdateTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncFixedUpdateTrigger : AsyncTriggerBase + { + void FixedUpdate() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncFixedUpdateHandler GetFixedUpdateAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncFixedUpdateHandler GetFixedUpdateAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask FixedUpdateAsync() + { + return ((IAsyncFixedUpdateHandler)new AsyncTriggerHandler(this, true)).FixedUpdateAsync(); + } + + public UniTask FixedUpdateAsync(CancellationToken cancellationToken) + { + return ((IAsyncFixedUpdateHandler)new AsyncTriggerHandler(this, cancellationToken, true)).FixedUpdateAsync(); + } + } +#endregion + +#region LateUpdate + + public interface IAsyncLateUpdateHandler + { + UniTask LateUpdateAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncLateUpdateHandler + { + UniTask IAsyncLateUpdateHandler.LateUpdateAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncLateUpdateTrigger GetAsyncLateUpdateTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncLateUpdateTrigger GetAsyncLateUpdateTrigger(this Component component) + { + return component.gameObject.GetAsyncLateUpdateTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncLateUpdateTrigger : AsyncTriggerBase + { + void LateUpdate() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncLateUpdateHandler GetLateUpdateAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncLateUpdateHandler GetLateUpdateAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask LateUpdateAsync() + { + return ((IAsyncLateUpdateHandler)new AsyncTriggerHandler(this, true)).LateUpdateAsync(); + } + + public UniTask LateUpdateAsync(CancellationToken cancellationToken) + { + return ((IAsyncLateUpdateHandler)new AsyncTriggerHandler(this, cancellationToken, true)).LateUpdateAsync(); + } + } +#endregion + +#region AnimatorIK + + public interface IAsyncOnAnimatorIKHandler + { + UniTask OnAnimatorIKAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnAnimatorIKHandler + { + UniTask IAsyncOnAnimatorIKHandler.OnAnimatorIKAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncAnimatorIKTrigger GetAsyncAnimatorIKTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncAnimatorIKTrigger GetAsyncAnimatorIKTrigger(this Component component) + { + return component.gameObject.GetAsyncAnimatorIKTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncAnimatorIKTrigger : AsyncTriggerBase + { + void OnAnimatorIK(int layerIndex) + { + RaiseEvent((layerIndex)); + } + + public IAsyncOnAnimatorIKHandler GetOnAnimatorIKAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnAnimatorIKHandler GetOnAnimatorIKAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnAnimatorIKAsync() + { + return ((IAsyncOnAnimatorIKHandler)new AsyncTriggerHandler(this, true)).OnAnimatorIKAsync(); + } + + public UniTask OnAnimatorIKAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnAnimatorIKHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnAnimatorIKAsync(); + } + } +#endregion + +#region AnimatorMove + + public interface IAsyncOnAnimatorMoveHandler + { + UniTask OnAnimatorMoveAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnAnimatorMoveHandler + { + UniTask IAsyncOnAnimatorMoveHandler.OnAnimatorMoveAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncAnimatorMoveTrigger GetAsyncAnimatorMoveTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncAnimatorMoveTrigger GetAsyncAnimatorMoveTrigger(this Component component) + { + return component.gameObject.GetAsyncAnimatorMoveTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncAnimatorMoveTrigger : AsyncTriggerBase + { + void OnAnimatorMove() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnAnimatorMoveHandler GetOnAnimatorMoveAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnAnimatorMoveHandler GetOnAnimatorMoveAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnAnimatorMoveAsync() + { + return ((IAsyncOnAnimatorMoveHandler)new AsyncTriggerHandler(this, true)).OnAnimatorMoveAsync(); + } + + public UniTask OnAnimatorMoveAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnAnimatorMoveHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnAnimatorMoveAsync(); + } + } +#endregion + +#region ApplicationFocus + + public interface IAsyncOnApplicationFocusHandler + { + UniTask OnApplicationFocusAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnApplicationFocusHandler + { + UniTask IAsyncOnApplicationFocusHandler.OnApplicationFocusAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncApplicationFocusTrigger GetAsyncApplicationFocusTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncApplicationFocusTrigger GetAsyncApplicationFocusTrigger(this Component component) + { + return component.gameObject.GetAsyncApplicationFocusTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncApplicationFocusTrigger : AsyncTriggerBase + { + void OnApplicationFocus(bool hasFocus) + { + RaiseEvent((hasFocus)); + } + + public IAsyncOnApplicationFocusHandler GetOnApplicationFocusAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnApplicationFocusHandler GetOnApplicationFocusAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnApplicationFocusAsync() + { + return ((IAsyncOnApplicationFocusHandler)new AsyncTriggerHandler(this, true)).OnApplicationFocusAsync(); + } + + public UniTask OnApplicationFocusAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnApplicationFocusHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnApplicationFocusAsync(); + } + } +#endregion + +#region ApplicationPause + + public interface IAsyncOnApplicationPauseHandler + { + UniTask OnApplicationPauseAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnApplicationPauseHandler + { + UniTask IAsyncOnApplicationPauseHandler.OnApplicationPauseAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncApplicationPauseTrigger GetAsyncApplicationPauseTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncApplicationPauseTrigger GetAsyncApplicationPauseTrigger(this Component component) + { + return component.gameObject.GetAsyncApplicationPauseTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncApplicationPauseTrigger : AsyncTriggerBase + { + void OnApplicationPause(bool pauseStatus) + { + RaiseEvent((pauseStatus)); + } + + public IAsyncOnApplicationPauseHandler GetOnApplicationPauseAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnApplicationPauseHandler GetOnApplicationPauseAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnApplicationPauseAsync() + { + return ((IAsyncOnApplicationPauseHandler)new AsyncTriggerHandler(this, true)).OnApplicationPauseAsync(); + } + + public UniTask OnApplicationPauseAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnApplicationPauseHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnApplicationPauseAsync(); + } + } +#endregion + +#region ApplicationQuit + + public interface IAsyncOnApplicationQuitHandler + { + UniTask OnApplicationQuitAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnApplicationQuitHandler + { + UniTask IAsyncOnApplicationQuitHandler.OnApplicationQuitAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncApplicationQuitTrigger GetAsyncApplicationQuitTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncApplicationQuitTrigger GetAsyncApplicationQuitTrigger(this Component component) + { + return component.gameObject.GetAsyncApplicationQuitTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncApplicationQuitTrigger : AsyncTriggerBase + { + void OnApplicationQuit() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnApplicationQuitHandler GetOnApplicationQuitAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnApplicationQuitHandler GetOnApplicationQuitAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnApplicationQuitAsync() + { + return ((IAsyncOnApplicationQuitHandler)new AsyncTriggerHandler(this, true)).OnApplicationQuitAsync(); + } + + public UniTask OnApplicationQuitAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnApplicationQuitHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnApplicationQuitAsync(); + } + } +#endregion + +#region AudioFilterRead + + public interface IAsyncOnAudioFilterReadHandler + { + UniTask<(float[] data, int channels)> OnAudioFilterReadAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnAudioFilterReadHandler + { + UniTask<(float[] data, int channels)> IAsyncOnAudioFilterReadHandler.OnAudioFilterReadAsync() + { + core.Reset(); + return new UniTask<(float[] data, int channels)>((IUniTaskSource<(float[] data, int channels)>)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncAudioFilterReadTrigger GetAsyncAudioFilterReadTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncAudioFilterReadTrigger GetAsyncAudioFilterReadTrigger(this Component component) + { + return component.gameObject.GetAsyncAudioFilterReadTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncAudioFilterReadTrigger : AsyncTriggerBase<(float[] data, int channels)> + { + void OnAudioFilterRead(float[] data, int channels) + { + RaiseEvent((data, channels)); + } + + public IAsyncOnAudioFilterReadHandler GetOnAudioFilterReadAsyncHandler() + { + return new AsyncTriggerHandler<(float[] data, int channels)>(this, false); + } + + public IAsyncOnAudioFilterReadHandler GetOnAudioFilterReadAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler<(float[] data, int channels)>(this, cancellationToken, false); + } + + public UniTask<(float[] data, int channels)> OnAudioFilterReadAsync() + { + return ((IAsyncOnAudioFilterReadHandler)new AsyncTriggerHandler<(float[] data, int channels)>(this, true)).OnAudioFilterReadAsync(); + } + + public UniTask<(float[] data, int channels)> OnAudioFilterReadAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnAudioFilterReadHandler)new AsyncTriggerHandler<(float[] data, int channels)>(this, cancellationToken, true)).OnAudioFilterReadAsync(); + } + } +#endregion + +#region BecameInvisible + + public interface IAsyncOnBecameInvisibleHandler + { + UniTask OnBecameInvisibleAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnBecameInvisibleHandler + { + UniTask IAsyncOnBecameInvisibleHandler.OnBecameInvisibleAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncBecameInvisibleTrigger GetAsyncBecameInvisibleTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncBecameInvisibleTrigger GetAsyncBecameInvisibleTrigger(this Component component) + { + return component.gameObject.GetAsyncBecameInvisibleTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncBecameInvisibleTrigger : AsyncTriggerBase + { + void OnBecameInvisible() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnBecameInvisibleHandler GetOnBecameInvisibleAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnBecameInvisibleHandler GetOnBecameInvisibleAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnBecameInvisibleAsync() + { + return ((IAsyncOnBecameInvisibleHandler)new AsyncTriggerHandler(this, true)).OnBecameInvisibleAsync(); + } + + public UniTask OnBecameInvisibleAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnBecameInvisibleHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnBecameInvisibleAsync(); + } + } +#endregion + +#region BecameVisible + + public interface IAsyncOnBecameVisibleHandler + { + UniTask OnBecameVisibleAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnBecameVisibleHandler + { + UniTask IAsyncOnBecameVisibleHandler.OnBecameVisibleAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncBecameVisibleTrigger GetAsyncBecameVisibleTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncBecameVisibleTrigger GetAsyncBecameVisibleTrigger(this Component component) + { + return component.gameObject.GetAsyncBecameVisibleTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncBecameVisibleTrigger : AsyncTriggerBase + { + void OnBecameVisible() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnBecameVisibleHandler GetOnBecameVisibleAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnBecameVisibleHandler GetOnBecameVisibleAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnBecameVisibleAsync() + { + return ((IAsyncOnBecameVisibleHandler)new AsyncTriggerHandler(this, true)).OnBecameVisibleAsync(); + } + + public UniTask OnBecameVisibleAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnBecameVisibleHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnBecameVisibleAsync(); + } + } +#endregion + +#region BeforeTransformParentChanged + + public interface IAsyncOnBeforeTransformParentChangedHandler + { + UniTask OnBeforeTransformParentChangedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnBeforeTransformParentChangedHandler + { + UniTask IAsyncOnBeforeTransformParentChangedHandler.OnBeforeTransformParentChangedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncBeforeTransformParentChangedTrigger GetAsyncBeforeTransformParentChangedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncBeforeTransformParentChangedTrigger GetAsyncBeforeTransformParentChangedTrigger(this Component component) + { + return component.gameObject.GetAsyncBeforeTransformParentChangedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncBeforeTransformParentChangedTrigger : AsyncTriggerBase + { + void OnBeforeTransformParentChanged() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnBeforeTransformParentChangedHandler GetOnBeforeTransformParentChangedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnBeforeTransformParentChangedHandler GetOnBeforeTransformParentChangedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnBeforeTransformParentChangedAsync() + { + return ((IAsyncOnBeforeTransformParentChangedHandler)new AsyncTriggerHandler(this, true)).OnBeforeTransformParentChangedAsync(); + } + + public UniTask OnBeforeTransformParentChangedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnBeforeTransformParentChangedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnBeforeTransformParentChangedAsync(); + } + } +#endregion + +#region OnCanvasGroupChanged + + public interface IAsyncOnCanvasGroupChangedHandler + { + UniTask OnCanvasGroupChangedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnCanvasGroupChangedHandler + { + UniTask IAsyncOnCanvasGroupChangedHandler.OnCanvasGroupChangedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncOnCanvasGroupChangedTrigger GetAsyncOnCanvasGroupChangedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncOnCanvasGroupChangedTrigger GetAsyncOnCanvasGroupChangedTrigger(this Component component) + { + return component.gameObject.GetAsyncOnCanvasGroupChangedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncOnCanvasGroupChangedTrigger : AsyncTriggerBase + { + void OnCanvasGroupChanged() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnCanvasGroupChangedHandler GetOnCanvasGroupChangedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnCanvasGroupChangedHandler GetOnCanvasGroupChangedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnCanvasGroupChangedAsync() + { + return ((IAsyncOnCanvasGroupChangedHandler)new AsyncTriggerHandler(this, true)).OnCanvasGroupChangedAsync(); + } + + public UniTask OnCanvasGroupChangedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnCanvasGroupChangedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnCanvasGroupChangedAsync(); + } + } +#endregion + +#region CollisionEnter +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS_SUPPORT + + public interface IAsyncOnCollisionEnterHandler + { + UniTask OnCollisionEnterAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnCollisionEnterHandler + { + UniTask IAsyncOnCollisionEnterHandler.OnCollisionEnterAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncCollisionEnterTrigger GetAsyncCollisionEnterTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncCollisionEnterTrigger GetAsyncCollisionEnterTrigger(this Component component) + { + return component.gameObject.GetAsyncCollisionEnterTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncCollisionEnterTrigger : AsyncTriggerBase + { + void OnCollisionEnter(Collision coll) + { + RaiseEvent((coll)); + } + + public IAsyncOnCollisionEnterHandler GetOnCollisionEnterAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnCollisionEnterHandler GetOnCollisionEnterAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnCollisionEnterAsync() + { + return ((IAsyncOnCollisionEnterHandler)new AsyncTriggerHandler(this, true)).OnCollisionEnterAsync(); + } + + public UniTask OnCollisionEnterAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnCollisionEnterHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnCollisionEnterAsync(); + } + } +#endif +#endregion + +#region CollisionEnter2D +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS2D_SUPPORT + + public interface IAsyncOnCollisionEnter2DHandler + { + UniTask OnCollisionEnter2DAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnCollisionEnter2DHandler + { + UniTask IAsyncOnCollisionEnter2DHandler.OnCollisionEnter2DAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncCollisionEnter2DTrigger GetAsyncCollisionEnter2DTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncCollisionEnter2DTrigger GetAsyncCollisionEnter2DTrigger(this Component component) + { + return component.gameObject.GetAsyncCollisionEnter2DTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncCollisionEnter2DTrigger : AsyncTriggerBase + { + void OnCollisionEnter2D(Collision2D coll) + { + RaiseEvent((coll)); + } + + public IAsyncOnCollisionEnter2DHandler GetOnCollisionEnter2DAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnCollisionEnter2DHandler GetOnCollisionEnter2DAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnCollisionEnter2DAsync() + { + return ((IAsyncOnCollisionEnter2DHandler)new AsyncTriggerHandler(this, true)).OnCollisionEnter2DAsync(); + } + + public UniTask OnCollisionEnter2DAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnCollisionEnter2DHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnCollisionEnter2DAsync(); + } + } +#endif +#endregion + +#region CollisionExit +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS_SUPPORT + + public interface IAsyncOnCollisionExitHandler + { + UniTask OnCollisionExitAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnCollisionExitHandler + { + UniTask IAsyncOnCollisionExitHandler.OnCollisionExitAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncCollisionExitTrigger GetAsyncCollisionExitTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncCollisionExitTrigger GetAsyncCollisionExitTrigger(this Component component) + { + return component.gameObject.GetAsyncCollisionExitTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncCollisionExitTrigger : AsyncTriggerBase + { + void OnCollisionExit(Collision coll) + { + RaiseEvent((coll)); + } + + public IAsyncOnCollisionExitHandler GetOnCollisionExitAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnCollisionExitHandler GetOnCollisionExitAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnCollisionExitAsync() + { + return ((IAsyncOnCollisionExitHandler)new AsyncTriggerHandler(this, true)).OnCollisionExitAsync(); + } + + public UniTask OnCollisionExitAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnCollisionExitHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnCollisionExitAsync(); + } + } +#endif +#endregion + +#region CollisionExit2D +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS2D_SUPPORT + + public interface IAsyncOnCollisionExit2DHandler + { + UniTask OnCollisionExit2DAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnCollisionExit2DHandler + { + UniTask IAsyncOnCollisionExit2DHandler.OnCollisionExit2DAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncCollisionExit2DTrigger GetAsyncCollisionExit2DTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncCollisionExit2DTrigger GetAsyncCollisionExit2DTrigger(this Component component) + { + return component.gameObject.GetAsyncCollisionExit2DTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncCollisionExit2DTrigger : AsyncTriggerBase + { + void OnCollisionExit2D(Collision2D coll) + { + RaiseEvent((coll)); + } + + public IAsyncOnCollisionExit2DHandler GetOnCollisionExit2DAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnCollisionExit2DHandler GetOnCollisionExit2DAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnCollisionExit2DAsync() + { + return ((IAsyncOnCollisionExit2DHandler)new AsyncTriggerHandler(this, true)).OnCollisionExit2DAsync(); + } + + public UniTask OnCollisionExit2DAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnCollisionExit2DHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnCollisionExit2DAsync(); + } + } +#endif +#endregion + +#region CollisionStay +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS_SUPPORT + + public interface IAsyncOnCollisionStayHandler + { + UniTask OnCollisionStayAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnCollisionStayHandler + { + UniTask IAsyncOnCollisionStayHandler.OnCollisionStayAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncCollisionStayTrigger GetAsyncCollisionStayTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncCollisionStayTrigger GetAsyncCollisionStayTrigger(this Component component) + { + return component.gameObject.GetAsyncCollisionStayTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncCollisionStayTrigger : AsyncTriggerBase + { + void OnCollisionStay(Collision coll) + { + RaiseEvent((coll)); + } + + public IAsyncOnCollisionStayHandler GetOnCollisionStayAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnCollisionStayHandler GetOnCollisionStayAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnCollisionStayAsync() + { + return ((IAsyncOnCollisionStayHandler)new AsyncTriggerHandler(this, true)).OnCollisionStayAsync(); + } + + public UniTask OnCollisionStayAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnCollisionStayHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnCollisionStayAsync(); + } + } +#endif +#endregion + +#region CollisionStay2D +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS2D_SUPPORT + + public interface IAsyncOnCollisionStay2DHandler + { + UniTask OnCollisionStay2DAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnCollisionStay2DHandler + { + UniTask IAsyncOnCollisionStay2DHandler.OnCollisionStay2DAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncCollisionStay2DTrigger GetAsyncCollisionStay2DTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncCollisionStay2DTrigger GetAsyncCollisionStay2DTrigger(this Component component) + { + return component.gameObject.GetAsyncCollisionStay2DTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncCollisionStay2DTrigger : AsyncTriggerBase + { + void OnCollisionStay2D(Collision2D coll) + { + RaiseEvent((coll)); + } + + public IAsyncOnCollisionStay2DHandler GetOnCollisionStay2DAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnCollisionStay2DHandler GetOnCollisionStay2DAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnCollisionStay2DAsync() + { + return ((IAsyncOnCollisionStay2DHandler)new AsyncTriggerHandler(this, true)).OnCollisionStay2DAsync(); + } + + public UniTask OnCollisionStay2DAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnCollisionStay2DHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnCollisionStay2DAsync(); + } + } +#endif +#endregion + +#region ControllerColliderHit +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS_SUPPORT + + public interface IAsyncOnControllerColliderHitHandler + { + UniTask OnControllerColliderHitAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnControllerColliderHitHandler + { + UniTask IAsyncOnControllerColliderHitHandler.OnControllerColliderHitAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncControllerColliderHitTrigger GetAsyncControllerColliderHitTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncControllerColliderHitTrigger GetAsyncControllerColliderHitTrigger(this Component component) + { + return component.gameObject.GetAsyncControllerColliderHitTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncControllerColliderHitTrigger : AsyncTriggerBase + { + void OnControllerColliderHit(ControllerColliderHit hit) + { + RaiseEvent((hit)); + } + + public IAsyncOnControllerColliderHitHandler GetOnControllerColliderHitAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnControllerColliderHitHandler GetOnControllerColliderHitAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnControllerColliderHitAsync() + { + return ((IAsyncOnControllerColliderHitHandler)new AsyncTriggerHandler(this, true)).OnControllerColliderHitAsync(); + } + + public UniTask OnControllerColliderHitAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnControllerColliderHitHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnControllerColliderHitAsync(); + } + } +#endif +#endregion + +#region Disable + + public interface IAsyncOnDisableHandler + { + UniTask OnDisableAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnDisableHandler + { + UniTask IAsyncOnDisableHandler.OnDisableAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncDisableTrigger GetAsyncDisableTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncDisableTrigger GetAsyncDisableTrigger(this Component component) + { + return component.gameObject.GetAsyncDisableTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncDisableTrigger : AsyncTriggerBase + { + void OnDisable() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnDisableHandler GetOnDisableAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnDisableHandler GetOnDisableAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnDisableAsync() + { + return ((IAsyncOnDisableHandler)new AsyncTriggerHandler(this, true)).OnDisableAsync(); + } + + public UniTask OnDisableAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnDisableHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnDisableAsync(); + } + } +#endregion + +#region DrawGizmos + + public interface IAsyncOnDrawGizmosHandler + { + UniTask OnDrawGizmosAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnDrawGizmosHandler + { + UniTask IAsyncOnDrawGizmosHandler.OnDrawGizmosAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncDrawGizmosTrigger GetAsyncDrawGizmosTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncDrawGizmosTrigger GetAsyncDrawGizmosTrigger(this Component component) + { + return component.gameObject.GetAsyncDrawGizmosTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncDrawGizmosTrigger : AsyncTriggerBase + { + void OnDrawGizmos() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnDrawGizmosHandler GetOnDrawGizmosAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnDrawGizmosHandler GetOnDrawGizmosAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnDrawGizmosAsync() + { + return ((IAsyncOnDrawGizmosHandler)new AsyncTriggerHandler(this, true)).OnDrawGizmosAsync(); + } + + public UniTask OnDrawGizmosAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnDrawGizmosHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnDrawGizmosAsync(); + } + } +#endregion + +#region DrawGizmosSelected + + public interface IAsyncOnDrawGizmosSelectedHandler + { + UniTask OnDrawGizmosSelectedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnDrawGizmosSelectedHandler + { + UniTask IAsyncOnDrawGizmosSelectedHandler.OnDrawGizmosSelectedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncDrawGizmosSelectedTrigger GetAsyncDrawGizmosSelectedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncDrawGizmosSelectedTrigger GetAsyncDrawGizmosSelectedTrigger(this Component component) + { + return component.gameObject.GetAsyncDrawGizmosSelectedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncDrawGizmosSelectedTrigger : AsyncTriggerBase + { + void OnDrawGizmosSelected() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnDrawGizmosSelectedHandler GetOnDrawGizmosSelectedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnDrawGizmosSelectedHandler GetOnDrawGizmosSelectedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnDrawGizmosSelectedAsync() + { + return ((IAsyncOnDrawGizmosSelectedHandler)new AsyncTriggerHandler(this, true)).OnDrawGizmosSelectedAsync(); + } + + public UniTask OnDrawGizmosSelectedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnDrawGizmosSelectedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnDrawGizmosSelectedAsync(); + } + } +#endregion + +#region Enable + + public interface IAsyncOnEnableHandler + { + UniTask OnEnableAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnEnableHandler + { + UniTask IAsyncOnEnableHandler.OnEnableAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncEnableTrigger GetAsyncEnableTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncEnableTrigger GetAsyncEnableTrigger(this Component component) + { + return component.gameObject.GetAsyncEnableTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncEnableTrigger : AsyncTriggerBase + { + void OnEnable() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnEnableHandler GetOnEnableAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnEnableHandler GetOnEnableAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnEnableAsync() + { + return ((IAsyncOnEnableHandler)new AsyncTriggerHandler(this, true)).OnEnableAsync(); + } + + public UniTask OnEnableAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnEnableHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnEnableAsync(); + } + } +#endregion + +#region GUI + + public interface IAsyncOnGUIHandler + { + UniTask OnGUIAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnGUIHandler + { + UniTask IAsyncOnGUIHandler.OnGUIAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncGUITrigger GetAsyncGUITrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncGUITrigger GetAsyncGUITrigger(this Component component) + { + return component.gameObject.GetAsyncGUITrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncGUITrigger : AsyncTriggerBase + { + void OnGUI() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnGUIHandler GetOnGUIAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnGUIHandler GetOnGUIAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnGUIAsync() + { + return ((IAsyncOnGUIHandler)new AsyncTriggerHandler(this, true)).OnGUIAsync(); + } + + public UniTask OnGUIAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnGUIHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnGUIAsync(); + } + } +#endregion + +#region JointBreak +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS_SUPPORT + + public interface IAsyncOnJointBreakHandler + { + UniTask OnJointBreakAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnJointBreakHandler + { + UniTask IAsyncOnJointBreakHandler.OnJointBreakAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncJointBreakTrigger GetAsyncJointBreakTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncJointBreakTrigger GetAsyncJointBreakTrigger(this Component component) + { + return component.gameObject.GetAsyncJointBreakTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncJointBreakTrigger : AsyncTriggerBase + { + void OnJointBreak(float breakForce) + { + RaiseEvent((breakForce)); + } + + public IAsyncOnJointBreakHandler GetOnJointBreakAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnJointBreakHandler GetOnJointBreakAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnJointBreakAsync() + { + return ((IAsyncOnJointBreakHandler)new AsyncTriggerHandler(this, true)).OnJointBreakAsync(); + } + + public UniTask OnJointBreakAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnJointBreakHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnJointBreakAsync(); + } + } +#endif +#endregion + +#region JointBreak2D +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS2D_SUPPORT + + public interface IAsyncOnJointBreak2DHandler + { + UniTask OnJointBreak2DAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnJointBreak2DHandler + { + UniTask IAsyncOnJointBreak2DHandler.OnJointBreak2DAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncJointBreak2DTrigger GetAsyncJointBreak2DTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncJointBreak2DTrigger GetAsyncJointBreak2DTrigger(this Component component) + { + return component.gameObject.GetAsyncJointBreak2DTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncJointBreak2DTrigger : AsyncTriggerBase + { + void OnJointBreak2D(Joint2D brokenJoint) + { + RaiseEvent((brokenJoint)); + } + + public IAsyncOnJointBreak2DHandler GetOnJointBreak2DAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnJointBreak2DHandler GetOnJointBreak2DAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnJointBreak2DAsync() + { + return ((IAsyncOnJointBreak2DHandler)new AsyncTriggerHandler(this, true)).OnJointBreak2DAsync(); + } + + public UniTask OnJointBreak2DAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnJointBreak2DHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnJointBreak2DAsync(); + } + } +#endif +#endregion + +#region MouseDown +#if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO) + + public interface IAsyncOnMouseDownHandler + { + UniTask OnMouseDownAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnMouseDownHandler + { + UniTask IAsyncOnMouseDownHandler.OnMouseDownAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncMouseDownTrigger GetAsyncMouseDownTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncMouseDownTrigger GetAsyncMouseDownTrigger(this Component component) + { + return component.gameObject.GetAsyncMouseDownTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncMouseDownTrigger : AsyncTriggerBase + { + void OnMouseDown() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnMouseDownHandler GetOnMouseDownAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnMouseDownHandler GetOnMouseDownAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnMouseDownAsync() + { + return ((IAsyncOnMouseDownHandler)new AsyncTriggerHandler(this, true)).OnMouseDownAsync(); + } + + public UniTask OnMouseDownAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnMouseDownHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnMouseDownAsync(); + } + } +#endif +#endregion + +#region MouseDrag +#if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO) + + public interface IAsyncOnMouseDragHandler + { + UniTask OnMouseDragAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnMouseDragHandler + { + UniTask IAsyncOnMouseDragHandler.OnMouseDragAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncMouseDragTrigger GetAsyncMouseDragTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncMouseDragTrigger GetAsyncMouseDragTrigger(this Component component) + { + return component.gameObject.GetAsyncMouseDragTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncMouseDragTrigger : AsyncTriggerBase + { + void OnMouseDrag() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnMouseDragHandler GetOnMouseDragAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnMouseDragHandler GetOnMouseDragAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnMouseDragAsync() + { + return ((IAsyncOnMouseDragHandler)new AsyncTriggerHandler(this, true)).OnMouseDragAsync(); + } + + public UniTask OnMouseDragAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnMouseDragHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnMouseDragAsync(); + } + } +#endif +#endregion + +#region MouseEnter +#if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO) + + public interface IAsyncOnMouseEnterHandler + { + UniTask OnMouseEnterAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnMouseEnterHandler + { + UniTask IAsyncOnMouseEnterHandler.OnMouseEnterAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncMouseEnterTrigger GetAsyncMouseEnterTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncMouseEnterTrigger GetAsyncMouseEnterTrigger(this Component component) + { + return component.gameObject.GetAsyncMouseEnterTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncMouseEnterTrigger : AsyncTriggerBase + { + void OnMouseEnter() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnMouseEnterHandler GetOnMouseEnterAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnMouseEnterHandler GetOnMouseEnterAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnMouseEnterAsync() + { + return ((IAsyncOnMouseEnterHandler)new AsyncTriggerHandler(this, true)).OnMouseEnterAsync(); + } + + public UniTask OnMouseEnterAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnMouseEnterHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnMouseEnterAsync(); + } + } +#endif +#endregion + +#region MouseExit +#if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO) + + public interface IAsyncOnMouseExitHandler + { + UniTask OnMouseExitAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnMouseExitHandler + { + UniTask IAsyncOnMouseExitHandler.OnMouseExitAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncMouseExitTrigger GetAsyncMouseExitTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncMouseExitTrigger GetAsyncMouseExitTrigger(this Component component) + { + return component.gameObject.GetAsyncMouseExitTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncMouseExitTrigger : AsyncTriggerBase + { + void OnMouseExit() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnMouseExitHandler GetOnMouseExitAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnMouseExitHandler GetOnMouseExitAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnMouseExitAsync() + { + return ((IAsyncOnMouseExitHandler)new AsyncTriggerHandler(this, true)).OnMouseExitAsync(); + } + + public UniTask OnMouseExitAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnMouseExitHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnMouseExitAsync(); + } + } +#endif +#endregion + +#region MouseOver +#if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO) + + public interface IAsyncOnMouseOverHandler + { + UniTask OnMouseOverAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnMouseOverHandler + { + UniTask IAsyncOnMouseOverHandler.OnMouseOverAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncMouseOverTrigger GetAsyncMouseOverTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncMouseOverTrigger GetAsyncMouseOverTrigger(this Component component) + { + return component.gameObject.GetAsyncMouseOverTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncMouseOverTrigger : AsyncTriggerBase + { + void OnMouseOver() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnMouseOverHandler GetOnMouseOverAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnMouseOverHandler GetOnMouseOverAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnMouseOverAsync() + { + return ((IAsyncOnMouseOverHandler)new AsyncTriggerHandler(this, true)).OnMouseOverAsync(); + } + + public UniTask OnMouseOverAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnMouseOverHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnMouseOverAsync(); + } + } +#endif +#endregion + +#region MouseUp +#if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO) + + public interface IAsyncOnMouseUpHandler + { + UniTask OnMouseUpAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnMouseUpHandler + { + UniTask IAsyncOnMouseUpHandler.OnMouseUpAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncMouseUpTrigger GetAsyncMouseUpTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncMouseUpTrigger GetAsyncMouseUpTrigger(this Component component) + { + return component.gameObject.GetAsyncMouseUpTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncMouseUpTrigger : AsyncTriggerBase + { + void OnMouseUp() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnMouseUpHandler GetOnMouseUpAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnMouseUpHandler GetOnMouseUpAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnMouseUpAsync() + { + return ((IAsyncOnMouseUpHandler)new AsyncTriggerHandler(this, true)).OnMouseUpAsync(); + } + + public UniTask OnMouseUpAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnMouseUpHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnMouseUpAsync(); + } + } +#endif +#endregion + +#region MouseUpAsButton +#if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO) + + public interface IAsyncOnMouseUpAsButtonHandler + { + UniTask OnMouseUpAsButtonAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnMouseUpAsButtonHandler + { + UniTask IAsyncOnMouseUpAsButtonHandler.OnMouseUpAsButtonAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncMouseUpAsButtonTrigger GetAsyncMouseUpAsButtonTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncMouseUpAsButtonTrigger GetAsyncMouseUpAsButtonTrigger(this Component component) + { + return component.gameObject.GetAsyncMouseUpAsButtonTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncMouseUpAsButtonTrigger : AsyncTriggerBase + { + void OnMouseUpAsButton() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnMouseUpAsButtonHandler GetOnMouseUpAsButtonAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnMouseUpAsButtonHandler GetOnMouseUpAsButtonAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnMouseUpAsButtonAsync() + { + return ((IAsyncOnMouseUpAsButtonHandler)new AsyncTriggerHandler(this, true)).OnMouseUpAsButtonAsync(); + } + + public UniTask OnMouseUpAsButtonAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnMouseUpAsButtonHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnMouseUpAsButtonAsync(); + } + } +#endif +#endregion + +#region ParticleCollision + + public interface IAsyncOnParticleCollisionHandler + { + UniTask OnParticleCollisionAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnParticleCollisionHandler + { + UniTask IAsyncOnParticleCollisionHandler.OnParticleCollisionAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncParticleCollisionTrigger GetAsyncParticleCollisionTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncParticleCollisionTrigger GetAsyncParticleCollisionTrigger(this Component component) + { + return component.gameObject.GetAsyncParticleCollisionTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncParticleCollisionTrigger : AsyncTriggerBase + { + void OnParticleCollision(GameObject other) + { + RaiseEvent((other)); + } + + public IAsyncOnParticleCollisionHandler GetOnParticleCollisionAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnParticleCollisionHandler GetOnParticleCollisionAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnParticleCollisionAsync() + { + return ((IAsyncOnParticleCollisionHandler)new AsyncTriggerHandler(this, true)).OnParticleCollisionAsync(); + } + + public UniTask OnParticleCollisionAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnParticleCollisionHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnParticleCollisionAsync(); + } + } +#endregion + +#region ParticleSystemStopped + + public interface IAsyncOnParticleSystemStoppedHandler + { + UniTask OnParticleSystemStoppedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnParticleSystemStoppedHandler + { + UniTask IAsyncOnParticleSystemStoppedHandler.OnParticleSystemStoppedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncParticleSystemStoppedTrigger GetAsyncParticleSystemStoppedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncParticleSystemStoppedTrigger GetAsyncParticleSystemStoppedTrigger(this Component component) + { + return component.gameObject.GetAsyncParticleSystemStoppedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncParticleSystemStoppedTrigger : AsyncTriggerBase + { + void OnParticleSystemStopped() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnParticleSystemStoppedHandler GetOnParticleSystemStoppedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnParticleSystemStoppedHandler GetOnParticleSystemStoppedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnParticleSystemStoppedAsync() + { + return ((IAsyncOnParticleSystemStoppedHandler)new AsyncTriggerHandler(this, true)).OnParticleSystemStoppedAsync(); + } + + public UniTask OnParticleSystemStoppedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnParticleSystemStoppedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnParticleSystemStoppedAsync(); + } + } +#endregion + +#region ParticleTrigger + + public interface IAsyncOnParticleTriggerHandler + { + UniTask OnParticleTriggerAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnParticleTriggerHandler + { + UniTask IAsyncOnParticleTriggerHandler.OnParticleTriggerAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncParticleTriggerTrigger GetAsyncParticleTriggerTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncParticleTriggerTrigger GetAsyncParticleTriggerTrigger(this Component component) + { + return component.gameObject.GetAsyncParticleTriggerTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncParticleTriggerTrigger : AsyncTriggerBase + { + void OnParticleTrigger() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnParticleTriggerHandler GetOnParticleTriggerAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnParticleTriggerHandler GetOnParticleTriggerAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnParticleTriggerAsync() + { + return ((IAsyncOnParticleTriggerHandler)new AsyncTriggerHandler(this, true)).OnParticleTriggerAsync(); + } + + public UniTask OnParticleTriggerAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnParticleTriggerHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnParticleTriggerAsync(); + } + } +#endregion + +#region ParticleUpdateJobScheduled +#if UNITY_2019_3_OR_NEWER && (!UNITY_2019_1_OR_NEWER || UNITASK_PARTICLESYSTEM_SUPPORT) + + public interface IAsyncOnParticleUpdateJobScheduledHandler + { + UniTask OnParticleUpdateJobScheduledAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnParticleUpdateJobScheduledHandler + { + UniTask IAsyncOnParticleUpdateJobScheduledHandler.OnParticleUpdateJobScheduledAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncParticleUpdateJobScheduledTrigger GetAsyncParticleUpdateJobScheduledTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncParticleUpdateJobScheduledTrigger GetAsyncParticleUpdateJobScheduledTrigger(this Component component) + { + return component.gameObject.GetAsyncParticleUpdateJobScheduledTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncParticleUpdateJobScheduledTrigger : AsyncTriggerBase + { + void OnParticleUpdateJobScheduled(UnityEngine.ParticleSystemJobs.ParticleSystemJobData particles) + { + RaiseEvent((particles)); + } + + public IAsyncOnParticleUpdateJobScheduledHandler GetOnParticleUpdateJobScheduledAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnParticleUpdateJobScheduledHandler GetOnParticleUpdateJobScheduledAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnParticleUpdateJobScheduledAsync() + { + return ((IAsyncOnParticleUpdateJobScheduledHandler)new AsyncTriggerHandler(this, true)).OnParticleUpdateJobScheduledAsync(); + } + + public UniTask OnParticleUpdateJobScheduledAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnParticleUpdateJobScheduledHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnParticleUpdateJobScheduledAsync(); + } + } +#endif +#endregion + +#region PostRender + + public interface IAsyncOnPostRenderHandler + { + UniTask OnPostRenderAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnPostRenderHandler + { + UniTask IAsyncOnPostRenderHandler.OnPostRenderAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncPostRenderTrigger GetAsyncPostRenderTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncPostRenderTrigger GetAsyncPostRenderTrigger(this Component component) + { + return component.gameObject.GetAsyncPostRenderTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncPostRenderTrigger : AsyncTriggerBase + { + void OnPostRender() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnPostRenderHandler GetOnPostRenderAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnPostRenderHandler GetOnPostRenderAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnPostRenderAsync() + { + return ((IAsyncOnPostRenderHandler)new AsyncTriggerHandler(this, true)).OnPostRenderAsync(); + } + + public UniTask OnPostRenderAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnPostRenderHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnPostRenderAsync(); + } + } +#endregion + +#region PreCull + + public interface IAsyncOnPreCullHandler + { + UniTask OnPreCullAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnPreCullHandler + { + UniTask IAsyncOnPreCullHandler.OnPreCullAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncPreCullTrigger GetAsyncPreCullTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncPreCullTrigger GetAsyncPreCullTrigger(this Component component) + { + return component.gameObject.GetAsyncPreCullTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncPreCullTrigger : AsyncTriggerBase + { + void OnPreCull() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnPreCullHandler GetOnPreCullAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnPreCullHandler GetOnPreCullAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnPreCullAsync() + { + return ((IAsyncOnPreCullHandler)new AsyncTriggerHandler(this, true)).OnPreCullAsync(); + } + + public UniTask OnPreCullAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnPreCullHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnPreCullAsync(); + } + } +#endregion + +#region PreRender + + public interface IAsyncOnPreRenderHandler + { + UniTask OnPreRenderAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnPreRenderHandler + { + UniTask IAsyncOnPreRenderHandler.OnPreRenderAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncPreRenderTrigger GetAsyncPreRenderTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncPreRenderTrigger GetAsyncPreRenderTrigger(this Component component) + { + return component.gameObject.GetAsyncPreRenderTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncPreRenderTrigger : AsyncTriggerBase + { + void OnPreRender() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnPreRenderHandler GetOnPreRenderAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnPreRenderHandler GetOnPreRenderAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnPreRenderAsync() + { + return ((IAsyncOnPreRenderHandler)new AsyncTriggerHandler(this, true)).OnPreRenderAsync(); + } + + public UniTask OnPreRenderAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnPreRenderHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnPreRenderAsync(); + } + } +#endregion + +#region RectTransformDimensionsChange + + public interface IAsyncOnRectTransformDimensionsChangeHandler + { + UniTask OnRectTransformDimensionsChangeAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnRectTransformDimensionsChangeHandler + { + UniTask IAsyncOnRectTransformDimensionsChangeHandler.OnRectTransformDimensionsChangeAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncRectTransformDimensionsChangeTrigger GetAsyncRectTransformDimensionsChangeTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncRectTransformDimensionsChangeTrigger GetAsyncRectTransformDimensionsChangeTrigger(this Component component) + { + return component.gameObject.GetAsyncRectTransformDimensionsChangeTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncRectTransformDimensionsChangeTrigger : AsyncTriggerBase + { + void OnRectTransformDimensionsChange() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnRectTransformDimensionsChangeHandler GetOnRectTransformDimensionsChangeAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnRectTransformDimensionsChangeHandler GetOnRectTransformDimensionsChangeAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnRectTransformDimensionsChangeAsync() + { + return ((IAsyncOnRectTransformDimensionsChangeHandler)new AsyncTriggerHandler(this, true)).OnRectTransformDimensionsChangeAsync(); + } + + public UniTask OnRectTransformDimensionsChangeAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnRectTransformDimensionsChangeHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnRectTransformDimensionsChangeAsync(); + } + } +#endregion + +#region RectTransformRemoved + + public interface IAsyncOnRectTransformRemovedHandler + { + UniTask OnRectTransformRemovedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnRectTransformRemovedHandler + { + UniTask IAsyncOnRectTransformRemovedHandler.OnRectTransformRemovedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncRectTransformRemovedTrigger GetAsyncRectTransformRemovedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncRectTransformRemovedTrigger GetAsyncRectTransformRemovedTrigger(this Component component) + { + return component.gameObject.GetAsyncRectTransformRemovedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncRectTransformRemovedTrigger : AsyncTriggerBase + { + void OnRectTransformRemoved() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnRectTransformRemovedHandler GetOnRectTransformRemovedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnRectTransformRemovedHandler GetOnRectTransformRemovedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnRectTransformRemovedAsync() + { + return ((IAsyncOnRectTransformRemovedHandler)new AsyncTriggerHandler(this, true)).OnRectTransformRemovedAsync(); + } + + public UniTask OnRectTransformRemovedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnRectTransformRemovedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnRectTransformRemovedAsync(); + } + } +#endregion + +#region RenderImage + + public interface IAsyncOnRenderImageHandler + { + UniTask<(RenderTexture source, RenderTexture destination)> OnRenderImageAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnRenderImageHandler + { + UniTask<(RenderTexture source, RenderTexture destination)> IAsyncOnRenderImageHandler.OnRenderImageAsync() + { + core.Reset(); + return new UniTask<(RenderTexture source, RenderTexture destination)>((IUniTaskSource<(RenderTexture source, RenderTexture destination)>)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncRenderImageTrigger GetAsyncRenderImageTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncRenderImageTrigger GetAsyncRenderImageTrigger(this Component component) + { + return component.gameObject.GetAsyncRenderImageTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncRenderImageTrigger : AsyncTriggerBase<(RenderTexture source, RenderTexture destination)> + { + void OnRenderImage(RenderTexture source, RenderTexture destination) + { + RaiseEvent((source, destination)); + } + + public IAsyncOnRenderImageHandler GetOnRenderImageAsyncHandler() + { + return new AsyncTriggerHandler<(RenderTexture source, RenderTexture destination)>(this, false); + } + + public IAsyncOnRenderImageHandler GetOnRenderImageAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler<(RenderTexture source, RenderTexture destination)>(this, cancellationToken, false); + } + + public UniTask<(RenderTexture source, RenderTexture destination)> OnRenderImageAsync() + { + return ((IAsyncOnRenderImageHandler)new AsyncTriggerHandler<(RenderTexture source, RenderTexture destination)>(this, true)).OnRenderImageAsync(); + } + + public UniTask<(RenderTexture source, RenderTexture destination)> OnRenderImageAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnRenderImageHandler)new AsyncTriggerHandler<(RenderTexture source, RenderTexture destination)>(this, cancellationToken, true)).OnRenderImageAsync(); + } + } +#endregion + +#region RenderObject + + public interface IAsyncOnRenderObjectHandler + { + UniTask OnRenderObjectAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnRenderObjectHandler + { + UniTask IAsyncOnRenderObjectHandler.OnRenderObjectAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncRenderObjectTrigger GetAsyncRenderObjectTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncRenderObjectTrigger GetAsyncRenderObjectTrigger(this Component component) + { + return component.gameObject.GetAsyncRenderObjectTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncRenderObjectTrigger : AsyncTriggerBase + { + void OnRenderObject() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnRenderObjectHandler GetOnRenderObjectAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnRenderObjectHandler GetOnRenderObjectAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnRenderObjectAsync() + { + return ((IAsyncOnRenderObjectHandler)new AsyncTriggerHandler(this, true)).OnRenderObjectAsync(); + } + + public UniTask OnRenderObjectAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnRenderObjectHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnRenderObjectAsync(); + } + } +#endregion + +#region ServerInitialized + + public interface IAsyncOnServerInitializedHandler + { + UniTask OnServerInitializedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnServerInitializedHandler + { + UniTask IAsyncOnServerInitializedHandler.OnServerInitializedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncServerInitializedTrigger GetAsyncServerInitializedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncServerInitializedTrigger GetAsyncServerInitializedTrigger(this Component component) + { + return component.gameObject.GetAsyncServerInitializedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncServerInitializedTrigger : AsyncTriggerBase + { + void OnServerInitialized() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnServerInitializedHandler GetOnServerInitializedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnServerInitializedHandler GetOnServerInitializedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnServerInitializedAsync() + { + return ((IAsyncOnServerInitializedHandler)new AsyncTriggerHandler(this, true)).OnServerInitializedAsync(); + } + + public UniTask OnServerInitializedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnServerInitializedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnServerInitializedAsync(); + } + } +#endregion + +#region TransformChildrenChanged + + public interface IAsyncOnTransformChildrenChangedHandler + { + UniTask OnTransformChildrenChangedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnTransformChildrenChangedHandler + { + UniTask IAsyncOnTransformChildrenChangedHandler.OnTransformChildrenChangedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncTransformChildrenChangedTrigger GetAsyncTransformChildrenChangedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncTransformChildrenChangedTrigger GetAsyncTransformChildrenChangedTrigger(this Component component) + { + return component.gameObject.GetAsyncTransformChildrenChangedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncTransformChildrenChangedTrigger : AsyncTriggerBase + { + void OnTransformChildrenChanged() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnTransformChildrenChangedHandler GetOnTransformChildrenChangedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnTransformChildrenChangedHandler GetOnTransformChildrenChangedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnTransformChildrenChangedAsync() + { + return ((IAsyncOnTransformChildrenChangedHandler)new AsyncTriggerHandler(this, true)).OnTransformChildrenChangedAsync(); + } + + public UniTask OnTransformChildrenChangedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnTransformChildrenChangedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnTransformChildrenChangedAsync(); + } + } +#endregion + +#region TransformParentChanged + + public interface IAsyncOnTransformParentChangedHandler + { + UniTask OnTransformParentChangedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnTransformParentChangedHandler + { + UniTask IAsyncOnTransformParentChangedHandler.OnTransformParentChangedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncTransformParentChangedTrigger GetAsyncTransformParentChangedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncTransformParentChangedTrigger GetAsyncTransformParentChangedTrigger(this Component component) + { + return component.gameObject.GetAsyncTransformParentChangedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncTransformParentChangedTrigger : AsyncTriggerBase + { + void OnTransformParentChanged() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnTransformParentChangedHandler GetOnTransformParentChangedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnTransformParentChangedHandler GetOnTransformParentChangedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnTransformParentChangedAsync() + { + return ((IAsyncOnTransformParentChangedHandler)new AsyncTriggerHandler(this, true)).OnTransformParentChangedAsync(); + } + + public UniTask OnTransformParentChangedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnTransformParentChangedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnTransformParentChangedAsync(); + } + } +#endregion + +#region TriggerEnter +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS_SUPPORT + + public interface IAsyncOnTriggerEnterHandler + { + UniTask OnTriggerEnterAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnTriggerEnterHandler + { + UniTask IAsyncOnTriggerEnterHandler.OnTriggerEnterAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncTriggerEnterTrigger GetAsyncTriggerEnterTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncTriggerEnterTrigger GetAsyncTriggerEnterTrigger(this Component component) + { + return component.gameObject.GetAsyncTriggerEnterTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncTriggerEnterTrigger : AsyncTriggerBase + { + void OnTriggerEnter(Collider other) + { + RaiseEvent((other)); + } + + public IAsyncOnTriggerEnterHandler GetOnTriggerEnterAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnTriggerEnterHandler GetOnTriggerEnterAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnTriggerEnterAsync() + { + return ((IAsyncOnTriggerEnterHandler)new AsyncTriggerHandler(this, true)).OnTriggerEnterAsync(); + } + + public UniTask OnTriggerEnterAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnTriggerEnterHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnTriggerEnterAsync(); + } + } +#endif +#endregion + +#region TriggerEnter2D +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS2D_SUPPORT + + public interface IAsyncOnTriggerEnter2DHandler + { + UniTask OnTriggerEnter2DAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnTriggerEnter2DHandler + { + UniTask IAsyncOnTriggerEnter2DHandler.OnTriggerEnter2DAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncTriggerEnter2DTrigger GetAsyncTriggerEnter2DTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncTriggerEnter2DTrigger GetAsyncTriggerEnter2DTrigger(this Component component) + { + return component.gameObject.GetAsyncTriggerEnter2DTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncTriggerEnter2DTrigger : AsyncTriggerBase + { + void OnTriggerEnter2D(Collider2D other) + { + RaiseEvent((other)); + } + + public IAsyncOnTriggerEnter2DHandler GetOnTriggerEnter2DAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnTriggerEnter2DHandler GetOnTriggerEnter2DAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnTriggerEnter2DAsync() + { + return ((IAsyncOnTriggerEnter2DHandler)new AsyncTriggerHandler(this, true)).OnTriggerEnter2DAsync(); + } + + public UniTask OnTriggerEnter2DAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnTriggerEnter2DHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnTriggerEnter2DAsync(); + } + } +#endif +#endregion + +#region TriggerExit +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS_SUPPORT + + public interface IAsyncOnTriggerExitHandler + { + UniTask OnTriggerExitAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnTriggerExitHandler + { + UniTask IAsyncOnTriggerExitHandler.OnTriggerExitAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncTriggerExitTrigger GetAsyncTriggerExitTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncTriggerExitTrigger GetAsyncTriggerExitTrigger(this Component component) + { + return component.gameObject.GetAsyncTriggerExitTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncTriggerExitTrigger : AsyncTriggerBase + { + void OnTriggerExit(Collider other) + { + RaiseEvent((other)); + } + + public IAsyncOnTriggerExitHandler GetOnTriggerExitAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnTriggerExitHandler GetOnTriggerExitAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnTriggerExitAsync() + { + return ((IAsyncOnTriggerExitHandler)new AsyncTriggerHandler(this, true)).OnTriggerExitAsync(); + } + + public UniTask OnTriggerExitAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnTriggerExitHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnTriggerExitAsync(); + } + } +#endif +#endregion + +#region TriggerExit2D +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS2D_SUPPORT + + public interface IAsyncOnTriggerExit2DHandler + { + UniTask OnTriggerExit2DAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnTriggerExit2DHandler + { + UniTask IAsyncOnTriggerExit2DHandler.OnTriggerExit2DAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncTriggerExit2DTrigger GetAsyncTriggerExit2DTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncTriggerExit2DTrigger GetAsyncTriggerExit2DTrigger(this Component component) + { + return component.gameObject.GetAsyncTriggerExit2DTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncTriggerExit2DTrigger : AsyncTriggerBase + { + void OnTriggerExit2D(Collider2D other) + { + RaiseEvent((other)); + } + + public IAsyncOnTriggerExit2DHandler GetOnTriggerExit2DAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnTriggerExit2DHandler GetOnTriggerExit2DAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnTriggerExit2DAsync() + { + return ((IAsyncOnTriggerExit2DHandler)new AsyncTriggerHandler(this, true)).OnTriggerExit2DAsync(); + } + + public UniTask OnTriggerExit2DAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnTriggerExit2DHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnTriggerExit2DAsync(); + } + } +#endif +#endregion + +#region TriggerStay +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS_SUPPORT + + public interface IAsyncOnTriggerStayHandler + { + UniTask OnTriggerStayAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnTriggerStayHandler + { + UniTask IAsyncOnTriggerStayHandler.OnTriggerStayAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncTriggerStayTrigger GetAsyncTriggerStayTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncTriggerStayTrigger GetAsyncTriggerStayTrigger(this Component component) + { + return component.gameObject.GetAsyncTriggerStayTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncTriggerStayTrigger : AsyncTriggerBase + { + void OnTriggerStay(Collider other) + { + RaiseEvent((other)); + } + + public IAsyncOnTriggerStayHandler GetOnTriggerStayAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnTriggerStayHandler GetOnTriggerStayAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnTriggerStayAsync() + { + return ((IAsyncOnTriggerStayHandler)new AsyncTriggerHandler(this, true)).OnTriggerStayAsync(); + } + + public UniTask OnTriggerStayAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnTriggerStayHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnTriggerStayAsync(); + } + } +#endif +#endregion + +#region TriggerStay2D +#if !UNITY_2019_1_OR_NEWER || UNITASK_PHYSICS2D_SUPPORT + + public interface IAsyncOnTriggerStay2DHandler + { + UniTask OnTriggerStay2DAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnTriggerStay2DHandler + { + UniTask IAsyncOnTriggerStay2DHandler.OnTriggerStay2DAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncTriggerStay2DTrigger GetAsyncTriggerStay2DTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncTriggerStay2DTrigger GetAsyncTriggerStay2DTrigger(this Component component) + { + return component.gameObject.GetAsyncTriggerStay2DTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncTriggerStay2DTrigger : AsyncTriggerBase + { + void OnTriggerStay2D(Collider2D other) + { + RaiseEvent((other)); + } + + public IAsyncOnTriggerStay2DHandler GetOnTriggerStay2DAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnTriggerStay2DHandler GetOnTriggerStay2DAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnTriggerStay2DAsync() + { + return ((IAsyncOnTriggerStay2DHandler)new AsyncTriggerHandler(this, true)).OnTriggerStay2DAsync(); + } + + public UniTask OnTriggerStay2DAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnTriggerStay2DHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnTriggerStay2DAsync(); + } + } +#endif +#endregion + +#region Validate + + public interface IAsyncOnValidateHandler + { + UniTask OnValidateAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnValidateHandler + { + UniTask IAsyncOnValidateHandler.OnValidateAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncValidateTrigger GetAsyncValidateTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncValidateTrigger GetAsyncValidateTrigger(this Component component) + { + return component.gameObject.GetAsyncValidateTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncValidateTrigger : AsyncTriggerBase + { + void OnValidate() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnValidateHandler GetOnValidateAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnValidateHandler GetOnValidateAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnValidateAsync() + { + return ((IAsyncOnValidateHandler)new AsyncTriggerHandler(this, true)).OnValidateAsync(); + } + + public UniTask OnValidateAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnValidateHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnValidateAsync(); + } + } +#endregion + +#region WillRenderObject + + public interface IAsyncOnWillRenderObjectHandler + { + UniTask OnWillRenderObjectAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnWillRenderObjectHandler + { + UniTask IAsyncOnWillRenderObjectHandler.OnWillRenderObjectAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncWillRenderObjectTrigger GetAsyncWillRenderObjectTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncWillRenderObjectTrigger GetAsyncWillRenderObjectTrigger(this Component component) + { + return component.gameObject.GetAsyncWillRenderObjectTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncWillRenderObjectTrigger : AsyncTriggerBase + { + void OnWillRenderObject() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncOnWillRenderObjectHandler GetOnWillRenderObjectAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnWillRenderObjectHandler GetOnWillRenderObjectAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnWillRenderObjectAsync() + { + return ((IAsyncOnWillRenderObjectHandler)new AsyncTriggerHandler(this, true)).OnWillRenderObjectAsync(); + } + + public UniTask OnWillRenderObjectAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnWillRenderObjectHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnWillRenderObjectAsync(); + } + } +#endregion + +#region Reset + + public interface IAsyncResetHandler + { + UniTask ResetAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncResetHandler + { + UniTask IAsyncResetHandler.ResetAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncResetTrigger GetAsyncResetTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncResetTrigger GetAsyncResetTrigger(this Component component) + { + return component.gameObject.GetAsyncResetTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncResetTrigger : AsyncTriggerBase + { + void Reset() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncResetHandler GetResetAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncResetHandler GetResetAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask ResetAsync() + { + return ((IAsyncResetHandler)new AsyncTriggerHandler(this, true)).ResetAsync(); + } + + public UniTask ResetAsync(CancellationToken cancellationToken) + { + return ((IAsyncResetHandler)new AsyncTriggerHandler(this, cancellationToken, true)).ResetAsync(); + } + } +#endregion + +#region Update + + public interface IAsyncUpdateHandler + { + UniTask UpdateAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncUpdateHandler + { + UniTask IAsyncUpdateHandler.UpdateAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncUpdateTrigger GetAsyncUpdateTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncUpdateTrigger GetAsyncUpdateTrigger(this Component component) + { + return component.gameObject.GetAsyncUpdateTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncUpdateTrigger : AsyncTriggerBase + { + void Update() + { + RaiseEvent(AsyncUnit.Default); + } + + public IAsyncUpdateHandler GetUpdateAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncUpdateHandler GetUpdateAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask UpdateAsync() + { + return ((IAsyncUpdateHandler)new AsyncTriggerHandler(this, true)).UpdateAsync(); + } + + public UniTask UpdateAsync(CancellationToken cancellationToken) + { + return ((IAsyncUpdateHandler)new AsyncTriggerHandler(this, cancellationToken, true)).UpdateAsync(); + } + } +#endregion + +#region BeginDrag +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnBeginDragHandler + { + UniTask OnBeginDragAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnBeginDragHandler + { + UniTask IAsyncOnBeginDragHandler.OnBeginDragAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncBeginDragTrigger GetAsyncBeginDragTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncBeginDragTrigger GetAsyncBeginDragTrigger(this Component component) + { + return component.gameObject.GetAsyncBeginDragTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncBeginDragTrigger : AsyncTriggerBase, IBeginDragHandler + { + void IBeginDragHandler.OnBeginDrag(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnBeginDragHandler GetOnBeginDragAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnBeginDragHandler GetOnBeginDragAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnBeginDragAsync() + { + return ((IAsyncOnBeginDragHandler)new AsyncTriggerHandler(this, true)).OnBeginDragAsync(); + } + + public UniTask OnBeginDragAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnBeginDragHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnBeginDragAsync(); + } + } +#endif +#endregion + +#region Cancel +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnCancelHandler + { + UniTask OnCancelAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnCancelHandler + { + UniTask IAsyncOnCancelHandler.OnCancelAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncCancelTrigger GetAsyncCancelTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncCancelTrigger GetAsyncCancelTrigger(this Component component) + { + return component.gameObject.GetAsyncCancelTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncCancelTrigger : AsyncTriggerBase, ICancelHandler + { + void ICancelHandler.OnCancel(BaseEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnCancelHandler GetOnCancelAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnCancelHandler GetOnCancelAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnCancelAsync() + { + return ((IAsyncOnCancelHandler)new AsyncTriggerHandler(this, true)).OnCancelAsync(); + } + + public UniTask OnCancelAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnCancelHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnCancelAsync(); + } + } +#endif +#endregion + +#region Deselect +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnDeselectHandler + { + UniTask OnDeselectAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnDeselectHandler + { + UniTask IAsyncOnDeselectHandler.OnDeselectAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncDeselectTrigger GetAsyncDeselectTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncDeselectTrigger GetAsyncDeselectTrigger(this Component component) + { + return component.gameObject.GetAsyncDeselectTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncDeselectTrigger : AsyncTriggerBase, IDeselectHandler + { + void IDeselectHandler.OnDeselect(BaseEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnDeselectHandler GetOnDeselectAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnDeselectHandler GetOnDeselectAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnDeselectAsync() + { + return ((IAsyncOnDeselectHandler)new AsyncTriggerHandler(this, true)).OnDeselectAsync(); + } + + public UniTask OnDeselectAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnDeselectHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnDeselectAsync(); + } + } +#endif +#endregion + +#region Drag +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnDragHandler + { + UniTask OnDragAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnDragHandler + { + UniTask IAsyncOnDragHandler.OnDragAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncDragTrigger GetAsyncDragTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncDragTrigger GetAsyncDragTrigger(this Component component) + { + return component.gameObject.GetAsyncDragTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncDragTrigger : AsyncTriggerBase, IDragHandler + { + void IDragHandler.OnDrag(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnDragHandler GetOnDragAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnDragHandler GetOnDragAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnDragAsync() + { + return ((IAsyncOnDragHandler)new AsyncTriggerHandler(this, true)).OnDragAsync(); + } + + public UniTask OnDragAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnDragHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnDragAsync(); + } + } +#endif +#endregion + +#region Drop +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnDropHandler + { + UniTask OnDropAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnDropHandler + { + UniTask IAsyncOnDropHandler.OnDropAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncDropTrigger GetAsyncDropTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncDropTrigger GetAsyncDropTrigger(this Component component) + { + return component.gameObject.GetAsyncDropTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncDropTrigger : AsyncTriggerBase, IDropHandler + { + void IDropHandler.OnDrop(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnDropHandler GetOnDropAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnDropHandler GetOnDropAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnDropAsync() + { + return ((IAsyncOnDropHandler)new AsyncTriggerHandler(this, true)).OnDropAsync(); + } + + public UniTask OnDropAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnDropHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnDropAsync(); + } + } +#endif +#endregion + +#region EndDrag +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnEndDragHandler + { + UniTask OnEndDragAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnEndDragHandler + { + UniTask IAsyncOnEndDragHandler.OnEndDragAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncEndDragTrigger GetAsyncEndDragTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncEndDragTrigger GetAsyncEndDragTrigger(this Component component) + { + return component.gameObject.GetAsyncEndDragTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncEndDragTrigger : AsyncTriggerBase, IEndDragHandler + { + void IEndDragHandler.OnEndDrag(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnEndDragHandler GetOnEndDragAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnEndDragHandler GetOnEndDragAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnEndDragAsync() + { + return ((IAsyncOnEndDragHandler)new AsyncTriggerHandler(this, true)).OnEndDragAsync(); + } + + public UniTask OnEndDragAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnEndDragHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnEndDragAsync(); + } + } +#endif +#endregion + +#region InitializePotentialDrag +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnInitializePotentialDragHandler + { + UniTask OnInitializePotentialDragAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnInitializePotentialDragHandler + { + UniTask IAsyncOnInitializePotentialDragHandler.OnInitializePotentialDragAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncInitializePotentialDragTrigger GetAsyncInitializePotentialDragTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncInitializePotentialDragTrigger GetAsyncInitializePotentialDragTrigger(this Component component) + { + return component.gameObject.GetAsyncInitializePotentialDragTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncInitializePotentialDragTrigger : AsyncTriggerBase, IInitializePotentialDragHandler + { + void IInitializePotentialDragHandler.OnInitializePotentialDrag(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnInitializePotentialDragHandler GetOnInitializePotentialDragAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnInitializePotentialDragHandler GetOnInitializePotentialDragAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnInitializePotentialDragAsync() + { + return ((IAsyncOnInitializePotentialDragHandler)new AsyncTriggerHandler(this, true)).OnInitializePotentialDragAsync(); + } + + public UniTask OnInitializePotentialDragAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnInitializePotentialDragHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnInitializePotentialDragAsync(); + } + } +#endif +#endregion + +#region Move +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnMoveHandler + { + UniTask OnMoveAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnMoveHandler + { + UniTask IAsyncOnMoveHandler.OnMoveAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncMoveTrigger GetAsyncMoveTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncMoveTrigger GetAsyncMoveTrigger(this Component component) + { + return component.gameObject.GetAsyncMoveTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncMoveTrigger : AsyncTriggerBase, IMoveHandler + { + void IMoveHandler.OnMove(AxisEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnMoveHandler GetOnMoveAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnMoveHandler GetOnMoveAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnMoveAsync() + { + return ((IAsyncOnMoveHandler)new AsyncTriggerHandler(this, true)).OnMoveAsync(); + } + + public UniTask OnMoveAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnMoveHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnMoveAsync(); + } + } +#endif +#endregion + +#region PointerClick +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnPointerClickHandler + { + UniTask OnPointerClickAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnPointerClickHandler + { + UniTask IAsyncOnPointerClickHandler.OnPointerClickAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncPointerClickTrigger GetAsyncPointerClickTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncPointerClickTrigger GetAsyncPointerClickTrigger(this Component component) + { + return component.gameObject.GetAsyncPointerClickTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncPointerClickTrigger : AsyncTriggerBase, IPointerClickHandler + { + void IPointerClickHandler.OnPointerClick(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnPointerClickHandler GetOnPointerClickAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnPointerClickHandler GetOnPointerClickAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnPointerClickAsync() + { + return ((IAsyncOnPointerClickHandler)new AsyncTriggerHandler(this, true)).OnPointerClickAsync(); + } + + public UniTask OnPointerClickAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnPointerClickHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnPointerClickAsync(); + } + } +#endif +#endregion + +#region PointerDown +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnPointerDownHandler + { + UniTask OnPointerDownAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnPointerDownHandler + { + UniTask IAsyncOnPointerDownHandler.OnPointerDownAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncPointerDownTrigger GetAsyncPointerDownTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncPointerDownTrigger GetAsyncPointerDownTrigger(this Component component) + { + return component.gameObject.GetAsyncPointerDownTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncPointerDownTrigger : AsyncTriggerBase, IPointerDownHandler + { + void IPointerDownHandler.OnPointerDown(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnPointerDownHandler GetOnPointerDownAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnPointerDownHandler GetOnPointerDownAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnPointerDownAsync() + { + return ((IAsyncOnPointerDownHandler)new AsyncTriggerHandler(this, true)).OnPointerDownAsync(); + } + + public UniTask OnPointerDownAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnPointerDownHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnPointerDownAsync(); + } + } +#endif +#endregion + +#region PointerEnter +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnPointerEnterHandler + { + UniTask OnPointerEnterAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnPointerEnterHandler + { + UniTask IAsyncOnPointerEnterHandler.OnPointerEnterAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncPointerEnterTrigger GetAsyncPointerEnterTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncPointerEnterTrigger GetAsyncPointerEnterTrigger(this Component component) + { + return component.gameObject.GetAsyncPointerEnterTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncPointerEnterTrigger : AsyncTriggerBase, IPointerEnterHandler + { + void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnPointerEnterHandler GetOnPointerEnterAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnPointerEnterHandler GetOnPointerEnterAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnPointerEnterAsync() + { + return ((IAsyncOnPointerEnterHandler)new AsyncTriggerHandler(this, true)).OnPointerEnterAsync(); + } + + public UniTask OnPointerEnterAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnPointerEnterHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnPointerEnterAsync(); + } + } +#endif +#endregion + +#region PointerExit +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnPointerExitHandler + { + UniTask OnPointerExitAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnPointerExitHandler + { + UniTask IAsyncOnPointerExitHandler.OnPointerExitAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncPointerExitTrigger GetAsyncPointerExitTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncPointerExitTrigger GetAsyncPointerExitTrigger(this Component component) + { + return component.gameObject.GetAsyncPointerExitTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncPointerExitTrigger : AsyncTriggerBase, IPointerExitHandler + { + void IPointerExitHandler.OnPointerExit(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnPointerExitHandler GetOnPointerExitAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnPointerExitHandler GetOnPointerExitAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnPointerExitAsync() + { + return ((IAsyncOnPointerExitHandler)new AsyncTriggerHandler(this, true)).OnPointerExitAsync(); + } + + public UniTask OnPointerExitAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnPointerExitHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnPointerExitAsync(); + } + } +#endif +#endregion + +#region PointerUp +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnPointerUpHandler + { + UniTask OnPointerUpAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnPointerUpHandler + { + UniTask IAsyncOnPointerUpHandler.OnPointerUpAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncPointerUpTrigger GetAsyncPointerUpTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncPointerUpTrigger GetAsyncPointerUpTrigger(this Component component) + { + return component.gameObject.GetAsyncPointerUpTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncPointerUpTrigger : AsyncTriggerBase, IPointerUpHandler + { + void IPointerUpHandler.OnPointerUp(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnPointerUpHandler GetOnPointerUpAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnPointerUpHandler GetOnPointerUpAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnPointerUpAsync() + { + return ((IAsyncOnPointerUpHandler)new AsyncTriggerHandler(this, true)).OnPointerUpAsync(); + } + + public UniTask OnPointerUpAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnPointerUpHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnPointerUpAsync(); + } + } +#endif +#endregion + +#region Scroll +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnScrollHandler + { + UniTask OnScrollAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnScrollHandler + { + UniTask IAsyncOnScrollHandler.OnScrollAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncScrollTrigger GetAsyncScrollTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncScrollTrigger GetAsyncScrollTrigger(this Component component) + { + return component.gameObject.GetAsyncScrollTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncScrollTrigger : AsyncTriggerBase, IScrollHandler + { + void IScrollHandler.OnScroll(PointerEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnScrollHandler GetOnScrollAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnScrollHandler GetOnScrollAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnScrollAsync() + { + return ((IAsyncOnScrollHandler)new AsyncTriggerHandler(this, true)).OnScrollAsync(); + } + + public UniTask OnScrollAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnScrollHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnScrollAsync(); + } + } +#endif +#endregion + +#region Select +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnSelectHandler + { + UniTask OnSelectAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnSelectHandler + { + UniTask IAsyncOnSelectHandler.OnSelectAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncSelectTrigger GetAsyncSelectTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncSelectTrigger GetAsyncSelectTrigger(this Component component) + { + return component.gameObject.GetAsyncSelectTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncSelectTrigger : AsyncTriggerBase, ISelectHandler + { + void ISelectHandler.OnSelect(BaseEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnSelectHandler GetOnSelectAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnSelectHandler GetOnSelectAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnSelectAsync() + { + return ((IAsyncOnSelectHandler)new AsyncTriggerHandler(this, true)).OnSelectAsync(); + } + + public UniTask OnSelectAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnSelectHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnSelectAsync(); + } + } +#endif +#endregion + +#region Submit +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnSubmitHandler + { + UniTask OnSubmitAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnSubmitHandler + { + UniTask IAsyncOnSubmitHandler.OnSubmitAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncSubmitTrigger GetAsyncSubmitTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncSubmitTrigger GetAsyncSubmitTrigger(this Component component) + { + return component.gameObject.GetAsyncSubmitTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncSubmitTrigger : AsyncTriggerBase, ISubmitHandler + { + void ISubmitHandler.OnSubmit(BaseEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnSubmitHandler GetOnSubmitAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnSubmitHandler GetOnSubmitAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnSubmitAsync() + { + return ((IAsyncOnSubmitHandler)new AsyncTriggerHandler(this, true)).OnSubmitAsync(); + } + + public UniTask OnSubmitAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnSubmitHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnSubmitAsync(); + } + } +#endif +#endregion + +#region UpdateSelected +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + + public interface IAsyncOnUpdateSelectedHandler + { + UniTask OnUpdateSelectedAsync(); + } + + public partial class AsyncTriggerHandler : IAsyncOnUpdateSelectedHandler + { + UniTask IAsyncOnUpdateSelectedHandler.OnUpdateSelectedAsync() + { + core.Reset(); + return new UniTask((IUniTaskSource)(object)this, core.Version); + } + } + + public static partial class AsyncTriggerExtensions + { + public static AsyncUpdateSelectedTrigger GetAsyncUpdateSelectedTrigger(this GameObject gameObject) + { + return GetOrAddComponent(gameObject); + } + + public static AsyncUpdateSelectedTrigger GetAsyncUpdateSelectedTrigger(this Component component) + { + return component.gameObject.GetAsyncUpdateSelectedTrigger(); + } + } + + [DisallowMultipleComponent] + public sealed class AsyncUpdateSelectedTrigger : AsyncTriggerBase, IUpdateSelectedHandler + { + void IUpdateSelectedHandler.OnUpdateSelected(BaseEventData eventData) + { + RaiseEvent((eventData)); + } + + public IAsyncOnUpdateSelectedHandler GetOnUpdateSelectedAsyncHandler() + { + return new AsyncTriggerHandler(this, false); + } + + public IAsyncOnUpdateSelectedHandler GetOnUpdateSelectedAsyncHandler(CancellationToken cancellationToken) + { + return new AsyncTriggerHandler(this, cancellationToken, false); + } + + public UniTask OnUpdateSelectedAsync() + { + return ((IAsyncOnUpdateSelectedHandler)new AsyncTriggerHandler(this, true)).OnUpdateSelectedAsync(); + } + + public UniTask OnUpdateSelectedAsync(CancellationToken cancellationToken) + { + return ((IAsyncOnUpdateSelectedHandler)new AsyncTriggerHandler(this, cancellationToken, true)).OnUpdateSelectedAsync(); + } + } +#endif +#endregion + +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs.meta new file mode 100644 index 0000000..82aa679 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c30655636c35c3d4da44064af3d2d9a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Bridge.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Bridge.cs new file mode 100644 index 0000000..c904299 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Bridge.cs @@ -0,0 +1,18 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Collections; + +namespace Cysharp.Threading.Tasks +{ + // UnityEngine Bridges. + + public partial struct UniTask + { + public static IEnumerator ToCoroutine(Func taskFactory) + { + return taskFactory().ToCoroutine(); + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Bridge.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Bridge.cs.meta new file mode 100644 index 0000000..6f8da80 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Bridge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd6beac8e0ebd264e9ba246c39429c72 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Delay.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Delay.cs new file mode 100644 index 0000000..0986c00 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Delay.cs @@ -0,0 +1,965 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Collections; +using System.Runtime.CompilerServices; +using System.Threading; +using UnityEngine; + +namespace Cysharp.Threading.Tasks +{ + public enum DelayType + { + /// use Time.deltaTime. + DeltaTime, + /// Ignore timescale, use Time.unscaledDeltaTime. + UnscaledDeltaTime, + /// use Stopwatch.GetTimestamp(). + Realtime + } + + public partial struct UniTask + { + public static YieldAwaitable Yield() + { + // optimized for single continuation + return new YieldAwaitable(PlayerLoopTiming.Update); + } + + public static YieldAwaitable Yield(PlayerLoopTiming timing) + { + // optimized for single continuation + return new YieldAwaitable(timing); + } + + public static UniTask Yield(CancellationToken cancellationToken) + { + return new UniTask(YieldPromise.Create(PlayerLoopTiming.Update, cancellationToken, out var token), token); + } + + public static UniTask Yield(PlayerLoopTiming timing, CancellationToken cancellationToken) + { + return new UniTask(YieldPromise.Create(timing, cancellationToken, out var token), token); + } + + /// + /// Similar as UniTask.Yield but guaranteed run on next frame. + /// + public static UniTask NextFrame() + { + return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, CancellationToken.None, out var token), token); + } + + /// + /// Similar as UniTask.Yield but guaranteed run on next frame. + /// + public static UniTask NextFrame(PlayerLoopTiming timing) + { + return new UniTask(NextFramePromise.Create(timing, CancellationToken.None, out var token), token); + } + + /// + /// Similar as UniTask.Yield but guaranteed run on next frame. + /// + public static UniTask NextFrame(CancellationToken cancellationToken) + { + return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, cancellationToken, out var token), token); + } + + /// + /// Similar as UniTask.Yield but guaranteed run on next frame. + /// + public static UniTask NextFrame(PlayerLoopTiming timing, CancellationToken cancellationToken) + { + return new UniTask(NextFramePromise.Create(timing, cancellationToken, out var token), token); + } + + [Obsolete("Use WaitForEndOfFrame(MonoBehaviour) instead or UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate). Equivalent for coroutine's WaitForEndOfFrame requires MonoBehaviour(runner of Coroutine).")] + public static YieldAwaitable WaitForEndOfFrame() + { + return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate); + } + + [Obsolete("Use WaitForEndOfFrame(MonoBehaviour) instead or UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate). Equivalent for coroutine's WaitForEndOfFrame requires MonoBehaviour(runner of Coroutine).")] + public static UniTask WaitForEndOfFrame(CancellationToken cancellationToken) + { + return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken); + } + + public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner, CancellationToken cancellationToken = default) + { + var source = WaitForEndOfFramePromise.Create(coroutineRunner, cancellationToken, out var token); + return new UniTask(source, token); + } + + /// + /// Same as UniTask.Yield(PlayerLoopTiming.LastFixedUpdate). + /// + public static YieldAwaitable WaitForFixedUpdate() + { + // use LastFixedUpdate instead of FixedUpdate + // https://github.com/Cysharp/UniTask/issues/377 + return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate); + } + + /// + /// Same as UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken). + /// + public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken) + { + return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken); + } + + public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + if (delayFrameCount < 0) + { + throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayFrameCount:" + delayFrameCount); + } + + return new UniTask(DelayFramePromise.Create(delayFrameCount, delayTiming, cancellationToken, out var token), token); + } + + public static UniTask Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay); + return Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cancellationToken); + } + + public static UniTask Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + var delayType = ignoreTimeScale ? DelayType.UnscaledDeltaTime : DelayType.DeltaTime; + return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken); + } + + public static UniTask Delay(int millisecondsDelay, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay); + return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken); + } + + public static UniTask Delay(TimeSpan delayTimeSpan, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + if (delayTimeSpan < TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException("Delay does not allow minus delayTimeSpan. delayTimeSpan:" + delayTimeSpan); + } + +#if UNITY_EDITOR + // force use Realtime. + if (PlayerLoopHelper.IsMainThread && !UnityEditor.EditorApplication.isPlaying) + { + delayType = DelayType.Realtime; + } +#endif + + switch (delayType) + { + case DelayType.UnscaledDeltaTime: + { + return new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token); + } + case DelayType.Realtime: + { + return new UniTask(DelayRealtimePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token); + } + case DelayType.DeltaTime: + default: + { + return new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token); + } + } + } + + sealed class YieldPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + YieldPromise nextNode; + public ref YieldPromise NextNode => ref nextNode; + + static YieldPromise() + { + TaskPool.RegisterSizeGetter(typeof(YieldPromise), () => pool.Size); + } + + CancellationToken cancellationToken; + UniTaskCompletionSourceCore core; + + YieldPromise() + { + } + + public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new YieldPromise(); + } + + + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + core.TrySetResult(null); + return false; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + cancellationToken = default; + return pool.TryPush(this); + } + } + + sealed class NextFramePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + NextFramePromise nextNode; + public ref NextFramePromise NextNode => ref nextNode; + + static NextFramePromise() + { + TaskPool.RegisterSizeGetter(typeof(NextFramePromise), () => pool.Size); + } + + int frameCount; + CancellationToken cancellationToken; + UniTaskCompletionSourceCore core; + + NextFramePromise() + { + } + + public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new NextFramePromise(); + } + + result.frameCount = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (frameCount == Time.frameCount) + { + return true; + } + + core.TrySetResult(AsyncUnit.Default); + return false; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + cancellationToken = default; + return pool.TryPush(this); + } + } + + sealed class WaitForEndOfFramePromise : IUniTaskSource, ITaskPoolNode, System.Collections.IEnumerator + { + static TaskPool pool; + WaitForEndOfFramePromise nextNode; + public ref WaitForEndOfFramePromise NextNode => ref nextNode; + + static WaitForEndOfFramePromise() + { + TaskPool.RegisterSizeGetter(typeof(WaitForEndOfFramePromise), () => pool.Size); + } + + CancellationToken cancellationToken; + UniTaskCompletionSourceCore core; + + WaitForEndOfFramePromise() + { + } + + public static IUniTaskSource Create(MonoBehaviour coroutineRunner, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new WaitForEndOfFramePromise(); + } + + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + coroutineRunner.StartCoroutine(result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + Reset(); // Reset Enumerator + cancellationToken = default; + return pool.TryPush(this); + } + + // Coroutine Runner implementation + + static readonly WaitForEndOfFrame waitForEndOfFrameYieldInstruction = new WaitForEndOfFrame(); + bool isFirst = true; + + object IEnumerator.Current => waitForEndOfFrameYieldInstruction; + + bool IEnumerator.MoveNext() + { + if (isFirst) + { + isFirst = false; + return true; // start WaitForEndOfFrame + } + + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + core.TrySetResult(null); + return false; + } + + public void Reset() + { + isFirst = true; + } + } + + sealed class DelayFramePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + DelayFramePromise nextNode; + public ref DelayFramePromise NextNode => ref nextNode; + + static DelayFramePromise() + { + TaskPool.RegisterSizeGetter(typeof(DelayFramePromise), () => pool.Size); + } + + int initialFrame; + int delayFrameCount; + CancellationToken cancellationToken; + + int currentFrameCount; + UniTaskCompletionSourceCore core; + + DelayFramePromise() + { + } + + public static IUniTaskSource Create(int delayFrameCount, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new DelayFramePromise(); + } + + result.delayFrameCount = delayFrameCount; + result.cancellationToken = cancellationToken; + result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (currentFrameCount == 0) + { + if (delayFrameCount == 0) // same as Yield + { + core.TrySetResult(AsyncUnit.Default); + return false; + } + + // skip in initial frame. + if (initialFrame == Time.frameCount) + { +#if UNITY_EDITOR + // force use Realtime. + if (PlayerLoopHelper.IsMainThread && !UnityEditor.EditorApplication.isPlaying) + { + //goto ++currentFrameCount + } + else + { + return true; + } +#else + return true; +#endif + } + } + + if (++currentFrameCount >= delayFrameCount) + { + core.TrySetResult(AsyncUnit.Default); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + currentFrameCount = default; + delayFrameCount = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + sealed class DelayPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + DelayPromise nextNode; + public ref DelayPromise NextNode => ref nextNode; + + static DelayPromise() + { + TaskPool.RegisterSizeGetter(typeof(DelayPromise), () => pool.Size); + } + + int initialFrame; + float delayTimeSpan; + float elapsed; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + DelayPromise() + { + } + + public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new DelayPromise(); + } + + result.elapsed = 0.0f; + result.delayTimeSpan = (float)delayTimeSpan.TotalSeconds; + result.cancellationToken = cancellationToken; + result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (elapsed == 0.0f) + { + if (initialFrame == Time.frameCount) + { + return true; + } + } + + elapsed += Time.deltaTime; + if (elapsed >= delayTimeSpan) + { + core.TrySetResult(null); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + delayTimeSpan = default; + elapsed = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + sealed class DelayIgnoreTimeScalePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + DelayIgnoreTimeScalePromise nextNode; + public ref DelayIgnoreTimeScalePromise NextNode => ref nextNode; + + static DelayIgnoreTimeScalePromise() + { + TaskPool.RegisterSizeGetter(typeof(DelayIgnoreTimeScalePromise), () => pool.Size); + } + + float delayFrameTimeSpan; + float elapsed; + int initialFrame; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + DelayIgnoreTimeScalePromise() + { + } + + public static IUniTaskSource Create(TimeSpan delayFrameTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new DelayIgnoreTimeScalePromise(); + } + + result.elapsed = 0.0f; + result.delayFrameTimeSpan = (float)delayFrameTimeSpan.TotalSeconds; + result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (elapsed == 0.0f) + { + if (initialFrame == Time.frameCount) + { + return true; + } + } + + elapsed += Time.unscaledDeltaTime; + if (elapsed >= delayFrameTimeSpan) + { + core.TrySetResult(null); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + delayFrameTimeSpan = default; + elapsed = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + sealed class DelayRealtimePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + DelayRealtimePromise nextNode; + public ref DelayRealtimePromise NextNode => ref nextNode; + + static DelayRealtimePromise() + { + TaskPool.RegisterSizeGetter(typeof(DelayRealtimePromise), () => pool.Size); + } + + long delayTimeSpanTicks; + ValueStopwatch stopwatch; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + DelayRealtimePromise() + { + } + + public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new DelayRealtimePromise(); + } + + result.stopwatch = ValueStopwatch.StartNew(); + result.delayTimeSpanTicks = delayTimeSpan.Ticks; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (stopwatch.IsInvalid) + { + core.TrySetResult(AsyncUnit.Default); + return false; + } + + if (stopwatch.ElapsedTicks >= delayTimeSpanTicks) + { + core.TrySetResult(AsyncUnit.Default); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + stopwatch = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + } + + public readonly struct YieldAwaitable + { + readonly PlayerLoopTiming timing; + + public YieldAwaitable(PlayerLoopTiming timing) + { + this.timing = timing; + } + + public Awaiter GetAwaiter() + { + return new Awaiter(timing); + } + + public UniTask ToUniTask() + { + return UniTask.Yield(timing, CancellationToken.None); + } + + public readonly struct Awaiter : ICriticalNotifyCompletion + { + readonly PlayerLoopTiming timing; + + public Awaiter(PlayerLoopTiming timing) + { + this.timing = timing; + } + + public bool IsCompleted => false; + + public void GetResult() { } + + public void OnCompleted(Action continuation) + { + PlayerLoopHelper.AddContinuation(timing, continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + PlayerLoopHelper.AddContinuation(timing, continuation); + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Delay.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Delay.cs.meta new file mode 100644 index 0000000..08ce579 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Delay.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ecff7972251de0848b2c0fa89bbd3489 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Factory.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Factory.cs new file mode 100644 index 0000000..2f6a6a9 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Factory.cs @@ -0,0 +1,499 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public partial struct UniTask + { + static readonly UniTask CanceledUniTask = new Func(() => + { + return new UniTask(new CanceledResultSource(CancellationToken.None), 0); + })(); + + static class CanceledUniTaskCache + { + public static readonly UniTask Task; + + static CanceledUniTaskCache() + { + Task = new UniTask(new CanceledResultSource(CancellationToken.None), 0); + } + } + + public static readonly UniTask CompletedTask = new UniTask(); + + public static UniTask FromException(Exception ex) + { + if (ex is OperationCanceledException oce) + { + return FromCanceled(oce.CancellationToken); + } + + return new UniTask(new ExceptionResultSource(ex), 0); + } + + public static UniTask FromException(Exception ex) + { + if (ex is OperationCanceledException oce) + { + return FromCanceled(oce.CancellationToken); + } + + return new UniTask(new ExceptionResultSource(ex), 0); + } + + public static UniTask FromResult(T value) + { + return new UniTask(value); + } + + public static UniTask FromCanceled(CancellationToken cancellationToken = default) + { + if (cancellationToken == CancellationToken.None) + { + return CanceledUniTask; + } + else + { + return new UniTask(new CanceledResultSource(cancellationToken), 0); + } + } + + public static UniTask FromCanceled(CancellationToken cancellationToken = default) + { + if (cancellationToken == CancellationToken.None) + { + return CanceledUniTaskCache.Task; + } + else + { + return new UniTask(new CanceledResultSource(cancellationToken), 0); + } + } + + public static UniTask Create(Func factory) + { + return factory(); + } + + public static UniTask Create(Func> factory) + { + return factory(); + } + + public static AsyncLazy Lazy(Func factory) + { + return new AsyncLazy(factory); + } + + public static AsyncLazy Lazy(Func> factory) + { + return new AsyncLazy(factory); + } + + /// + /// helper of fire and forget void action. + /// + public static void Void(Func asyncAction) + { + asyncAction().Forget(); + } + + /// + /// helper of fire and forget void action. + /// + public static void Void(Func asyncAction, CancellationToken cancellationToken) + { + asyncAction(cancellationToken).Forget(); + } + + /// + /// helper of fire and forget void action. + /// + public static void Void(Func asyncAction, T state) + { + asyncAction(state).Forget(); + } + + /// + /// helper of create add UniTaskVoid to delegate. + /// For example: FooAction = UniTask.Action(async () => { /* */ }) + /// + public static Action Action(Func asyncAction) + { + return () => asyncAction().Forget(); + } + + /// + /// helper of create add UniTaskVoid to delegate. + /// + public static Action Action(Func asyncAction, CancellationToken cancellationToken) + { + return () => asyncAction(cancellationToken).Forget(); + } + +#if UNITY_2018_3_OR_NEWER + + /// + /// Create async void(UniTaskVoid) UnityAction. + /// For exampe: onClick.AddListener(UniTask.UnityAction(async () => { /* */ } )) + /// + public static UnityEngine.Events.UnityAction UnityAction(Func asyncAction) + { + return () => asyncAction().Forget(); + } + + /// + /// Create async void(UniTaskVoid) UnityAction. + /// For exampe: onClick.AddListener(UniTask.UnityAction(FooAsync, this.GetCancellationTokenOnDestroy())) + /// + public static UnityEngine.Events.UnityAction UnityAction(Func asyncAction, CancellationToken cancellationToken) + { + return () => asyncAction(cancellationToken).Forget(); + } + +#endif + + /// + /// Defer the task creation just before call await. + /// + public static UniTask Defer(Func factory) + { + return new UniTask(new DeferPromise(factory), 0); + } + + /// + /// Defer the task creation just before call await. + /// + public static UniTask Defer(Func> factory) + { + return new UniTask(new DeferPromise(factory), 0); + } + + /// + /// Never complete. + /// + public static UniTask Never(CancellationToken cancellationToken) + { + return new UniTask(new NeverPromise(cancellationToken), 0); + } + + /// + /// Never complete. + /// + public static UniTask Never(CancellationToken cancellationToken) + { + return new UniTask(new NeverPromise(cancellationToken), 0); + } + + sealed class ExceptionResultSource : IUniTaskSource + { + readonly ExceptionDispatchInfo exception; + bool calledGet; + + public ExceptionResultSource(Exception exception) + { + this.exception = ExceptionDispatchInfo.Capture(exception); + } + + public void GetResult(short token) + { + if (!calledGet) + { + calledGet = true; + GC.SuppressFinalize(this); + } + exception.Throw(); + } + + public UniTaskStatus GetStatus(short token) + { + return UniTaskStatus.Faulted; + } + + public UniTaskStatus UnsafeGetStatus() + { + return UniTaskStatus.Faulted; + } + + public void OnCompleted(Action continuation, object state, short token) + { + continuation(state); + } + + ~ExceptionResultSource() + { + if (!calledGet) + { + UniTaskScheduler.PublishUnobservedTaskException(exception.SourceException); + } + } + } + + sealed class ExceptionResultSource : IUniTaskSource + { + readonly ExceptionDispatchInfo exception; + bool calledGet; + + public ExceptionResultSource(Exception exception) + { + this.exception = ExceptionDispatchInfo.Capture(exception); + } + + public T GetResult(short token) + { + if (!calledGet) + { + calledGet = true; + GC.SuppressFinalize(this); + } + exception.Throw(); + return default; + } + + void IUniTaskSource.GetResult(short token) + { + if (!calledGet) + { + calledGet = true; + GC.SuppressFinalize(this); + } + exception.Throw(); + } + + public UniTaskStatus GetStatus(short token) + { + return UniTaskStatus.Faulted; + } + + public UniTaskStatus UnsafeGetStatus() + { + return UniTaskStatus.Faulted; + } + + public void OnCompleted(Action continuation, object state, short token) + { + continuation(state); + } + + ~ExceptionResultSource() + { + if (!calledGet) + { + UniTaskScheduler.PublishUnobservedTaskException(exception.SourceException); + } + } + } + + sealed class CanceledResultSource : IUniTaskSource + { + readonly CancellationToken cancellationToken; + + public CanceledResultSource(CancellationToken cancellationToken) + { + this.cancellationToken = cancellationToken; + } + + public void GetResult(short token) + { + throw new OperationCanceledException(cancellationToken); + } + + public UniTaskStatus GetStatus(short token) + { + return UniTaskStatus.Canceled; + } + + public UniTaskStatus UnsafeGetStatus() + { + return UniTaskStatus.Canceled; + } + + public void OnCompleted(Action continuation, object state, short token) + { + continuation(state); + } + } + + sealed class CanceledResultSource : IUniTaskSource + { + readonly CancellationToken cancellationToken; + + public CanceledResultSource(CancellationToken cancellationToken) + { + this.cancellationToken = cancellationToken; + } + + public T GetResult(short token) + { + throw new OperationCanceledException(cancellationToken); + } + + void IUniTaskSource.GetResult(short token) + { + throw new OperationCanceledException(cancellationToken); + } + + public UniTaskStatus GetStatus(short token) + { + return UniTaskStatus.Canceled; + } + + public UniTaskStatus UnsafeGetStatus() + { + return UniTaskStatus.Canceled; + } + + public void OnCompleted(Action continuation, object state, short token) + { + continuation(state); + } + } + + sealed class DeferPromise : IUniTaskSource + { + Func factory; + UniTask task; + UniTask.Awaiter awaiter; + + public DeferPromise(Func factory) + { + this.factory = factory; + } + + public void GetResult(short token) + { + awaiter.GetResult(); + } + + public UniTaskStatus GetStatus(short token) + { + var f = Interlocked.Exchange(ref factory, null); + if (f != null) + { + task = f(); + awaiter = task.GetAwaiter(); + } + + return task.Status; + } + + public void OnCompleted(Action continuation, object state, short token) + { + awaiter.SourceOnCompleted(continuation, state); + } + + public UniTaskStatus UnsafeGetStatus() + { + return task.Status; + } + } + + sealed class DeferPromise : IUniTaskSource + { + Func> factory; + UniTask task; + UniTask.Awaiter awaiter; + + public DeferPromise(Func> factory) + { + this.factory = factory; + } + + public T GetResult(short token) + { + return awaiter.GetResult(); + } + + void IUniTaskSource.GetResult(short token) + { + awaiter.GetResult(); + } + + public UniTaskStatus GetStatus(short token) + { + var f = Interlocked.Exchange(ref factory, null); + if (f != null) + { + task = f(); + awaiter = task.GetAwaiter(); + } + + return task.Status; + } + + public void OnCompleted(Action continuation, object state, short token) + { + awaiter.SourceOnCompleted(continuation, state); + } + + public UniTaskStatus UnsafeGetStatus() + { + return task.Status; + } + } + + sealed class NeverPromise : IUniTaskSource + { + static readonly Action cancellationCallback = CancellationCallback; + + CancellationToken cancellationToken; + UniTaskCompletionSourceCore core; + + public NeverPromise(CancellationToken cancellationToken) + { + this.cancellationToken = cancellationToken; + if (this.cancellationToken.CanBeCanceled) + { + this.cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); + } + } + + static void CancellationCallback(object state) + { + var self = (NeverPromise)state; + self.core.TrySetCanceled(self.cancellationToken); + } + + public T GetResult(short token) + { + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + void IUniTaskSource.GetResult(short token) + { + core.GetResult(token); + } + } + } + + internal static class CompletedTasks + { + public static readonly UniTask AsyncUnit = UniTask.FromResult(Cysharp.Threading.Tasks.AsyncUnit.Default); + public static readonly UniTask True = UniTask.FromResult(true); + public static readonly UniTask False = UniTask.FromResult(false); + public static readonly UniTask Zero = UniTask.FromResult(0); + public static readonly UniTask MinusOne = UniTask.FromResult(-1); + public static readonly UniTask One = UniTask.FromResult(1); + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Factory.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Factory.cs.meta new file mode 100644 index 0000000..31bc0c9 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Factory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e12b66d6b9bd7845b04a594cbe386b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Run.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Run.cs new file mode 100644 index 0000000..ac3e795 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Run.cs @@ -0,0 +1,289 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public partial struct UniTask + { + #region OBSOLETE_RUN + + [Obsolete("UniTask.Run is similar as Task.Run, it uses ThreadPool. For equivalent behaviour, use UniTask.RunOnThreadPool instead. If you don't want to use ThreadPool, you can use UniTask.Void(async void) or UniTask.Create(async UniTask) too.")] + public static UniTask Run(Action action, bool configureAwait = true, CancellationToken cancellationToken = default) + { + return RunOnThreadPool(action, configureAwait, cancellationToken); + } + + [Obsolete("UniTask.Run is similar as Task.Run, it uses ThreadPool. For equivalent behaviour, use UniTask.RunOnThreadPool instead. If you don't want to use ThreadPool, you can use UniTask.Void(async void) or UniTask.Create(async UniTask) too.")] + public static UniTask Run(Action action, object state, bool configureAwait = true, CancellationToken cancellationToken = default) + { + return RunOnThreadPool(action, state, configureAwait, cancellationToken); + } + + [Obsolete("UniTask.Run is similar as Task.Run, it uses ThreadPool. For equivalent behaviour, use UniTask.RunOnThreadPool instead. If you don't want to use ThreadPool, you can use UniTask.Void(async void) or UniTask.Create(async UniTask) too.")] + public static UniTask Run(Func action, bool configureAwait = true, CancellationToken cancellationToken = default) + { + return RunOnThreadPool(action, configureAwait, cancellationToken); + } + + [Obsolete("UniTask.Run is similar as Task.Run, it uses ThreadPool. For equivalent behaviour, use UniTask.RunOnThreadPool instead. If you don't want to use ThreadPool, you can use UniTask.Void(async void) or UniTask.Create(async UniTask) too.")] + public static UniTask Run(Func action, object state, bool configureAwait = true, CancellationToken cancellationToken = default) + { + return RunOnThreadPool(action, state, configureAwait, cancellationToken); + } + + [Obsolete("UniTask.Run is similar as Task.Run, it uses ThreadPool. For equivalent behaviour, use UniTask.RunOnThreadPool instead. If you don't want to use ThreadPool, you can use UniTask.Void(async void) or UniTask.Create(async UniTask) too.")] + public static UniTask Run(Func func, bool configureAwait = true, CancellationToken cancellationToken = default) + { + return RunOnThreadPool(func, configureAwait, cancellationToken); + } + + [Obsolete("UniTask.Run is similar as Task.Run, it uses ThreadPool. For equivalent behaviour, use UniTask.RunOnThreadPool instead. If you don't want to use ThreadPool, you can use UniTask.Void(async void) or UniTask.Create(async UniTask) too.")] + public static UniTask Run(Func> func, bool configureAwait = true, CancellationToken cancellationToken = default) + { + return RunOnThreadPool(func, configureAwait, cancellationToken); + } + + [Obsolete("UniTask.Run is similar as Task.Run, it uses ThreadPool. For equivalent behaviour, use UniTask.RunOnThreadPool instead. If you don't want to use ThreadPool, you can use UniTask.Void(async void) or UniTask.Create(async UniTask) too.")] + public static UniTask Run(Func func, object state, bool configureAwait = true, CancellationToken cancellationToken = default) + { + return RunOnThreadPool(func, state, configureAwait, cancellationToken); + } + + [Obsolete("UniTask.Run is similar as Task.Run, it uses ThreadPool. For equivalent behaviour, use UniTask.RunOnThreadPool instead. If you don't want to use ThreadPool, you can use UniTask.Void(async void) or UniTask.Create(async UniTask) too.")] + public static UniTask Run(Func> func, object state, bool configureAwait = true, CancellationToken cancellationToken = default) + { + return RunOnThreadPool(func, state, configureAwait, cancellationToken); + } + + #endregion + + /// Run action on the threadPool and return to main thread if configureAwait = true. + public static async UniTask RunOnThreadPool(Action action, bool configureAwait = true, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + await UniTask.SwitchToThreadPool(); + + cancellationToken.ThrowIfCancellationRequested(); + + if (configureAwait) + { + try + { + action(); + } + finally + { + await UniTask.Yield(); + } + } + else + { + action(); + } + + cancellationToken.ThrowIfCancellationRequested(); + } + + /// Run action on the threadPool and return to main thread if configureAwait = true. + public static async UniTask RunOnThreadPool(Action action, object state, bool configureAwait = true, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + await UniTask.SwitchToThreadPool(); + + cancellationToken.ThrowIfCancellationRequested(); + + if (configureAwait) + { + try + { + action(state); + } + finally + { + await UniTask.Yield(); + } + } + else + { + action(state); + } + + cancellationToken.ThrowIfCancellationRequested(); + } + + /// Run action on the threadPool and return to main thread if configureAwait = true. + public static async UniTask RunOnThreadPool(Func action, bool configureAwait = true, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + await UniTask.SwitchToThreadPool(); + + cancellationToken.ThrowIfCancellationRequested(); + + if (configureAwait) + { + try + { + await action(); + } + finally + { + await UniTask.Yield(); + } + } + else + { + await action(); + } + + cancellationToken.ThrowIfCancellationRequested(); + } + + /// Run action on the threadPool and return to main thread if configureAwait = true. + public static async UniTask RunOnThreadPool(Func action, object state, bool configureAwait = true, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + await UniTask.SwitchToThreadPool(); + + cancellationToken.ThrowIfCancellationRequested(); + + if (configureAwait) + { + try + { + await action(state); + } + finally + { + await UniTask.Yield(); + } + } + else + { + await action(state); + } + + cancellationToken.ThrowIfCancellationRequested(); + } + + /// Run action on the threadPool and return to main thread if configureAwait = true. + public static async UniTask RunOnThreadPool(Func func, bool configureAwait = true, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + await UniTask.SwitchToThreadPool(); + + cancellationToken.ThrowIfCancellationRequested(); + + if (configureAwait) + { + try + { + return func(); + } + finally + { + await UniTask.Yield(); + cancellationToken.ThrowIfCancellationRequested(); + } + } + else + { + return func(); + } + } + + /// Run action on the threadPool and return to main thread if configureAwait = true. + public static async UniTask RunOnThreadPool(Func> func, bool configureAwait = true, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + await UniTask.SwitchToThreadPool(); + + cancellationToken.ThrowIfCancellationRequested(); + + if (configureAwait) + { + try + { + return await func(); + } + finally + { + cancellationToken.ThrowIfCancellationRequested(); + await UniTask.Yield(); + cancellationToken.ThrowIfCancellationRequested(); + } + } + else + { + var result = await func(); + cancellationToken.ThrowIfCancellationRequested(); + return result; + } + } + + /// Run action on the threadPool and return to main thread if configureAwait = true. + public static async UniTask RunOnThreadPool(Func func, object state, bool configureAwait = true, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + await UniTask.SwitchToThreadPool(); + + cancellationToken.ThrowIfCancellationRequested(); + + if (configureAwait) + { + try + { + return func(state); + } + finally + { + await UniTask.Yield(); + cancellationToken.ThrowIfCancellationRequested(); + } + } + else + { + return func(state); + } + } + + /// Run action on the threadPool and return to main thread if configureAwait = true. + public static async UniTask RunOnThreadPool(Func> func, object state, bool configureAwait = true, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + await UniTask.SwitchToThreadPool(); + + cancellationToken.ThrowIfCancellationRequested(); + + if (configureAwait) + { + try + { + return await func(state); + } + finally + { + cancellationToken.ThrowIfCancellationRequested(); + await UniTask.Yield(); + cancellationToken.ThrowIfCancellationRequested(); + } + } + else + { + var result = await func(state); + cancellationToken.ThrowIfCancellationRequested(); + return result; + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Run.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Run.cs.meta new file mode 100644 index 0000000..9a780ae --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Run.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8473162fc285a5f44bcca90f7da073e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Threading.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Threading.cs new file mode 100644 index 0000000..71d6aec --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Threading.cs @@ -0,0 +1,412 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public partial struct UniTask + { +#if UNITY_2018_3_OR_NEWER + + /// + /// If running on mainthread, do nothing. Otherwise, same as UniTask.Yield(PlayerLoopTiming.Update). + /// + public static SwitchToMainThreadAwaitable SwitchToMainThread(CancellationToken cancellationToken = default) + { + return new SwitchToMainThreadAwaitable(PlayerLoopTiming.Update, cancellationToken); + } + + /// + /// If running on mainthread, do nothing. Otherwise, same as UniTask.Yield(timing). + /// + public static SwitchToMainThreadAwaitable SwitchToMainThread(PlayerLoopTiming timing, CancellationToken cancellationToken = default) + { + return new SwitchToMainThreadAwaitable(timing, cancellationToken); + } + + /// + /// Return to mainthread(same as await SwitchToMainThread) after using scope is closed. + /// + public static ReturnToMainThread ReturnToMainThread(CancellationToken cancellationToken = default) + { + return new ReturnToMainThread(PlayerLoopTiming.Update, cancellationToken); + } + + /// + /// Return to mainthread(same as await SwitchToMainThread) after using scope is closed. + /// + public static ReturnToMainThread ReturnToMainThread(PlayerLoopTiming timing, CancellationToken cancellationToken = default) + { + return new ReturnToMainThread(timing, cancellationToken); + } + + /// + /// Queue the action to PlayerLoop. + /// + public static void Post(Action action, PlayerLoopTiming timing = PlayerLoopTiming.Update) + { + PlayerLoopHelper.AddContinuation(timing, action); + } + +#endif + + public static SwitchToThreadPoolAwaitable SwitchToThreadPool() + { + return new SwitchToThreadPoolAwaitable(); + } + + /// + /// Note: use SwitchToThreadPool is recommended. + /// + public static SwitchToTaskPoolAwaitable SwitchToTaskPool() + { + return new SwitchToTaskPoolAwaitable(); + } + + public static SwitchToSynchronizationContextAwaitable SwitchToSynchronizationContext(SynchronizationContext synchronizationContext, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(synchronizationContext, nameof(synchronizationContext)); + return new SwitchToSynchronizationContextAwaitable(synchronizationContext, cancellationToken); + } + + public static ReturnToSynchronizationContext ReturnToSynchronizationContext(SynchronizationContext synchronizationContext, CancellationToken cancellationToken = default) + { + return new ReturnToSynchronizationContext(synchronizationContext, false, cancellationToken); + } + + public static ReturnToSynchronizationContext ReturnToCurrentSynchronizationContext(bool dontPostWhenSameContext = true, CancellationToken cancellationToken = default) + { + return new ReturnToSynchronizationContext(SynchronizationContext.Current, dontPostWhenSameContext, cancellationToken); + } + } + +#if UNITY_2018_3_OR_NEWER + + public struct SwitchToMainThreadAwaitable + { + readonly PlayerLoopTiming playerLoopTiming; + readonly CancellationToken cancellationToken; + + public SwitchToMainThreadAwaitable(PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken) + { + this.playerLoopTiming = playerLoopTiming; + this.cancellationToken = cancellationToken; + } + + public Awaiter GetAwaiter() => new Awaiter(playerLoopTiming, cancellationToken); + + public struct Awaiter : ICriticalNotifyCompletion + { + readonly PlayerLoopTiming playerLoopTiming; + readonly CancellationToken cancellationToken; + + public Awaiter(PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken) + { + this.playerLoopTiming = playerLoopTiming; + this.cancellationToken = cancellationToken; + } + + public bool IsCompleted + { + get + { + var currentThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; + if (PlayerLoopHelper.MainThreadId == currentThreadId) + { + return true; // run immediate. + } + else + { + return false; // register continuation. + } + } + } + + public void GetResult() { cancellationToken.ThrowIfCancellationRequested(); } + + public void OnCompleted(Action continuation) + { + PlayerLoopHelper.AddContinuation(playerLoopTiming, continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + PlayerLoopHelper.AddContinuation(playerLoopTiming, continuation); + } + } + } + + public struct ReturnToMainThread + { + readonly PlayerLoopTiming playerLoopTiming; + readonly CancellationToken cancellationToken; + + public ReturnToMainThread(PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken) + { + this.playerLoopTiming = playerLoopTiming; + this.cancellationToken = cancellationToken; + } + + public Awaiter DisposeAsync() + { + return new Awaiter(playerLoopTiming, cancellationToken); // run immediate. + } + + public readonly struct Awaiter : ICriticalNotifyCompletion + { + readonly PlayerLoopTiming timing; + readonly CancellationToken cancellationToken; + + public Awaiter(PlayerLoopTiming timing, CancellationToken cancellationToken) + { + this.timing = timing; + this.cancellationToken = cancellationToken; + } + + public Awaiter GetAwaiter() => this; + + public bool IsCompleted => PlayerLoopHelper.MainThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId; + + public void GetResult() { cancellationToken.ThrowIfCancellationRequested(); } + + public void OnCompleted(Action continuation) + { + PlayerLoopHelper.AddContinuation(timing, continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + PlayerLoopHelper.AddContinuation(timing, continuation); + } + } + } + +#endif + + public struct SwitchToThreadPoolAwaitable + { + public Awaiter GetAwaiter() => new Awaiter(); + + public struct Awaiter : ICriticalNotifyCompletion + { + static readonly WaitCallback switchToCallback = Callback; + + public bool IsCompleted => false; + public void GetResult() { } + + public void OnCompleted(Action continuation) + { + ThreadPool.QueueUserWorkItem(switchToCallback, continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { +#if NETCOREAPP3_1 + ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false); +#else + ThreadPool.UnsafeQueueUserWorkItem(switchToCallback, continuation); +#endif + } + + static void Callback(object state) + { + var continuation = (Action)state; + continuation(); + } + } + +#if NETCOREAPP3_1 + + sealed class ThreadPoolWorkItem : IThreadPoolWorkItem, ITaskPoolNode + { + static TaskPool pool; + ThreadPoolWorkItem nextNode; + public ref ThreadPoolWorkItem NextNode => ref nextNode; + + static ThreadPoolWorkItem() + { + TaskPool.RegisterSizeGetter(typeof(ThreadPoolWorkItem), () => pool.Size); + } + + Action continuation; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ThreadPoolWorkItem Create(Action continuation) + { + if (!pool.TryPop(out var item)) + { + item = new ThreadPoolWorkItem(); + } + + item.continuation = continuation; + return item; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Execute() + { + var call = continuation; + continuation = null; + if (call != null) + { + pool.TryPush(this); + call.Invoke(); + } + } + } + +#endif + } + + public struct SwitchToTaskPoolAwaitable + { + public Awaiter GetAwaiter() => new Awaiter(); + + public struct Awaiter : ICriticalNotifyCompletion + { + static readonly Action switchToCallback = Callback; + + public bool IsCompleted => false; + public void GetResult() { } + + public void OnCompleted(Action continuation) + { + Task.Factory.StartNew(switchToCallback, continuation, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + } + + public void UnsafeOnCompleted(Action continuation) + { + Task.Factory.StartNew(switchToCallback, continuation, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + } + + static void Callback(object state) + { + var continuation = (Action)state; + continuation(); + } + } + } + + public struct SwitchToSynchronizationContextAwaitable + { + readonly SynchronizationContext synchronizationContext; + readonly CancellationToken cancellationToken; + + public SwitchToSynchronizationContextAwaitable(SynchronizationContext synchronizationContext, CancellationToken cancellationToken) + { + this.synchronizationContext = synchronizationContext; + this.cancellationToken = cancellationToken; + } + + public Awaiter GetAwaiter() => new Awaiter(synchronizationContext, cancellationToken); + + public struct Awaiter : ICriticalNotifyCompletion + { + static readonly SendOrPostCallback switchToCallback = Callback; + readonly SynchronizationContext synchronizationContext; + readonly CancellationToken cancellationToken; + + public Awaiter(SynchronizationContext synchronizationContext, CancellationToken cancellationToken) + { + this.synchronizationContext = synchronizationContext; + this.cancellationToken = cancellationToken; + } + + public bool IsCompleted => false; + public void GetResult() { cancellationToken.ThrowIfCancellationRequested(); } + + public void OnCompleted(Action continuation) + { + synchronizationContext.Post(switchToCallback, continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + synchronizationContext.Post(switchToCallback, continuation); + } + + static void Callback(object state) + { + var continuation = (Action)state; + continuation(); + } + } + } + + public struct ReturnToSynchronizationContext + { + readonly SynchronizationContext syncContext; + readonly bool dontPostWhenSameContext; + readonly CancellationToken cancellationToken; + + public ReturnToSynchronizationContext(SynchronizationContext syncContext, bool dontPostWhenSameContext, CancellationToken cancellationToken) + { + this.syncContext = syncContext; + this.dontPostWhenSameContext = dontPostWhenSameContext; + this.cancellationToken = cancellationToken; + } + + public Awaiter DisposeAsync() + { + return new Awaiter(syncContext, dontPostWhenSameContext, cancellationToken); + } + + public struct Awaiter : ICriticalNotifyCompletion + { + static readonly SendOrPostCallback switchToCallback = Callback; + + readonly SynchronizationContext synchronizationContext; + readonly bool dontPostWhenSameContext; + readonly CancellationToken cancellationToken; + + public Awaiter(SynchronizationContext synchronizationContext, bool dontPostWhenSameContext, CancellationToken cancellationToken) + { + this.synchronizationContext = synchronizationContext; + this.dontPostWhenSameContext = dontPostWhenSameContext; + this.cancellationToken = cancellationToken; + } + + public Awaiter GetAwaiter() => this; + + public bool IsCompleted + { + get + { + if (!dontPostWhenSameContext) return false; + + var current = SynchronizationContext.Current; + if (current == synchronizationContext) + { + return true; + } + else + { + return false; + } + } + } + + public void GetResult() { cancellationToken.ThrowIfCancellationRequested(); } + + public void OnCompleted(Action continuation) + { + synchronizationContext.Post(switchToCallback, continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + synchronizationContext.Post(switchToCallback, continuation); + } + + static void Callback(object state) + { + var continuation = (Action)state; + continuation(); + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Threading.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Threading.cs.meta new file mode 100644 index 0000000..fa512b8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.Threading.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4132ea600454134439fa2c7eb931b5e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WaitUntil.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WaitUntil.cs new file mode 100644 index 0000000..0a09fe0 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WaitUntil.cs @@ -0,0 +1,582 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public partial struct UniTask + { + public static UniTask WaitUntil(Func predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + return new UniTask(WaitUntilPromise.Create(predicate, timing, cancellationToken, out var token), token); + } + + public static UniTask WaitWhile(Func predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + return new UniTask(WaitWhilePromise.Create(predicate, timing, cancellationToken, out var token), token); + } + + public static UniTask WaitUntilCanceled(CancellationToken cancellationToken, PlayerLoopTiming timing = PlayerLoopTiming.Update) + { + return new UniTask(WaitUntilCanceledPromise.Create(cancellationToken, timing, out var token), token); + } + + public static UniTask WaitUntilValueChanged(T target, Func monitorFunction, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer equalityComparer = null, CancellationToken cancellationToken = default(CancellationToken)) + where T : class + { + var unityObject = target as UnityEngine.Object; + var isUnityObject = target is UnityEngine.Object; // don't use (unityObject == null) + + return new UniTask(isUnityObject + ? WaitUntilValueChangedUnityObjectPromise.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out var token) + : WaitUntilValueChangedStandardObjectPromise.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out token), token); + } + + sealed class WaitUntilPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + WaitUntilPromise nextNode; + public ref WaitUntilPromise NextNode => ref nextNode; + + static WaitUntilPromise() + { + TaskPool.RegisterSizeGetter(typeof(WaitUntilPromise), () => pool.Size); + } + + Func predicate; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + WaitUntilPromise() + { + } + + public static IUniTaskSource Create(Func predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new WaitUntilPromise(); + } + + result.predicate = predicate; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + try + { + if (!predicate()) + { + return true; + } + } + catch (Exception ex) + { + core.TrySetException(ex); + return false; + } + + core.TrySetResult(null); + return false; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + predicate = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + sealed class WaitWhilePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + WaitWhilePromise nextNode; + public ref WaitWhilePromise NextNode => ref nextNode; + + static WaitWhilePromise() + { + TaskPool.RegisterSizeGetter(typeof(WaitWhilePromise), () => pool.Size); + } + + Func predicate; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + WaitWhilePromise() + { + } + + public static IUniTaskSource Create(Func predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new WaitWhilePromise(); + } + + result.predicate = predicate; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + try + { + if (predicate()) + { + return true; + } + } + catch (Exception ex) + { + core.TrySetException(ex); + return false; + } + + core.TrySetResult(null); + return false; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + predicate = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + sealed class WaitUntilCanceledPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + WaitUntilCanceledPromise nextNode; + public ref WaitUntilCanceledPromise NextNode => ref nextNode; + + static WaitUntilCanceledPromise() + { + TaskPool.RegisterSizeGetter(typeof(WaitUntilCanceledPromise), () => pool.Size); + } + + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + WaitUntilCanceledPromise() + { + } + + public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new WaitUntilCanceledPromise(); + } + + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetResult(null); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + cancellationToken = default; + return pool.TryPush(this); + } + } + + // where T : UnityEngine.Object, can not add constraint + sealed class WaitUntilValueChangedUnityObjectPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode> + { + static TaskPool> pool; + WaitUntilValueChangedUnityObjectPromise nextNode; + public ref WaitUntilValueChangedUnityObjectPromise NextNode => ref nextNode; + + static WaitUntilValueChangedUnityObjectPromise() + { + TaskPool.RegisterSizeGetter(typeof(WaitUntilValueChangedUnityObjectPromise), () => pool.Size); + } + + T target; + UnityEngine.Object targetAsUnityObject; + U currentValue; + Func monitorFunction; + IEqualityComparer equalityComparer; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + WaitUntilValueChangedUnityObjectPromise() + { + } + + public static IUniTaskSource Create(T target, Func monitorFunction, IEqualityComparer equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new WaitUntilValueChangedUnityObjectPromise(); + } + + result.target = target; + result.targetAsUnityObject = target as UnityEngine.Object; + result.monitorFunction = monitorFunction; + result.currentValue = monitorFunction(target); + result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault(); + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public U GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested || targetAsUnityObject == null) // destroyed = cancel. + { + core.TrySetCanceled(cancellationToken); + return false; + } + + U nextValue = default(U); + try + { + nextValue = monitorFunction(target); + if (equalityComparer.Equals(currentValue, nextValue)) + { + return true; + } + } + catch (Exception ex) + { + core.TrySetException(ex); + return false; + } + + core.TrySetResult(nextValue); + return false; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + target = default; + currentValue = default; + monitorFunction = default; + equalityComparer = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + sealed class WaitUntilValueChangedStandardObjectPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode> + where T : class + { + static TaskPool> pool; + WaitUntilValueChangedStandardObjectPromise nextNode; + public ref WaitUntilValueChangedStandardObjectPromise NextNode => ref nextNode; + + static WaitUntilValueChangedStandardObjectPromise() + { + TaskPool.RegisterSizeGetter(typeof(WaitUntilValueChangedStandardObjectPromise), () => pool.Size); + } + + WeakReference target; + U currentValue; + Func monitorFunction; + IEqualityComparer equalityComparer; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + WaitUntilValueChangedStandardObjectPromise() + { + } + + public static IUniTaskSource Create(T target, Func monitorFunction, IEqualityComparer equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new WaitUntilValueChangedStandardObjectPromise(); + } + + result.target = new WeakReference(target, false); // wrap in WeakReference. + result.monitorFunction = monitorFunction; + result.currentValue = monitorFunction(target); + result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault(); + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public U GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested || !target.TryGetTarget(out var t)) // doesn't find = cancel. + { + core.TrySetCanceled(cancellationToken); + return false; + } + + U nextValue = default(U); + try + { + nextValue = monitorFunction(t); + if (equalityComparer.Equals(currentValue, nextValue)) + { + return true; + } + } + catch (Exception ex) + { + core.TrySetException(ex); + return false; + } + + core.TrySetResult(nextValue); + return false; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + target = default; + currentValue = default; + monitorFunction = default; + equalityComparer = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WaitUntil.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WaitUntil.cs.meta new file mode 100644 index 0000000..6e64dc7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WaitUntil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87c9c533491903a4288536b5ac173db8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.Generated.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.Generated.cs new file mode 100644 index 0000000..9ef07d6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.Generated.cs @@ -0,0 +1,5011 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public partial struct UniTask + { + + public static UniTask<(T1, T2)> WhenAll(UniTask task1, UniTask task2) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2)>(new WhenAllPromise(task1, task2), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2)> + { + T1 t1 = default; + T2 t2 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2)> core; + + public WhenAllPromise(UniTask task1, UniTask task2) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 2) + { + self.core.TrySetResult((self.t1, self.t2)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 2) + { + self.core.TrySetResult((self.t1, self.t2)); + } + } + + + public (T1, T2) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3)> WhenAll(UniTask task1, UniTask task2, UniTask task3) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3)>(new WhenAllPromise(task1, task2, task3), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 3) + { + self.core.TrySetResult((self.t1, self.t2, self.t3)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 3) + { + self.core.TrySetResult((self.t1, self.t2, self.t3)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 3) + { + self.core.TrySetResult((self.t1, self.t2, self.t3)); + } + } + + + public (T1, T2, T3) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4)>(new WhenAllPromise(task1, task2, task3, task4), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 4) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 4) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 4) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 4) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4)); + } + } + + + public (T1, T2, T3, T4) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5)>(new WhenAllPromise(task1, task2, task3, task4, task5), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + + public (T1, T2, T3, T4, T5) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + + public (T1, T2, T3, T4, T5, T6) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully() && task12.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult(), task12.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + T12 t12 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT12(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t12 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully() && task12.Status.IsCompletedSuccessfully() && task13.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult(), task12.GetAwaiter().GetResult(), task13.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + T12 t12 = default; + T13 t13 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT12(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t12 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT13(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t13 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully() && task12.Status.IsCompletedSuccessfully() && task13.Status.IsCompletedSuccessfully() && task14.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult(), task12.GetAwaiter().GetResult(), task13.GetAwaiter().GetResult(), task14.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13, task14), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + T12 t12 = default; + T13 t13 = default; + T14 t14 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task14.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT14(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT14(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT12(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t12 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT13(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t13 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT14(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t14 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully() && task12.Status.IsCompletedSuccessfully() && task13.Status.IsCompletedSuccessfully() && task14.Status.IsCompletedSuccessfully() && task15.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult(), task12.GetAwaiter().GetResult(), task13.GetAwaiter().GetResult(), task14.GetAwaiter().GetResult(), task15.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13, task14, task15), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + T12 t12 = default; + T13 t13 = default; + T14 t14 = default; + T15 t15 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task14.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT14(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT14(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task15.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT15(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT15(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT12(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t12 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT13(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t13 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT14(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t14 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT15(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t15 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.Generated.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.Generated.cs.meta new file mode 100644 index 0000000..40ed46c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.Generated.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5110117231c8a6d4095fd0cbd3f4c142 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.cs new file mode 100644 index 0000000..39f6a9a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.cs @@ -0,0 +1,237 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public partial struct UniTask + { + public static UniTask WhenAll(params UniTask[] tasks) + { + if (tasks.Length == 0) + { + return UniTask.FromResult(Array.Empty()); + } + + return new UniTask(new WhenAllPromise(tasks, tasks.Length), 0); + } + + public static UniTask WhenAll(IEnumerable> tasks) + { + using (var span = ArrayPoolUtil.Materialize(tasks)) + { + var promise = new WhenAllPromise(span.Array, span.Length); // consumed array in constructor. + return new UniTask(promise, 0); + } + } + + public static UniTask WhenAll(params UniTask[] tasks) + { + if (tasks.Length == 0) + { + return UniTask.CompletedTask; + } + + return new UniTask(new WhenAllPromise(tasks, tasks.Length), 0); + } + + public static UniTask WhenAll(IEnumerable tasks) + { + using (var span = ArrayPoolUtil.Materialize(tasks)) + { + var promise = new WhenAllPromise(span.Array, span.Length); // consumed array in constructor. + return new UniTask(promise, 0); + } + } + + sealed class WhenAllPromise : IUniTaskSource + { + T[] result; + int completeCount; + UniTaskCompletionSourceCore core; // don't reset(called after GetResult, will invoke TrySetException.) + + public WhenAllPromise(UniTask[] tasks, int tasksLength) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completeCount = 0; + + if (tasksLength == 0) + { + this.result = Array.Empty(); + core.TrySetResult(result); + return; + } + + this.result = new T[tasksLength]; + + for (int i = 0; i < tasksLength; i++) + { + UniTask.Awaiter awaiter; + try + { + awaiter = tasks[i].GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + continue; + } + + if (awaiter.IsCompleted) + { + TryInvokeContinuation(this, awaiter, i); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter, int>)state) + { + TryInvokeContinuation(t.Item1, t.Item2, t.Item3); + } + }, StateTuple.Create(this, awaiter, i)); + } + } + } + + static void TryInvokeContinuation(WhenAllPromise self, in UniTask.Awaiter awaiter, int i) + { + try + { + self.result[i] = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completeCount) == self.result.Length) + { + self.core.TrySetResult(self.result); + } + } + + public T[] GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + sealed class WhenAllPromise : IUniTaskSource + { + int completeCount; + int tasksLength; + UniTaskCompletionSourceCore core; // don't reset(called after GetResult, will invoke TrySetException.) + + public WhenAllPromise(UniTask[] tasks, int tasksLength) + { + TaskTracker.TrackActiveTask(this, 3); + + this.tasksLength = tasksLength; + this.completeCount = 0; + + if (tasksLength == 0) + { + core.TrySetResult(AsyncUnit.Default); + return; + } + + for (int i = 0; i < tasksLength; i++) + { + UniTask.Awaiter awaiter; + try + { + awaiter = tasks[i].GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + continue; + } + + if (awaiter.IsCompleted) + { + TryInvokeContinuation(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple)state) + { + TryInvokeContinuation(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuation(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completeCount) == self.tasksLength) + { + self.core.TrySetResult(AsyncUnit.Default); + } + } + + public void GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.cs.meta new file mode 100644 index 0000000..0366aa8 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAll.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 355997a305ba64248822eec34998a1a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.Generated.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.Generated.cs new file mode 100644 index 0000000..09b98e6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.Generated.cs @@ -0,0 +1,5060 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public partial struct UniTask + { + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2)> WhenAny(UniTask task1, UniTask task2) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2)>(new WhenAnyPromise(task1, task2), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result)); + } + } + + + public (int, T1 result1, T2 result2) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3)> WhenAny(UniTask task1, UniTask task2, UniTask task3) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3)>(new WhenAnyPromise(task1, task2, task3), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4)>(new WhenAnyPromise(task1, task2, task3, task4), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5)>(new WhenAnyPromise(task1, task2, task3, task4, task5), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, default, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, default, default, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, default, default, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, default, default, default, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, default, default, default, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, default, default, default, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, default, default, default, default, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, default, default, default, default, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, default, default, default, default, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, default, default, default, default, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, default, default, default, default, default, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, default, default, default, default, default, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, default, default, default, default, default, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, default, default, default, default, default, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT12(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T12 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((11, default, default, default, default, default, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, default, default, default, default, default, default, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, default, default, default, default, default, default, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, default, default, default, default, default, default, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, default, default, default, default, default, default, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT12(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T12 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((11, default, default, default, default, default, default, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT13(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T13 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((12, default, default, default, default, default, default, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13, task14), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task14.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT14(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT14(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, default, default, default, default, default, default, default, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, default, default, default, default, default, default, default, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, default, default, default, default, default, default, default, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, default, default, default, default, default, default, default, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT12(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T12 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((11, default, default, default, default, default, default, default, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT13(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T13 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((12, default, default, default, default, default, default, default, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT14(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T14 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((13, default, default, default, default, default, default, default, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14, T15 result15)> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) + { + return new UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14, T15 result15)>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13, task14, task15), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14, T15 result15)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14, T15 result15)> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) + { + TaskTracker.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task14.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT14(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT14(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task15.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT15(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT15(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, result, default, default, default, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, default, result, default, default, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, default, default, result, default, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, default, default, default, result, default, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, default, default, default, default, result, default, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, default, default, default, default, default, result, default, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, default, default, default, default, default, default, result, default, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, default, default, default, default, default, default, default, result, default, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, default, default, default, default, default, default, default, default, result, default, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, default, default, default, default, default, default, default, default, default, result, default, default, default, default, default)); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, default, default, default, default, default, default, default, default, default, default, result, default, default, default, default)); + } + } + + static void TryInvokeContinuationT12(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T12 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((11, default, default, default, default, default, default, default, default, default, default, default, result, default, default, default)); + } + } + + static void TryInvokeContinuationT13(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T13 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((12, default, default, default, default, default, default, default, default, default, default, default, default, result, default, default)); + } + } + + static void TryInvokeContinuationT14(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T14 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((13, default, default, default, default, default, default, default, default, default, default, default, default, default, result, default)); + } + } + + static void TryInvokeContinuationT15(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T15 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((14, default, default, default, default, default, default, default, default, default, default, default, default, default, default, result)); + } + } + + + public (int, T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7, T8 result8, T9 result9, T10 result10, T11 result11, T12 result12, T13 result13, T14 result14, T15 result15) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.Generated.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.Generated.cs.meta new file mode 100644 index 0000000..49a2c3f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.Generated.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 13d604ac281570c4eac9962429f19ca9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.cs new file mode 100644 index 0000000..09eb32d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.cs @@ -0,0 +1,359 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public partial struct UniTask + { + public static UniTask<(bool hasResultLeft, T result)> WhenAny(UniTask leftTask, UniTask rightTask) + { + return new UniTask<(bool, T)>(new WhenAnyLRPromise(leftTask, rightTask), 0); + } + + public static UniTask<(int winArgumentIndex, T result)> WhenAny(params UniTask[] tasks) + { + return new UniTask<(int, T)>(new WhenAnyPromise(tasks, tasks.Length), 0); + } + + public static UniTask<(int winArgumentIndex, T result)> WhenAny(IEnumerable> tasks) + { + using (var span = ArrayPoolUtil.Materialize(tasks)) + { + return new UniTask<(int, T)>(new WhenAnyPromise(span.Array, span.Length), 0); + } + } + + /// Return value is winArgumentIndex + public static UniTask WhenAny(params UniTask[] tasks) + { + return new UniTask(new WhenAnyPromise(tasks, tasks.Length), 0); + } + + /// Return value is winArgumentIndex + public static UniTask WhenAny(IEnumerable tasks) + { + using (var span = ArrayPoolUtil.Materialize(tasks)) + { + return new UniTask(new WhenAnyPromise(span.Array, span.Length), 0); + } + } + + sealed class WhenAnyLRPromise : IUniTaskSource<(bool, T)> + { + int completedCount; + UniTaskCompletionSourceCore<(bool, T)> core; + + public WhenAnyLRPromise(UniTask leftTask, UniTask rightTask) + { + TaskTracker.TrackActiveTask(this, 3); + + { + UniTask.Awaiter awaiter; + try + { + awaiter = leftTask.GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + goto RIGHT; + } + + if (awaiter.IsCompleted) + { + TryLeftInvokeContinuation(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryLeftInvokeContinuation(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + RIGHT: + { + UniTask.Awaiter awaiter; + try + { + awaiter = rightTask.GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + return; + } + + if (awaiter.IsCompleted) + { + TryRightInvokeContinuation(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryRightInvokeContinuation(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryLeftInvokeContinuation(WhenAnyLRPromise self, in UniTask.Awaiter awaiter) + { + T result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((true, result)); + } + } + + static void TryRightInvokeContinuation(WhenAnyLRPromise self, in UniTask.Awaiter awaiter) + { + try + { + awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((false, default)); + } + } + + public (bool, T) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + + sealed class WhenAnyPromise : IUniTaskSource<(int, T)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, T)> core; + + public WhenAnyPromise(UniTask[] tasks, int tasksLength) + { + if (tasksLength == 0) + { + throw new ArgumentException("The tasks argument contains no tasks."); + } + + TaskTracker.TrackActiveTask(this, 3); + + for (int i = 0; i < tasksLength; i++) + { + UniTask.Awaiter awaiter; + try + { + awaiter = tasks[i].GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + continue; // consume others. + } + + if (awaiter.IsCompleted) + { + TryInvokeContinuation(this, awaiter, i); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter, int>)state) + { + TryInvokeContinuation(t.Item1, t.Item2, t.Item3); + } + }, StateTuple.Create(this, awaiter, i)); + } + } + } + + static void TryInvokeContinuation(WhenAnyPromise self, in UniTask.Awaiter awaiter, int i) + { + T result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((i, result)); + } + } + + public (int, T) GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + sealed class WhenAnyPromise : IUniTaskSource + { + int completedCount; + UniTaskCompletionSourceCore core; + + public WhenAnyPromise(UniTask[] tasks, int tasksLength) + { + if (tasksLength == 0) + { + throw new ArgumentException("The tasks argument contains no tasks."); + } + + TaskTracker.TrackActiveTask(this, 3); + + for (int i = 0; i < tasksLength; i++) + { + UniTask.Awaiter awaiter; + try + { + awaiter = tasks[i].GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + continue; // consume others. + } + + if (awaiter.IsCompleted) + { + TryInvokeContinuation(this, awaiter, i); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple)state) + { + TryInvokeContinuation(t.Item1, t.Item2, t.Item3); + } + }, StateTuple.Create(this, awaiter, i)); + } + } + } + + static void TryInvokeContinuation(WhenAnyPromise self, in UniTask.Awaiter awaiter, int i) + { + try + { + awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult(i); + } + } + + public int GetResult(short token) + { + TaskTracker.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.cs.meta new file mode 100644 index 0000000..c10f762 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.WhenAny.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c32578978c37eaf41bdd90e1b034637d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.asmdef b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.asmdef new file mode 100644 index 0000000..a5c594d --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.asmdef @@ -0,0 +1,45 @@ +{ + "name": "UniTask", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.modules.assetbundle", + "expression": "", + "define": "UNITASK_ASSETBUNDLE_SUPPORT" + }, + { + "name": "com.unity.modules.physics", + "expression": "", + "define": "UNITASK_PHYSICS_SUPPORT" + }, + { + "name": "com.unity.modules.physics2d", + "expression": "", + "define": "UNITASK_PHYSICS2D_SUPPORT" + }, + { + "name": "com.unity.modules.particlesystem", + "expression": "", + "define": "UNITASK_PARTICLESYSTEM_SUPPORT" + }, + { + "name": "com.unity.ugui", + "expression": "", + "define": "UNITASK_UGUI_SUPPORT" + }, + { + "name": "com.unity.modules.unitywebrequest", + "expression": "", + "define": "UNITASK_WEBREQUEST_SUPPORT" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.asmdef.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.asmdef.meta new file mode 100644 index 0000000..e497045 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f51ebe6a0ceec4240a699833d6309b23 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.cs new file mode 100644 index 0000000..8eb2087 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.cs @@ -0,0 +1,707 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#pragma warning disable CS0436 + +using Cysharp.Threading.Tasks.CompilerServices; +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Runtime.InteropServices; + +namespace Cysharp.Threading.Tasks +{ + internal static class AwaiterActions + { + internal static readonly Action InvokeContinuationDelegate = Continuation; + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Continuation(object state) + { + ((Action)state).Invoke(); + } + } + + /// + /// Lightweight unity specified task-like object. + /// + [AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder))] + [StructLayout(LayoutKind.Auto)] + public readonly partial struct UniTask + { + readonly IUniTaskSource source; + readonly short token; + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UniTask(IUniTaskSource source, short token) + { + this.source = source; + this.token = token; + } + + public UniTaskStatus Status + { + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + if (source == null) return UniTaskStatus.Succeeded; + return source.GetStatus(token); + } + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Awaiter GetAwaiter() + { + return new Awaiter(this); + } + + /// + /// returns (bool IsCanceled) instead of throws OperationCanceledException. + /// + public UniTask SuppressCancellationThrow() + { + var status = Status; + if (status == UniTaskStatus.Succeeded) return CompletedTasks.False; + if (status == UniTaskStatus.Canceled) return CompletedTasks.True; + return new UniTask(new IsCanceledSource(source), token); + } + +#if !UNITY_2018_3_OR_NEWER + + public static implicit operator System.Threading.Tasks.ValueTask(in UniTask self) + { + if (self.source == null) + { + return default; + } + +#if NETSTANDARD2_0 + return self.AsValueTask(); +#else + return new System.Threading.Tasks.ValueTask(self.source, self.token); +#endif + } + +#endif + + public override string ToString() + { + if (source == null) return "()"; + return "(" + source.UnsafeGetStatus() + ")"; + } + + /// + /// Memoizing inner IValueTaskSource. The result UniTask can await multiple. + /// + public UniTask Preserve() + { + if (source == null) + { + return this; + } + else + { + return new UniTask(new MemoizeSource(source), token); + } + } + + public UniTask AsAsyncUnitUniTask() + { + if (this.source == null) return CompletedTasks.AsyncUnit; + + var status = this.source.GetStatus(this.token); + if (status.IsCompletedSuccessfully()) + { + this.source.GetResult(this.token); + return CompletedTasks.AsyncUnit; + } + else if(this.source is IUniTaskSource asyncUnitSource) + { + return new UniTask(asyncUnitSource, this.token); + } + + return new UniTask(new AsyncUnitSource(this.source), this.token); + } + + sealed class AsyncUnitSource : IUniTaskSource + { + readonly IUniTaskSource source; + + public AsyncUnitSource(IUniTaskSource source) + { + this.source = source; + } + + public AsyncUnit GetResult(short token) + { + source.GetResult(token); + return AsyncUnit.Default; + } + + public UniTaskStatus GetStatus(short token) + { + return source.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + source.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return source.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + } + + sealed class IsCanceledSource : IUniTaskSource + { + readonly IUniTaskSource source; + + public IsCanceledSource(IUniTaskSource source) + { + this.source = source; + } + + public bool GetResult(short token) + { + if (source.GetStatus(token) == UniTaskStatus.Canceled) + { + return true; + } + + source.GetResult(token); + return false; + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return source.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return source.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + source.OnCompleted(continuation, state, token); + } + } + + sealed class MemoizeSource : IUniTaskSource + { + IUniTaskSource source; + ExceptionDispatchInfo exception; + UniTaskStatus status; + + public MemoizeSource(IUniTaskSource source) + { + this.source = source; + } + + public void GetResult(short token) + { + if (source == null) + { + if (exception != null) + { + exception.Throw(); + } + } + else + { + try + { + source.GetResult(token); + status = UniTaskStatus.Succeeded; + } + catch (Exception ex) + { + exception = ExceptionDispatchInfo.Capture(ex); + if (ex is OperationCanceledException) + { + status = UniTaskStatus.Canceled; + } + else + { + status = UniTaskStatus.Faulted; + } + throw; + } + finally + { + source = null; + } + } + } + + public UniTaskStatus GetStatus(short token) + { + if (source == null) + { + return status; + } + + return source.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + if (source == null) + { + continuation(state); + } + else + { + source.OnCompleted(continuation, state, token); + } + } + + public UniTaskStatus UnsafeGetStatus() + { + if (source == null) + { + return status; + } + + return source.UnsafeGetStatus(); + } + } + + public readonly struct Awaiter : ICriticalNotifyCompletion + { + readonly UniTask task; + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Awaiter(in UniTask task) + { + this.task = task; + } + + public bool IsCompleted + { + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return task.Status.IsCompleted(); + } + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void GetResult() + { + if (task.source == null) return; + task.source.GetResult(task.token); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void OnCompleted(Action continuation) + { + if (task.source == null) + { + continuation(); + } + else + { + task.source.OnCompleted(AwaiterActions.InvokeContinuationDelegate, continuation, task.token); + } + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnsafeOnCompleted(Action continuation) + { + if (task.source == null) + { + continuation(); + } + else + { + task.source.OnCompleted(AwaiterActions.InvokeContinuationDelegate, continuation, task.token); + } + } + + /// + /// If register manually continuation, you can use it instead of for compiler OnCompleted methods. + /// + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SourceOnCompleted(Action continuation, object state) + { + if (task.source == null) + { + continuation(state); + } + else + { + task.source.OnCompleted(continuation, state, task.token); + } + } + } + } + + /// + /// Lightweight unity specified task-like object. + /// + [AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder<>))] + [StructLayout(LayoutKind.Auto)] + public readonly struct UniTask + { + readonly IUniTaskSource source; + readonly T result; + readonly short token; + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UniTask(T result) + { + this.source = default; + this.token = default; + this.result = result; + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UniTask(IUniTaskSource source, short token) + { + this.source = source; + this.token = token; + this.result = default; + } + + public UniTaskStatus Status + { + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return (source == null) ? UniTaskStatus.Succeeded : source.GetStatus(token); + } + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Awaiter GetAwaiter() + { + return new Awaiter(this); + } + + /// + /// Memoizing inner IValueTaskSource. The result UniTask can await multiple. + /// + public UniTask Preserve() + { + if (source == null) + { + return this; + } + else + { + return new UniTask(new MemoizeSource(source), token); + } + } + + public UniTask AsUniTask() + { + if (this.source == null) return UniTask.CompletedTask; + + var status = this.source.GetStatus(this.token); + if (status.IsCompletedSuccessfully()) + { + this.source.GetResult(this.token); + return UniTask.CompletedTask; + } + + // Converting UniTask -> UniTask is zero overhead. + return new UniTask(this.source, this.token); + } + + public static implicit operator UniTask(UniTask self) + { + return self.AsUniTask(); + } + +#if !UNITY_2018_3_OR_NEWER + + public static implicit operator System.Threading.Tasks.ValueTask(in UniTask self) + { + if (self.source == null) + { + return new System.Threading.Tasks.ValueTask(self.result); + } + +#if NETSTANDARD2_0 + return self.AsValueTask(); +#else + return new System.Threading.Tasks.ValueTask(self.source, self.token); +#endif + } + +#endif + + /// + /// returns (bool IsCanceled, T Result) instead of throws OperationCanceledException. + /// + public UniTask<(bool IsCanceled, T Result)> SuppressCancellationThrow() + { + if (source == null) + { + return new UniTask<(bool IsCanceled, T Result)>((false, result)); + } + + return new UniTask<(bool, T)>(new IsCanceledSource(source), token); + } + + public override string ToString() + { + return (this.source == null) ? result?.ToString() + : "(" + this.source.UnsafeGetStatus() + ")"; + } + + sealed class IsCanceledSource : IUniTaskSource<(bool, T)> + { + readonly IUniTaskSource source; + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IsCanceledSource(IUniTaskSource source) + { + this.source = source; + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public (bool, T) GetResult(short token) + { + if (source.GetStatus(token) == UniTaskStatus.Canceled) + { + return (true, default); + } + + var result = source.GetResult(token); + return (false, result); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UniTaskStatus GetStatus(short token) + { + return source.GetStatus(token); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UniTaskStatus UnsafeGetStatus() + { + return source.UnsafeGetStatus(); + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void OnCompleted(Action continuation, object state, short token) + { + source.OnCompleted(continuation, state, token); + } + } + + sealed class MemoizeSource : IUniTaskSource + { + IUniTaskSource source; + T result; + ExceptionDispatchInfo exception; + UniTaskStatus status; + + public MemoizeSource(IUniTaskSource source) + { + this.source = source; + } + + public T GetResult(short token) + { + if (source == null) + { + if (exception != null) + { + exception.Throw(); + } + return result; + } + else + { + try + { + result = source.GetResult(token); + status = UniTaskStatus.Succeeded; + return result; + } + catch (Exception ex) + { + exception = ExceptionDispatchInfo.Capture(ex); + if (ex is OperationCanceledException) + { + status = UniTaskStatus.Canceled; + } + else + { + status = UniTaskStatus.Faulted; + } + throw; + } + finally + { + source = null; + } + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + if (source == null) + { + return status; + } + + return source.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + if (source == null) + { + continuation(state); + } + else + { + source.OnCompleted(continuation, state, token); + } + } + + public UniTaskStatus UnsafeGetStatus() + { + if (source == null) + { + return status; + } + + return source.UnsafeGetStatus(); + } + } + + public readonly struct Awaiter : ICriticalNotifyCompletion + { + readonly UniTask task; + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Awaiter(in UniTask task) + { + this.task = task; + } + + public bool IsCompleted + { + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return task.Status.IsCompleted(); + } + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T GetResult() + { + var s = task.source; + if (s == null) + { + return task.result; + } + else + { + return s.GetResult(task.token); + } + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void OnCompleted(Action continuation) + { + var s = task.source; + if (s == null) + { + continuation(); + } + else + { + s.OnCompleted(AwaiterActions.InvokeContinuationDelegate, continuation, task.token); + } + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnsafeOnCompleted(Action continuation) + { + var s = task.source; + if (s == null) + { + continuation(); + } + else + { + s.OnCompleted(AwaiterActions.InvokeContinuationDelegate, continuation, task.token); + } + } + + /// + /// If register manually continuation, you can use it instead of for compiler OnCompleted methods. + /// + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SourceOnCompleted(Action continuation, object state) + { + var s = task.source; + if (s == null) + { + continuation(state); + } + else + { + s.OnCompleted(continuation, state, task.token); + } + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.cs.meta new file mode 100644 index 0000000..04eb6b6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8947adf23181ff04db73829df217ca94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskCompletionSource.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskCompletionSource.cs new file mode 100644 index 0000000..67b882e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskCompletionSource.cs @@ -0,0 +1,941 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Runtime.InteropServices; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public interface IResolvePromise + { + bool TrySetResult(); + } + + public interface IResolvePromise + { + bool TrySetResult(T value); + } + + public interface IRejectPromise + { + bool TrySetException(Exception exception); + } + + public interface ICancelPromise + { + bool TrySetCanceled(CancellationToken cancellationToken = default); + } + + public interface IPromise : IResolvePromise, IRejectPromise, ICancelPromise + { + } + + public interface IPromise : IResolvePromise, IRejectPromise, ICancelPromise + { + } + + internal class ExceptionHolder + { + ExceptionDispatchInfo exception; + bool calledGet = false; + + public ExceptionHolder(ExceptionDispatchInfo exception) + { + this.exception = exception; + } + + public ExceptionDispatchInfo GetException() + { + if (!calledGet) + { + calledGet = true; + GC.SuppressFinalize(this); + } + return exception; + } + + ~ExceptionHolder() + { + if (!calledGet) + { + UniTaskScheduler.PublishUnobservedTaskException(exception.SourceException); + } + } + } + + [StructLayout(LayoutKind.Auto)] + public struct UniTaskCompletionSourceCore + { + // Struct Size: TResult + (8 + 2 + 1 + 1 + 8 + 8) + + TResult result; + object error; // ExceptionHolder or OperationCanceledException + short version; + bool hasUnhandledError; + int completedCount; // 0: completed == false + Action continuation; + object continuationState; + + [DebuggerHidden] + public void Reset() + { + ReportUnhandledError(); + + unchecked + { + version += 1; // incr version. + } + completedCount = 0; + result = default; + error = null; + hasUnhandledError = false; + continuation = null; + continuationState = null; + } + + void ReportUnhandledError() + { + if (hasUnhandledError) + { + try + { + if (error is OperationCanceledException oc) + { + UniTaskScheduler.PublishUnobservedTaskException(oc); + } + else if (error is ExceptionHolder e) + { + UniTaskScheduler.PublishUnobservedTaskException(e.GetException().SourceException); + } + } + catch + { + } + } + } + + internal void MarkHandled() + { + hasUnhandledError = false; + } + + /// Completes with a successful result. + /// The result. + [DebuggerHidden] + public bool TrySetResult(TResult result) + { + if (Interlocked.Increment(ref completedCount) == 1) + { + // setup result + this.result = result; + + if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null) + { + continuation(continuationState); + return true; + } + } + + return false; + } + + /// Completes with an error. + /// The exception. + [DebuggerHidden] + public bool TrySetException(Exception error) + { + if (Interlocked.Increment(ref completedCount) == 1) + { + // setup result + this.hasUnhandledError = true; + if (error is OperationCanceledException) + { + this.error = error; + } + else + { + this.error = new ExceptionHolder(ExceptionDispatchInfo.Capture(error)); + } + + if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null) + { + continuation(continuationState); + return true; + } + } + + return false; + } + + [DebuggerHidden] + public bool TrySetCanceled(CancellationToken cancellationToken = default) + { + if (Interlocked.Increment(ref completedCount) == 1) + { + // setup result + this.hasUnhandledError = true; + this.error = new OperationCanceledException(cancellationToken); + + if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null) + { + continuation(continuationState); + return true; + } + } + + return false; + } + + /// Gets the operation version. + [DebuggerHidden] + public short Version => version; + + /// Gets the status of the operation. + /// Opaque value that was provided to the 's constructor. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UniTaskStatus GetStatus(short token) + { + ValidateToken(token); + return (continuation == null || (completedCount == 0)) ? UniTaskStatus.Pending + : (error == null) ? UniTaskStatus.Succeeded + : (error is OperationCanceledException) ? UniTaskStatus.Canceled + : UniTaskStatus.Faulted; + } + + /// Gets the status of the operation without token validation. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UniTaskStatus UnsafeGetStatus() + { + return (continuation == null || (completedCount == 0)) ? UniTaskStatus.Pending + : (error == null) ? UniTaskStatus.Succeeded + : (error is OperationCanceledException) ? UniTaskStatus.Canceled + : UniTaskStatus.Faulted; + } + + /// Gets the result of the operation. + /// Opaque value that was provided to the 's constructor. + // [StackTraceHidden] + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult GetResult(short token) + { + ValidateToken(token); + if (completedCount == 0) + { + throw new InvalidOperationException("Not yet completed, UniTask only allow to use await."); + } + + if (error != null) + { + hasUnhandledError = false; + if (error is OperationCanceledException oce) + { + throw oce; + } + else if (error is ExceptionHolder eh) + { + eh.GetException().Throw(); + } + + throw new InvalidOperationException("Critical: invalid exception type was held."); + } + + return result; + } + + /// Schedules the continuation action for this operation. + /// The continuation to invoke when the operation has completed. + /// The state object to pass to when it's invoked. + /// Opaque value that was provided to the 's constructor. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void OnCompleted(Action continuation, object state, short token /*, ValueTaskSourceOnCompletedFlags flags */) + { + if (continuation == null) + { + throw new ArgumentNullException(nameof(continuation)); + } + ValidateToken(token); + + /* no use ValueTaskSourceOnCOmpletedFlags, always no capture ExecutionContext and SynchronizationContext. */ + + /* + PatternA: GetStatus=Pending => OnCompleted => TrySet*** => GetResult + PatternB: TrySet*** => GetStatus=!Pending => GetResult + PatternC: GetStatus=Pending => TrySet/OnCompleted(race condition) => GetResult + C.1: win OnCompleted -> TrySet invoke saved continuation + C.2: win TrySet -> should invoke continuation here. + */ + + // not set continuation yet. + object oldContinuation = this.continuation; + if (oldContinuation == null) + { + continuationState = state; + oldContinuation = Interlocked.CompareExchange(ref this.continuation, continuation, null); + } + + if (oldContinuation != null) + { + // already running continuation in TrySet. + // It will cause call OnCompleted multiple time, invalid. + if (!ReferenceEquals(oldContinuation, UniTaskCompletionSourceCoreShared.s_sentinel)) + { + throw new InvalidOperationException("Already continuation registered, can not await twice or get Status after await."); + } + + continuation(state); + } + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ValidateToken(short token) + { + if (token != version) + { + throw new InvalidOperationException("Token version is not matched, can not await twice or get Status after await."); + } + } + } + + internal static class UniTaskCompletionSourceCoreShared // separated out of generic to avoid unnecessary duplication + { + internal static readonly Action s_sentinel = CompletionSentinel; + + private static void CompletionSentinel(object _) // named method to aid debugging + { + throw new InvalidOperationException("The sentinel delegate should never be invoked."); + } + } + + public class AutoResetUniTaskCompletionSource : IUniTaskSource, ITaskPoolNode, IPromise + { + static TaskPool pool; + AutoResetUniTaskCompletionSource nextNode; + public ref AutoResetUniTaskCompletionSource NextNode => ref nextNode; + + static AutoResetUniTaskCompletionSource() + { + TaskPool.RegisterSizeGetter(typeof(AutoResetUniTaskCompletionSource), () => pool.Size); + } + + UniTaskCompletionSourceCore core; + + AutoResetUniTaskCompletionSource() + { + } + + [DebuggerHidden] + public static AutoResetUniTaskCompletionSource Create() + { + if (!pool.TryPop(out var result)) + { + result = new AutoResetUniTaskCompletionSource(); + } + TaskTracker.TrackActiveTask(result, 2); + return result; + } + + [DebuggerHidden] + public static AutoResetUniTaskCompletionSource CreateFromCanceled(CancellationToken cancellationToken, out short token) + { + var source = Create(); + source.TrySetCanceled(cancellationToken); + token = source.core.Version; + return source; + } + + [DebuggerHidden] + public static AutoResetUniTaskCompletionSource CreateFromException(Exception exception, out short token) + { + var source = Create(); + source.TrySetException(exception); + token = source.core.Version; + return source; + } + + [DebuggerHidden] + public static AutoResetUniTaskCompletionSource CreateCompleted(out short token) + { + var source = Create(); + source.TrySetResult(); + token = source.core.Version; + return source; + } + + public UniTask Task + { + [DebuggerHidden] + get + { + return new UniTask(this, core.Version); + } + } + + [DebuggerHidden] + public bool TrySetResult() + { + return core.TrySetResult(AsyncUnit.Default); + } + + [DebuggerHidden] + public bool TrySetCanceled(CancellationToken cancellationToken = default) + { + return core.TrySetCanceled(cancellationToken); + } + + [DebuggerHidden] + public bool TrySetException(Exception exception) + { + return core.TrySetException(exception); + } + + [DebuggerHidden] + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + + } + + [DebuggerHidden] + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + [DebuggerHidden] + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + [DebuggerHidden] + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + [DebuggerHidden] + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + return pool.TryPush(this); + } + } + + public class AutoResetUniTaskCompletionSource : IUniTaskSource, ITaskPoolNode>, IPromise + { + static TaskPool> pool; + AutoResetUniTaskCompletionSource nextNode; + public ref AutoResetUniTaskCompletionSource NextNode => ref nextNode; + + static AutoResetUniTaskCompletionSource() + { + TaskPool.RegisterSizeGetter(typeof(AutoResetUniTaskCompletionSource), () => pool.Size); + } + + UniTaskCompletionSourceCore core; + + AutoResetUniTaskCompletionSource() + { + } + + [DebuggerHidden] + public static AutoResetUniTaskCompletionSource Create() + { + if (!pool.TryPop(out var result)) + { + result = new AutoResetUniTaskCompletionSource(); + } + TaskTracker.TrackActiveTask(result, 2); + return result; + } + + [DebuggerHidden] + public static AutoResetUniTaskCompletionSource CreateFromCanceled(CancellationToken cancellationToken, out short token) + { + var source = Create(); + source.TrySetCanceled(cancellationToken); + token = source.core.Version; + return source; + } + + [DebuggerHidden] + public static AutoResetUniTaskCompletionSource CreateFromException(Exception exception, out short token) + { + var source = Create(); + source.TrySetException(exception); + token = source.core.Version; + return source; + } + + [DebuggerHidden] + public static AutoResetUniTaskCompletionSource CreateFromResult(T result, out short token) + { + var source = Create(); + source.TrySetResult(result); + token = source.core.Version; + return source; + } + + public UniTask Task + { + [DebuggerHidden] + get + { + return new UniTask(this, core.Version); + } + } + + [DebuggerHidden] + public bool TrySetResult(T result) + { + return core.TrySetResult(result); + } + + [DebuggerHidden] + public bool TrySetCanceled(CancellationToken cancellationToken = default) + { + return core.TrySetCanceled(cancellationToken); + } + + [DebuggerHidden] + public bool TrySetException(Exception exception) + { + return core.TrySetException(exception); + } + + [DebuggerHidden] + public T GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + [DebuggerHidden] + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + [DebuggerHidden] + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + [DebuggerHidden] + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + [DebuggerHidden] + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + [DebuggerHidden] + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + return pool.TryPush(this); + } + } + + public class UniTaskCompletionSource : IUniTaskSource, IPromise + { + CancellationToken cancellationToken; + ExceptionHolder exception; + object gate; + Action singleContinuation; + object singleState; + List<(Action, object)> secondaryContinuationList; + + int intStatus; // UniTaskStatus + bool handled = false; + + public UniTaskCompletionSource() + { + TaskTracker.TrackActiveTask(this, 2); + } + + [DebuggerHidden] + internal void MarkHandled() + { + if (!handled) + { + handled = true; + TaskTracker.RemoveTracking(this); + } + } + + public UniTask Task + { + [DebuggerHidden] + get + { + return new UniTask(this, 0); + } + } + + [DebuggerHidden] + public bool TrySetResult() + { + return TrySignalCompletion(UniTaskStatus.Succeeded); + } + + [DebuggerHidden] + public bool TrySetCanceled(CancellationToken cancellationToken = default) + { + if (UnsafeGetStatus() != UniTaskStatus.Pending) return false; + + this.cancellationToken = cancellationToken; + return TrySignalCompletion(UniTaskStatus.Canceled); + } + + [DebuggerHidden] + public bool TrySetException(Exception exception) + { + if (exception is OperationCanceledException oce) + { + return TrySetCanceled(oce.CancellationToken); + } + + if (UnsafeGetStatus() != UniTaskStatus.Pending) return false; + + this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(exception)); + return TrySignalCompletion(UniTaskStatus.Faulted); + } + + [DebuggerHidden] + public void GetResult(short token) + { + MarkHandled(); + + var status = (UniTaskStatus)intStatus; + switch (status) + { + case UniTaskStatus.Succeeded: + return; + case UniTaskStatus.Faulted: + exception.GetException().Throw(); + return; + case UniTaskStatus.Canceled: + throw new OperationCanceledException(cancellationToken); + default: + case UniTaskStatus.Pending: + throw new InvalidOperationException("not yet completed."); + } + } + + [DebuggerHidden] + public UniTaskStatus GetStatus(short token) + { + return (UniTaskStatus)intStatus; + } + + [DebuggerHidden] + public UniTaskStatus UnsafeGetStatus() + { + return (UniTaskStatus)intStatus; + } + + [DebuggerHidden] + public void OnCompleted(Action continuation, object state, short token) + { + if (gate == null) + { + Interlocked.CompareExchange(ref gate, new object(), null); + } + + var lockGate = Thread.VolatileRead(ref gate); + lock (lockGate) // wait TrySignalCompletion, after status is not pending. + { + if ((UniTaskStatus)intStatus != UniTaskStatus.Pending) + { + continuation(state); + return; + } + + if (singleContinuation == null) + { + singleContinuation = continuation; + singleState = state; + } + else + { + if (secondaryContinuationList == null) + { + secondaryContinuationList = new List<(Action, object)>(); + } + secondaryContinuationList.Add((continuation, state)); + } + } + } + + [DebuggerHidden] + bool TrySignalCompletion(UniTaskStatus status) + { + if (Interlocked.CompareExchange(ref intStatus, (int)status, (int)UniTaskStatus.Pending) == (int)UniTaskStatus.Pending) + { + if (gate == null) + { + Interlocked.CompareExchange(ref gate, new object(), null); + } + + var lockGate = Thread.VolatileRead(ref gate); + lock (lockGate) // wait OnCompleted. + { + if (singleContinuation != null) + { + try + { + singleContinuation(singleState); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + + if (secondaryContinuationList != null) + { + foreach (var (c, state) in secondaryContinuationList) + { + try + { + c(state); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + } + + singleContinuation = null; + singleState = null; + secondaryContinuationList = null; + } + return true; + } + return false; + } + } + + public class UniTaskCompletionSource : IUniTaskSource, IPromise + { + CancellationToken cancellationToken; + T result; + ExceptionHolder exception; + object gate; + Action singleContinuation; + object singleState; + List<(Action, object)> secondaryContinuationList; + + int intStatus; // UniTaskStatus + bool handled = false; + + public UniTaskCompletionSource() + { + TaskTracker.TrackActiveTask(this, 2); + } + + [DebuggerHidden] + internal void MarkHandled() + { + if (!handled) + { + handled = true; + TaskTracker.RemoveTracking(this); + } + } + + public UniTask Task + { + [DebuggerHidden] + get + { + return new UniTask(this, 0); + } + } + + [DebuggerHidden] + public bool TrySetResult(T result) + { + if (UnsafeGetStatus() != UniTaskStatus.Pending) return false; + + this.result = result; + return TrySignalCompletion(UniTaskStatus.Succeeded); + } + + [DebuggerHidden] + public bool TrySetCanceled(CancellationToken cancellationToken = default) + { + if (UnsafeGetStatus() != UniTaskStatus.Pending) return false; + + this.cancellationToken = cancellationToken; + return TrySignalCompletion(UniTaskStatus.Canceled); + } + + [DebuggerHidden] + public bool TrySetException(Exception exception) + { + if (exception is OperationCanceledException oce) + { + return TrySetCanceled(oce.CancellationToken); + } + + if (UnsafeGetStatus() != UniTaskStatus.Pending) return false; + + this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(exception)); + return TrySignalCompletion(UniTaskStatus.Faulted); + } + + [DebuggerHidden] + public T GetResult(short token) + { + MarkHandled(); + + var status = (UniTaskStatus)intStatus; + switch (status) + { + case UniTaskStatus.Succeeded: + return result; + case UniTaskStatus.Faulted: + exception.GetException().Throw(); + return default; + case UniTaskStatus.Canceled: + throw new OperationCanceledException(cancellationToken); + default: + case UniTaskStatus.Pending: + throw new InvalidOperationException("not yet completed."); + } + } + + [DebuggerHidden] + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + [DebuggerHidden] + public UniTaskStatus GetStatus(short token) + { + return (UniTaskStatus)intStatus; + } + + [DebuggerHidden] + public UniTaskStatus UnsafeGetStatus() + { + return (UniTaskStatus)intStatus; + } + + [DebuggerHidden] + public void OnCompleted(Action continuation, object state, short token) + { + if (gate == null) + { + Interlocked.CompareExchange(ref gate, new object(), null); + } + + var lockGate = Thread.VolatileRead(ref gate); + lock (lockGate) // wait TrySignalCompletion, after status is not pending. + { + if ((UniTaskStatus)intStatus != UniTaskStatus.Pending) + { + continuation(state); + return; + } + + if (singleContinuation == null) + { + singleContinuation = continuation; + singleState = state; + } + else + { + if (secondaryContinuationList == null) + { + secondaryContinuationList = new List<(Action, object)>(); + } + secondaryContinuationList.Add((continuation, state)); + } + } + } + + [DebuggerHidden] + bool TrySignalCompletion(UniTaskStatus status) + { + if (Interlocked.CompareExchange(ref intStatus, (int)status, (int)UniTaskStatus.Pending) == (int)UniTaskStatus.Pending) + { + if (gate == null) + { + Interlocked.CompareExchange(ref gate, new object(), null); + } + + var lockGate = Thread.VolatileRead(ref gate); + lock (lockGate) // wait OnCompleted. + { + if (singleContinuation != null) + { + try + { + singleContinuation(singleState); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + + if (secondaryContinuationList != null) + { + foreach (var (c, state) in secondaryContinuationList) + { + try + { + c(state); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + } + + singleContinuation = null; + singleState = null; + secondaryContinuationList = null; + } + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskCompletionSource.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskCompletionSource.cs.meta new file mode 100644 index 0000000..2ae5ee3 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskCompletionSource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed03524d09e7eb24a9fb9137198feb84 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.Shorthand.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.Shorthand.cs new file mode 100644 index 0000000..0e51a45 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.Shorthand.cs @@ -0,0 +1,187 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System.Collections.Generic; + +namespace Cysharp.Threading.Tasks +{ + public static partial class UniTaskExtensions + { + // shorthand of WhenAll + + public static UniTask.Awaiter GetAwaiter(this UniTask[] tasks) + { + return UniTask.WhenAll(tasks).GetAwaiter(); + } + + public static UniTask.Awaiter GetAwaiter(this IEnumerable tasks) + { + return UniTask.WhenAll(tasks).GetAwaiter(); + } + + public static UniTask.Awaiter GetAwaiter(this UniTask[] tasks) + { + return UniTask.WhenAll(tasks).GetAwaiter(); + } + + public static UniTask.Awaiter GetAwaiter(this IEnumerable> tasks) + { + return UniTask.WhenAll(tasks).GetAwaiter(); + } + + public static UniTask<(T1, T2)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12, tasks.Item13).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12, tasks.Item13, tasks.Item14).GetAwaiter(); + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12, tasks.Item13, tasks.Item14, tasks.Item15).GetAwaiter(); + } + + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12, tasks.Item13).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12, tasks.Item13, tasks.Item14).GetAwaiter(); + } + + + public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) tasks) + { + return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12, tasks.Item13, tasks.Item14, tasks.Item15).GetAwaiter(); + } + + + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.Shorthand.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.Shorthand.cs.meta new file mode 100644 index 0000000..e2dcc14 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.Shorthand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b4ff020f73dc6d4b8ebd4760d61fb43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.cs new file mode 100644 index 0000000..d330109 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.cs @@ -0,0 +1,921 @@ +#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 System.Threading.Tasks; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public static partial class UniTaskExtensions + { + /// + /// Convert Task[T] -> UniTask[T]. + /// + public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true) + { + var promise = new UniTaskCompletionSource(); + + task.ContinueWith((x, state) => + { + var p = (UniTaskCompletionSource)state; + + switch (x.Status) + { + case TaskStatus.Canceled: + p.TrySetCanceled(); + break; + case TaskStatus.Faulted: + p.TrySetException(x.Exception); + break; + case TaskStatus.RanToCompletion: + p.TrySetResult(x.Result); + break; + default: + throw new NotSupportedException(); + } + }, promise, useCurrentSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current); + + return promise.Task; + } + + /// + /// Convert Task -> UniTask. + /// + public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true) + { + var promise = new UniTaskCompletionSource(); + + task.ContinueWith((x, state) => + { + var p = (UniTaskCompletionSource)state; + + switch (x.Status) + { + case TaskStatus.Canceled: + p.TrySetCanceled(); + break; + case TaskStatus.Faulted: + p.TrySetException(x.Exception); + break; + case TaskStatus.RanToCompletion: + p.TrySetResult(); + break; + default: + throw new NotSupportedException(); + } + }, promise, useCurrentSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current); + + return promise.Task; + } + + public static Task AsTask(this UniTask task) + { + try + { + UniTask.Awaiter awaiter; + try + { + awaiter = task.GetAwaiter(); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + + if (awaiter.IsCompleted) + { + try + { + var result = awaiter.GetResult(); + return Task.FromResult(result); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + var tcs = new TaskCompletionSource(); + + awaiter.SourceOnCompleted(state => + { + using (var tuple = (StateTuple, UniTask.Awaiter>)state) + { + var (inTcs, inAwaiter) = tuple; + try + { + var result = inAwaiter.GetResult(); + inTcs.SetResult(result); + } + catch (Exception ex) + { + inTcs.SetException(ex); + } + } + }, StateTuple.Create(tcs, awaiter)); + + return tcs.Task; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + public static Task AsTask(this UniTask task) + { + try + { + UniTask.Awaiter awaiter; + try + { + awaiter = task.GetAwaiter(); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + + if (awaiter.IsCompleted) + { + try + { + awaiter.GetResult(); // check token valid on Succeeded + return Task.CompletedTask; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + var tcs = new TaskCompletionSource(); + + awaiter.SourceOnCompleted(state => + { + using (var tuple = (StateTuple, UniTask.Awaiter>)state) + { + var (inTcs, inAwaiter) = tuple; + try + { + inAwaiter.GetResult(); + inTcs.SetResult(null); + } + catch (Exception ex) + { + inTcs.SetException(ex); + } + } + }, StateTuple.Create(tcs, awaiter)); + + return tcs.Task; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + public static AsyncLazy ToAsyncLazy(this UniTask task) + { + return new AsyncLazy(task); + } + + public static AsyncLazy ToAsyncLazy(this UniTask task) + { + return new AsyncLazy(task); + } + + /// + /// Ignore task result when cancel raised first. + /// + public static UniTask AttachExternalCancellation(this UniTask task, CancellationToken cancellationToken) + { + if (!cancellationToken.CanBeCanceled) + { + return task; + } + + if (cancellationToken.IsCancellationRequested) + { + return UniTask.FromCanceled(cancellationToken); + } + + if (task.Status.IsCompleted()) + { + return task; + } + + return new UniTask(new AttachExternalCancellationSource(task, cancellationToken), 0); + } + + /// + /// Ignore task result when cancel raised first. + /// + public static UniTask AttachExternalCancellation(this UniTask task, CancellationToken cancellationToken) + { + if (!cancellationToken.CanBeCanceled) + { + return task; + } + + if (cancellationToken.IsCancellationRequested) + { + return UniTask.FromCanceled(cancellationToken); + } + + if (task.Status.IsCompleted()) + { + return task; + } + + return new UniTask(new AttachExternalCancellationSource(task, cancellationToken), 0); + } + + sealed class AttachExternalCancellationSource : IUniTaskSource + { + static readonly Action cancellationCallbackDelegate = CancellationCallback; + + CancellationToken cancellationToken; + CancellationTokenRegistration tokenRegistration; + UniTaskCompletionSourceCore core; + + public AttachExternalCancellationSource(UniTask task, CancellationToken cancellationToken) + { + this.cancellationToken = cancellationToken; + this.tokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallbackDelegate, this); + RunTask(task).Forget(); + } + + async UniTaskVoid RunTask(UniTask task) + { + try + { + await task; + core.TrySetResult(AsyncUnit.Default); + } + catch (Exception ex) + { + core.TrySetException(ex); + } + finally + { + tokenRegistration.Dispose(); + } + } + + static void CancellationCallback(object state) + { + var self = (AttachExternalCancellationSource)state; + self.core.TrySetCanceled(self.cancellationToken); + } + + public void GetResult(short token) + { + core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + } + + sealed class AttachExternalCancellationSource : IUniTaskSource + { + static readonly Action cancellationCallbackDelegate = CancellationCallback; + + CancellationToken cancellationToken; + CancellationTokenRegistration tokenRegistration; + UniTaskCompletionSourceCore core; + + public AttachExternalCancellationSource(UniTask task, CancellationToken cancellationToken) + { + this.cancellationToken = cancellationToken; + this.tokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallbackDelegate, this); + RunTask(task).Forget(); + } + + async UniTaskVoid RunTask(UniTask task) + { + try + { + core.TrySetResult(await task); + } + catch (Exception ex) + { + core.TrySetException(ex); + } + finally + { + tokenRegistration.Dispose(); + } + } + + static void CancellationCallback(object state) + { + var self = (AttachExternalCancellationSource)state; + self.core.TrySetCanceled(self.cancellationToken); + } + + void IUniTaskSource.GetResult(short token) + { + core.GetResult(token); + } + + public T GetResult(short token) + { + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + } + +#if UNITY_2018_3_OR_NEWER + + public static IEnumerator ToCoroutine(this UniTask task, Action resultHandler = null, Action exceptionHandler = null) + { + return new ToCoroutineEnumerator(task, resultHandler, exceptionHandler); + } + + public static IEnumerator ToCoroutine(this UniTask task, Action exceptionHandler = null) + { + return new ToCoroutineEnumerator(task, exceptionHandler); + } + + public static async UniTask Timeout(this UniTask task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) + { + var delayCancellationTokenSource = new CancellationTokenSource(); + var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow(); + + int winArgIndex; + bool taskResultIsCanceled; + try + { + (winArgIndex, taskResultIsCanceled, _) = await UniTask.WhenAny(task.SuppressCancellationThrow(), timeoutTask); + } + catch + { + delayCancellationTokenSource.Cancel(); + delayCancellationTokenSource.Dispose(); + throw; + } + + // timeout + if (winArgIndex == 1) + { + if (taskCancellationTokenSource != null) + { + taskCancellationTokenSource.Cancel(); + taskCancellationTokenSource.Dispose(); + } + + throw new TimeoutException("Exceed Timeout:" + timeout); + } + else + { + delayCancellationTokenSource.Cancel(); + delayCancellationTokenSource.Dispose(); + } + + if (taskResultIsCanceled) + { + Error.ThrowOperationCanceledException(); + } + } + + public static async UniTask Timeout(this UniTask task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) + { + var delayCancellationTokenSource = new CancellationTokenSource(); + var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow(); + + int winArgIndex; + (bool IsCanceled, T Result) taskResult; + try + { + (winArgIndex, taskResult, _) = await UniTask.WhenAny(task.SuppressCancellationThrow(), timeoutTask); + } + catch + { + delayCancellationTokenSource.Cancel(); + delayCancellationTokenSource.Dispose(); + throw; + } + + // timeout + if (winArgIndex == 1) + { + if (taskCancellationTokenSource != null) + { + taskCancellationTokenSource.Cancel(); + taskCancellationTokenSource.Dispose(); + } + + throw new TimeoutException("Exceed Timeout:" + timeout); + } + else + { + delayCancellationTokenSource.Cancel(); + delayCancellationTokenSource.Dispose(); + } + + if (taskResult.IsCanceled) + { + Error.ThrowOperationCanceledException(); + } + + return taskResult.Result; + } + + /// + /// Timeout with suppress OperationCanceledException. Returns (bool, IsCacneled). + /// + public static async UniTask TimeoutWithoutException(this UniTask task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) + { + var delayCancellationTokenSource = new CancellationTokenSource(); + var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow(); + + int winArgIndex; + bool taskResultIsCanceled; + try + { + (winArgIndex, taskResultIsCanceled, _) = await UniTask.WhenAny(task.SuppressCancellationThrow(), timeoutTask); + } + catch + { + delayCancellationTokenSource.Cancel(); + delayCancellationTokenSource.Dispose(); + return true; + } + + // timeout + if (winArgIndex == 1) + { + if (taskCancellationTokenSource != null) + { + taskCancellationTokenSource.Cancel(); + taskCancellationTokenSource.Dispose(); + } + + return true; + } + else + { + delayCancellationTokenSource.Cancel(); + delayCancellationTokenSource.Dispose(); + } + + if (taskResultIsCanceled) + { + return true; + } + + return false; + } + + /// + /// Timeout with suppress OperationCanceledException. Returns (bool IsTimeout, T Result). + /// + public static async UniTask<(bool IsTimeout, T Result)> TimeoutWithoutException(this UniTask task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) + { + var delayCancellationTokenSource = new CancellationTokenSource(); + var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow(); + + int winArgIndex; + (bool IsCanceled, T Result) taskResult; + try + { + (winArgIndex, taskResult, _) = await UniTask.WhenAny(task.SuppressCancellationThrow(), timeoutTask); + } + catch + { + delayCancellationTokenSource.Cancel(); + delayCancellationTokenSource.Dispose(); + return (true, default); + } + + // timeout + if (winArgIndex == 1) + { + if (taskCancellationTokenSource != null) + { + taskCancellationTokenSource.Cancel(); + taskCancellationTokenSource.Dispose(); + } + + return (true, default); + } + else + { + delayCancellationTokenSource.Cancel(); + delayCancellationTokenSource.Dispose(); + } + + if (taskResult.IsCanceled) + { + return (true, default); + } + + return (false, taskResult.Result); + } + +#endif + + public static void Forget(this UniTask task) + { + var awaiter = task.GetAwaiter(); + if (awaiter.IsCompleted) + { + try + { + awaiter.GetResult(); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple)state) + { + try + { + t.Item1.GetResult(); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + }, StateTuple.Create(awaiter)); + } + } + + public static void Forget(this UniTask task, Action exceptionHandler, bool handleExceptionOnMainThread = true) + { + if (exceptionHandler == null) + { + Forget(task); + } + else + { + ForgetCoreWithCatch(task, exceptionHandler, handleExceptionOnMainThread).Forget(); + } + } + + static async UniTaskVoid ForgetCoreWithCatch(UniTask task, Action exceptionHandler, bool handleExceptionOnMainThread) + { + try + { + await task; + } + catch (Exception ex) + { + try + { + if (handleExceptionOnMainThread) + { +#if UNITY_2018_3_OR_NEWER + await UniTask.SwitchToMainThread(); +#endif + } + exceptionHandler(ex); + } + catch (Exception ex2) + { + UniTaskScheduler.PublishUnobservedTaskException(ex2); + } + } + } + + public static void Forget(this UniTask task) + { + var awaiter = task.GetAwaiter(); + if (awaiter.IsCompleted) + { + try + { + awaiter.GetResult(); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple.Awaiter>)state) + { + try + { + t.Item1.GetResult(); + } + catch (Exception ex) + { + UniTaskScheduler.PublishUnobservedTaskException(ex); + } + } + }, StateTuple.Create(awaiter)); + } + } + + public static void Forget(this UniTask task, Action exceptionHandler, bool handleExceptionOnMainThread = true) + { + if (exceptionHandler == null) + { + task.Forget(); + } + else + { + ForgetCoreWithCatch(task, exceptionHandler, handleExceptionOnMainThread).Forget(); + } + } + + static async UniTaskVoid ForgetCoreWithCatch(UniTask task, Action exceptionHandler, bool handleExceptionOnMainThread) + { + try + { + await task; + } + catch (Exception ex) + { + try + { + if (handleExceptionOnMainThread) + { +#if UNITY_2018_3_OR_NEWER + await UniTask.SwitchToMainThread(); +#endif + } + exceptionHandler(ex); + } + catch (Exception ex2) + { + UniTaskScheduler.PublishUnobservedTaskException(ex2); + } + } + } + + public static async UniTask ContinueWith(this UniTask task, Action continuationFunction) + { + continuationFunction(await task); + } + + public static async UniTask ContinueWith(this UniTask task, Func continuationFunction) + { + await continuationFunction(await task); + } + + public static async UniTask ContinueWith(this UniTask task, Func continuationFunction) + { + return continuationFunction(await task); + } + + public static async UniTask ContinueWith(this UniTask task, Func> continuationFunction) + { + return await continuationFunction(await task); + } + + public static async UniTask ContinueWith(this UniTask task, Action continuationFunction) + { + await task; + continuationFunction(); + } + + public static async UniTask ContinueWith(this UniTask task, Func continuationFunction) + { + await task; + await continuationFunction(); + } + + public static async UniTask ContinueWith(this UniTask task, Func continuationFunction) + { + await task; + return continuationFunction(); + } + + public static async UniTask ContinueWith(this UniTask task, Func> continuationFunction) + { + await task; + return await continuationFunction(); + } + + public static async UniTask Unwrap(this UniTask> task) + { + return await await task; + } + + public static async UniTask Unwrap(this UniTask task) + { + await await task; + } + + public static async UniTask Unwrap(this Task> task) + { + return await await task; + } + + public static async UniTask Unwrap(this Task> task, bool continueOnCapturedContext) + { + return await await task.ConfigureAwait(continueOnCapturedContext); + } + + public static async UniTask Unwrap(this Task task) + { + await await task; + } + + public static async UniTask Unwrap(this Task task, bool continueOnCapturedContext) + { + await await task.ConfigureAwait(continueOnCapturedContext); + } + + public static async UniTask Unwrap(this UniTask> task) + { + return await await task; + } + + public static async UniTask Unwrap(this UniTask> task, bool continueOnCapturedContext) + { + return await (await task).ConfigureAwait(continueOnCapturedContext); + } + + public static async UniTask Unwrap(this UniTask task) + { + await await task; + } + + public static async UniTask Unwrap(this UniTask task, bool continueOnCapturedContext) + { + await (await task).ConfigureAwait(continueOnCapturedContext); + } + +#if UNITY_2018_3_OR_NEWER + + sealed class ToCoroutineEnumerator : IEnumerator + { + bool completed; + UniTask task; + Action exceptionHandler = null; + bool isStarted = false; + ExceptionDispatchInfo exception; + + public ToCoroutineEnumerator(UniTask task, Action exceptionHandler) + { + completed = false; + this.exceptionHandler = exceptionHandler; + this.task = task; + } + + async UniTaskVoid RunTask(UniTask task) + { + try + { + await task; + } + catch (Exception ex) + { + if (exceptionHandler != null) + { + exceptionHandler(ex); + } + else + { + this.exception = ExceptionDispatchInfo.Capture(ex); + } + } + finally + { + completed = true; + } + } + + public object Current => null; + + public bool MoveNext() + { + if (!isStarted) + { + isStarted = true; + RunTask(task).Forget(); + } + + if (exception != null) + { + exception.Throw(); + return false; + } + + return !completed; + } + + void IEnumerator.Reset() + { + } + } + + sealed class ToCoroutineEnumerator : IEnumerator + { + bool completed; + Action resultHandler = null; + Action exceptionHandler = null; + bool isStarted = false; + UniTask task; + object current = null; + ExceptionDispatchInfo exception; + + public ToCoroutineEnumerator(UniTask task, Action resultHandler, Action exceptionHandler) + { + completed = false; + this.task = task; + this.resultHandler = resultHandler; + this.exceptionHandler = exceptionHandler; + } + + async UniTaskVoid RunTask(UniTask task) + { + try + { + var value = await task; + current = value; // boxed if T is struct... + if (resultHandler != null) + { + resultHandler(value); + } + } + catch (Exception ex) + { + if (exceptionHandler != null) + { + exceptionHandler(ex); + } + else + { + this.exception = ExceptionDispatchInfo.Capture(ex); + } + } + finally + { + completed = true; + } + } + + public object Current => current; + + public bool MoveNext() + { + if (!isStarted) + { + isStarted = true; + RunTask(task).Forget(); + } + + if (exception != null) + { + exception.Throw(); + return false; + } + + return !completed; + } + + void IEnumerator.Reset() + { + } + } + +#endif + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.cs.meta new file mode 100644 index 0000000..0d22946 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05460c617dae1e440861a7438535389f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskObservableExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskObservableExtensions.cs new file mode 100644 index 0000000..d2bd961 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskObservableExtensions.cs @@ -0,0 +1,750 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Runtime.ExceptionServices; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks +{ + public static class UniTaskObservableExtensions + { + public static UniTask ToUniTask(this IObservable source, bool useFirstValue = false, CancellationToken cancellationToken = default) + { + var promise = new UniTaskCompletionSource(); + var disposable = new SingleAssignmentDisposable(); + + var observer = useFirstValue + ? (IObserver)new FirstValueToUniTaskObserver(promise, disposable, cancellationToken) + : (IObserver)new ToUniTaskObserver(promise, disposable, cancellationToken); + + try + { + disposable.Disposable = source.Subscribe(observer); + } + catch (Exception ex) + { + promise.TrySetException(ex); + } + + return promise.Task; + } + + public static IObservable ToObservable(this UniTask task) + { + if (task.Status.IsCompleted()) + { + try + { + return new ReturnObservable(task.GetAwaiter().GetResult()); + } + catch (Exception ex) + { + return new ThrowObservable(ex); + } + } + + var subject = new AsyncSubject(); + Fire(subject, task).Forget(); + return subject; + } + + /// + /// Ideally returns IObservabl[Unit] is best but Cysharp.Threading.Tasks does not have Unit so return AsyncUnit instead. + /// + public static IObservable ToObservable(this UniTask task) + { + if (task.Status.IsCompleted()) + { + try + { + task.GetAwaiter().GetResult(); + return new ReturnObservable(AsyncUnit.Default); + } + catch (Exception ex) + { + return new ThrowObservable(ex); + } + } + + var subject = new AsyncSubject(); + Fire(subject, task).Forget(); + return subject; + } + + static async UniTaskVoid Fire(AsyncSubject subject, UniTask task) + { + T value; + try + { + value = await task; + } + catch (Exception ex) + { + subject.OnError(ex); + return; + } + + subject.OnNext(value); + subject.OnCompleted(); + } + + static async UniTaskVoid Fire(AsyncSubject subject, UniTask task) + { + try + { + await task; + } + catch (Exception ex) + { + subject.OnError(ex); + return; + } + + subject.OnNext(AsyncUnit.Default); + subject.OnCompleted(); + } + + class ToUniTaskObserver : IObserver + { + static readonly Action callback = OnCanceled; + + readonly UniTaskCompletionSource promise; + readonly SingleAssignmentDisposable disposable; + readonly CancellationToken cancellationToken; + readonly CancellationTokenRegistration registration; + + bool hasValue; + T latestValue; + + public ToUniTaskObserver(UniTaskCompletionSource promise, SingleAssignmentDisposable disposable, CancellationToken cancellationToken) + { + this.promise = promise; + this.disposable = disposable; + this.cancellationToken = cancellationToken; + + if (this.cancellationToken.CanBeCanceled) + { + this.registration = this.cancellationToken.RegisterWithoutCaptureExecutionContext(callback, this); + } + } + + static void OnCanceled(object state) + { + var self = (ToUniTaskObserver)state; + self.disposable.Dispose(); + self.promise.TrySetCanceled(self.cancellationToken); + } + + public void OnNext(T value) + { + hasValue = true; + latestValue = value; + } + + public void OnError(Exception error) + { + try + { + promise.TrySetException(error); + } + finally + { + registration.Dispose(); + disposable.Dispose(); + } + } + + public void OnCompleted() + { + try + { + if (hasValue) + { + promise.TrySetResult(latestValue); + } + else + { + promise.TrySetException(new InvalidOperationException("Sequence has no elements")); + } + } + finally + { + registration.Dispose(); + disposable.Dispose(); + } + } + } + + class FirstValueToUniTaskObserver : IObserver + { + static readonly Action callback = OnCanceled; + + readonly UniTaskCompletionSource promise; + readonly SingleAssignmentDisposable disposable; + readonly CancellationToken cancellationToken; + readonly CancellationTokenRegistration registration; + + bool hasValue; + + public FirstValueToUniTaskObserver(UniTaskCompletionSource promise, SingleAssignmentDisposable disposable, CancellationToken cancellationToken) + { + this.promise = promise; + this.disposable = disposable; + this.cancellationToken = cancellationToken; + + if (this.cancellationToken.CanBeCanceled) + { + this.registration = this.cancellationToken.RegisterWithoutCaptureExecutionContext(callback, this); + } + } + + static void OnCanceled(object state) + { + var self = (FirstValueToUniTaskObserver)state; + self.disposable.Dispose(); + self.promise.TrySetCanceled(self.cancellationToken); + } + + public void OnNext(T value) + { + hasValue = true; + try + { + promise.TrySetResult(value); + } + finally + { + registration.Dispose(); + disposable.Dispose(); + } + } + + public void OnError(Exception error) + { + try + { + promise.TrySetException(error); + } + finally + { + registration.Dispose(); + disposable.Dispose(); + } + } + + public void OnCompleted() + { + try + { + if (!hasValue) + { + promise.TrySetException(new InvalidOperationException("Sequence has no elements")); + } + } + finally + { + registration.Dispose(); + disposable.Dispose(); + } + } + } + + class ReturnObservable : IObservable + { + readonly T value; + + public ReturnObservable(T value) + { + this.value = value; + } + + public IDisposable Subscribe(IObserver observer) + { + observer.OnNext(value); + observer.OnCompleted(); + return EmptyDisposable.Instance; + } + } + + class ThrowObservable : IObservable + { + readonly Exception value; + + public ThrowObservable(Exception value) + { + this.value = value; + } + + public IDisposable Subscribe(IObserver observer) + { + observer.OnError(value); + return EmptyDisposable.Instance; + } + } + } +} + +namespace Cysharp.Threading.Tasks.Internal +{ + // Bridges for Rx. + + internal class EmptyDisposable : IDisposable + { + public static EmptyDisposable Instance = new EmptyDisposable(); + + EmptyDisposable() + { + + } + + public void Dispose() + { + } + } + + internal sealed class SingleAssignmentDisposable : IDisposable + { + readonly object gate = new object(); + IDisposable current; + bool disposed; + + public bool IsDisposed { get { lock (gate) { return disposed; } } } + + public IDisposable Disposable + { + get + { + return current; + } + set + { + var old = default(IDisposable); + bool alreadyDisposed; + lock (gate) + { + alreadyDisposed = disposed; + old = current; + if (!alreadyDisposed) + { + if (value == null) return; + current = value; + } + } + + if (alreadyDisposed && value != null) + { + value.Dispose(); + return; + } + + if (old != null) throw new InvalidOperationException("Disposable is already set"); + } + } + + + public void Dispose() + { + IDisposable old = null; + + lock (gate) + { + if (!disposed) + { + disposed = true; + old = current; + current = null; + } + } + + if (old != null) old.Dispose(); + } + } + + internal sealed class AsyncSubject : IObservable, IObserver + { + object observerLock = new object(); + + T lastValue; + bool hasValue; + bool isStopped; + bool isDisposed; + Exception lastError; + IObserver outObserver = EmptyObserver.Instance; + + public T Value + { + get + { + ThrowIfDisposed(); + if (!isStopped) throw new InvalidOperationException("AsyncSubject is not completed yet"); + if (lastError != null) ExceptionDispatchInfo.Capture(lastError).Throw(); + return lastValue; + } + } + + public bool HasObservers + { + get + { + return !(outObserver is EmptyObserver) && !isStopped && !isDisposed; + } + } + + public bool IsCompleted { get { return isStopped; } } + + public void OnCompleted() + { + IObserver old; + T v; + bool hv; + lock (observerLock) + { + ThrowIfDisposed(); + if (isStopped) return; + + old = outObserver; + outObserver = EmptyObserver.Instance; + isStopped = true; + v = lastValue; + hv = hasValue; + } + + if (hv) + { + old.OnNext(v); + old.OnCompleted(); + } + else + { + old.OnCompleted(); + } + } + + public void OnError(Exception error) + { + if (error == null) throw new ArgumentNullException("error"); + + IObserver old; + lock (observerLock) + { + ThrowIfDisposed(); + if (isStopped) return; + + old = outObserver; + outObserver = EmptyObserver.Instance; + isStopped = true; + lastError = error; + } + + old.OnError(error); + } + + public void OnNext(T value) + { + lock (observerLock) + { + ThrowIfDisposed(); + if (isStopped) return; + + this.hasValue = true; + this.lastValue = value; + } + } + + public IDisposable Subscribe(IObserver observer) + { + if (observer == null) throw new ArgumentNullException("observer"); + + var ex = default(Exception); + var v = default(T); + var hv = false; + + lock (observerLock) + { + ThrowIfDisposed(); + if (!isStopped) + { + var listObserver = outObserver as ListObserver; + if (listObserver != null) + { + outObserver = listObserver.Add(observer); + } + else + { + var current = outObserver; + if (current is EmptyObserver) + { + outObserver = observer; + } + else + { + outObserver = new ListObserver(new ImmutableList>(new[] { current, observer })); + } + } + + return new Subscription(this, observer); + } + + ex = lastError; + v = lastValue; + hv = hasValue; + } + + if (ex != null) + { + observer.OnError(ex); + } + else if (hv) + { + observer.OnNext(v); + observer.OnCompleted(); + } + else + { + observer.OnCompleted(); + } + + return EmptyDisposable.Instance; + } + + public void Dispose() + { + lock (observerLock) + { + isDisposed = true; + outObserver = DisposedObserver.Instance; + lastError = null; + lastValue = default(T); + } + } + + void ThrowIfDisposed() + { + if (isDisposed) throw new ObjectDisposedException(""); + } + + class Subscription : IDisposable + { + readonly object gate = new object(); + AsyncSubject parent; + IObserver unsubscribeTarget; + + public Subscription(AsyncSubject parent, IObserver unsubscribeTarget) + { + this.parent = parent; + this.unsubscribeTarget = unsubscribeTarget; + } + + public void Dispose() + { + lock (gate) + { + if (parent != null) + { + lock (parent.observerLock) + { + var listObserver = parent.outObserver as ListObserver; + if (listObserver != null) + { + parent.outObserver = listObserver.Remove(unsubscribeTarget); + } + else + { + parent.outObserver = EmptyObserver.Instance; + } + + unsubscribeTarget = null; + parent = null; + } + } + } + } + } + } + + internal class ListObserver : IObserver + { + private readonly ImmutableList> _observers; + + public ListObserver(ImmutableList> observers) + { + _observers = observers; + } + + public void OnCompleted() + { + var targetObservers = _observers.Data; + for (int i = 0; i < targetObservers.Length; i++) + { + targetObservers[i].OnCompleted(); + } + } + + public void OnError(Exception error) + { + var targetObservers = _observers.Data; + for (int i = 0; i < targetObservers.Length; i++) + { + targetObservers[i].OnError(error); + } + } + + public void OnNext(T value) + { + var targetObservers = _observers.Data; + for (int i = 0; i < targetObservers.Length; i++) + { + targetObservers[i].OnNext(value); + } + } + + internal IObserver Add(IObserver observer) + { + return new ListObserver(_observers.Add(observer)); + } + + internal IObserver Remove(IObserver observer) + { + var i = Array.IndexOf(_observers.Data, observer); + if (i < 0) + return this; + + if (_observers.Data.Length == 2) + { + return _observers.Data[1 - i]; + } + else + { + return new ListObserver(_observers.Remove(observer)); + } + } + } + + internal class EmptyObserver : IObserver + { + public static readonly EmptyObserver Instance = new EmptyObserver(); + + EmptyObserver() + { + + } + + public void OnCompleted() + { + } + + public void OnError(Exception error) + { + } + + public void OnNext(T value) + { + } + } + + internal class ThrowObserver : IObserver + { + public static readonly ThrowObserver Instance = new ThrowObserver(); + + ThrowObserver() + { + + } + + public void OnCompleted() + { + } + + public void OnError(Exception error) + { + ExceptionDispatchInfo.Capture(error).Throw(); + } + + public void OnNext(T value) + { + } + } + + internal class DisposedObserver : IObserver + { + public static readonly DisposedObserver Instance = new DisposedObserver(); + + DisposedObserver() + { + + } + + public void OnCompleted() + { + throw new ObjectDisposedException(""); + } + + public void OnError(Exception error) + { + throw new ObjectDisposedException(""); + } + + public void OnNext(T value) + { + throw new ObjectDisposedException(""); + } + } + + internal class ImmutableList + { + public static readonly ImmutableList Empty = new ImmutableList(); + + T[] data; + + public T[] Data + { + get { return data; } + } + + ImmutableList() + { + data = new T[0]; + } + + public ImmutableList(T[] data) + { + this.data = data; + } + + public ImmutableList Add(T value) + { + var newData = new T[data.Length + 1]; + Array.Copy(data, newData, data.Length); + newData[data.Length] = value; + return new ImmutableList(newData); + } + + public ImmutableList Remove(T value) + { + var i = IndexOf(value); + if (i < 0) return this; + + var length = data.Length; + if (length == 1) return Empty; + + var newData = new T[length - 1]; + + Array.Copy(data, 0, newData, 0, i); + Array.Copy(data, i + 1, newData, i, length - i - 1); + + return new ImmutableList(newData); + } + + public int IndexOf(T value) + { + for (var i = 0; i < data.Length; ++i) + { + // ImmutableList only use for IObserver(no worry for boxed) + if (object.Equals(data[i], value)) return i; + } + return -1; + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskObservableExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskObservableExtensions.cs.meta new file mode 100644 index 0000000..527a49f --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskObservableExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eaea262a5ad393d419c15b3b2901d664 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskScheduler.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskScheduler.cs new file mode 100644 index 0000000..2f91f2a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskScheduler.cs @@ -0,0 +1,103 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + // UniTask has no scheduler like TaskScheduler. + // Only handle unobserved exception. + + public static class UniTaskScheduler + { + public static event Action UnobservedTaskException; + + /// + /// Propagate OperationCanceledException to UnobservedTaskException when true. Default is false. + /// + public static bool PropagateOperationCanceledException = false; + +#if UNITY_2018_3_OR_NEWER + + /// + /// Write log type when catch unobserved exception and not registered UnobservedTaskException. Default is Exception. + /// + public static UnityEngine.LogType UnobservedExceptionWriteLogType = UnityEngine.LogType.Exception; + + /// + /// Dispatch exception event to Unity MainThread. Default is true. + /// + public static bool DispatchUnityMainThread = true; + + // cache delegate. + static readonly SendOrPostCallback handleExceptionInvoke = InvokeUnobservedTaskException; + + static void InvokeUnobservedTaskException(object state) + { + UnobservedTaskException((Exception)state); + } +#endif + + internal static void PublishUnobservedTaskException(Exception ex) + { + if (ex != null) + { + if (!PropagateOperationCanceledException && ex is OperationCanceledException) + { + return; + } + + if (UnobservedTaskException != null) + { +#if UNITY_2018_3_OR_NEWER + if (!DispatchUnityMainThread || Thread.CurrentThread.ManagedThreadId == PlayerLoopHelper.MainThreadId) + { + // allows inlining call. + UnobservedTaskException.Invoke(ex); + } + else + { + // Post to MainThread. + PlayerLoopHelper.UnitySynchronizationContext.Post(handleExceptionInvoke, ex); + } +#else + UnobservedTaskException.Invoke(ex); +#endif + } + else + { +#if UNITY_2018_3_OR_NEWER + string msg = null; + if (UnobservedExceptionWriteLogType != UnityEngine.LogType.Exception) + { + msg = "UnobservedTaskException: " + ex.ToString(); + } + switch (UnobservedExceptionWriteLogType) + { + case UnityEngine.LogType.Error: + UnityEngine.Debug.LogError(msg); + break; + case UnityEngine.LogType.Assert: + UnityEngine.Debug.LogAssertion(msg); + break; + case UnityEngine.LogType.Warning: + UnityEngine.Debug.LogWarning(msg); + break; + case UnityEngine.LogType.Log: + UnityEngine.Debug.Log(msg); + break; + case UnityEngine.LogType.Exception: + UnityEngine.Debug.LogException(ex); + break; + default: + break; + } +#else + Console.WriteLine("UnobservedTaskException: " + ex.ToString()); +#endif + } + } + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskScheduler.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskScheduler.cs.meta new file mode 100644 index 0000000..5e29191 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskScheduler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6cad69921702d5488d96b5ef30df1b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskSynchronizationContext.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskSynchronizationContext.cs new file mode 100644 index 0000000..450e019 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskSynchronizationContext.cs @@ -0,0 +1,158 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public class UniTaskSynchronizationContext : SynchronizationContext + { + const int MaxArrayLength = 0X7FEFFFFF; + const int InitialSize = 16; + + static SpinLock gate = new SpinLock(false); + static bool dequing = false; + + static int actionListCount = 0; + static Callback[] actionList = new Callback[InitialSize]; + + static int waitingListCount = 0; + static Callback[] waitingList = new Callback[InitialSize]; + + static int opCount; + + public override void Send(SendOrPostCallback d, object state) + { + d(state); + } + + public override void Post(SendOrPostCallback d, object state) + { + 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 Callback[newLength]; + Array.Copy(waitingList, newArray, waitingListCount); + waitingList = newArray; + } + waitingList[waitingListCount] = new Callback(d, state); + waitingListCount++; + } + else + { + // Ensure Capacity + if (actionList.Length == actionListCount) + { + var newLength = actionListCount * 2; + if ((uint)newLength > MaxArrayLength) newLength = MaxArrayLength; + + var newArray = new Callback[newLength]; + Array.Copy(actionList, newArray, actionListCount); + actionList = newArray; + } + actionList[actionListCount] = new Callback(d, state); + actionListCount++; + } + } + finally + { + if (lockTaken) gate.Exit(false); + } + } + + public override void OperationStarted() + { + Interlocked.Increment(ref opCount); + } + + public override void OperationCompleted() + { + Interlocked.Decrement(ref opCount); + } + + public override SynchronizationContext CreateCopy() + { + return this; + } + + // delegate entrypoint. + internal static 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] = default; + action.Invoke(); + } + + { + 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); + } + } + } + + [StructLayout(LayoutKind.Auto)] + readonly struct Callback + { + readonly SendOrPostCallback callback; + readonly object state; + + public Callback(SendOrPostCallback callback, object state) + { + this.callback = callback; + this.state = state; + } + + public void Invoke() + { + try + { + callback(state); + } + catch (Exception ex) + { + UnityEngine.Debug.LogException(ex); + } + } + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskSynchronizationContext.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskSynchronizationContext.cs.meta new file mode 100644 index 0000000..9828c89 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskSynchronizationContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: abf3aae9813db2849bce518f8596e920 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskVoid.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskVoid.cs new file mode 100644 index 0000000..c7e9ed9 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskVoid.cs @@ -0,0 +1,19 @@ +#pragma warning disable CS1591 +#pragma warning disable CS0436 + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using Cysharp.Threading.Tasks.CompilerServices; + +namespace Cysharp.Threading.Tasks +{ + [AsyncMethodBuilder(typeof(AsyncUniTaskVoidMethodBuilder))] + public readonly struct UniTaskVoid + { + public void Forget() + { + } + } +} + diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskVoid.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskVoid.cs.meta new file mode 100644 index 0000000..01f7156 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UniTaskVoid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9f28cd922179634d863011548f89ae7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs new file mode 100644 index 0000000..1a1e011 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs @@ -0,0 +1,198 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +#if UNITY_2018_4 || UNITY_2019_4_OR_NEWER +#if UNITASK_ASSETBUNDLE_SUPPORT + +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Runtime.CompilerServices; +using System.Threading; +using UnityEngine; + +namespace Cysharp.Threading.Tasks +{ + public static partial class UnityAsyncExtensions + { + public static AssetBundleRequestAllAssetsAwaiter AwaitForAllAssets(this AssetBundleRequest asyncOperation) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + return new AssetBundleRequestAllAssetsAwaiter(asyncOperation); + } + + public static UniTask AwaitForAllAssets(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken) + { + return AwaitForAllAssets(asyncOperation, null, PlayerLoopTiming.Update, cancellationToken: cancellationToken); + } + + public static UniTask AwaitForAllAssets(this AssetBundleRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.allAssets); + return new UniTask(AssetBundleRequestAllAssetsConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); + } + + public struct AssetBundleRequestAllAssetsAwaiter : ICriticalNotifyCompletion + { + AssetBundleRequest asyncOperation; + Action continuationAction; + + public AssetBundleRequestAllAssetsAwaiter(AssetBundleRequest asyncOperation) + { + this.asyncOperation = asyncOperation; + this.continuationAction = null; + } + + public AssetBundleRequestAllAssetsAwaiter GetAwaiter() + { + return this; + } + + public bool IsCompleted => asyncOperation.isDone; + + public UnityEngine.Object[] GetResult() + { + if (continuationAction != null) + { + asyncOperation.completed -= continuationAction; + continuationAction = null; + var result = asyncOperation.allAssets; + asyncOperation = null; + return result; + } + else + { + var result = asyncOperation.allAssets; + asyncOperation = null; + return result; + } + } + + public void OnCompleted(Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction); + continuationAction = PooledDelegate.Create(continuation); + asyncOperation.completed += continuationAction; + } + } + + sealed class AssetBundleRequestAllAssetsConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + AssetBundleRequestAllAssetsConfiguredSource nextNode; + public ref AssetBundleRequestAllAssetsConfiguredSource NextNode => ref nextNode; + + static AssetBundleRequestAllAssetsConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(AssetBundleRequestAllAssetsConfiguredSource), () => pool.Size); + } + + AssetBundleRequest asyncOperation; + IProgress progress; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + AssetBundleRequestAllAssetsConfiguredSource() + { + + } + + public static IUniTaskSource Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new AssetBundleRequestAllAssetsConfiguredSource(); + } + + result.asyncOperation = asyncOperation; + result.progress = progress; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public UnityEngine.Object[] GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (progress != null) + { + progress.Report(asyncOperation.progress); + } + + if (asyncOperation.isDone) + { + core.TrySetResult(asyncOperation.allAssets); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + asyncOperation = default; + progress = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + } +} + +#endif +#endif \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs.meta new file mode 100644 index 0000000..79be923 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9147caba40da434da95b39709c13784 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs new file mode 100644 index 0000000..5805dbb --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs @@ -0,0 +1,140 @@ + #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Threading; +using UnityEngine.Rendering; + +namespace Cysharp.Threading.Tasks +{ + public static partial class UnityAsyncExtensions + { + #region AsyncGPUReadbackRequest + + public static UniTask.Awaiter GetAwaiter(this AsyncGPUReadbackRequest asyncOperation) + { + return ToUniTask(asyncOperation).GetAwaiter(); + } + + public static UniTask WithCancellation(this AsyncGPUReadbackRequest asyncOperation, CancellationToken cancellationToken) + { + return ToUniTask(asyncOperation, cancellationToken: cancellationToken); + } + + public static UniTask ToUniTask(this AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + if (asyncOperation.done) return UniTask.FromResult(asyncOperation); + return new UniTask(AsyncGPUReadbackRequestAwaiterConfiguredSource.Create(asyncOperation, timing, cancellationToken, out var token), token); + } + + sealed class AsyncGPUReadbackRequestAwaiterConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + AsyncGPUReadbackRequestAwaiterConfiguredSource nextNode; + public ref AsyncGPUReadbackRequestAwaiterConfiguredSource NextNode => ref nextNode; + + static AsyncGPUReadbackRequestAwaiterConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(AsyncGPUReadbackRequestAwaiterConfiguredSource), () => pool.Size); + } + + AsyncGPUReadbackRequest asyncOperation; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + AsyncGPUReadbackRequestAwaiterConfiguredSource() + { + + } + + public static IUniTaskSource Create(AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new AsyncGPUReadbackRequestAwaiterConfiguredSource(); + } + + result.asyncOperation = asyncOperation; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public AsyncGPUReadbackRequest GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (asyncOperation.hasError) + { + core.TrySetException(new Exception("AsyncGPUReadbackRequest.hasError = true")); + return false; + } + + if (asyncOperation.done) + { + core.TrySetResult(asyncOperation); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + asyncOperation = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs.meta new file mode 100644 index 0000000..510c49e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98f5fedb44749ab4688674d79126b46a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs new file mode 100644 index 0000000..db0a892 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs @@ -0,0 +1,102 @@ +#if ENABLE_MANAGED_JOBS +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Threading; +using Unity.Jobs; +using UnityEngine; + +namespace Cysharp.Threading.Tasks +{ + public static partial class UnityAsyncExtensions + { + public static async UniTask WaitAsync(this JobHandle jobHandle, PlayerLoopTiming waitTiming, CancellationToken cancellationToken = default) + { + await UniTask.Yield(waitTiming); + jobHandle.Complete(); + cancellationToken.ThrowIfCancellationRequested(); // call cancel after Complete. + } + + public static UniTask.Awaiter GetAwaiter(this JobHandle jobHandle) + { + var handler = JobHandlePromise.Create(jobHandle, out var token); + { + PlayerLoopHelper.AddAction(PlayerLoopTiming.EarlyUpdate, handler); + PlayerLoopHelper.AddAction(PlayerLoopTiming.PreUpdate, handler); + PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, handler); + PlayerLoopHelper.AddAction(PlayerLoopTiming.PreLateUpdate, handler); + PlayerLoopHelper.AddAction(PlayerLoopTiming.PostLateUpdate, handler); + } + + return new UniTask(handler, token).GetAwaiter(); + } + + // can not pass CancellationToken because can't handle JobHandle's Complete and NativeArray.Dispose. + + public static UniTask ToUniTask(this JobHandle jobHandle, PlayerLoopTiming waitTiming) + { + var handler = JobHandlePromise.Create(jobHandle, out var token); + { + PlayerLoopHelper.AddAction(waitTiming, handler); + } + + return new UniTask(handler, token); + } + + sealed class JobHandlePromise : IUniTaskSource, IPlayerLoopItem + { + JobHandle jobHandle; + + UniTaskCompletionSourceCore core; + + // Cancellation is not supported. + public static JobHandlePromise Create(JobHandle jobHandle, out short token) + { + // not use pool. + var result = new JobHandlePromise(); + + result.jobHandle = jobHandle; + + TaskTracker.TrackActiveTask(result, 3); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + TaskTracker.RemoveTracking(this); + core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (jobHandle.IsCompleted | PlayerLoopHelper.IsEditorApplicationQuitting) + { + jobHandle.Complete(); + core.TrySetResult(AsyncUnit.Default); + return false; + } + + return true; + } + } + } +} + +#endif \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs.meta new file mode 100644 index 0000000..c07df0b --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30979a768fbd4b94f8694eee8a305c99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs new file mode 100644 index 0000000..fdfe55c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs @@ -0,0 +1,14 @@ +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks +{ + public static partial class UnityAsyncExtensions + { + public static UniTask StartAsyncCoroutine(this UnityEngine.MonoBehaviour monoBehaviour, Func asyncCoroutine) + { + var token = monoBehaviour.GetCancellationTokenOnDestroy(); + return asyncCoroutine(token); + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs.meta new file mode 100644 index 0000000..6e45863 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2edd588bb09eb0a4695d039d6a1f02b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.cs new file mode 100644 index 0000000..2f72604 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.cs @@ -0,0 +1,932 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using System; +using System.Runtime.CompilerServices; +using System.Threading; +using UnityEngine; +using Cysharp.Threading.Tasks.Internal; +#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT) +using UnityEngine.Networking; +#endif + +namespace Cysharp.Threading.Tasks +{ + public static partial class UnityAsyncExtensions + { + #region AsyncOperation + +#if !UNITY_2023_1_OR_NEWER + // from Unity2023.1.0a15, AsyncOperationAwaitableExtensions.GetAwaiter is defined in UnityEngine. + + public static AsyncOperationAwaiter GetAwaiter(this AsyncOperation asyncOperation) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + return new AsyncOperationAwaiter(asyncOperation); + } +#endif + + public static UniTask WithCancellation(this AsyncOperation asyncOperation, CancellationToken cancellationToken) + { + return ToUniTask(asyncOperation, cancellationToken: cancellationToken); + } + + public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); + if (asyncOperation.isDone) return UniTask.CompletedTask; + return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); + } + + public struct AsyncOperationAwaiter : ICriticalNotifyCompletion + { + AsyncOperation asyncOperation; + Action continuationAction; + + public AsyncOperationAwaiter(AsyncOperation asyncOperation) + { + this.asyncOperation = asyncOperation; + this.continuationAction = null; + } + + public bool IsCompleted => asyncOperation.isDone; + + public void GetResult() + { + if (continuationAction != null) + { + asyncOperation.completed -= continuationAction; + continuationAction = null; + asyncOperation = null; + } + else + { + asyncOperation = null; + } + } + + public void OnCompleted(Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction); + continuationAction = PooledDelegate.Create(continuation); + asyncOperation.completed += continuationAction; + } + } + + sealed class AsyncOperationConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + AsyncOperationConfiguredSource nextNode; + public ref AsyncOperationConfiguredSource NextNode => ref nextNode; + + static AsyncOperationConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(AsyncOperationConfiguredSource), () => pool.Size); + } + + AsyncOperation asyncOperation; + IProgress progress; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + AsyncOperationConfiguredSource() + { + + } + + public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new AsyncOperationConfiguredSource(); + } + + result.asyncOperation = asyncOperation; + result.progress = progress; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (progress != null) + { + progress.Report(asyncOperation.progress); + } + + if (asyncOperation.isDone) + { + core.TrySetResult(AsyncUnit.Default); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + asyncOperation = default; + progress = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + #endregion + + #region ResourceRequest + + public static ResourceRequestAwaiter GetAwaiter(this ResourceRequest asyncOperation) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + return new ResourceRequestAwaiter(asyncOperation); + } + + public static UniTask WithCancellation(this ResourceRequest asyncOperation, CancellationToken cancellationToken) + { + return ToUniTask(asyncOperation, cancellationToken: cancellationToken); + } + + public static UniTask ToUniTask(this ResourceRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); + return new UniTask(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); + } + + public struct ResourceRequestAwaiter : ICriticalNotifyCompletion + { + ResourceRequest asyncOperation; + Action continuationAction; + + public ResourceRequestAwaiter(ResourceRequest asyncOperation) + { + this.asyncOperation = asyncOperation; + this.continuationAction = null; + } + + public bool IsCompleted => asyncOperation.isDone; + + public UnityEngine.Object GetResult() + { + if (continuationAction != null) + { + asyncOperation.completed -= continuationAction; + continuationAction = null; + var result = asyncOperation.asset; + asyncOperation = null; + return result; + } + else + { + var result = asyncOperation.asset; + asyncOperation = null; + return result; + } + } + + public void OnCompleted(Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction); + continuationAction = PooledDelegate.Create(continuation); + asyncOperation.completed += continuationAction; + } + } + + sealed class ResourceRequestConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + ResourceRequestConfiguredSource nextNode; + public ref ResourceRequestConfiguredSource NextNode => ref nextNode; + + static ResourceRequestConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(ResourceRequestConfiguredSource), () => pool.Size); + } + + ResourceRequest asyncOperation; + IProgress progress; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + ResourceRequestConfiguredSource() + { + + } + + public static IUniTaskSource Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new ResourceRequestConfiguredSource(); + } + + result.asyncOperation = asyncOperation; + result.progress = progress; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public UnityEngine.Object GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (progress != null) + { + progress.Report(asyncOperation.progress); + } + + if (asyncOperation.isDone) + { + core.TrySetResult(asyncOperation.asset); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + asyncOperation = default; + progress = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + #endregion + +#if UNITASK_ASSETBUNDLE_SUPPORT + #region AssetBundleRequest + + public static AssetBundleRequestAwaiter GetAwaiter(this AssetBundleRequest asyncOperation) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + return new AssetBundleRequestAwaiter(asyncOperation); + } + + public static UniTask WithCancellation(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken) + { + return ToUniTask(asyncOperation, cancellationToken: cancellationToken); + } + + public static UniTask ToUniTask(this AssetBundleRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); + return new UniTask(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); + } + + public struct AssetBundleRequestAwaiter : ICriticalNotifyCompletion + { + AssetBundleRequest asyncOperation; + Action continuationAction; + + public AssetBundleRequestAwaiter(AssetBundleRequest asyncOperation) + { + this.asyncOperation = asyncOperation; + this.continuationAction = null; + } + + public bool IsCompleted => asyncOperation.isDone; + + public UnityEngine.Object GetResult() + { + if (continuationAction != null) + { + asyncOperation.completed -= continuationAction; + continuationAction = null; + var result = asyncOperation.asset; + asyncOperation = null; + return result; + } + else + { + var result = asyncOperation.asset; + asyncOperation = null; + return result; + } + } + + public void OnCompleted(Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction); + continuationAction = PooledDelegate.Create(continuation); + asyncOperation.completed += continuationAction; + } + } + + sealed class AssetBundleRequestConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + AssetBundleRequestConfiguredSource nextNode; + public ref AssetBundleRequestConfiguredSource NextNode => ref nextNode; + + static AssetBundleRequestConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(AssetBundleRequestConfiguredSource), () => pool.Size); + } + + AssetBundleRequest asyncOperation; + IProgress progress; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + AssetBundleRequestConfiguredSource() + { + + } + + public static IUniTaskSource Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new AssetBundleRequestConfiguredSource(); + } + + result.asyncOperation = asyncOperation; + result.progress = progress; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public UnityEngine.Object GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (progress != null) + { + progress.Report(asyncOperation.progress); + } + + if (asyncOperation.isDone) + { + core.TrySetResult(asyncOperation.asset); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + asyncOperation = default; + progress = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + #endregion +#endif + +#if UNITASK_ASSETBUNDLE_SUPPORT + #region AssetBundleCreateRequest + + public static AssetBundleCreateRequestAwaiter GetAwaiter(this AssetBundleCreateRequest asyncOperation) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + return new AssetBundleCreateRequestAwaiter(asyncOperation); + } + + public static UniTask WithCancellation(this AssetBundleCreateRequest asyncOperation, CancellationToken cancellationToken) + { + return ToUniTask(asyncOperation, cancellationToken: cancellationToken); + } + + public static UniTask ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle); + return new UniTask(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); + } + + public struct AssetBundleCreateRequestAwaiter : ICriticalNotifyCompletion + { + AssetBundleCreateRequest asyncOperation; + Action continuationAction; + + public AssetBundleCreateRequestAwaiter(AssetBundleCreateRequest asyncOperation) + { + this.asyncOperation = asyncOperation; + this.continuationAction = null; + } + + public bool IsCompleted => asyncOperation.isDone; + + public AssetBundle GetResult() + { + if (continuationAction != null) + { + asyncOperation.completed -= continuationAction; + continuationAction = null; + var result = asyncOperation.assetBundle; + asyncOperation = null; + return result; + } + else + { + var result = asyncOperation.assetBundle; + asyncOperation = null; + return result; + } + } + + public void OnCompleted(Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction); + continuationAction = PooledDelegate.Create(continuation); + asyncOperation.completed += continuationAction; + } + } + + sealed class AssetBundleCreateRequestConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + AssetBundleCreateRequestConfiguredSource nextNode; + public ref AssetBundleCreateRequestConfiguredSource NextNode => ref nextNode; + + static AssetBundleCreateRequestConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(AssetBundleCreateRequestConfiguredSource), () => pool.Size); + } + + AssetBundleCreateRequest asyncOperation; + IProgress progress; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + AssetBundleCreateRequestConfiguredSource() + { + + } + + public static IUniTaskSource Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new AssetBundleCreateRequestConfiguredSource(); + } + + result.asyncOperation = asyncOperation; + result.progress = progress; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public AssetBundle GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + return false; + } + + if (progress != null) + { + progress.Report(asyncOperation.progress); + } + + if (asyncOperation.isDone) + { + core.TrySetResult(asyncOperation.assetBundle); + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + asyncOperation = default; + progress = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + #endregion +#endif + +#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT) + #region UnityWebRequestAsyncOperation + + public static UnityWebRequestAsyncOperationAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOperation) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + return new UnityWebRequestAsyncOperationAwaiter(asyncOperation); + } + + public static UniTask WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, CancellationToken cancellationToken) + { + return ToUniTask(asyncOperation, cancellationToken: cancellationToken); + } + + public static UniTask ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + { + Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); + if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); + if (asyncOperation.isDone) + { + if (asyncOperation.webRequest.IsError()) + { + return UniTask.FromException(new UnityWebRequestException(asyncOperation.webRequest)); + } + return UniTask.FromResult(asyncOperation.webRequest); + } + return new UniTask(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); + } + + public struct UnityWebRequestAsyncOperationAwaiter : ICriticalNotifyCompletion + { + UnityWebRequestAsyncOperation asyncOperation; + Action continuationAction; + + public UnityWebRequestAsyncOperationAwaiter(UnityWebRequestAsyncOperation asyncOperation) + { + this.asyncOperation = asyncOperation; + this.continuationAction = null; + } + + public bool IsCompleted => asyncOperation.isDone; + + public UnityWebRequest GetResult() + { + if (continuationAction != null) + { + asyncOperation.completed -= continuationAction; + continuationAction = null; + var result = asyncOperation.webRequest; + asyncOperation = null; + if (result.IsError()) + { + throw new UnityWebRequestException(result); + } + return result; + } + else + { + var result = asyncOperation.webRequest; + asyncOperation = null; + if (result.IsError()) + { + throw new UnityWebRequestException(result); + } + return result; + } + } + + public void OnCompleted(Action continuation) + { + UnsafeOnCompleted(continuation); + } + + public void UnsafeOnCompleted(Action continuation) + { + Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction); + continuationAction = PooledDelegate.Create(continuation); + asyncOperation.completed += continuationAction; + } + } + + sealed class UnityWebRequestAsyncOperationConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode + { + static TaskPool pool; + UnityWebRequestAsyncOperationConfiguredSource nextNode; + public ref UnityWebRequestAsyncOperationConfiguredSource NextNode => ref nextNode; + + static UnityWebRequestAsyncOperationConfiguredSource() + { + TaskPool.RegisterSizeGetter(typeof(UnityWebRequestAsyncOperationConfiguredSource), () => pool.Size); + } + + UnityWebRequestAsyncOperation asyncOperation; + IProgress progress; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + UnityWebRequestAsyncOperationConfiguredSource() + { + + } + + public static IUniTaskSource Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + if (!pool.TryPop(out var result)) + { + result = new UnityWebRequestAsyncOperationConfiguredSource(); + } + + result.asyncOperation = asyncOperation; + result.progress = progress; + result.cancellationToken = cancellationToken; + + TaskTracker.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public UnityWebRequest GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + TryReturn(); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + asyncOperation.webRequest.Abort(); + core.TrySetCanceled(cancellationToken); + return false; + } + + if (progress != null) + { + progress.Report(asyncOperation.progress); + } + + if (asyncOperation.isDone) + { + if (asyncOperation.webRequest.IsError()) + { + core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest)); + } + else + { + core.TrySetResult(asyncOperation.webRequest); + } + return false; + } + + return true; + } + + bool TryReturn() + { + TaskTracker.RemoveTracking(this); + core.Reset(); + asyncOperation = default; + progress = default; + cancellationToken = default; + return pool.TryPush(this); + } + } + + #endregion +#endif + + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.cs.meta new file mode 100644 index 0000000..6dfab81 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8cc7fd65dd1433e419be4764aeb51391 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs new file mode 100644 index 0000000..7f1a90c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs @@ -0,0 +1,858 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT +using System; +using System.Threading; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.UI; + +namespace Cysharp.Threading.Tasks +{ + public static partial class UnityAsyncExtensions + { + public static AsyncUnityEventHandler GetAsyncEventHandler(this UnityEvent unityEvent, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(unityEvent, cancellationToken, false); + } + + public static UniTask OnInvokeAsync(this UnityEvent unityEvent, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(unityEvent, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnInvokeAsAsyncEnumerable(this UnityEvent unityEvent, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(unityEvent, cancellationToken); + } + + public static AsyncUnityEventHandler GetAsyncEventHandler(this UnityEvent unityEvent, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(unityEvent, cancellationToken, false); + } + + public static UniTask OnInvokeAsync(this UnityEvent unityEvent, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(unityEvent, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnInvokeAsAsyncEnumerable(this UnityEvent unityEvent, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(unityEvent, cancellationToken); + } + + public static IAsyncClickEventHandler GetAsyncClickEventHandler(this Button button) + { + return new AsyncUnityEventHandler(button.onClick, button.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncClickEventHandler GetAsyncClickEventHandler(this Button button, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(button.onClick, cancellationToken, false); + } + + public static UniTask OnClickAsync(this Button button) + { + return new AsyncUnityEventHandler(button.onClick, button.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnClickAsync(this Button button, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(button.onClick, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnClickAsAsyncEnumerable(this Button button) + { + return new UnityEventHandlerAsyncEnumerable(button.onClick, button.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnClickAsAsyncEnumerable(this Button button, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(button.onClick, cancellationToken); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this Toggle toggle) + { + return new AsyncUnityEventHandler(toggle.onValueChanged, toggle.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this Toggle toggle, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(toggle.onValueChanged, cancellationToken, false); + } + + public static UniTask OnValueChangedAsync(this Toggle toggle) + { + return new AsyncUnityEventHandler(toggle.onValueChanged, toggle.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnValueChangedAsync(this Toggle toggle, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(toggle.onValueChanged, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this Toggle toggle) + { + return new UnityEventHandlerAsyncEnumerable(toggle.onValueChanged, toggle.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this Toggle toggle, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(toggle.onValueChanged, cancellationToken); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this Scrollbar scrollbar) + { + return new AsyncUnityEventHandler(scrollbar.onValueChanged, scrollbar.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this Scrollbar scrollbar, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(scrollbar.onValueChanged, cancellationToken, false); + } + + public static UniTask OnValueChangedAsync(this Scrollbar scrollbar) + { + return new AsyncUnityEventHandler(scrollbar.onValueChanged, scrollbar.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnValueChangedAsync(this Scrollbar scrollbar, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(scrollbar.onValueChanged, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this Scrollbar scrollbar) + { + return new UnityEventHandlerAsyncEnumerable(scrollbar.onValueChanged, scrollbar.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this Scrollbar scrollbar, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(scrollbar.onValueChanged, cancellationToken); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this ScrollRect scrollRect) + { + return new AsyncUnityEventHandler(scrollRect.onValueChanged, scrollRect.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this ScrollRect scrollRect, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(scrollRect.onValueChanged, cancellationToken, false); + } + + public static UniTask OnValueChangedAsync(this ScrollRect scrollRect) + { + return new AsyncUnityEventHandler(scrollRect.onValueChanged, scrollRect.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnValueChangedAsync(this ScrollRect scrollRect, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(scrollRect.onValueChanged, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this ScrollRect scrollRect) + { + return new UnityEventHandlerAsyncEnumerable(scrollRect.onValueChanged, scrollRect.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this ScrollRect scrollRect, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(scrollRect.onValueChanged, cancellationToken); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this Slider slider) + { + return new AsyncUnityEventHandler(slider.onValueChanged, slider.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this Slider slider, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(slider.onValueChanged, cancellationToken, false); + } + + public static UniTask OnValueChangedAsync(this Slider slider) + { + return new AsyncUnityEventHandler(slider.onValueChanged, slider.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnValueChangedAsync(this Slider slider, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(slider.onValueChanged, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this Slider slider) + { + return new UnityEventHandlerAsyncEnumerable(slider.onValueChanged, slider.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this Slider slider, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(slider.onValueChanged, cancellationToken); + } + + public static IAsyncEndEditEventHandler GetAsyncEndEditEventHandler(this InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncEndEditEventHandler GetAsyncEndEditEventHandler(this InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onEndEdit, cancellationToken, false); + } + + public static UniTask OnEndEditAsync(this InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnEndEditAsync(this InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onEndEdit, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnEndEditAsAsyncEnumerable(this InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnEndEditAsAsyncEnumerable(this InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onEndEdit, cancellationToken); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onValueChanged, cancellationToken, false); + } + + public static UniTask OnValueChangedAsync(this InputField inputField) + { + return new AsyncUnityEventHandler(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnValueChangedAsync(this InputField inputField, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(inputField.onValueChanged, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this InputField inputField) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this InputField inputField, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(inputField.onValueChanged, cancellationToken); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this Dropdown dropdown) + { + return new AsyncUnityEventHandler(dropdown.onValueChanged, dropdown.GetCancellationTokenOnDestroy(), false); + } + + public static IAsyncValueChangedEventHandler GetAsyncValueChangedEventHandler(this Dropdown dropdown, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(dropdown.onValueChanged, cancellationToken, false); + } + + public static UniTask OnValueChangedAsync(this Dropdown dropdown) + { + return new AsyncUnityEventHandler(dropdown.onValueChanged, dropdown.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); + } + + public static UniTask OnValueChangedAsync(this Dropdown dropdown, CancellationToken cancellationToken) + { + return new AsyncUnityEventHandler(dropdown.onValueChanged, cancellationToken, true).OnInvokeAsync(); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this Dropdown dropdown) + { + return new UnityEventHandlerAsyncEnumerable(dropdown.onValueChanged, dropdown.GetCancellationTokenOnDestroy()); + } + + public static IUniTaskAsyncEnumerable OnValueChangedAsAsyncEnumerable(this Dropdown dropdown, CancellationToken cancellationToken) + { + return new UnityEventHandlerAsyncEnumerable(dropdown.onValueChanged, cancellationToken); + } + } + + public interface IAsyncClickEventHandler : IDisposable + { + UniTask OnClickAsync(); + } + + public interface IAsyncValueChangedEventHandler : IDisposable + { + UniTask OnValueChangedAsync(); + } + + public interface IAsyncEndEditEventHandler : IDisposable + { + UniTask OnEndEditAsync(); + } + + // for TMP_PRO + + public interface IAsyncEndTextSelectionEventHandler : IDisposable + { + UniTask OnEndTextSelectionAsync(); + } + + public interface IAsyncTextSelectionEventHandler : IDisposable + { + UniTask OnTextSelectionAsync(); + } + + public interface IAsyncDeselectEventHandler : IDisposable + { + UniTask OnDeselectAsync(); + } + + public interface IAsyncSelectEventHandler : IDisposable + { + UniTask OnSelectAsync(); + } + + public interface IAsyncSubmitEventHandler : IDisposable + { + UniTask OnSubmitAsync(); + } + + internal class TextSelectionEventConverter : UnityEvent<(string, int, int)>, IDisposable + { + readonly UnityEvent innerEvent; + readonly UnityAction invokeDelegate; + + + public TextSelectionEventConverter(UnityEvent unityEvent) + { + this.innerEvent = unityEvent; + this.invokeDelegate = InvokeCore; + + innerEvent.AddListener(invokeDelegate); + } + + void InvokeCore(string item1, int item2, int item3) + { + innerEvent.Invoke(item1, item2, item3); + } + + public void Dispose() + { + innerEvent.RemoveListener(invokeDelegate); + } + } + + public class AsyncUnityEventHandler : IUniTaskSource, IDisposable, IAsyncClickEventHandler + { + static Action cancellationCallback = CancellationCallback; + + readonly UnityAction action; + readonly UnityEvent unityEvent; + + CancellationToken cancellationToken; + CancellationTokenRegistration registration; + bool isDisposed; + bool callOnce; + + UniTaskCompletionSourceCore core; + + public AsyncUnityEventHandler(UnityEvent unityEvent, CancellationToken cancellationToken, bool callOnce) + { + this.cancellationToken = cancellationToken; + if (cancellationToken.IsCancellationRequested) + { + isDisposed = true; + return; + } + + this.action = Invoke; + this.unityEvent = unityEvent; + this.callOnce = callOnce; + + unityEvent.AddListener(action); + + if (cancellationToken.CanBeCanceled) + { + registration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); + } + + TaskTracker.TrackActiveTask(this, 3); + } + + public UniTask OnInvokeAsync() + { + core.Reset(); + if (isDisposed) + { + core.TrySetCanceled(this.cancellationToken); + } + return new UniTask(this, core.Version); + } + + void Invoke() + { + core.TrySetResult(AsyncUnit.Default); + } + + static void CancellationCallback(object state) + { + var self = (AsyncUnityEventHandler)state; + self.Dispose(); + } + + public void Dispose() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + registration.Dispose(); + if (unityEvent != null) + { + unityEvent.RemoveListener(action); + } + core.TrySetCanceled(cancellationToken); + } + } + + UniTask IAsyncClickEventHandler.OnClickAsync() + { + return OnInvokeAsync(); + } + + void IUniTaskSource.GetResult(short token) + { + try + { + core.GetResult(token); + } + finally + { + if (callOnce) + { + Dispose(); + } + } + } + + UniTaskStatus IUniTaskSource.GetStatus(short token) + { + return core.GetStatus(token); + } + + UniTaskStatus IUniTaskSource.UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public class AsyncUnityEventHandler : IUniTaskSource, IDisposable, IAsyncValueChangedEventHandler, IAsyncEndEditEventHandler + , IAsyncEndTextSelectionEventHandler, IAsyncTextSelectionEventHandler, IAsyncDeselectEventHandler, IAsyncSelectEventHandler, IAsyncSubmitEventHandler + { + static Action cancellationCallback = CancellationCallback; + + readonly UnityAction action; + readonly UnityEvent unityEvent; + + CancellationToken cancellationToken; + CancellationTokenRegistration registration; + bool isDisposed; + bool callOnce; + + UniTaskCompletionSourceCore core; + + public AsyncUnityEventHandler(UnityEvent unityEvent, CancellationToken cancellationToken, bool callOnce) + { + this.cancellationToken = cancellationToken; + if (cancellationToken.IsCancellationRequested) + { + isDisposed = true; + return; + } + + this.action = Invoke; + this.unityEvent = unityEvent; + this.callOnce = callOnce; + + unityEvent.AddListener(action); + + if (cancellationToken.CanBeCanceled) + { + registration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); + } + + TaskTracker.TrackActiveTask(this, 3); + } + + public UniTask OnInvokeAsync() + { + core.Reset(); + if (isDisposed) + { + core.TrySetCanceled(this.cancellationToken); + } + return new UniTask(this, core.Version); + } + + void Invoke(T result) + { + core.TrySetResult(result); + } + + static void CancellationCallback(object state) + { + var self = (AsyncUnityEventHandler)state; + self.Dispose(); + } + + public void Dispose() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + registration.Dispose(); + if (unityEvent != null) + { + // Dispose inner delegate for TextSelectionEventConverter + if (unityEvent is IDisposable disp) + { + disp.Dispose(); + } + + unityEvent.RemoveListener(action); + } + + core.TrySetCanceled(); + } + } + + UniTask IAsyncValueChangedEventHandler.OnValueChangedAsync() + { + return OnInvokeAsync(); + } + + UniTask IAsyncEndEditEventHandler.OnEndEditAsync() + { + return OnInvokeAsync(); + } + + UniTask IAsyncEndTextSelectionEventHandler.OnEndTextSelectionAsync() + { + return OnInvokeAsync(); + } + + UniTask IAsyncTextSelectionEventHandler.OnTextSelectionAsync() + { + return OnInvokeAsync(); + } + + UniTask IAsyncDeselectEventHandler.OnDeselectAsync() + { + return OnInvokeAsync(); + } + + UniTask IAsyncSelectEventHandler.OnSelectAsync() + { + return OnInvokeAsync(); + } + + UniTask IAsyncSubmitEventHandler.OnSubmitAsync() + { + return OnInvokeAsync(); + } + + T IUniTaskSource.GetResult(short token) + { + try + { + return core.GetResult(token); + } + finally + { + if (callOnce) + { + Dispose(); + } + } + } + + void IUniTaskSource.GetResult(short token) + { + ((IUniTaskSource)this).GetResult(token); + } + + UniTaskStatus IUniTaskSource.GetStatus(short token) + { + return core.GetStatus(token); + } + + UniTaskStatus IUniTaskSource.UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + } + + public class UnityEventHandlerAsyncEnumerable : IUniTaskAsyncEnumerable + { + readonly UnityEvent unityEvent; + readonly CancellationToken cancellationToken1; + + public UnityEventHandlerAsyncEnumerable(UnityEvent unityEvent, CancellationToken cancellationToken) + { + this.unityEvent = unityEvent; + this.cancellationToken1 = cancellationToken; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + if (this.cancellationToken1 == cancellationToken) + { + return new UnityEventHandlerAsyncEnumerator(unityEvent, this.cancellationToken1, CancellationToken.None); + } + else + { + return new UnityEventHandlerAsyncEnumerator(unityEvent, this.cancellationToken1, cancellationToken); + } + } + + class UnityEventHandlerAsyncEnumerator : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action cancel1 = OnCanceled1; + static readonly Action cancel2 = OnCanceled2; + + readonly UnityEvent unityEvent; + CancellationToken cancellationToken1; + CancellationToken cancellationToken2; + + UnityAction unityAction; + CancellationTokenRegistration registration1; + CancellationTokenRegistration registration2; + bool isDisposed; + + public UnityEventHandlerAsyncEnumerator(UnityEvent unityEvent, CancellationToken cancellationToken1, CancellationToken cancellationToken2) + { + this.unityEvent = unityEvent; + this.cancellationToken1 = cancellationToken1; + this.cancellationToken2 = cancellationToken2; + } + + public AsyncUnit Current => default; + + public UniTask MoveNextAsync() + { + cancellationToken1.ThrowIfCancellationRequested(); + cancellationToken2.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (unityAction == null) + { + unityAction = Invoke; + + TaskTracker.TrackActiveTask(this, 3); + unityEvent.AddListener(unityAction); + if (cancellationToken1.CanBeCanceled) + { + registration1 = cancellationToken1.RegisterWithoutCaptureExecutionContext(cancel1, this); + } + if (cancellationToken2.CanBeCanceled) + { + registration2 = cancellationToken2.RegisterWithoutCaptureExecutionContext(cancel2, this); + } + } + + return new UniTask(this, completionSource.Version); + } + + void Invoke() + { + completionSource.TrySetResult(true); + } + + static void OnCanceled1(object state) + { + var self = (UnityEventHandlerAsyncEnumerator)state; + try + { + self.completionSource.TrySetCanceled(self.cancellationToken1); + } + finally + { + self.DisposeAsync().Forget(); + } + } + + static void OnCanceled2(object state) + { + var self = (UnityEventHandlerAsyncEnumerator)state; + try + { + self.completionSource.TrySetCanceled(self.cancellationToken2); + } + finally + { + self.DisposeAsync().Forget(); + } + } + + public UniTask DisposeAsync() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + registration1.Dispose(); + registration2.Dispose(); + unityEvent.RemoveListener(unityAction); + + completionSource.TrySetCanceled(); + } + + return default; + } + } + } + + public class UnityEventHandlerAsyncEnumerable : IUniTaskAsyncEnumerable + { + readonly UnityEvent unityEvent; + readonly CancellationToken cancellationToken1; + + public UnityEventHandlerAsyncEnumerable(UnityEvent unityEvent, CancellationToken cancellationToken) + { + this.unityEvent = unityEvent; + this.cancellationToken1 = cancellationToken; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + if (this.cancellationToken1 == cancellationToken) + { + return new UnityEventHandlerAsyncEnumerator(unityEvent, this.cancellationToken1, CancellationToken.None); + } + else + { + return new UnityEventHandlerAsyncEnumerator(unityEvent, this.cancellationToken1, cancellationToken); + } + } + + class UnityEventHandlerAsyncEnumerator : MoveNextSource, IUniTaskAsyncEnumerator + { + static readonly Action cancel1 = OnCanceled1; + static readonly Action cancel2 = OnCanceled2; + + readonly UnityEvent unityEvent; + CancellationToken cancellationToken1; + CancellationToken cancellationToken2; + + UnityAction unityAction; + CancellationTokenRegistration registration1; + CancellationTokenRegistration registration2; + bool isDisposed; + + public UnityEventHandlerAsyncEnumerator(UnityEvent unityEvent, CancellationToken cancellationToken1, CancellationToken cancellationToken2) + { + this.unityEvent = unityEvent; + this.cancellationToken1 = cancellationToken1; + this.cancellationToken2 = cancellationToken2; + } + + public T Current { get; private set; } + + public UniTask MoveNextAsync() + { + cancellationToken1.ThrowIfCancellationRequested(); + cancellationToken2.ThrowIfCancellationRequested(); + completionSource.Reset(); + + if (unityAction == null) + { + unityAction = Invoke; + + TaskTracker.TrackActiveTask(this, 3); + unityEvent.AddListener(unityAction); + if (cancellationToken1.CanBeCanceled) + { + registration1 = cancellationToken1.RegisterWithoutCaptureExecutionContext(cancel1, this); + } + if (cancellationToken2.CanBeCanceled) + { + registration2 = cancellationToken2.RegisterWithoutCaptureExecutionContext(cancel2, this); + } + } + + return new UniTask(this, completionSource.Version); + } + + void Invoke(T value) + { + Current = value; + completionSource.TrySetResult(true); + } + + static void OnCanceled1(object state) + { + var self = (UnityEventHandlerAsyncEnumerator)state; + try + { + self.completionSource.TrySetCanceled(self.cancellationToken1); + } + finally + { + self.DisposeAsync().Forget(); + } + } + + static void OnCanceled2(object state) + { + var self = (UnityEventHandlerAsyncEnumerator)state; + try + { + self.completionSource.TrySetCanceled(self.cancellationToken2); + } + finally + { + self.DisposeAsync().Forget(); + } + } + + public UniTask DisposeAsync() + { + if (!isDisposed) + { + isDisposed = true; + TaskTracker.RemoveTracking(this); + registration1.Dispose(); + registration2.Dispose(); + if (unityEvent is IDisposable disp) + { + disp.Dispose(); + } + unityEvent.RemoveListener(unityAction); + + completionSource.TrySetCanceled(); + } + + return default; + } + } + } +} + +#endif \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs.meta new file mode 100644 index 0000000..90c5d51 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6804799fba2376d4099561d176101aff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityBindingExtensions.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityBindingExtensions.cs new file mode 100644 index 0000000..269fee2 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityBindingExtensions.cs @@ -0,0 +1,245 @@ +using System; +using System.Threading; +using UnityEngine; +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT +using UnityEngine.UI; +#endif + +namespace Cysharp.Threading.Tasks +{ + public static class UnityBindingExtensions + { +#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT + // -> Text + + public static void BindTo(this IUniTaskAsyncEnumerable source, UnityEngine.UI.Text text, bool rebindOnError = true) + { + BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + public static void BindTo(this IUniTaskAsyncEnumerable source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError = true) + { + BindToCore(source, text, cancellationToken, rebindOnError).Forget(); + } + + static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError) + { + var repeat = false; + BIND_AGAIN: + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (true) + { + bool moveNext; + try + { + moveNext = await e.MoveNextAsync(); + repeat = false; + } + catch (Exception ex) + { + if (ex is OperationCanceledException) return; + + if (rebindOnError && !repeat) + { + repeat = true; + goto BIND_AGAIN; + } + else + { + throw; + } + } + + if (!moveNext) return; + + text.text = e.Current; + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + // -> Text + + public static void BindTo(this IUniTaskAsyncEnumerable source, UnityEngine.UI.Text text, bool rebindOnError = true) + { + BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + public static void BindTo(this IUniTaskAsyncEnumerable source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError = true) + { + BindToCore(source, text, cancellationToken, rebindOnError).Forget(); + } + + public static void BindTo(this AsyncReactiveProperty source, UnityEngine.UI.Text text, bool rebindOnError = true) + { + BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError) + { + var repeat = false; + BIND_AGAIN: + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (true) + { + bool moveNext; + try + { + moveNext = await e.MoveNextAsync(); + repeat = false; + } + catch (Exception ex) + { + if (ex is OperationCanceledException) return; + + if (rebindOnError && !repeat) + { + repeat = true; + goto BIND_AGAIN; + } + else + { + throw; + } + } + + if (!moveNext) return; + + text.text = e.Current.ToString(); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + + // -> Selectable + + public static void BindTo(this IUniTaskAsyncEnumerable source, Selectable selectable, bool rebindOnError = true) + { + BindToCore(source, selectable, selectable.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + public static void BindTo(this IUniTaskAsyncEnumerable source, Selectable selectable, CancellationToken cancellationToken, bool rebindOnError = true) + { + BindToCore(source, selectable, cancellationToken, rebindOnError).Forget(); + } + + static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, Selectable selectable, CancellationToken cancellationToken, bool rebindOnError) + { + var repeat = false; + BIND_AGAIN: + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (true) + { + bool moveNext; + try + { + moveNext = await e.MoveNextAsync(); + repeat = false; + } + catch (Exception ex) + { + if (ex is OperationCanceledException) return; + + if (rebindOnError && !repeat) + { + repeat = true; + goto BIND_AGAIN; + } + else + { + throw; + } + } + + if (!moveNext) return; + + + selectable.interactable = e.Current; + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } +#endif + + // -> Action + + public static void BindTo(this IUniTaskAsyncEnumerable source, TObject monoBehaviour, Action bindAction, bool rebindOnError = true) + where TObject : MonoBehaviour + { + BindToCore(source, monoBehaviour, bindAction, monoBehaviour.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); + } + + public static void BindTo(this IUniTaskAsyncEnumerable source, TObject bindTarget, Action bindAction, CancellationToken cancellationToken, bool rebindOnError = true) + { + BindToCore(source, bindTarget, bindAction, cancellationToken, rebindOnError).Forget(); + } + + static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, TObject bindTarget, Action bindAction, CancellationToken cancellationToken, bool rebindOnError) + { + var repeat = false; + BIND_AGAIN: + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (true) + { + bool moveNext; + try + { + moveNext = await e.MoveNextAsync(); + repeat = false; + } + catch (Exception ex) + { + if (ex is OperationCanceledException) return; + + if (rebindOnError && !repeat) + { + repeat = true; + goto BIND_AGAIN; + } + else + { + throw; + } + } + + if (!moveNext) return; + + bindAction(bindTarget, e.Current); + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityBindingExtensions.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityBindingExtensions.cs.meta new file mode 100644 index 0000000..3fae798 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityBindingExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 090b20e3528552b4a8d751f7df525c2b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityWebRequestException.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityWebRequestException.cs new file mode 100644 index 0000000..9585769 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityWebRequestException.cs @@ -0,0 +1,67 @@ +#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT) + +using System; +using System.Collections.Generic; +using UnityEngine.Networking; + +namespace Cysharp.Threading.Tasks +{ + public class UnityWebRequestException : Exception + { + public UnityWebRequest UnityWebRequest { get; } +#if UNITY_2020_2_OR_NEWER + public UnityWebRequest.Result Result { get; } +#else + public bool IsNetworkError { get; } + public bool IsHttpError { get; } +#endif + public string Error { get; } + public string Text { get; } + public long ResponseCode { get; } + public Dictionary ResponseHeaders { get; } + + string msg; + + public UnityWebRequestException(UnityWebRequest unityWebRequest) + { + this.UnityWebRequest = unityWebRequest; +#if UNITY_2020_2_OR_NEWER + this.Result = unityWebRequest.result; +#else + this.IsNetworkError = unityWebRequest.isNetworkError; + this.IsHttpError = unityWebRequest.isHttpError; +#endif + this.Error = unityWebRequest.error; + this.ResponseCode = unityWebRequest.responseCode; + if (UnityWebRequest.downloadHandler != null) + { + if (unityWebRequest.downloadHandler is DownloadHandlerBuffer dhb) + { + this.Text = dhb.text; + } + } + this.ResponseHeaders = unityWebRequest.GetResponseHeaders(); + } + + public override string Message + { + get + { + if (msg == null) + { + if(!string.IsNullOrWhiteSpace(Text)) + { + msg = Error + Environment.NewLine + Text; + } + else + { + msg = Error; + } + } + return msg; + } + } + } +} + +#endif \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityWebRequestException.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityWebRequestException.cs.meta new file mode 100644 index 0000000..50c475e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/UnityWebRequestException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 013a499e522703a42962a779b4d9850c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/_InternalVisibleTo.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/_InternalVisibleTo.cs new file mode 100644 index 0000000..ab7c10c --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/_InternalVisibleTo.cs @@ -0,0 +1,6 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("UniTask.Linq")] +[assembly: InternalsVisibleTo("UniTask.Addressables")] +[assembly: InternalsVisibleTo("UniTask.DOTween")] +[assembly: InternalsVisibleTo("UniTask.TextMeshPro")] \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/_InternalVisibleTo.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/_InternalVisibleTo.cs.meta new file mode 100644 index 0000000..2ec6cd3 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/Runtime/_InternalVisibleTo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8507e97eb606fad4b99c6edf92e19cb8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/package.json b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/package.json new file mode 100644 index 0000000..42f9e4a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/package.json @@ -0,0 +1,12 @@ +{ + "name": "com.cysharp.unitask", + "displayName": "UniTask", + "author": { "name": "Cysharp, Inc.", "url": "https://cysharp.co.jp/en/" }, + "version": "2.3.3", + "unity": "2018.4", + "description": "Provides an efficient async/await integration to Unity.", + "keywords": [ "async/await", "async", "Task", "UniTask" ], + "license": "MIT", + "category": "Task", + "dependencies": {} +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/package.json.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/package.json.meta new file mode 100644 index 0000000..65439e6 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/UniTask/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d1a9a71f68bb0d04db91ddaa3329abf9 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/FileUtil.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/FileUtil.cs new file mode 100644 index 0000000..a9730d2 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/FileUtil.cs @@ -0,0 +1,86 @@ +using System.IO; +using System.Text; +using UnityEngine; + + +namespace Adam +{ + public class FileUtil + { + public static void WriteToLocal(string data, string fileName) + { + string path = GetPath(fileName); + if (!File.Exists(path)) + { + File.Create(path).Close(); + } + File.WriteAllText(path, data, Encoding.UTF8); + } + + public static string ReadFromLocal(string fileName) + { + string path = GetPath(fileName); + if (!File.Exists(path)) return "空"; + string data = File.ReadAllText(path); + return data; + } + + /// + /// 返回指定行的数据 + /// + /// + /// + /// + public static string ReadFromLocal(string fileName, int index) + { + string path = GetPath(fileName); + if (!File.Exists(path)) return "请选择场景"; + string[] data = File.ReadAllLines(path); + return data[index]; + } + + /// + /// 返回所有行的数据 + /// + /// + /// + /// + public static string[] ReadAllLineFromLocal(string fileName) + { + string path = GetPath(fileName); + if (!File.Exists(path)) return null; + string[] data = File.ReadAllLines(path); + return data; + } + + public static string Split(string data, int index) + { + string[] s = data.Split(','); + if (index > s.Length) + return "科目不存在"; + else + return s[index]; + } + /// + /// 路径 + /// + /// 数据文件 + /// + public static string GetPath(string fileName) + { + string path = Application.dataPath + "/StreamingAssets/" + fileName; + return path; + } + /// + /// 路径 + /// + /// 子文件夹 + /// 数据文件 + /// + public static string GetPath(string file, string fileName) + { + string path = Application.dataPath + "/StreamingAssets/" + file + "/" + fileName; + return path; + } + } +} \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/FileUtil.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/FileUtil.cs.meta new file mode 100644 index 0000000..30c9325 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/FileUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c667593ea1c532147a17431fcfc0b0a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/IOHelper.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/IOHelper.cs new file mode 100644 index 0000000..a32fcf1 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/IOHelper.cs @@ -0,0 +1,69 @@ +using System.IO; +namespace SMHFramework.Helper +{ + public static class IOHelper + { + public static void CheckFolder(string path) + { + if (!string.IsNullOrEmpty(path)) + { + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + } + } + + public static void CheckFile(string path) + { + if (!File.Exists(path)) + { + File.Create(path).Dispose(); + } + } + + public static void Write2File(string content, string path) + { + CheckFile(path); + File.WriteAllText(path, content); + } + + public static void Write2File(byte[] content, string path) + { + CheckFile(path); + File.WriteAllBytes(path, content); + } + + public static void Write2File(string[] contents, string path) + { + CheckFile(path); + File.WriteAllLines(path, contents); + } + + public static string ReadStringFormFile(string path) + { + CheckFile(path); + var str = File.ReadAllText(path); + return str; + } + + public static string[] ReadStringArrayFormFile(string path) + { + CheckFile(path); + var str = File.ReadAllLines(path); + return str; + } + + public static byte[] ReadBytesFormFile(string path) + { + CheckFile(path); + var bytes = File.ReadAllBytes(path); + return bytes; + } + + public static string GetPath(params string[] pathParams) + { + return Path.Combine(pathParams); + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/IOHelper.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/IOHelper.cs.meta new file mode 100644 index 0000000..f12f5dc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/IOHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce9dd1591edc3854fab526f1fb5ef523 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/JsonHelper.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/JsonHelper.cs new file mode 100644 index 0000000..4629211 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/JsonHelper.cs @@ -0,0 +1,30 @@ + +using Newtonsoft.Json; + +namespace SMHFramework.Helper +{ + public static class JsonHelper + { + public static T GetObject(string json) where T : class + { + return JsonConvert.DeserializeObject(json); + } + + public static string GetJson(T t) where T : class + { + return JsonConvert.SerializeObject(t); + } + + public static void WriteJsonToFile(string path,T t) where T : class + { + var json = GetJson(t); + IOHelper.Write2File(json, path); + } + + public static T ReadObjectFormFile(string path) where T : class + { + var json = IOHelper.ReadStringFormFile(path); + return GetObject(json); + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/JsonHelper.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/JsonHelper.cs.meta new file mode 100644 index 0000000..4023ae7 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/JsonHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2b7bb224d53bf34bb3f73e0d36475bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/StringHelper.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/StringHelper.cs new file mode 100644 index 0000000..897f774 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/StringHelper.cs @@ -0,0 +1,27 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class StringHelper +{ + public const string format = "{0}:{1}:{2}"; + + public const char zero = '0'; + + public const int hour2Second = 3600; + + public const int minute2Second = 60; + + /// + /// 倒计时格式 + /// + /// 秒数 + /// + public static string GetCountDownStr(int second) + { + int h = second / hour2Second; + int m = (second - h * minute2Second) / minute2Second; + int s = second % minute2Second; + return string.Format(format, h.ToString().PadLeft(2, zero), m.ToString().PadLeft(2, zero), s.ToString().PadLeft(2, zero)); + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/StringHelper.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/StringHelper.cs.meta new file mode 100644 index 0000000..501df69 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/StringHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 575b68a6f410dc34188de253a5fa8031 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/ToolUtility.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/ToolUtility.cs new file mode 100644 index 0000000..716d0c9 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/ToolUtility.cs @@ -0,0 +1,118 @@ +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; +using Newtonsoft.Json; +//============================================================ +//支持中文,文件使用UTF-8编码 +//@author YangHua +//@create 20230914 +//@company QianHuo +// +//@description: +//============================================================ +namespace Utility +{ + public class ToolUtility + { + /// + /// 分割字符串 + /// + /// + /// + public static string[] GetInfos(string info, char t) + { + string[] result = info.Split(t); + return result; + } + + public static string GetInfo(string info, char t) + { + string[] result = info.Split(t); + return result[1]; + } + + public static string SubUserNum(string userNum) + { + string rightUserNum = ""; + if (userNum.Length == 13) + { + var tempstr = userNum.Substring(3, 10); + if (tempstr.Length.Equals(10)) + { + rightUserNum = tempstr; + } + } + else + { + rightUserNum = userNum; + } + return rightUserNum; + } + + + /// + /// 剔除字符串 + /// + /// + /// + /// + public static string GetEliminateInfo(string info, string eliminate) + { + string result = info.Replace(eliminate, ""); + return result; + } + + + public static bool CheckGuiRaycastObjects() + { + PointerEventData eventData = new PointerEventData(EventSystem.current); + eventData.pressPosition = Input.mousePosition;//touch.position + eventData.position = Input.mousePosition;//touch.position + + var results = new List(); + //gr.Raycast(eventData, results); + EventSystem.current.RaycastAll(eventData, results); //使用此方式也可 + return results.Count > 0; + } + + public static void ReadFromLocal(string fileName, T monoBehaviour) + { + //string path = Application.dataPath + "/StreamingAssets/" + fileName+".json"; + + if (!File.Exists(fileName)) + { + Debug.Log("没有地址信息"); + return; + } + //Debug.Log(path); + string json = File.ReadAllText(fileName); + JsonUtility.FromJsonOverwrite(json, monoBehaviour); + } + + + public static void WriteToLocal(string fileName, T monoBehaviour) + { + string path = Application.dataPath + "/StreamingAssets/" + fileName + ".json"; + //string json = JsonUtility.ToJson(monoBehaviour); + string json = JsonConvert.SerializeObject(monoBehaviour); + if (!File.Exists(path)) File.Create(path).Close(); + File.WriteAllText(path, json, Encoding.UTF8); + Debug.Log("path...." + path); + } + + /// + /// 路径 + /// + /// xxx.xxxx + /// + public string GetPath(string fileType) + { + string path = Application.dataPath + "/StreamingAssets/" + fileType; + return path; + } + } +} diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/ToolUtility.cs.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/ToolUtility.cs.meta new file mode 100644 index 0000000..1fe3a4a --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/Utility/ToolUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 66cd72c307b290c42b9544f9de8eb560 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/WebAdapter.cs b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/WebAdapter.cs index 18f8717..b98952a 100644 --- a/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/WebAdapter.cs +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Adam/Scripts/WebAdapter.cs @@ -7,6 +7,8 @@ using UnityEngine.Events; public class WebAdapter : MonoBehaviour { #if UNITY_WEBGL && !UNITY_EDITOR + public string head; + public string token; [DllImport("__Internal")] private static extern void OnLevelChange(string level); #else @@ -16,6 +18,8 @@ public class WebAdapter : MonoBehaviour } #endif public UnityEvent onStation; + public string head; + public string token; public void LevelChange(string level) { OnLevelChange(level); @@ -25,4 +29,12 @@ public class WebAdapter : MonoBehaviour { onStation?.Invoke(station); } + + public void SetHeadAndToken(string _headAndToken) + { + string[] data = _headAndToken.Split("+"); + head = data[0].Replace(" ", ""); + token = data[1].Replace(" ", ""); + } + } diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Excels.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Excels.meta new file mode 100644 index 0000000..31c6d2e --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Excels.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1693d519ad59c384db26e3709b78b26e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Excels/山东行政区划数据.xlsx b/u3d-ShanDongVirtualPowerPlant/Assets/Excels/山东行政区划数据.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..769e500344bae2b27622bde18c9dfeba2f545500 GIT binary patch literal 18052 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 E2J25n)&Kwi literal 0 HcmV?d00001 diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Excel.dll.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Excel.dll.meta new file mode 100644 index 0000000..b579cbb --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Excel.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: c688e563921e12845848cb56e3e50c1d +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/ICSharpCode.SharpZipLib.dll b/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/ICSharpCode.SharpZipLib.dll new file mode 100644 index 0000000000000000000000000000000000000000..e829ebf4baa5601ed650a56b821e266ef0c0d9cc GIT binary patch literal 192512 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�|E}~iBJT{unWB(}k ziNLX>0z>wsalffJZ$?6AIe zbas4Yv=iuvJAYU$=R2kjB|4@AaUD~#GS;QFvCb(*z6+vcxxrC#D~3bMkbRJDkzL40 zd5tGepe1O+e@B}%sUL@XG~2gmQZ|+wxS|zu3>2gFNE2|q$0;5ZZsi?WvFa*TBbjL2 z=MGHI07T^Y?w}~sq~2f~p{{hw&Oug*126Pic=<5R%>@y^mStG-nHXzcn4iAP(<9C( zp5NF3=Op9Sknjr2&TNcT)vn6zUGBQeDK#J?jm8$S(T1!$N{fBWl`6ze*&Su~PS||| zt9}o~76bv^pDy zoeK5Z-X+d6)L`@seY?T#Qjl^MIH*c5l9YOA!60_6v8Ae~<&>*y2e8;tcv zi%Onct_RQ?xhb#}t%<-ckfjg;5loX;$_i(7Iz1z95n3>v1unGAAm~)bR6RvJp(|j@ zxE4N)rxRNz>K=aHK)a4>imU@3USz8d!SCfm#1B)R^Hi+mqz!69f@9)9mbFcZXBovv zm?3XqQ>=Pnv6madOM2aC&aFAEq6Krsg;#1&HI_EPY9cuU2_0=C^(+W|#HfiK1itqf z0*z;ycYzH%)>CMP>M;7N_-#ozK4J528S_XJ1~V+RFm7%VzgAf{+xY#ck=TgC|6N4J4`7%OnPa?Ud;T^7*FhK!&f)K1P|#=4E;&=P~}>%7znc$X{aKWpbG)};;7%$9sBBs89VU|ZWL z$$qjYoC63X#DGH$kx$i82Wujq!q3hPD9r94hk3fx29FAI-7`fzSwpvU))b`=#yAqb zh%=;elzp6Y!E|lgNiFl-WWZxNQwqf<%5ny_q@U>N)8u}*s}4_v^);k$h6zcGt)G}G zGHN6)d$dOKUYU)D-arVy0wQBtGUnWM`7TI3USeq}hg%-6%%>*1aCO&jjxEUhoU7Y$ zf1htt+9M`&Y~-oze;MUFd7kPFIEgKNmeGDJ#N#TUCbDIL<->g4>noTWfF%3mX5mmy z@a&QJ4-ABj{M{*S0UfZ zz>ES)1=4(_gq*739F*tND1$o?kc;$P5Srx(R}fx~^enbc%5C7+WL+-Y43E|l>ql#Y z{D8lc#*q>lw-Cn-@`4KQOL_{sL5$m1^fao4!0r2^J@lqa_R_rU zd*O63YSmk4r@d~@FeMunKxLK-<`c#|@d?B#4_2AZ`Ii*jcgK2Yf$ShgwE>3-%+p@K zgG;P`CmmNjNZ&HgSI~~)T-+WY?yJq9*lmX5bBEE7O-bJs7vrfM75TIFO8GHwJCr4I!M_Eqm>pp6A*cczH$h^6u_w7jB{Psty z?<4T@SC3vZDT*|3B>wvmAmHjf6rx*4@2BVJoi%eYocxpa9B!nMdF(QOmwX+eRETRK zUCIqm`=K5TEutKjbhx7ULweiAe=0?k2gQ4)dbri|9%qhDyf$O=m=CO-bxrlq3^br8 zr~!7P5pzZBI+%vyV-M>5n3kMCPssPI9q=;et5d&J$wVkARdXhYQ=}(q|7?Yv*{u9% z<;fu(FVvp9md=3xHDu-!kB1s@NiagBch5OvUUItkHu~c|I$8^3R7z7`GmaVnr4Pq} z-)K)iXV`$GSuQsraR% zA%|Q=Yt$LoD*Q_4*uOfUq!_CDii02_tNIFMKlV}>^999$&~`Wr8R__i_q&{tk$sfD zBwl(@--$5?j%2Z0&pc&@)`Ra`NF|3uDzW!FAFY9K;uNe-G;-2uB2pj|@ZR`&&ioXV zke>!(sS-(5j&8g-NvcB7-Oc5MK5H72ni5+dt=~EchXLlWX-Mq-mygyQ=hI==(ZE8E zN}z;(64Ig@a5vBq%rt(pIX;W_sn?HTWNc;3TrroZefQ6zE^;R4n-BSn84QWVJm>f}ITuMO z94#SZZSw&V-vsi2d*Qyv!{q3ZG_=Zt>-Y#-S?TcFJpb}izKb^UfIj(Jj-=5&Pp=|n zG<6vDVbQ9h{W^^|ZV9v$XrAanL>fHhv3#Qd_aaa>>RsgK z6nI07%4fqQo>j9ePS_o)$6TDLI>m}?&AFNxrisa3aCA;(>N=f!KgZ7C*YxmITJIEv z9J&XNt_~5Kh=HMx*ip2zS>pru+*-w6h?$9z1$6cxj5bd?%vQjL^_s_Dm4VWSLeI_` zMnVhKe5|WC=;cY|R=(-iuiC}8n_kt6=@n+*R^fxdwfLx;Xv3bU9l(iHRl!Z2PQW&D z(w|2Qgu19&t%R3br=o7hdN?r~=CpYpxoBTI3S}wU%jyvY#Xe0#_z=~D;gCtfI~ zhk4`P;r7<)m$CI;p`>D)ZmgbP9_+{aar84WK-l4KP=w8M#CJcsIG5urkf|Wwg=MtU zL{72@?UlnWVu{0~u)MiaM&1xh&cdg!nhzm!$k+ymjm&codPWg&@;E{qAU-M+ahOiJ zAZ75Md7e_taes385K5tB;kr-Au83K##se&_3vsrmUZe+HR zynCDhw&iS9(B_5CIO-j$ExOs^ECv>5&ljkGZ9O^`ggH^(~m* zFB;T#CfPdOFRqdF^f5xmUWlzBW&x}b8*_|_?-??Fc-}W`0oP# znJc#dAKGTb@;L5LdT|a^(@~BSKzfe6nH0jABBV60v!19p(qpJ2P`DLL1^LOPDbZP` zgwj^$z5S!q*Gca|&HWA!%q6#K+o_e2Ytfsx1z6C(6wbX_QVoP7WV*^lg-ED*a27-R z(4{#T5EDsxs@sQjWIjeb#fC=6d}Wr zsHVxXoB{SNg43C*#IdJ@MO>P3X1ULc=dB1OGsHeI({5xk9{gH92f0m2*vs8UpzT`IU~M<}vPNmh9wPsvSL;^O+Y(iKME~Wv+($0r|ILQM)Zj-aw6;n8FrGzpsb|^5f<;T77%J z%I>vKtqzVvM|UZQU$EPflua|P8!J4B5v$2_77f!}X-5?TeO&||!A`c$FI+^4FC}~L z;9yT2L#OE1MGp#fw@@1P)Lg2fZaQz2wRpzla}x=;p@q}IDPo?H-J^ z8)s6v2Z_D+3x64%=Bzu#P7QftH8HIrn63=ZsZzm^TFR20;n6+68yu;U;@hhw56a&u zBCw@l@rJM`HFYU+oPbfY)GI&)rsEX^dMEl2uT=>T#fl50I!Y;?3Y=J~YJa69RAl-T;w=CZwh$93HdC^kjhdQlx6Io2GTHRgxk^(PJHf%hqrD3?tsswavNzoVXKmjYQwkvrY3eUJkeSTGe6vjuzleD6_{7+B7=i^y=yQ!BAsf>Kl|}WZYx$6`zM?Y(^+!$s%|f0gY7aUm^|HskA> zYKp09r5*-llI9Xe6UTwL2ynd(JreM$zZ^o%&EGj0ryIF9-@1s#a<|d2B*#N&wsWKc z)B;rySg(gz;$=tKP6#=bB|fT<=5Ge=m=_P?2kio>ldcTb!rXrAg&3cuz~xN1zL4kY zs7U?MY7|!G4#b<6<9-j0+G7F%p!X_ury7S1ou;-q*$#Q0RSNrOUeY}%TqLKg zb9KdcS{}Fu^vWzC6P|4%1lrGObhCZU^Km?Kc;+C;xg};pep^anOz8X7zLKIT>nKm# zX&c%Geq55X;v}7FIl5jJ$9qRvAw?<2VOjKIB<^<7eGX?)GbO0GdKB5r5j;RHFREtQ zT{{ZZ)$Ve{=`!@R>i$hth^aG;o9iMqNH^+v?Q~Uj!)%Wefd}-VDbXr9YpYxiCaTrxQ85^geP+Kx56)z9TA)aE-F$j-P&aR<{l&C7v z6&pf~HrTqTlD-`#-Fb-PNbI}T#!)-nPGj8IyYQJexuYla-f{lDHhdJ9;aQC3!R{;V z$!YAkgCS<2*v`|4XVk7Sdo@ZzH;Q&hDE2rl!|!Wy+L=Ge=N-I+N;^L`6YX3!ToaF< zHq}0~Zvny&rGhiKldA>uDZqj`iPOpn<5p38jogjEoMAu0{RJWI){#c&5i4ZJ%+pnT zs{^{-UL{qUo)Z_MI#S2U%oU}( zIgH8e!6cO{k0l^+@_40J9Sy+M>~V+W+nAAU;nkk!d5Y|m zQMwMJd!XE|UNds=m_ZRpb#5ky=bSlfW1gClvAJ1OyO6LC@|fNazP!0~@!jdK{__u- z`}eP0GMV3b`-``p82{eiN}FUNKbRlPm>zv&Uu+`Tmr1?*Hxee5Oc;}T+~9$KCWSAP z>f_@)AB;@hoW|o(gnIf$GU)Lk2F+u`8Ov#|mM9!oWBN_RxCzHt}`;t9<`Df4< zyhnOdeIp|oL<}bT`jdUVJ*Q0)|FYBs0tdPeY_HN9++t@W9nUi_h@9{lS=)ySPd*Hi!NL)7>o{t(~aYm)u_z36`~ z*_T5mK&B^=%VrUCBH5Qk%n7!b129a!gzlD7rx9S>@W~Hb_A~wHzXXU{+3Y}}H(z1R09C3F>3HmY7X$sY zEwT4~TVn6~#H*7`|9+}(XzyQSS<~L{=J(#q%pKFY|GNj{+VElNe2mCC(=gW&l5fkv-y=M~!H0ytjWhx%EiXclS>Kb_K4Hu17ahVI_~SsUbe{e4sW|m*4v!19T!lh(BQMfCCU8gt+&o zfGVea1iVtm_yLDCl1UA)0+jtDKE8*?{s}%FMlN8>9}#Hs!O@~GGwh`>u%Xvk!_ey> z{nttQuj?=#C2#u@llVm8XEgp94s8F^{J<+iE|N>;0Qi&y`Vo;IWQ_349B3k(G>0zF$|5T5^D%0`RL&T z=TS^5$Hzl_Jj_RO9ghMZC;3QV&jUmT9;o1Q>J?VC#|Qqy|KMFIQ^4a4<37#@bOV!m zjE@`Fds29$GkA=S;*m(=(bvaE8js#yKKdZxIQt0*t|Tc0aKbBXdW3`+sbm6@#|JXx zdNL@1{=AYJWIH)Lh{id=pIjz`LCXY=>I9C0u_Ory6uFk{ODFpV1g4`2NcjZFIY9)% zOy7`FH<<5+1Ip!OyE`p~x|#Rz6(Rm-e0_p0PxrAXU<4OmP03=AQ2V?-9H zZ{t~rVN#v)z=xqb^yRk%XQ&$t?cd|$%bN2YY3s{)0%PP^)ONp2d?`x1U&fQEd=`Nb zXkaflK+(*A@cN9`_DnZF4 zBuNrLyqDkq*?#ClNF3V#WrR@lz5KpPl6}jI-cT5ZXNBdu66gr5q z5)^$aO&Is{F@O$b(12!sms0oyDQ;haSu!gmzpE7>?%`~9(4{9I&OXczXL8!NcO)Z( zAO^bs?!(k>()ibpe*+-rY$i*UD#7uf0GmQ6V=$~c2ms#zh-`1)2tF`N_X$Mu;{C7l z@tb|8QE^e26-a+qV9tPr`7d)KzekX3%Vw!yu=CKPkoD&|sThrv;|I|D=e41C5E51)n%x#T z%~sTf?~tQqSzC%P&>?0JJmwGB3ouwfzJkKws(bI6XFz;=#!%k&CGo)b&FaJ$Sp%f5 z`FH?{dd1|;feJp{-E+3zn48T{AVw}{qJ}G=D)r5_FU@L zZ?CO?Y-YXuZ_??W{Kqrk!*~zl&Dr>qeopD$w}$q9KM5r~oyerpP^7_+dhnM?gKzRL zInsksLJmEZ{`d&A>Jf(ZkJO#vKmI+M9+GeU;^@|WqufB1u5kFMg)io>qqD=j%PnMcwOF;V|U zh6)Tkk$#jfF-!b-7}c9*ed#oqFGiM253ozp2Hv(91htf8e)|XTiGUv3?*$ZLO{9DJ z`-L-qK$y=b^RMvz8s6Z#`D^)czHaENnE%XU>A{g4_)Wf)FF}3hBZL2iREG9HhU&=~ zdcaH}0|?0^QmG$iXl~?dJ^c?u^B8%`JOyP8`3xvwWN80n28ny$LKyi^U`j`N@(WbM zda|e@zdw|}l7E)-lFPt+NCTOnN`kF}vEw6OKb0^~EwpNd5`G00_rkC8236dnh>I-? zxH58=*GHSabPsZ7SsKC%wnWAxhhAqLQrGK4uMects56_*Uq%jCE5tF3g5ddz0a!-* zApkJM{uFFQ!Vj=VD8EDv8Mep%6?73^^*UT(7*hfu*)EmJ_lo2RNqI_gGdM5gj0!0 z17U7pdUED&(*hJB--BGa;q*hO4f-uopll(5xrS=n4-fS9v+6xAqKaJw@ zN9<)J2@EP5xe{u%>V>l|ecg7ygng0)t@aD-UPVy}}$bPo^IO!*hRRVE%6? zO?nKYY(*SUW@MP?JPZwe=qpgphraUhtm|5D=JE6+@w#lSpzCCQUf7=SJNX8~lQ%dX zC+zjXESTaKVFuv;!E_4TXdl8K`pG*4KU6pX< z13?9TsNxE=hnY}*Njij%*#o_jZXu2+UxPjN1Tn+@v`|IvPWC8yI$=%)$+&rzmqs_- zum1UrjvD07Wc?YYNn9Z;bQZBl$3}U}Y%%(ktazS?R`jyjgR1&e!hDh)6WX)C7O4c& z+3d-L8D?I+ZdYrJH|pp<=zZ1Q`s>H|2}?y){AyAIw_bP2;(G70@OIrU*&JBg0kMwX z-M}v^`6eTl5JIC%g`)}cDGpJ7=gfkG7yY`yc2s;OVNMH7!itOd6`o!EtQv&Cf+ z`LT9rN7wy!>5eet&w+!0*WUs6&+p%t=T8SBqY(@fq?;T7arHx4NcZ81w+r;s*j8eK zKn0r_di|kve|~>kmkocBeL|9kUeDUEUOlr^M8zK0U# zM2SD<=6;INNa0;e%Szer2#D^(-I$>m+`m5nMhjCQKZu72&*70Ybof1(Rv_2?`TVEp zfCQ`D|1MPUeCe;HA4$Rr#a};Ebm6f8O)ir~UqS7|&<6w@G!D=;aAlNC6%xZ#p`bO9 z+w2z^yA78DGE0!G+UgpaY#MGwG>O_FPqQw}I)=$|bL3rv`Muvnk8=RsAQYTISWn-D zT*hE%a%90p;V>6<5YJq?Pt##cARo9@BLBka^ds3Uj7l}j@OoDg@y=hN0rV_YH2xFd ze>eNd^wX$zU|=8%%_f;0$U+uCSO^p{{iqpc5ymAJ<6!>e(EcwF@OPjOStwj_+=xO^ zetx1uDjEY_kv-Ud7j;7{^+4H>7vA8XSOUNt!FWRoy+07l^aim_u;*VH+W%GH5+q74 z|0b~x;|7e9G6&oA^8qH*7qi(MOo2Y2JQQjuHBk2O&Vsv(_C`SpAp-G(yg6!)nI5f* z*)eg*n@0ALVg3gsLnDu;QMH>`&L-yr!0Uyehiinkm>EczzR|OnUpR}CbLSK0O!P}} zh4Z7M_}zrj(MyF&{f%1T`pzBvqSDT%3!iOnGzvFsb^P$1F^?w9L*=O|eo+8F-mzLc z+rTgGm=g(;#_z7xcze8g82714I=IqIeOV(;=?8yb(in2oi2{E03Nvu35Zv`%*sL#W z7IMI#lEPYZr*L+*G+&tBfg;13+6(8;;+B$3g03h0L82wheDbkZcb2win~mshbo?Me z^KL6)zWawXO!e>287{c5`1=PzKA(c0cHSv&ZdPzryxD54;HLcA+0{+lJ%GOtpEZS7 zBy{{ZhQKidjv;Uifnx|9L*N(!|9?Or!PQ`cCBMD+ctzX99?Z^o=DUV}uYE6R_ENso zUTPd4w{X^H5zi9t8K~l()j6E9!Ou?PIgK#?{zK}2{yA3`77%_f(JODRdcG{FSc|~h zYkL}5#4CYXxf635yP~+iS9iBHCBrjPY96WF6V^hyKLepP{Oi>B;G#^RPuyk3J!|V- zYWiKtGm3HRf8*H61{mPxi>FXFz8ebriE$eqcbjqNRt=#ka|+M){a|i~W&A|5F|Ppf zu1@{Uh~PvL>Mo37MU#oUxI!UF0d{J7go_p9?)U(TaNLco~IW*}%UzBiNUqsVy~H+r0vf8%&^BNy<* z45J)pD?F{__MII(PCxdr-)FH~ktZ97m}gNh_v7k)J)9k$QXvF*$e%FkjN^znw`17H zsG&<3Wd&t;D@XymqIa+-k#+Jk75D#r7WHnR_XW8*gSf}Nz{dP+Tl#)SAnIK3kHH36t`zb?;e=sAPK%AG|^4$oM}@!v57jv;Uifnx|9L*N(!#}GJ% zz%c}lAh literal 0 HcmV?d00001 diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/ICSharpCode.SharpZipLib.dll.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/ICSharpCode.SharpZipLib.dll.meta new file mode 100644 index 0000000..6fe3419 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/ICSharpCode.SharpZipLib.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 63a064c5cf0d4b044b60915a37dace14 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Newtonsoft.Json.dll b/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/Newtonsoft.Json.dll new file mode 100644 index 0000000000000000000000000000000000000000..7fdad2ef7294a7644e9f91ac3d2a6b002faf8a4c GIT binary patch literal 690688 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�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 e`IWxaj=!(h8i&;NY(&5L`vJ<{ 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

RQRZ3Esm;B5omHsEao-iN^Z5O^N~ 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

$zRVH~lAdW5HFT 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

tFxr);*9+UEHjJ>20jJlv} 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
  • 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%0A|)f(pQ^H-LQw{PD>{lGWcDQ~-Ok;=?*0m#c) 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⩔=zkIsh#L( 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 literal 0 HcmV?d00001 diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/System.Data.dll.meta b/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/System.Data.dll.meta new file mode 100644 index 0000000..4690ff4 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/Plugins/System.Data.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 64033216c8176a9418319ef7592896b4 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets.meta b/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets.meta new file mode 100644 index 0000000..d62f9fc --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a65ba65706d028a469f14da5bc538923 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets/WebAddress.json b/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets/WebAddress.json new file mode 100644 index 0000000..3c5cad1 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets/WebAddress.json @@ -0,0 +1 @@ +地图弹出框=http://vpp.shiyuancloud.com:1443/api/vpp-operation-service/screen/mapRegionSummary/ \ No newline at end of file diff --git a/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets/WebAddress.json.meta b/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets/WebAddress.json.meta new file mode 100644 index 0000000..7efa2c3 --- /dev/null +++ b/u3d-ShanDongVirtualPowerPlant/Assets/StreamingAssets/WebAddress.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 86a3364d8190c614aa749c5712810f78 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/u3d-ShanDongVirtualPowerPlant/ProjectSettings/ProjectSettings.asset b/u3d-ShanDongVirtualPowerPlant/ProjectSettings/ProjectSettings.asset index 7104790..4dc5da6 100644 --- a/u3d-ShanDongVirtualPowerPlant/ProjectSettings/ProjectSettings.asset +++ b/u3d-ShanDongVirtualPowerPlant/ProjectSettings/ProjectSettings.asset @@ -923,4 +923,4 @@ PlayerSettings: hmiLoadingImage: {fileID: 0} platformRequiresReadableAssets: 0 virtualTexturingSupportEnabled: 0 - insecureHttpOption: 0 + insecureHttpOption: 2 diff --git a/u3d-ShanDongVirtualPowerPlant/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/u3d-ShanDongVirtualPowerPlant/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache index db043cc2590bb7ffbcda27ac03b2807e5613c32e..a9ff1d4f78d70ed7c7392dfa1831f885e7993786 100644 GIT binary patch literal 41351 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