From 8a877ed1d8d1f5a7c903c5c9bd69a2f7b739fa8e Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:19:18 +0700 Subject: [PATCH 01/58] feat: delete plugins, must load by nuget --- Plugins/LiteNetLib.meta | 8 - Plugins/LiteNetLib/BaseChannel.cs | 48 - Plugins/LiteNetLib/BaseChannel.cs.meta | 11 - Plugins/LiteNetLib/ConnectionRequest.cs | 134 - Plugins/LiteNetLib/ConnectionRequest.cs.meta | 11 - Plugins/LiteNetLib/INetEventListener.cs | 272 - Plugins/LiteNetLib/INetEventListener.cs.meta | 11 - Plugins/LiteNetLib/InternalPackets.cs | 133 - Plugins/LiteNetLib/InternalPackets.cs.meta | 11 - Plugins/LiteNetLib/Layers.meta | 8 - Plugins/LiteNetLib/Layers/Crc32cLayer.cs | 41 - Plugins/LiteNetLib/Layers/Crc32cLayer.cs.meta | 11 - Plugins/LiteNetLib/Layers/PacketLayerBase.cs | 17 - .../LiteNetLib/Layers/PacketLayerBase.cs.meta | 11 - Plugins/LiteNetLib/Layers/XorEncryptLayer.cs | 60 - .../LiteNetLib/Layers/XorEncryptLayer.cs.meta | 11 - Plugins/LiteNetLib/LiteNetLib.asmdef | 13 - Plugins/LiteNetLib/LiteNetLib.asmdef.meta | 7 - Plugins/LiteNetLib/LiteNetLib.csproj | 62 - Plugins/LiteNetLib/LiteNetLib.csproj.meta | 7 - Plugins/LiteNetLib/NatPunchModule.cs | 258 - Plugins/LiteNetLib/NatPunchModule.cs.meta | 11 - Plugins/LiteNetLib/NativeSocket.cs | 301 - Plugins/LiteNetLib/NativeSocket.cs.meta | 11 - Plugins/LiteNetLib/NetConstants.cs | 75 - Plugins/LiteNetLib/NetConstants.cs.meta | 11 - Plugins/LiteNetLib/NetDebug.cs | 92 - Plugins/LiteNetLib/NetDebug.cs.meta | 11 - Plugins/LiteNetLib/NetManager.PacketPool.cs | 82 - .../LiteNetLib/NetManager.PacketPool.cs.meta | 11 - Plugins/LiteNetLib/NetManager.Socket.cs | 728 - Plugins/LiteNetLib/NetManager.Socket.cs.meta | 11 - Plugins/LiteNetLib/NetManager.cs | 1821 --- Plugins/LiteNetLib/NetManager.cs.meta | 11 - Plugins/LiteNetLib/NetPacket.cs | 160 - Plugins/LiteNetLib/NetPacket.cs.meta | 11 - Plugins/LiteNetLib/NetPeer.cs | 1398 -- Plugins/LiteNetLib/NetPeer.cs.meta | 11 - Plugins/LiteNetLib/NetStatistics.cs | 81 - Plugins/LiteNetLib/NetStatistics.cs.meta | 11 - Plugins/LiteNetLib/NetUtils.cs | 190 - Plugins/LiteNetLib/NetUtils.cs.meta | 11 - Plugins/LiteNetLib/PausedSocketFix.cs | 57 - Plugins/LiteNetLib/PausedSocketFix.cs.meta | 11 - Plugins/LiteNetLib/PooledPacket.cs | 32 - Plugins/LiteNetLib/PooledPacket.cs.meta | 11 - Plugins/LiteNetLib/ReliableChannel.cs | 337 - Plugins/LiteNetLib/ReliableChannel.cs.meta | 11 - Plugins/LiteNetLib/SequencedChannel.cs | 114 - Plugins/LiteNetLib/SequencedChannel.cs.meta | 11 - Plugins/LiteNetLib/Utils.meta | 8 - Plugins/LiteNetLib/Utils/CRC32C.cs | 150 - Plugins/LiteNetLib/Utils/CRC32C.cs.meta | 11 - Plugins/LiteNetLib/Utils/FastBitConverter.cs | 175 - .../LiteNetLib/Utils/FastBitConverter.cs.meta | 11 - Plugins/LiteNetLib/Utils/INetSerializable.cs | 8 - .../LiteNetLib/Utils/INetSerializable.cs.meta | 11 - Plugins/LiteNetLib/Utils/NetDataReader.cs | 673 - .../LiteNetLib/Utils/NetDataReader.cs.meta | 11 - Plugins/LiteNetLib/Utils/NetDataWriter.cs | 381 - .../LiteNetLib/Utils/NetDataWriter.cs.meta | 11 - .../LiteNetLib/Utils/NetPacketProcessor.cs | 267 - .../Utils/NetPacketProcessor.cs.meta | 11 - Plugins/LiteNetLib/Utils/NetSerializer.cs | 738 - .../LiteNetLib/Utils/NetSerializer.cs.meta | 11 - Plugins/LiteNetLib/Utils/NtpPacket.cs | 423 - Plugins/LiteNetLib/Utils/NtpPacket.cs.meta | 11 - Plugins/LiteNetLib/Utils/NtpRequest.cs | 42 - Plugins/LiteNetLib/Utils/NtpRequest.cs.meta | 11 - Plugins/LiteNetLib/package.json | 11 - Plugins/LiteNetLib/package.json.meta | 7 - Plugins/Microsoft.Bcl.AsyncInterfaces.dll | Bin 21064 -> 0 bytes .../Microsoft.Bcl.AsyncInterfaces.dll.meta | 33 - ....Extensions.Configuration.Abstractions.dll | Bin 21368 -> 0 bytes ...nsions.Configuration.Abstractions.dll.meta | 33 - ...rosoft.Extensions.Configuration.Binder.dll | Bin 24952 -> 0 bytes ...t.Extensions.Configuration.Binder.dll.meta | 33 - .../Microsoft.Extensions.Configuration.dll | Bin 27000 -> 0 bytes ...icrosoft.Extensions.Configuration.dll.meta | 33 - ...sions.DependencyInjection.Abstractions.dll | Bin 37752 -> 0 bytes ....DependencyInjection.Abstractions.dll.meta | 33 - ...crosoft.Extensions.DependencyInjection.dll | Bin 64888 -> 0 bytes ...ft.Extensions.DependencyInjection.dll.meta | 33 - ...rosoft.Extensions.Logging.Abstractions.dll | Bin 48504 -> 0 bytes ...t.Extensions.Logging.Abstractions.dll.meta | 33 - ...osoft.Extensions.Logging.Configuration.dll | Bin 20344 -> 0 bytes ....Extensions.Logging.Configuration.dll.meta | 33 - Plugins/Microsoft.Extensions.Logging.dll | Bin 34168 -> 0 bytes Plugins/Microsoft.Extensions.Logging.dll.meta | 33 - ...nsions.Options.ConfigurationExtensions.dll | Bin 18296 -> 0 bytes ...s.Options.ConfigurationExtensions.dll.meta | 33 - Plugins/Microsoft.Extensions.Options.dll | Bin 50552 -> 0 bytes Plugins/Microsoft.Extensions.Options.dll.meta | 33 - Plugins/Microsoft.Extensions.Primitives.dll | Bin 38264 -> 0 bytes .../Microsoft.Extensions.Primitives.dll.meta | 33 - Plugins/NetCoreServer.meta | 8 - Plugins/NetCoreServer/Buffer.cs | 183 - Plugins/NetCoreServer/Buffer.cs.meta | 11 - Plugins/NetCoreServer/FileCache.cs | 491 - Plugins/NetCoreServer/FileCache.cs.meta | 11 - Plugins/NetCoreServer/HttpClient.cs | 417 - Plugins/NetCoreServer/HttpClient.cs.meta | 11 - Plugins/NetCoreServer/HttpRequest.cs | 849 -- Plugins/NetCoreServer/HttpRequest.cs.meta | 11 - Plugins/NetCoreServer/HttpResponse.cs | 945 -- Plugins/NetCoreServer/HttpResponse.cs.meta | 11 - Plugins/NetCoreServer/HttpServer.cs | 105 - Plugins/NetCoreServer/HttpServer.cs.meta | 11 - Plugins/NetCoreServer/HttpSession.cs | 193 - Plugins/NetCoreServer/HttpSession.cs.meta | 11 - Plugins/NetCoreServer/HttpsClient.cs | 423 - Plugins/NetCoreServer/HttpsClient.cs.meta | 11 - Plugins/NetCoreServer/HttpsServer.cs | 108 - Plugins/NetCoreServer/HttpsServer.cs.meta | 11 - Plugins/NetCoreServer/HttpsSession.cs | 193 - Plugins/NetCoreServer/HttpsSession.cs.meta | 11 - Plugins/NetCoreServer/IWebSocket.cs | 92 - Plugins/NetCoreServer/IWebSocket.cs.meta | 11 - Plugins/NetCoreServer/NetCoreServer.asmdef | 3 - .../NetCoreServer/NetCoreServer.asmdef.meta | 7 - Plugins/NetCoreServer/SslClient.cs | 1114 -- Plugins/NetCoreServer/SslClient.cs.meta | 11 - Plugins/NetCoreServer/SslContext.cs | 81 - Plugins/NetCoreServer/SslContext.cs.meta | 11 - Plugins/NetCoreServer/SslServer.cs | 582 - Plugins/NetCoreServer/SslServer.cs.meta | 11 - Plugins/NetCoreServer/SslSession.cs | 838 -- Plugins/NetCoreServer/SslSession.cs.meta | 11 - Plugins/NetCoreServer/TcpClient.cs | 994 -- Plugins/NetCoreServer/TcpClient.cs.meta | 11 - Plugins/NetCoreServer/TcpServer.cs | 561 - Plugins/NetCoreServer/TcpServer.cs.meta | 11 - Plugins/NetCoreServer/TcpSession.cs | 777 -- Plugins/NetCoreServer/TcpSession.cs.meta | 11 - Plugins/NetCoreServer/Utilities.cs | 164 - Plugins/NetCoreServer/Utilities.cs.meta | 11 - Plugins/NetCoreServer/WebSocket.cs | 620 - Plugins/NetCoreServer/WebSocket.cs.meta | 11 - Plugins/NetCoreServer/WsClient.cs | 443 - Plugins/NetCoreServer/WsClient.cs.meta | 11 - Plugins/NetCoreServer/WsServer.cs | 174 - Plugins/NetCoreServer/WsServer.cs.meta | 11 - Plugins/NetCoreServer/WsSession.cs | 398 - Plugins/NetCoreServer/WsSession.cs.meta | 11 - Plugins/NetCoreServer/WssClient.cs | 446 - Plugins/NetCoreServer/WssClient.cs.meta | 11 - Plugins/NetCoreServer/WssServer.cs | 177 - Plugins/NetCoreServer/WssServer.cs.meta | 11 - Plugins/NetCoreServer/WssSession.cs | 398 - Plugins/NetCoreServer/WssSession.cs.meta | 11 - Plugins/System.Buffers.dll | Bin 27840 -> 0 bytes Plugins/System.Buffers.dll.meta | 33 - Plugins/System.Memory.dll | Bin 144016 -> 0 bytes Plugins/System.Memory.dll.meta | 33 - ...System.Runtime.CompilerServices.Unsafe.dll | Bin 16776 -> 0 bytes ...m.Runtime.CompilerServices.Unsafe.dll.meta | 33 - Plugins/System.Threading.Channels.dll | Bin 45944 -> 0 bytes Plugins/System.Threading.Channels.dll.meta | 33 - Plugins/System.Threading.Tasks.Extensions.dll | Bin 25984 -> 0 bytes ...System.Threading.Tasks.Extensions.dll.meta | 33 - Plugins/UniTask.meta | 8 - Plugins/UniTask/Editor.meta | 8 - Plugins/UniTask/Editor/SplitterGUILayout.cs | 62 - .../UniTask/Editor/SplitterGUILayout.cs.meta | 11 - Plugins/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 - Plugins/UniTask/Runtime.meta | 8 - Plugins/UniTask/Runtime/AsyncLazy.cs | 245 - Plugins/UniTask/Runtime/AsyncLazy.cs.meta | 11 - .../UniTask/Runtime/AsyncReactiveProperty.cs | 644 - .../Runtime/AsyncReactiveProperty.cs.meta | 11 - Plugins/UniTask/Runtime/AsyncUnit.cs | 26 - Plugins/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 - Plugins/UniTask/Runtime/Channel.cs | 450 - Plugins/UniTask/Runtime/Channel.cs.meta | 11 - Plugins/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 - Plugins/UniTask/Runtime/External.meta | 8 - .../Runtime/External/Addressables.meta | 8 - .../AddressablesAsyncExtensions.cs | 401 - .../AddressablesAsyncExtensions.cs.meta | 11 - .../Addressables/UniTask.Addressables.asmdef | 22 - .../UniTask.Addressables.asmdef.meta | 7 - Plugins/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 - Plugins/UniTask/Runtime/IUniTaskSource.cs | 124 - .../UniTask/Runtime/IUniTaskSource.cs.meta | 11 - Plugins/UniTask/Runtime/Internal.meta | 8 - Plugins/UniTask/Runtime/Internal/ArrayPool.cs | 150 - .../Runtime/Internal/ArrayPool.cs.meta | 12 - .../UniTask/Runtime/Internal/ArrayPoolUtil.cs | 115 - .../Runtime/Internal/ArrayPoolUtil.cs.meta | 12 - Plugins/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 - Plugins/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 - Plugins/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 - Plugins/UniTask/Runtime/Linq.meta | 8 - Plugins/UniTask/Runtime/Linq/Aggregate.cs | 318 - .../UniTask/Runtime/Linq/Aggregate.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/All.cs | 108 - Plugins/UniTask/Runtime/Linq/All.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Any.cs | 136 - Plugins/UniTask/Runtime/Linq/Any.cs.meta | 11 - Plugins/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 - Plugins/UniTask/Runtime/Linq/Average.cs | 1524 --- Plugins/UniTask/Runtime/Linq/Average.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Buffer.cs | 345 - Plugins/UniTask/Runtime/Linq/Buffer.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Cast.cs | 53 - Plugins/UniTask/Runtime/Linq/Cast.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/CombineLatest.cs | 11372 ---------------- .../Runtime/Linq/CombineLatest.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Concat.cs | 164 - Plugins/UniTask/Runtime/Linq/Concat.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Contains.cs | 50 - Plugins/UniTask/Runtime/Linq/Contains.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Count.cs | 144 - Plugins/UniTask/Runtime/Linq/Count.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Create.cs | 174 - Plugins/UniTask/Runtime/Linq/Create.cs.meta | 11 - .../UniTask/Runtime/Linq/DefaultIfEmpty.cs | 142 - .../Runtime/Linq/DefaultIfEmpty.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Distinct.cs | 277 - Plugins/UniTask/Runtime/Linq/Distinct.cs.meta | 11 - .../Runtime/Linq/DistinctUntilChanged.cs | 662 - .../Runtime/Linq/DistinctUntilChanged.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Do.cs | 258 - Plugins/UniTask/Runtime/Linq/Do.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/ElementAt.cs | 58 - .../UniTask/Runtime/Linq/ElementAt.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Empty.cs | 47 - Plugins/UniTask/Runtime/Linq/Empty.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Except.cs | 116 - Plugins/UniTask/Runtime/Linq/Except.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/First.cs | 200 - Plugins/UniTask/Runtime/Linq/First.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/ForEach.cs | 193 - Plugins/UniTask/Runtime/Linq/ForEach.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/GroupBy.cs | 923 -- Plugins/UniTask/Runtime/Linq/GroupBy.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/GroupJoin.cs | 612 - .../UniTask/Runtime/Linq/GroupJoin.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Intersect.cs | 117 - .../UniTask/Runtime/Linq/Intersect.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Join.cs | 728 - Plugins/UniTask/Runtime/Linq/Join.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Last.cs | 240 - Plugins/UniTask/Runtime/Linq/Last.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/LongCount.cs | 144 - .../UniTask/Runtime/Linq/LongCount.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Max.cs | 200 - Plugins/UniTask/Runtime/Linq/Max.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Min.cs | 200 - Plugins/UniTask/Runtime/Linq/Min.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/MinMax.cs | 3763 ----- Plugins/UniTask/Runtime/Linq/MinMax.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Never.cs | 56 - Plugins/UniTask/Runtime/Linq/Never.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/OfType.cs | 61 - Plugins/UniTask/Runtime/Linq/OfType.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/OrderBy.cs | 558 - Plugins/UniTask/Runtime/Linq/OrderBy.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Pairwise.cs | 128 - Plugins/UniTask/Runtime/Linq/Pairwise.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Publish.cs | 173 - Plugins/UniTask/Runtime/Linq/Publish.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Queue.cs | 103 - Plugins/UniTask/Runtime/Linq/Queue.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Range.cs | 75 - Plugins/UniTask/Runtime/Linq/Range.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Repeat.cs | 68 - Plugins/UniTask/Runtime/Linq/Repeat.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Return.cs | 63 - Plugins/UniTask/Runtime/Linq/Return.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Reverse.cs | 78 - Plugins/UniTask/Runtime/Linq/Reverse.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Select.cs | 760 -- Plugins/UniTask/Runtime/Linq/Select.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/SelectMany.cs | 892 -- .../UniTask/Runtime/Linq/SelectMany.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/SequenceEqual.cs | 87 - .../Runtime/Linq/SequenceEqual.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Single.cs | 230 - Plugins/UniTask/Runtime/Linq/Single.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Skip.cs | 69 - Plugins/UniTask/Runtime/Linq/Skip.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/SkipLast.cs | 159 - Plugins/UniTask/Runtime/Linq/SkipLast.cs.meta | 11 - Plugins/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 - Plugins/UniTask/Runtime/Linq/SkipWhile.cs | 379 - .../UniTask/Runtime/Linq/SkipWhile.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Subscribe.cs | 536 - .../UniTask/Runtime/Linq/Subscribe.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Sum.cs | 1244 -- Plugins/UniTask/Runtime/Linq/Sum.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Take.cs | 124 - Plugins/UniTask/Runtime/Linq/Take.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/TakeLast.cs | 175 - Plugins/UniTask/Runtime/Linq/TakeLast.cs.meta | 11 - Plugins/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 - Plugins/UniTask/Runtime/Linq/TakeWhile.cs | 342 - .../UniTask/Runtime/Linq/TakeWhile.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Throw.cs | 54 - Plugins/UniTask/Runtime/Linq/Throw.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/ToArray.cs | 60 - Plugins/UniTask/Runtime/Linq/ToArray.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/ToDictionary.cs | 278 - .../UniTask/Runtime/Linq/ToDictionary.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/ToHashSet.cs | 50 - .../UniTask/Runtime/Linq/ToHashSet.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/ToList.cs | 42 - Plugins/UniTask/Runtime/Linq/ToList.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/ToLookup.cs | 554 - Plugins/UniTask/Runtime/Linq/ToLookup.cs.meta | 11 - Plugins/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 - Plugins/UniTask/Runtime/Linq/Union.cs | 26 - Plugins/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 - Plugins/UniTask/Runtime/Linq/Where.cs | 818 -- Plugins/UniTask/Runtime/Linq/Where.cs.meta | 11 - Plugins/UniTask/Runtime/Linq/Zip.cs | 541 - Plugins/UniTask/Runtime/Linq/Zip.cs.meta | 11 - Plugins/UniTask/Runtime/MoveNextSource.cs | 63 - .../UniTask/Runtime/MoveNextSource.cs.meta | 11 - Plugins/UniTask/Runtime/PlayerLoopHelper.cs | 564 - .../UniTask/Runtime/PlayerLoopHelper.cs.meta | 11 - Plugins/UniTask/Runtime/PlayerLoopTimer.cs | 262 - .../UniTask/Runtime/PlayerLoopTimer.cs.meta | 11 - Plugins/UniTask/Runtime/Progress.cs | 87 - Plugins/UniTask/Runtime/Progress.cs.meta | 11 - Plugins/UniTask/Runtime/TaskPool.cs | 123 - Plugins/UniTask/Runtime/TaskPool.cs.meta | 11 - Plugins/UniTask/Runtime/TimeoutController.cs | 129 - .../UniTask/Runtime/TimeoutController.cs.meta | 11 - Plugins/UniTask/Runtime/TriggerEvent.cs | 311 - Plugins/UniTask/Runtime/TriggerEvent.cs.meta | 11 - Plugins/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 | 85 - .../Triggers/AsyncTriggerExtensions.cs.meta | 11 - .../Triggers/MonoBehaviourMessagesTriggers.cs | 4457 ------ .../MonoBehaviourMessagesTriggers.cs.meta | 11 - Plugins/UniTask/Runtime/UniTask.Bridge.cs | 18 - .../UniTask/Runtime/UniTask.Bridge.cs.meta | 11 - Plugins/UniTask/Runtime/UniTask.Delay.cs | 963 -- Plugins/UniTask/Runtime/UniTask.Delay.cs.meta | 11 - Plugins/UniTask/Runtime/UniTask.Factory.cs | 499 - .../UniTask/Runtime/UniTask.Factory.cs.meta | 11 - Plugins/UniTask/Runtime/UniTask.Run.cs | 289 - Plugins/UniTask/Runtime/UniTask.Run.cs.meta | 11 - Plugins/UniTask/Runtime/UniTask.Threading.cs | 412 - .../UniTask/Runtime/UniTask.Threading.cs.meta | 11 - Plugins/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 - Plugins/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 - Plugins/UniTask/Runtime/UniTask.WhenAny.cs | 359 - .../UniTask/Runtime/UniTask.WhenAny.cs.meta | 11 - Plugins/UniTask/Runtime/UniTask.asmdef | 45 - Plugins/UniTask/Runtime/UniTask.asmdef.meta | 7 - Plugins/UniTask/Runtime/UniTask.cs | 707 - Plugins/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 - Plugins/UniTask/Runtime/UniTaskExtensions.cs | 921 -- .../UniTask/Runtime/UniTaskExtensions.cs.meta | 11 - .../Runtime/UniTaskObservableExtensions.cs | 750 - .../UniTaskObservableExtensions.cs.meta | 11 - Plugins/UniTask/Runtime/UniTaskScheduler.cs | 103 - .../UniTask/Runtime/UniTaskScheduler.cs.meta | 11 - .../Runtime/UniTaskSynchronizationContext.cs | 158 - .../UniTaskSynchronizationContext.cs.meta | 11 - Plugins/UniTask/Runtime/UniTaskVoid.cs | 19 - Plugins/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 | 928 -- .../Runtime/UnityAsyncExtensions.cs.meta | 11 - .../Runtime/UnityAsyncExtensions.uGUI.cs | 826 -- .../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 - Plugins/UniTask/Runtime/_InternalVisibleTo.cs | 6 - .../Runtime/_InternalVisibleTo.cs.meta | 11 - Plugins/UniTask/package.json | 12 - Plugins/UniTask/package.json.meta | 7 - Plugins/WebSocket.meta | 8 - Plugins/WebSocket/WebSocket_LnlM.asmdef | 3 - Plugins/WebSocket/WebSocket_LnlM.asmdef.meta | 7 - Plugins/WebSocket/WebSocket_LnlM.jslib | 143 - Plugins/WebSocket/WebSocket_LnlM.jslib.meta | 32 - Plugins/ZLogger.meta | 8 - Plugins/ZLogger/AsyncProcessZLogger.cs | 133 - Plugins/ZLogger/AsyncProcessZLogger.cs.meta | 11 - .../ZLogger/AsyncStreamLineMessageWriter.cs | 194 - .../AsyncStreamLineMessageWriter.cs.meta | 11 - Plugins/ZLogger/Entries.meta | 8 - Plugins/ZLogger/Entries/FormatLogEntry.cs | 3710 ----- .../ZLogger/Entries/FormatLogEntry.cs.meta | 11 - Plugins/ZLogger/Entries/MessageLogEntry.cs | 122 - .../ZLogger/Entries/MessageLogEntry.cs.meta | 11 - .../ZLogger/Entries/StringFormatterEntry.cs | 88 - .../Entries/StringFormatterEntry.cs.meta | 11 - Plugins/ZLogger/IAsyncLogProcessor.cs | 11 - Plugins/ZLogger/IAsyncLogProcessor.cs.meta | 11 - Plugins/ZLogger/IZLoggerEntry.cs | 33 - Plugins/ZLogger/IZLoggerEntry.cs.meta | 11 - Plugins/ZLogger/IZLoggerState.cs | 7 - Plugins/ZLogger/IZLoggerState.cs.meta | 11 - Plugins/ZLogger/LogInfo.cs | 100 - Plugins/ZLogger/LogInfo.cs.meta | 11 - Plugins/ZLogger/Providers.meta | 8 - .../ZLogger/Providers/RollingFilestream.cs | 228 - .../Providers/RollingFilestream.cs.meta | 11 - .../Providers/ZLoggerConsoleLoggerProvider.cs | 41 - .../ZLoggerConsoleLoggerProvider.cs.meta | 11 - .../Providers/ZLoggerFileLoggerProvider.cs | 48 - .../ZLoggerFileLoggerProvider.cs.meta | 11 - .../ZLoggerLogProcessorLoggerProvider.cs | 26 - .../ZLoggerLogProcessorLoggerProvider.cs.meta | 11 - .../ZLoggerRollingFileLoggerProvider.cs | 40 - .../ZLoggerRollingFileLoggerProvider.cs.meta | 11 - .../Providers/ZLoggerStreamLoggerProvider.cs | 36 - .../ZLoggerStreamLoggerProvider.cs.meta | 11 - Plugins/ZLogger/Shims.meta | 8 - Plugins/ZLogger/Shims/NullableAttributes.cs | 140 - .../ZLogger/Shims/NullableAttributes.cs.meta | 11 - Plugins/ZLogger/StreamBufferWriter.cs | 90 - Plugins/ZLogger/StreamBufferWriter.cs.meta | 11 - Plugins/ZLogger/Unity.meta | 8 - .../Unity/DiagnosticServiceProvider.cs | 339 - .../Unity/DiagnosticServiceProvider.cs.meta | 11 - Plugins/ZLogger/Unity/JsonPackageShims.cs | 94 - .../ZLogger/Unity/JsonPackageShims.cs.meta | 11 - Plugins/ZLogger/Unity/UnityLoggerFactory.cs | 249 - .../ZLogger/Unity/UnityLoggerFactory.cs.meta | 11 - .../Unity/ZLoggerUnityLoggerProvider.cs | 113 - .../Unity/ZLoggerUnityLoggerProvider.cs.meta | 11 - Plugins/ZLogger/WindowsConsoleMode.cs | 39 - Plugins/ZLogger/WindowsConsoleMode.cs.meta | 11 - Plugins/ZLogger/ZLogger.asmdef | 14 - Plugins/ZLogger/ZLogger.asmdef.meta | 7 - Plugins/ZLogger/ZLoggerExtensions.cs | 4926 ------- Plugins/ZLogger/ZLoggerExtensions.cs.meta | 11 - .../ZLoggerLoggingBuilderExtensions.cs | 176 - .../ZLoggerLoggingBuilderExtensions.cs.meta | 11 - Plugins/ZLogger/ZLoggerMessage.cs | 373 - Plugins/ZLogger/ZLoggerMessage.cs.meta | 11 - Plugins/ZLogger/ZLoggerOptions.cs | 133 - Plugins/ZLogger/ZLoggerOptions.cs.meta | 11 - Plugins/ZLogger/package.json | 18 - Plugins/ZLogger/package.json.meta | 7 - Plugins/ZString.meta | 8 - Plugins/ZString/EnumUtil.cs | 59 - Plugins/ZString/EnumUtil.cs.meta | 11 - Plugins/ZString/ExceptionUtil.cs | 24 - Plugins/ZString/ExceptionUtil.cs.meta | 11 - Plugins/ZString/FastNumberWriter.cs | 299 - Plugins/ZString/FastNumberWriter.cs.meta | 11 - Plugins/ZString/FormatHelper.cs | 172 - Plugins/ZString/FormatHelper.cs.meta | 11 - Plugins/ZString/FormatParser.cs | 218 - Plugins/ZString/FormatParser.cs.meta | 11 - Plugins/ZString/IResettableBufferWriter.cs | 12 - .../ZString/IResettableBufferWriter.cs.meta | 11 - .../NestedStringBuilderCreationException.cs | 22 - ...stedStringBuilderCreationException.cs.meta | 11 - Plugins/ZString/Number.meta | 8 - Plugins/ZString/Number/BitOperations.cs | 284 - Plugins/ZString/Number/BitOperations.cs.meta | 11 - Plugins/ZString/Number/BufferEx.cs | 28 - Plugins/ZString/Number/BufferEx.cs.meta | 11 - Plugins/ZString/Number/DecimalEx.cs | 93 - Plugins/ZString/Number/DecimalEx.cs.meta | 11 - Plugins/ZString/Number/FloatEx.cs | 43 - Plugins/ZString/Number/FloatEx.cs.meta | 11 - Plugins/ZString/Number/FormattingHelpers.cs | 138 - .../ZString/Number/FormattingHelpers.cs.meta | 11 - Plugins/ZString/Number/GuidEx.cs | 170 - Plugins/ZString/Number/GuidEx.cs.meta | 11 - Plugins/ZString/Number/HexConverter.cs | 133 - Plugins/ZString/Number/HexConverter.cs.meta | 11 - Plugins/ZString/Number/InternalSpanEx.cs | 237 - Plugins/ZString/Number/InternalSpanEx.cs.meta | 11 - Plugins/ZString/Number/MathEx.cs | 263 - Plugins/ZString/Number/MathEx.cs.meta | 11 - Plugins/ZString/Number/Number.BigInteger.cs | 1222 -- .../ZString/Number/Number.BigInteger.cs.meta | 11 - Plugins/ZString/Number/Number.DiyFp.cs | 157 - Plugins/ZString/Number/Number.DiyFp.cs.meta | 11 - Plugins/ZString/Number/Number.Dragon4.cs | 525 - Plugins/ZString/Number/Number.Dragon4.cs.meta | 11 - Plugins/ZString/Number/Number.Formatting.cs | 2544 ---- .../ZString/Number/Number.Formatting.cs.meta | 11 - Plugins/ZString/Number/Number.Grisu3.cs | 1067 -- Plugins/ZString/Number/Number.Grisu3.cs.meta | 11 - Plugins/ZString/Number/Number.NumberBuffer.cs | 124 - .../Number/Number.NumberBuffer.cs.meta | 11 - .../Number.NumberToFloatingPointBits.cs | 637 - .../Number.NumberToFloatingPointBits.cs.meta | 11 - Plugins/ZString/Number/Number.Parsing.cs | 2028 --- Plugins/ZString/Number/Number.Parsing.cs.meta | 11 - Plugins/ZString/Number/NumberFormatInfoEx.cs | 15 - .../ZString/Number/NumberFormatInfoEx.cs.meta | 11 - Plugins/ZString/Number/ValueStringBuilder.cs | 309 - .../ZString/Number/ValueStringBuilder.cs.meta | 11 - Plugins/ZString/PreparedFormat.cs | 3303 ----- Plugins/ZString/PreparedFormat.cs.meta | 11 - Plugins/ZString/PreparedFormatHelper.cs | 179 - Plugins/ZString/PreparedFormatHelper.cs.meta | 11 - Plugins/ZString/ReadOnlyListAdaptor.cs | 25 - Plugins/ZString/ReadOnlyListAdaptor.cs.meta | 11 - Plugins/ZString/Shims.cs | 244 - Plugins/ZString/Shims.cs.meta | 11 - Plugins/ZString/StringBuilder.AppendJoin.cs | 414 - .../ZString/StringBuilder.AppendJoin.cs.meta | 11 - Plugins/ZString/Unity.meta | 8 - .../TextMeshProExtensions.SetStringBuilder.cs | 14 - ...MeshProExtensions.SetStringBuilder.cs.meta | 11 - .../ZString/Unity/TextMeshProExtensions.cs | 195 - .../Unity/TextMeshProExtensions.cs.meta | 11 - Plugins/ZString/Utf16.meta | 8 - .../Utf16ValueStringBuilder.AppendFormat.cs | 1552 --- ...f16ValueStringBuilder.AppendFormat.cs.meta | 11 - ...Utf16ValueStringBuilder.CreateFormatter.cs | 150 - ...ValueStringBuilder.CreateFormatter.cs.meta | 11 - ...alueStringBuilder.SpanFormattableAppend.cs | 684 - ...tringBuilder.SpanFormattableAppend.cs.meta | 11 - Plugins/ZString/Utf16ValueStringBuilder.cs | 751 - .../ZString/Utf16ValueStringBuilder.cs.meta | 11 - Plugins/ZString/Utf8.meta | 8 - .../Utf8ValueStringBuilder.AppendFormat.cs | 1601 --- ...tf8ValueStringBuilder.AppendFormat.cs.meta | 11 - .../Utf8ValueStringBuilder.CreateFormatter.cs | 157 - ...ValueStringBuilder.CreateFormatter.cs.meta | 11 - ...alueStringBuilder.SpanFormattableAppend.cs | 747 - ...tringBuilder.SpanFormattableAppend.cs.meta | 11 - Plugins/ZString/Utf8ValueStringBuilder.cs | 517 - .../ZString/Utf8ValueStringBuilder.cs.meta | 11 - Plugins/ZString/ZString.Concat.cs | 2413 ---- Plugins/ZString/ZString.Concat.cs.meta | 11 - Plugins/ZString/ZString.Format.cs | 264 - Plugins/ZString/ZString.Format.cs.meta | 11 - Plugins/ZString/ZString.Prepare.cs | 200 - Plugins/ZString/ZString.Prepare.cs.meta | 11 - Plugins/ZString/ZString.Utf8Format.cs | 1732 --- Plugins/ZString/ZString.Utf8Format.cs.meta | 11 - Plugins/ZString/ZString.asmdef | 14 - Plugins/ZString/ZString.asmdef.meta | 7 - Plugins/ZString/ZString.cs | 273 - Plugins/ZString/ZString.cs.meta | 11 - Plugins/ZString/ZStringWriter.cs | 209 - Plugins/ZString/ZStringWriter.cs.meta | 11 - 655 files changed, 131878 deletions(-) delete mode 100644 Plugins/LiteNetLib.meta delete mode 100644 Plugins/LiteNetLib/BaseChannel.cs delete mode 100644 Plugins/LiteNetLib/BaseChannel.cs.meta delete mode 100644 Plugins/LiteNetLib/ConnectionRequest.cs delete mode 100644 Plugins/LiteNetLib/ConnectionRequest.cs.meta delete mode 100644 Plugins/LiteNetLib/INetEventListener.cs delete mode 100644 Plugins/LiteNetLib/INetEventListener.cs.meta delete mode 100644 Plugins/LiteNetLib/InternalPackets.cs delete mode 100644 Plugins/LiteNetLib/InternalPackets.cs.meta delete mode 100644 Plugins/LiteNetLib/Layers.meta delete mode 100644 Plugins/LiteNetLib/Layers/Crc32cLayer.cs delete mode 100644 Plugins/LiteNetLib/Layers/Crc32cLayer.cs.meta delete mode 100644 Plugins/LiteNetLib/Layers/PacketLayerBase.cs delete mode 100644 Plugins/LiteNetLib/Layers/PacketLayerBase.cs.meta delete mode 100644 Plugins/LiteNetLib/Layers/XorEncryptLayer.cs delete mode 100644 Plugins/LiteNetLib/Layers/XorEncryptLayer.cs.meta delete mode 100644 Plugins/LiteNetLib/LiteNetLib.asmdef delete mode 100644 Plugins/LiteNetLib/LiteNetLib.asmdef.meta delete mode 100644 Plugins/LiteNetLib/LiteNetLib.csproj delete mode 100644 Plugins/LiteNetLib/LiteNetLib.csproj.meta delete mode 100644 Plugins/LiteNetLib/NatPunchModule.cs delete mode 100644 Plugins/LiteNetLib/NatPunchModule.cs.meta delete mode 100644 Plugins/LiteNetLib/NativeSocket.cs delete mode 100644 Plugins/LiteNetLib/NativeSocket.cs.meta delete mode 100644 Plugins/LiteNetLib/NetConstants.cs delete mode 100644 Plugins/LiteNetLib/NetConstants.cs.meta delete mode 100644 Plugins/LiteNetLib/NetDebug.cs delete mode 100644 Plugins/LiteNetLib/NetDebug.cs.meta delete mode 100644 Plugins/LiteNetLib/NetManager.PacketPool.cs delete mode 100644 Plugins/LiteNetLib/NetManager.PacketPool.cs.meta delete mode 100644 Plugins/LiteNetLib/NetManager.Socket.cs delete mode 100644 Plugins/LiteNetLib/NetManager.Socket.cs.meta delete mode 100644 Plugins/LiteNetLib/NetManager.cs delete mode 100644 Plugins/LiteNetLib/NetManager.cs.meta delete mode 100644 Plugins/LiteNetLib/NetPacket.cs delete mode 100644 Plugins/LiteNetLib/NetPacket.cs.meta delete mode 100644 Plugins/LiteNetLib/NetPeer.cs delete mode 100644 Plugins/LiteNetLib/NetPeer.cs.meta delete mode 100644 Plugins/LiteNetLib/NetStatistics.cs delete mode 100644 Plugins/LiteNetLib/NetStatistics.cs.meta delete mode 100644 Plugins/LiteNetLib/NetUtils.cs delete mode 100644 Plugins/LiteNetLib/NetUtils.cs.meta delete mode 100644 Plugins/LiteNetLib/PausedSocketFix.cs delete mode 100644 Plugins/LiteNetLib/PausedSocketFix.cs.meta delete mode 100644 Plugins/LiteNetLib/PooledPacket.cs delete mode 100644 Plugins/LiteNetLib/PooledPacket.cs.meta delete mode 100644 Plugins/LiteNetLib/ReliableChannel.cs delete mode 100644 Plugins/LiteNetLib/ReliableChannel.cs.meta delete mode 100644 Plugins/LiteNetLib/SequencedChannel.cs delete mode 100644 Plugins/LiteNetLib/SequencedChannel.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils.meta delete mode 100644 Plugins/LiteNetLib/Utils/CRC32C.cs delete mode 100644 Plugins/LiteNetLib/Utils/CRC32C.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils/FastBitConverter.cs delete mode 100644 Plugins/LiteNetLib/Utils/FastBitConverter.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils/INetSerializable.cs delete mode 100644 Plugins/LiteNetLib/Utils/INetSerializable.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils/NetDataReader.cs delete mode 100644 Plugins/LiteNetLib/Utils/NetDataReader.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils/NetDataWriter.cs delete mode 100644 Plugins/LiteNetLib/Utils/NetDataWriter.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils/NetPacketProcessor.cs delete mode 100644 Plugins/LiteNetLib/Utils/NetPacketProcessor.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils/NetSerializer.cs delete mode 100644 Plugins/LiteNetLib/Utils/NetSerializer.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils/NtpPacket.cs delete mode 100644 Plugins/LiteNetLib/Utils/NtpPacket.cs.meta delete mode 100644 Plugins/LiteNetLib/Utils/NtpRequest.cs delete mode 100644 Plugins/LiteNetLib/Utils/NtpRequest.cs.meta delete mode 100644 Plugins/LiteNetLib/package.json delete mode 100644 Plugins/LiteNetLib/package.json.meta delete mode 100644 Plugins/Microsoft.Bcl.AsyncInterfaces.dll delete mode 100644 Plugins/Microsoft.Bcl.AsyncInterfaces.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Configuration.Abstractions.dll delete mode 100644 Plugins/Microsoft.Extensions.Configuration.Abstractions.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Configuration.Binder.dll delete mode 100644 Plugins/Microsoft.Extensions.Configuration.Binder.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Configuration.dll delete mode 100644 Plugins/Microsoft.Extensions.Configuration.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.DependencyInjection.Abstractions.dll delete mode 100644 Plugins/Microsoft.Extensions.DependencyInjection.Abstractions.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.DependencyInjection.dll delete mode 100644 Plugins/Microsoft.Extensions.DependencyInjection.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Logging.Abstractions.dll delete mode 100644 Plugins/Microsoft.Extensions.Logging.Abstractions.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Logging.Configuration.dll delete mode 100644 Plugins/Microsoft.Extensions.Logging.Configuration.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Logging.dll delete mode 100644 Plugins/Microsoft.Extensions.Logging.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Options.ConfigurationExtensions.dll delete mode 100644 Plugins/Microsoft.Extensions.Options.ConfigurationExtensions.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Options.dll delete mode 100644 Plugins/Microsoft.Extensions.Options.dll.meta delete mode 100644 Plugins/Microsoft.Extensions.Primitives.dll delete mode 100644 Plugins/Microsoft.Extensions.Primitives.dll.meta delete mode 100644 Plugins/NetCoreServer.meta delete mode 100644 Plugins/NetCoreServer/Buffer.cs delete mode 100644 Plugins/NetCoreServer/Buffer.cs.meta delete mode 100644 Plugins/NetCoreServer/FileCache.cs delete mode 100644 Plugins/NetCoreServer/FileCache.cs.meta delete mode 100644 Plugins/NetCoreServer/HttpClient.cs delete mode 100644 Plugins/NetCoreServer/HttpClient.cs.meta delete mode 100644 Plugins/NetCoreServer/HttpRequest.cs delete mode 100644 Plugins/NetCoreServer/HttpRequest.cs.meta delete mode 100644 Plugins/NetCoreServer/HttpResponse.cs delete mode 100644 Plugins/NetCoreServer/HttpResponse.cs.meta delete mode 100644 Plugins/NetCoreServer/HttpServer.cs delete mode 100644 Plugins/NetCoreServer/HttpServer.cs.meta delete mode 100644 Plugins/NetCoreServer/HttpSession.cs delete mode 100644 Plugins/NetCoreServer/HttpSession.cs.meta delete mode 100644 Plugins/NetCoreServer/HttpsClient.cs delete mode 100644 Plugins/NetCoreServer/HttpsClient.cs.meta delete mode 100644 Plugins/NetCoreServer/HttpsServer.cs delete mode 100644 Plugins/NetCoreServer/HttpsServer.cs.meta delete mode 100644 Plugins/NetCoreServer/HttpsSession.cs delete mode 100644 Plugins/NetCoreServer/HttpsSession.cs.meta delete mode 100644 Plugins/NetCoreServer/IWebSocket.cs delete mode 100644 Plugins/NetCoreServer/IWebSocket.cs.meta delete mode 100644 Plugins/NetCoreServer/NetCoreServer.asmdef delete mode 100644 Plugins/NetCoreServer/NetCoreServer.asmdef.meta delete mode 100644 Plugins/NetCoreServer/SslClient.cs delete mode 100644 Plugins/NetCoreServer/SslClient.cs.meta delete mode 100644 Plugins/NetCoreServer/SslContext.cs delete mode 100644 Plugins/NetCoreServer/SslContext.cs.meta delete mode 100644 Plugins/NetCoreServer/SslServer.cs delete mode 100644 Plugins/NetCoreServer/SslServer.cs.meta delete mode 100644 Plugins/NetCoreServer/SslSession.cs delete mode 100644 Plugins/NetCoreServer/SslSession.cs.meta delete mode 100644 Plugins/NetCoreServer/TcpClient.cs delete mode 100644 Plugins/NetCoreServer/TcpClient.cs.meta delete mode 100644 Plugins/NetCoreServer/TcpServer.cs delete mode 100644 Plugins/NetCoreServer/TcpServer.cs.meta delete mode 100644 Plugins/NetCoreServer/TcpSession.cs delete mode 100644 Plugins/NetCoreServer/TcpSession.cs.meta delete mode 100644 Plugins/NetCoreServer/Utilities.cs delete mode 100644 Plugins/NetCoreServer/Utilities.cs.meta delete mode 100644 Plugins/NetCoreServer/WebSocket.cs delete mode 100644 Plugins/NetCoreServer/WebSocket.cs.meta delete mode 100644 Plugins/NetCoreServer/WsClient.cs delete mode 100644 Plugins/NetCoreServer/WsClient.cs.meta delete mode 100644 Plugins/NetCoreServer/WsServer.cs delete mode 100644 Plugins/NetCoreServer/WsServer.cs.meta delete mode 100644 Plugins/NetCoreServer/WsSession.cs delete mode 100644 Plugins/NetCoreServer/WsSession.cs.meta delete mode 100644 Plugins/NetCoreServer/WssClient.cs delete mode 100644 Plugins/NetCoreServer/WssClient.cs.meta delete mode 100644 Plugins/NetCoreServer/WssServer.cs delete mode 100644 Plugins/NetCoreServer/WssServer.cs.meta delete mode 100644 Plugins/NetCoreServer/WssSession.cs delete mode 100644 Plugins/NetCoreServer/WssSession.cs.meta delete mode 100644 Plugins/System.Buffers.dll delete mode 100644 Plugins/System.Buffers.dll.meta delete mode 100644 Plugins/System.Memory.dll delete mode 100644 Plugins/System.Memory.dll.meta delete mode 100644 Plugins/System.Runtime.CompilerServices.Unsafe.dll delete mode 100644 Plugins/System.Runtime.CompilerServices.Unsafe.dll.meta delete mode 100644 Plugins/System.Threading.Channels.dll delete mode 100644 Plugins/System.Threading.Channels.dll.meta delete mode 100644 Plugins/System.Threading.Tasks.Extensions.dll delete mode 100644 Plugins/System.Threading.Tasks.Extensions.dll.meta delete mode 100644 Plugins/UniTask.meta delete mode 100644 Plugins/UniTask/Editor.meta delete mode 100644 Plugins/UniTask/Editor/SplitterGUILayout.cs delete mode 100644 Plugins/UniTask/Editor/SplitterGUILayout.cs.meta delete mode 100644 Plugins/UniTask/Editor/UniTask.Editor.asmdef delete mode 100644 Plugins/UniTask/Editor/UniTask.Editor.asmdef.meta delete mode 100644 Plugins/UniTask/Editor/UniTaskTrackerTreeView.cs delete mode 100644 Plugins/UniTask/Editor/UniTaskTrackerTreeView.cs.meta delete mode 100644 Plugins/UniTask/Editor/UniTaskTrackerWindow.cs delete mode 100644 Plugins/UniTask/Editor/UniTaskTrackerWindow.cs.meta delete mode 100644 Plugins/UniTask/Runtime.meta delete mode 100644 Plugins/UniTask/Runtime/AsyncLazy.cs delete mode 100644 Plugins/UniTask/Runtime/AsyncLazy.cs.meta delete mode 100644 Plugins/UniTask/Runtime/AsyncReactiveProperty.cs delete mode 100644 Plugins/UniTask/Runtime/AsyncReactiveProperty.cs.meta delete mode 100644 Plugins/UniTask/Runtime/AsyncUnit.cs delete mode 100644 Plugins/UniTask/Runtime/AsyncUnit.cs.meta delete mode 100644 Plugins/UniTask/Runtime/CancellationTokenEqualityComparer.cs delete mode 100644 Plugins/UniTask/Runtime/CancellationTokenEqualityComparer.cs.meta delete mode 100644 Plugins/UniTask/Runtime/CancellationTokenExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/CancellationTokenExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/CancellationTokenSourceExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/CancellationTokenSourceExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Channel.cs delete mode 100644 Plugins/UniTask/Runtime/Channel.cs.meta delete mode 100644 Plugins/UniTask/Runtime/CompilerServices.meta delete mode 100644 Plugins/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs delete mode 100644 Plugins/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs.meta delete mode 100644 Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs delete mode 100644 Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs.meta delete mode 100644 Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs delete mode 100644 Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs.meta delete mode 100644 Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs delete mode 100644 Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs.meta delete mode 100644 Plugins/UniTask/Runtime/EnumerableAsyncExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/EnumerableAsyncExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/ExceptionExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/ExceptionExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/External.meta delete mode 100644 Plugins/UniTask/Runtime/External/Addressables.meta delete mode 100644 Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef delete mode 100644 Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta delete mode 100644 Plugins/UniTask/Runtime/External/DOTween.meta delete mode 100644 Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef delete mode 100644 Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta delete mode 100644 Plugins/UniTask/Runtime/External/TextMeshPro.meta delete mode 100644 Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs delete mode 100644 Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs.meta delete mode 100644 Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef delete mode 100644 Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef.meta delete mode 100644 Plugins/UniTask/Runtime/IUniTaskAsyncEnumerable.cs delete mode 100644 Plugins/UniTask/Runtime/IUniTaskAsyncEnumerable.cs.meta delete mode 100644 Plugins/UniTask/Runtime/IUniTaskSource.cs delete mode 100644 Plugins/UniTask/Runtime/IUniTaskSource.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/ArrayPool.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/ArrayPool.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/ArrayPoolUtil.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/ArrayPoolUtil.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/ArrayUtil.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/ArrayUtil.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/DiagnosticsExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/DiagnosticsExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/Error.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/Error.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/MinimumQueue.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/MinimumQueue.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/PooledDelegate.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/PooledDelegate.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/StatePool.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/StatePool.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/TaskTracker.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/TaskTracker.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/UnityEqualityComparer.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/UnityEqualityComparer.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/ValueStopwatch.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/ValueStopwatch.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Internal/WeakDictionary.cs delete mode 100644 Plugins/UniTask/Runtime/Internal/WeakDictionary.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Aggregate.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Aggregate.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/All.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/All.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Any.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Any.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/AppendPrepend.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/AppendPrepend.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Average.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Average.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Buffer.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Buffer.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Cast.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Cast.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/CombineLatest.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/CombineLatest.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Concat.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Concat.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Contains.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Contains.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Count.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Count.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Create.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Create.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/DefaultIfEmpty.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/DefaultIfEmpty.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Distinct.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Distinct.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/DistinctUntilChanged.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/DistinctUntilChanged.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Do.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Do.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ElementAt.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ElementAt.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Empty.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Empty.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Except.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Except.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/First.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/First.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ForEach.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ForEach.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/GroupBy.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/GroupBy.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/GroupJoin.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/GroupJoin.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Intersect.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Intersect.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Join.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Join.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Last.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Last.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/LongCount.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/LongCount.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Max.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Max.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Min.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Min.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/MinMax.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/MinMax.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Never.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Never.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/OfType.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/OfType.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/OrderBy.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/OrderBy.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Pairwise.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Pairwise.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Publish.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Publish.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Queue.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Queue.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Range.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Range.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Repeat.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Repeat.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Return.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Return.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Reverse.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Reverse.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Select.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Select.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/SelectMany.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/SelectMany.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/SequenceEqual.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/SequenceEqual.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Single.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Single.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Skip.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Skip.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/SkipLast.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/SkipLast.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/SkipUntil.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/SkipUntil.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/SkipUntilCanceled.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/SkipUntilCanceled.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/SkipWhile.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/SkipWhile.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Subscribe.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Subscribe.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Sum.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Sum.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Take.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Take.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/TakeLast.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/TakeLast.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/TakeUntil.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/TakeUntil.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/TakeUntilCanceled.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/TakeUntilCanceled.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/TakeWhile.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/TakeWhile.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Throw.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Throw.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ToArray.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ToArray.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ToDictionary.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ToDictionary.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ToHashSet.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ToHashSet.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ToList.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ToList.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ToLookup.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ToLookup.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ToObservable.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ToObservable.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/UniTask.Linq.asmdef delete mode 100644 Plugins/UniTask/Runtime/Linq/UniTask.Linq.asmdef.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Union.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Union.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/UnityExtensions.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Where.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Where.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Linq/Zip.cs delete mode 100644 Plugins/UniTask/Runtime/Linq/Zip.cs.meta delete mode 100644 Plugins/UniTask/Runtime/MoveNextSource.cs delete mode 100644 Plugins/UniTask/Runtime/MoveNextSource.cs.meta delete mode 100644 Plugins/UniTask/Runtime/PlayerLoopHelper.cs delete mode 100644 Plugins/UniTask/Runtime/PlayerLoopHelper.cs.meta delete mode 100644 Plugins/UniTask/Runtime/PlayerLoopTimer.cs delete mode 100644 Plugins/UniTask/Runtime/PlayerLoopTimer.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Progress.cs delete mode 100644 Plugins/UniTask/Runtime/Progress.cs.meta delete mode 100644 Plugins/UniTask/Runtime/TaskPool.cs delete mode 100644 Plugins/UniTask/Runtime/TaskPool.cs.meta delete mode 100644 Plugins/UniTask/Runtime/TimeoutController.cs delete mode 100644 Plugins/UniTask/Runtime/TimeoutController.cs.meta delete mode 100644 Plugins/UniTask/Runtime/TriggerEvent.cs delete mode 100644 Plugins/UniTask/Runtime/TriggerEvent.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Triggers.meta delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncStartTrigger.cs delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncStartTrigger.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncTriggerBase.cs delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncTriggerBase.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs delete mode 100644 Plugins/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.Bridge.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.Bridge.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.Delay.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.Delay.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.Factory.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.Factory.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.Run.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.Run.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.Threading.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.Threading.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.WaitUntil.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.WaitUntil.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.WhenAll.Generated.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.WhenAll.Generated.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.WhenAll.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.WhenAll.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.WhenAny.Generated.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.WhenAny.Generated.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.WhenAny.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.WhenAny.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.asmdef delete mode 100644 Plugins/UniTask/Runtime/UniTask.asmdef.meta delete mode 100644 Plugins/UniTask/Runtime/UniTask.cs delete mode 100644 Plugins/UniTask/Runtime/UniTask.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTaskCompletionSource.cs delete mode 100644 Plugins/UniTask/Runtime/UniTaskCompletionSource.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTaskExtensions.Shorthand.cs delete mode 100644 Plugins/UniTask/Runtime/UniTaskExtensions.Shorthand.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTaskExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/UniTaskExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTaskObservableExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/UniTaskObservableExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTaskScheduler.cs delete mode 100644 Plugins/UniTask/Runtime/UniTaskScheduler.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTaskSynchronizationContext.cs delete mode 100644 Plugins/UniTask/Runtime/UniTaskSynchronizationContext.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UniTaskVoid.cs delete mode 100644 Plugins/UniTask/Runtime/UniTaskVoid.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs delete mode 100644 Plugins/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UnityBindingExtensions.cs delete mode 100644 Plugins/UniTask/Runtime/UnityBindingExtensions.cs.meta delete mode 100644 Plugins/UniTask/Runtime/UnityWebRequestException.cs delete mode 100644 Plugins/UniTask/Runtime/UnityWebRequestException.cs.meta delete mode 100644 Plugins/UniTask/Runtime/_InternalVisibleTo.cs delete mode 100644 Plugins/UniTask/Runtime/_InternalVisibleTo.cs.meta delete mode 100644 Plugins/UniTask/package.json delete mode 100644 Plugins/UniTask/package.json.meta delete mode 100644 Plugins/WebSocket.meta delete mode 100644 Plugins/WebSocket/WebSocket_LnlM.asmdef delete mode 100644 Plugins/WebSocket/WebSocket_LnlM.asmdef.meta delete mode 100644 Plugins/WebSocket/WebSocket_LnlM.jslib delete mode 100644 Plugins/WebSocket/WebSocket_LnlM.jslib.meta delete mode 100644 Plugins/ZLogger.meta delete mode 100644 Plugins/ZLogger/AsyncProcessZLogger.cs delete mode 100644 Plugins/ZLogger/AsyncProcessZLogger.cs.meta delete mode 100644 Plugins/ZLogger/AsyncStreamLineMessageWriter.cs delete mode 100644 Plugins/ZLogger/AsyncStreamLineMessageWriter.cs.meta delete mode 100644 Plugins/ZLogger/Entries.meta delete mode 100644 Plugins/ZLogger/Entries/FormatLogEntry.cs delete mode 100644 Plugins/ZLogger/Entries/FormatLogEntry.cs.meta delete mode 100644 Plugins/ZLogger/Entries/MessageLogEntry.cs delete mode 100644 Plugins/ZLogger/Entries/MessageLogEntry.cs.meta delete mode 100644 Plugins/ZLogger/Entries/StringFormatterEntry.cs delete mode 100644 Plugins/ZLogger/Entries/StringFormatterEntry.cs.meta delete mode 100644 Plugins/ZLogger/IAsyncLogProcessor.cs delete mode 100644 Plugins/ZLogger/IAsyncLogProcessor.cs.meta delete mode 100644 Plugins/ZLogger/IZLoggerEntry.cs delete mode 100644 Plugins/ZLogger/IZLoggerEntry.cs.meta delete mode 100644 Plugins/ZLogger/IZLoggerState.cs delete mode 100644 Plugins/ZLogger/IZLoggerState.cs.meta delete mode 100644 Plugins/ZLogger/LogInfo.cs delete mode 100644 Plugins/ZLogger/LogInfo.cs.meta delete mode 100644 Plugins/ZLogger/Providers.meta delete mode 100644 Plugins/ZLogger/Providers/RollingFilestream.cs delete mode 100644 Plugins/ZLogger/Providers/RollingFilestream.cs.meta delete mode 100644 Plugins/ZLogger/Providers/ZLoggerConsoleLoggerProvider.cs delete mode 100644 Plugins/ZLogger/Providers/ZLoggerConsoleLoggerProvider.cs.meta delete mode 100644 Plugins/ZLogger/Providers/ZLoggerFileLoggerProvider.cs delete mode 100644 Plugins/ZLogger/Providers/ZLoggerFileLoggerProvider.cs.meta delete mode 100644 Plugins/ZLogger/Providers/ZLoggerLogProcessorLoggerProvider.cs delete mode 100644 Plugins/ZLogger/Providers/ZLoggerLogProcessorLoggerProvider.cs.meta delete mode 100644 Plugins/ZLogger/Providers/ZLoggerRollingFileLoggerProvider.cs delete mode 100644 Plugins/ZLogger/Providers/ZLoggerRollingFileLoggerProvider.cs.meta delete mode 100644 Plugins/ZLogger/Providers/ZLoggerStreamLoggerProvider.cs delete mode 100644 Plugins/ZLogger/Providers/ZLoggerStreamLoggerProvider.cs.meta delete mode 100644 Plugins/ZLogger/Shims.meta delete mode 100644 Plugins/ZLogger/Shims/NullableAttributes.cs delete mode 100644 Plugins/ZLogger/Shims/NullableAttributes.cs.meta delete mode 100644 Plugins/ZLogger/StreamBufferWriter.cs delete mode 100644 Plugins/ZLogger/StreamBufferWriter.cs.meta delete mode 100644 Plugins/ZLogger/Unity.meta delete mode 100644 Plugins/ZLogger/Unity/DiagnosticServiceProvider.cs delete mode 100644 Plugins/ZLogger/Unity/DiagnosticServiceProvider.cs.meta delete mode 100644 Plugins/ZLogger/Unity/JsonPackageShims.cs delete mode 100644 Plugins/ZLogger/Unity/JsonPackageShims.cs.meta delete mode 100644 Plugins/ZLogger/Unity/UnityLoggerFactory.cs delete mode 100644 Plugins/ZLogger/Unity/UnityLoggerFactory.cs.meta delete mode 100644 Plugins/ZLogger/Unity/ZLoggerUnityLoggerProvider.cs delete mode 100644 Plugins/ZLogger/Unity/ZLoggerUnityLoggerProvider.cs.meta delete mode 100644 Plugins/ZLogger/WindowsConsoleMode.cs delete mode 100644 Plugins/ZLogger/WindowsConsoleMode.cs.meta delete mode 100644 Plugins/ZLogger/ZLogger.asmdef delete mode 100644 Plugins/ZLogger/ZLogger.asmdef.meta delete mode 100644 Plugins/ZLogger/ZLoggerExtensions.cs delete mode 100644 Plugins/ZLogger/ZLoggerExtensions.cs.meta delete mode 100644 Plugins/ZLogger/ZLoggerLoggingBuilderExtensions.cs delete mode 100644 Plugins/ZLogger/ZLoggerLoggingBuilderExtensions.cs.meta delete mode 100644 Plugins/ZLogger/ZLoggerMessage.cs delete mode 100644 Plugins/ZLogger/ZLoggerMessage.cs.meta delete mode 100644 Plugins/ZLogger/ZLoggerOptions.cs delete mode 100644 Plugins/ZLogger/ZLoggerOptions.cs.meta delete mode 100644 Plugins/ZLogger/package.json delete mode 100644 Plugins/ZLogger/package.json.meta delete mode 100644 Plugins/ZString.meta delete mode 100644 Plugins/ZString/EnumUtil.cs delete mode 100644 Plugins/ZString/EnumUtil.cs.meta delete mode 100644 Plugins/ZString/ExceptionUtil.cs delete mode 100644 Plugins/ZString/ExceptionUtil.cs.meta delete mode 100644 Plugins/ZString/FastNumberWriter.cs delete mode 100644 Plugins/ZString/FastNumberWriter.cs.meta delete mode 100644 Plugins/ZString/FormatHelper.cs delete mode 100644 Plugins/ZString/FormatHelper.cs.meta delete mode 100644 Plugins/ZString/FormatParser.cs delete mode 100644 Plugins/ZString/FormatParser.cs.meta delete mode 100644 Plugins/ZString/IResettableBufferWriter.cs delete mode 100644 Plugins/ZString/IResettableBufferWriter.cs.meta delete mode 100644 Plugins/ZString/NestedStringBuilderCreationException.cs delete mode 100644 Plugins/ZString/NestedStringBuilderCreationException.cs.meta delete mode 100644 Plugins/ZString/Number.meta delete mode 100644 Plugins/ZString/Number/BitOperations.cs delete mode 100644 Plugins/ZString/Number/BitOperations.cs.meta delete mode 100644 Plugins/ZString/Number/BufferEx.cs delete mode 100644 Plugins/ZString/Number/BufferEx.cs.meta delete mode 100644 Plugins/ZString/Number/DecimalEx.cs delete mode 100644 Plugins/ZString/Number/DecimalEx.cs.meta delete mode 100644 Plugins/ZString/Number/FloatEx.cs delete mode 100644 Plugins/ZString/Number/FloatEx.cs.meta delete mode 100644 Plugins/ZString/Number/FormattingHelpers.cs delete mode 100644 Plugins/ZString/Number/FormattingHelpers.cs.meta delete mode 100644 Plugins/ZString/Number/GuidEx.cs delete mode 100644 Plugins/ZString/Number/GuidEx.cs.meta delete mode 100644 Plugins/ZString/Number/HexConverter.cs delete mode 100644 Plugins/ZString/Number/HexConverter.cs.meta delete mode 100644 Plugins/ZString/Number/InternalSpanEx.cs delete mode 100644 Plugins/ZString/Number/InternalSpanEx.cs.meta delete mode 100644 Plugins/ZString/Number/MathEx.cs delete mode 100644 Plugins/ZString/Number/MathEx.cs.meta delete mode 100644 Plugins/ZString/Number/Number.BigInteger.cs delete mode 100644 Plugins/ZString/Number/Number.BigInteger.cs.meta delete mode 100644 Plugins/ZString/Number/Number.DiyFp.cs delete mode 100644 Plugins/ZString/Number/Number.DiyFp.cs.meta delete mode 100644 Plugins/ZString/Number/Number.Dragon4.cs delete mode 100644 Plugins/ZString/Number/Number.Dragon4.cs.meta delete mode 100644 Plugins/ZString/Number/Number.Formatting.cs delete mode 100644 Plugins/ZString/Number/Number.Formatting.cs.meta delete mode 100644 Plugins/ZString/Number/Number.Grisu3.cs delete mode 100644 Plugins/ZString/Number/Number.Grisu3.cs.meta delete mode 100644 Plugins/ZString/Number/Number.NumberBuffer.cs delete mode 100644 Plugins/ZString/Number/Number.NumberBuffer.cs.meta delete mode 100644 Plugins/ZString/Number/Number.NumberToFloatingPointBits.cs delete mode 100644 Plugins/ZString/Number/Number.NumberToFloatingPointBits.cs.meta delete mode 100644 Plugins/ZString/Number/Number.Parsing.cs delete mode 100644 Plugins/ZString/Number/Number.Parsing.cs.meta delete mode 100644 Plugins/ZString/Number/NumberFormatInfoEx.cs delete mode 100644 Plugins/ZString/Number/NumberFormatInfoEx.cs.meta delete mode 100644 Plugins/ZString/Number/ValueStringBuilder.cs delete mode 100644 Plugins/ZString/Number/ValueStringBuilder.cs.meta delete mode 100644 Plugins/ZString/PreparedFormat.cs delete mode 100644 Plugins/ZString/PreparedFormat.cs.meta delete mode 100644 Plugins/ZString/PreparedFormatHelper.cs delete mode 100644 Plugins/ZString/PreparedFormatHelper.cs.meta delete mode 100644 Plugins/ZString/ReadOnlyListAdaptor.cs delete mode 100644 Plugins/ZString/ReadOnlyListAdaptor.cs.meta delete mode 100644 Plugins/ZString/Shims.cs delete mode 100644 Plugins/ZString/Shims.cs.meta delete mode 100644 Plugins/ZString/StringBuilder.AppendJoin.cs delete mode 100644 Plugins/ZString/StringBuilder.AppendJoin.cs.meta delete mode 100644 Plugins/ZString/Unity.meta delete mode 100644 Plugins/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs delete mode 100644 Plugins/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs.meta delete mode 100644 Plugins/ZString/Unity/TextMeshProExtensions.cs delete mode 100644 Plugins/ZString/Unity/TextMeshProExtensions.cs.meta delete mode 100644 Plugins/ZString/Utf16.meta delete mode 100644 Plugins/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs delete mode 100644 Plugins/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta delete mode 100644 Plugins/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs delete mode 100644 Plugins/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta delete mode 100644 Plugins/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs delete mode 100644 Plugins/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta delete mode 100644 Plugins/ZString/Utf16ValueStringBuilder.cs delete mode 100644 Plugins/ZString/Utf16ValueStringBuilder.cs.meta delete mode 100644 Plugins/ZString/Utf8.meta delete mode 100644 Plugins/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs delete mode 100644 Plugins/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta delete mode 100644 Plugins/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs delete mode 100644 Plugins/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta delete mode 100644 Plugins/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs delete mode 100644 Plugins/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta delete mode 100644 Plugins/ZString/Utf8ValueStringBuilder.cs delete mode 100644 Plugins/ZString/Utf8ValueStringBuilder.cs.meta delete mode 100644 Plugins/ZString/ZString.Concat.cs delete mode 100644 Plugins/ZString/ZString.Concat.cs.meta delete mode 100644 Plugins/ZString/ZString.Format.cs delete mode 100644 Plugins/ZString/ZString.Format.cs.meta delete mode 100644 Plugins/ZString/ZString.Prepare.cs delete mode 100644 Plugins/ZString/ZString.Prepare.cs.meta delete mode 100644 Plugins/ZString/ZString.Utf8Format.cs delete mode 100644 Plugins/ZString/ZString.Utf8Format.cs.meta delete mode 100644 Plugins/ZString/ZString.asmdef delete mode 100644 Plugins/ZString/ZString.asmdef.meta delete mode 100644 Plugins/ZString/ZString.cs delete mode 100644 Plugins/ZString/ZString.cs.meta delete mode 100644 Plugins/ZString/ZStringWriter.cs delete mode 100644 Plugins/ZString/ZStringWriter.cs.meta diff --git a/Plugins/LiteNetLib.meta b/Plugins/LiteNetLib.meta deleted file mode 100644 index 08688c12..00000000 --- a/Plugins/LiteNetLib.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2a7a1d005d8c98049b49064b3758f693 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/BaseChannel.cs b/Plugins/LiteNetLib/BaseChannel.cs deleted file mode 100644 index b70c4360..00000000 --- a/Plugins/LiteNetLib/BaseChannel.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Collections.Generic; -using System.Threading; - -namespace LiteNetLib -{ - internal abstract class BaseChannel - { - protected readonly NetPeer Peer; - protected readonly Queue OutgoingQueue = new Queue(NetConstants.DefaultWindowSize); - private int _isAddedToPeerChannelSendQueue; - - public int PacketsInQueue => OutgoingQueue.Count; - - protected BaseChannel(NetPeer peer) - { - Peer = peer; - } - - public void AddToQueue(NetPacket packet) - { - lock (OutgoingQueue) - { - OutgoingQueue.Enqueue(packet); - } - AddToPeerChannelSendQueue(); - } - - protected void AddToPeerChannelSendQueue() - { - if (Interlocked.CompareExchange(ref _isAddedToPeerChannelSendQueue, 1, 0) == 0) - { - Peer.AddToReliableChannelSendQueue(this); - } - } - - public bool SendAndCheckQueue() - { - bool hasPacketsToSend = SendNextPackets(); - if (!hasPacketsToSend) - Interlocked.Exchange(ref _isAddedToPeerChannelSendQueue, 0); - - return hasPacketsToSend; - } - - protected abstract bool SendNextPackets(); - public abstract bool ProcessPacket(NetPacket packet); - } -} diff --git a/Plugins/LiteNetLib/BaseChannel.cs.meta b/Plugins/LiteNetLib/BaseChannel.cs.meta deleted file mode 100644 index 277c764a..00000000 --- a/Plugins/LiteNetLib/BaseChannel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 95b1b53aea1fc7043aba8be11481dfff -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/ConnectionRequest.cs b/Plugins/LiteNetLib/ConnectionRequest.cs deleted file mode 100644 index 4a2cdd93..00000000 --- a/Plugins/LiteNetLib/ConnectionRequest.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System.Net; -using System.Threading; -using LiteNetLib.Utils; - -namespace LiteNetLib -{ - internal enum ConnectionRequestResult - { - None, - Accept, - Reject, - RejectForce - } - - public class ConnectionRequest - { - private readonly NetManager _listener; - private int _used; - - public NetDataReader Data => InternalPacket.Data; - - internal ConnectionRequestResult Result { get; private set; } - internal NetConnectRequestPacket InternalPacket; - - public readonly IPEndPoint RemoteEndPoint; - - internal void UpdateRequest(NetConnectRequestPacket connectRequest) - { - //old request - if (connectRequest.ConnectionTime < InternalPacket.ConnectionTime) - return; - - if (connectRequest.ConnectionTime == InternalPacket.ConnectionTime && - connectRequest.ConnectionNumber == InternalPacket.ConnectionNumber) - return; - - InternalPacket = connectRequest; - } - - private bool TryActivate() - { - return Interlocked.CompareExchange(ref _used, 1, 0) == 0; - } - - internal ConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket requestPacket, NetManager listener) - { - InternalPacket = requestPacket; - RemoteEndPoint = remoteEndPoint; - _listener = listener; - } - - public NetPeer AcceptIfKey(string key) - { - if (!TryActivate()) - return null; - try - { - if (Data.GetString() == key) - Result = ConnectionRequestResult.Accept; - } - catch - { - NetDebug.WriteError("[AC] Invalid incoming data"); - } - if (Result == ConnectionRequestResult.Accept) - return _listener.OnConnectionSolved(this, null, 0, 0); - - Result = ConnectionRequestResult.Reject; - _listener.OnConnectionSolved(this, null, 0, 0); - return null; - } - - /// - /// Accept connection and get new NetPeer as result - /// - /// Connected NetPeer - public NetPeer Accept() - { - if (!TryActivate()) - return null; - Result = ConnectionRequestResult.Accept; - return _listener.OnConnectionSolved(this, null, 0, 0); - } - - public void Reject(byte[] rejectData, int start, int length, bool force) - { - if (!TryActivate()) - return; - Result = force ? ConnectionRequestResult.RejectForce : ConnectionRequestResult.Reject; - _listener.OnConnectionSolved(this, rejectData, start, length); - } - - public void Reject(byte[] rejectData, int start, int length) - { - Reject(rejectData, start, length, false); - } - - - public void RejectForce(byte[] rejectData, int start, int length) - { - Reject(rejectData, start, length, true); - } - - public void RejectForce() - { - Reject(null, 0, 0, true); - } - - public void RejectForce(byte[] rejectData) - { - Reject(rejectData, 0, rejectData.Length, true); - } - - public void RejectForce(NetDataWriter rejectData) - { - Reject(rejectData.Data, 0, rejectData.Length, true); - } - - public void Reject() - { - Reject(null, 0, 0, false); - } - - public void Reject(byte[] rejectData) - { - Reject(rejectData, 0, rejectData.Length, false); - } - - public void Reject(NetDataWriter rejectData) - { - Reject(rejectData.Data, 0, rejectData.Length, false); - } - } -} diff --git a/Plugins/LiteNetLib/ConnectionRequest.cs.meta b/Plugins/LiteNetLib/ConnectionRequest.cs.meta deleted file mode 100644 index 4f52e659..00000000 --- a/Plugins/LiteNetLib/ConnectionRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bd279b3b8c7f4ce459e072d379be2459 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/INetEventListener.cs b/Plugins/LiteNetLib/INetEventListener.cs deleted file mode 100644 index 13d8852e..00000000 --- a/Plugins/LiteNetLib/INetEventListener.cs +++ /dev/null @@ -1,272 +0,0 @@ -using System.Net; -using System.Net.Sockets; -using LiteNetLib.Utils; - -namespace LiteNetLib -{ - /// - /// Type of message that you receive in OnNetworkReceiveUnconnected event - /// - public enum UnconnectedMessageType - { - BasicMessage, - Broadcast - } - - /// - /// Disconnect reason that you receive in OnPeerDisconnected event - /// - public enum DisconnectReason - { - ConnectionFailed, - Timeout, - HostUnreachable, - NetworkUnreachable, - RemoteConnectionClose, - DisconnectPeerCalled, - ConnectionRejected, - InvalidProtocol, - UnknownHost, - Reconnect, - PeerToPeerConnection, - PeerNotFound - } - - /// - /// Additional information about disconnection - /// - public struct DisconnectInfo - { - /// - /// Additional info why peer disconnected - /// - public DisconnectReason Reason; - - /// - /// Error code (if reason is SocketSendError or SocketReceiveError) - /// - public SocketError SocketErrorCode; - - /// - /// Additional data that can be accessed (only if reason is RemoteConnectionClose) - /// - public NetPacketReader AdditionalData; - } - - public interface INetEventListener - { - /// - /// New remote peer connected to host, or client connected to remote host - /// - /// Connected peer object - void OnPeerConnected(NetPeer peer); - - /// - /// Peer disconnected - /// - /// disconnected peer - /// additional info about reason, errorCode or data received with disconnect message - void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo); - - /// - /// Network error (on send or receive) - /// - /// From endPoint (can be null) - /// Socket error - void OnNetworkError(IPEndPoint endPoint, SocketError socketError); - - /// - /// Received some data - /// - /// From peer - /// DataReader containing all received data - /// Number of channel at which packet arrived - /// Type of received packet - void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod); - - /// - /// Received unconnected message - /// - /// From address (IP and Port) - /// Message data - /// Message type (simple, discovery request or response) - void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType); - - /// - /// Latency information updated - /// - /// Peer with updated latency - /// latency value in milliseconds - void OnNetworkLatencyUpdate(NetPeer peer, int latency); - - /// - /// On peer connection requested - /// - /// Request information (EndPoint, internal id, additional data) - void OnConnectionRequest(ConnectionRequest request); - } - - public interface IDeliveryEventListener - { - /// - /// On reliable message delivered - /// - /// - /// - void OnMessageDelivered(NetPeer peer, object userData); - } - - public interface INtpEventListener - { - /// - /// Ntp response - /// - /// - void OnNtpResponse(NtpPacket packet); - } - - public interface IPeerAddressChangedListener - { - /// - /// Called when peer address changed (when AllowPeerAddressChange is enabled) - /// - /// Peer that changed address (with new address) - /// previous IP - void OnPeerAddressChanged(NetPeer peer, IPEndPoint previousAddress); - } - - public class EventBasedNetListener : INetEventListener, IDeliveryEventListener, INtpEventListener, IPeerAddressChangedListener - { - public delegate void OnPeerConnected(NetPeer peer); - public delegate void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo); - public delegate void OnNetworkError(IPEndPoint endPoint, SocketError socketError); - public delegate void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod); - public delegate void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType); - public delegate void OnNetworkLatencyUpdate(NetPeer peer, int latency); - public delegate void OnConnectionRequest(ConnectionRequest request); - public delegate void OnDeliveryEvent(NetPeer peer, object userData); - public delegate void OnNtpResponseEvent(NtpPacket packet); - public delegate void OnPeerAddressChangedEvent(NetPeer peer, IPEndPoint previousAddress); - - public event OnPeerConnected PeerConnectedEvent; - public event OnPeerDisconnected PeerDisconnectedEvent; - public event OnNetworkError NetworkErrorEvent; - public event OnNetworkReceive NetworkReceiveEvent; - public event OnNetworkReceiveUnconnected NetworkReceiveUnconnectedEvent; - public event OnNetworkLatencyUpdate NetworkLatencyUpdateEvent; - public event OnConnectionRequest ConnectionRequestEvent; - public event OnDeliveryEvent DeliveryEvent; - public event OnNtpResponseEvent NtpResponseEvent; - public event OnPeerAddressChangedEvent PeerAddressChangedEvent; - - public void ClearPeerConnectedEvent() - { - PeerConnectedEvent = null; - } - - public void ClearPeerDisconnectedEvent() - { - PeerDisconnectedEvent = null; - } - - public void ClearNetworkErrorEvent() - { - NetworkErrorEvent = null; - } - - public void ClearNetworkReceiveEvent() - { - NetworkReceiveEvent = null; - } - - public void ClearNetworkReceiveUnconnectedEvent() - { - NetworkReceiveUnconnectedEvent = null; - } - - public void ClearNetworkLatencyUpdateEvent() - { - NetworkLatencyUpdateEvent = null; - } - - public void ClearConnectionRequestEvent() - { - ConnectionRequestEvent = null; - } - - public void ClearDeliveryEvent() - { - DeliveryEvent = null; - } - - public void ClearNtpResponseEvent() - { - NtpResponseEvent = null; - } - - public void ClearPeerAddressChangedEvent() - { - PeerAddressChangedEvent = null; - } - - void INetEventListener.OnPeerConnected(NetPeer peer) - { - if (PeerConnectedEvent != null) - PeerConnectedEvent(peer); - } - - void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) - { - if (PeerDisconnectedEvent != null) - PeerDisconnectedEvent(peer, disconnectInfo); - } - - void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode) - { - if (NetworkErrorEvent != null) - NetworkErrorEvent(endPoint, socketErrorCode); - } - - void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) - { - if (NetworkReceiveEvent != null) - NetworkReceiveEvent(peer, reader, channelNumber, deliveryMethod); - } - - void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) - { - if (NetworkReceiveUnconnectedEvent != null) - NetworkReceiveUnconnectedEvent(remoteEndPoint, reader, messageType); - } - - void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency) - { - if (NetworkLatencyUpdateEvent != null) - NetworkLatencyUpdateEvent(peer, latency); - } - - void INetEventListener.OnConnectionRequest(ConnectionRequest request) - { - if (ConnectionRequestEvent != null) - ConnectionRequestEvent(request); - } - - void IDeliveryEventListener.OnMessageDelivered(NetPeer peer, object userData) - { - if (DeliveryEvent != null) - DeliveryEvent(peer, userData); - } - - void INtpEventListener.OnNtpResponse(NtpPacket packet) - { - if (NtpResponseEvent != null) - NtpResponseEvent(packet); - } - - void IPeerAddressChangedListener.OnPeerAddressChanged(NetPeer peer, IPEndPoint previousAddress) - { - if (PeerAddressChangedEvent != null) - PeerAddressChangedEvent(peer, previousAddress); - } - } -} diff --git a/Plugins/LiteNetLib/INetEventListener.cs.meta b/Plugins/LiteNetLib/INetEventListener.cs.meta deleted file mode 100644 index fb3c325f..00000000 --- a/Plugins/LiteNetLib/INetEventListener.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a0b19dab3f7116341ae49369ca471e81 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/InternalPackets.cs b/Plugins/LiteNetLib/InternalPackets.cs deleted file mode 100644 index 2eb09fe5..00000000 --- a/Plugins/LiteNetLib/InternalPackets.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Net; -using LiteNetLib.Utils; - -namespace LiteNetLib -{ - internal sealed class NetConnectRequestPacket - { - public const int HeaderSize = 18; - public readonly long ConnectionTime; - public byte ConnectionNumber; - public readonly byte[] TargetAddress; - public readonly NetDataReader Data; - public readonly int PeerId; - - private NetConnectRequestPacket(long connectionTime, byte connectionNumber, int localId, byte[] targetAddress, NetDataReader data) - { - ConnectionTime = connectionTime; - ConnectionNumber = connectionNumber; - TargetAddress = targetAddress; - Data = data; - PeerId = localId; - } - - public static int GetProtocolId(NetPacket packet) - { - return BitConverter.ToInt32(packet.RawData, 1); - } - - public static NetConnectRequestPacket FromData(NetPacket packet) - { - if (packet.ConnectionNumber >= NetConstants.MaxConnectionNumber) - return null; - - //Getting connection time for peer - long connectionTime = BitConverter.ToInt64(packet.RawData, 5); - - //Get peer id - int peerId = BitConverter.ToInt32(packet.RawData, 13); - - //Get target address - int addrSize = packet.RawData[HeaderSize-1]; - if (addrSize != 16 && addrSize != 28) - return null; - byte[] addressBytes = new byte[addrSize]; - Buffer.BlockCopy(packet.RawData, HeaderSize, addressBytes, 0, addrSize); - - // Read data and create request - var reader = new NetDataReader(null, 0, 0); - if (packet.Size > HeaderSize+addrSize) - reader.SetSource(packet.RawData, HeaderSize + addrSize, packet.Size); - - return new NetConnectRequestPacket(connectionTime, packet.ConnectionNumber, peerId, addressBytes, reader); - } - - public static NetPacket Make(NetDataWriter connectData, SocketAddress addressBytes, long connectTime, int localId) - { - //Make initial packet - var packet = new NetPacket(PacketProperty.ConnectRequest, connectData.Length+addressBytes.Size); - - //Add data - FastBitConverter.GetBytes(packet.RawData, 1, NetConstants.ProtocolId); - FastBitConverter.GetBytes(packet.RawData, 5, connectTime); - FastBitConverter.GetBytes(packet.RawData, 13, localId); - packet.RawData[HeaderSize-1] = (byte)addressBytes.Size; - for (int i = 0; i < addressBytes.Size; i++) - packet.RawData[HeaderSize + i] = addressBytes[i]; - Buffer.BlockCopy(connectData.Data, 0, packet.RawData, HeaderSize + addressBytes.Size, connectData.Length); - return packet; - } - } - - internal sealed class NetConnectAcceptPacket - { - public const int Size = 15; - public readonly long ConnectionTime; - public readonly byte ConnectionNumber; - public readonly int PeerId; - public readonly bool PeerNetworkChanged; - - private NetConnectAcceptPacket(long connectionTime, byte connectionNumber, int peerId, bool peerNetworkChanged) - { - ConnectionTime = connectionTime; - ConnectionNumber = connectionNumber; - PeerId = peerId; - PeerNetworkChanged = peerNetworkChanged; - } - - public static NetConnectAcceptPacket FromData(NetPacket packet) - { - if (packet.Size != Size) - return null; - - long connectionId = BitConverter.ToInt64(packet.RawData, 1); - - //check connect num - byte connectionNumber = packet.RawData[9]; - if (connectionNumber >= NetConstants.MaxConnectionNumber) - return null; - - //check reused flag - byte isReused = packet.RawData[10]; - if (isReused > 1) - return null; - - //get remote peer id - int peerId = BitConverter.ToInt32(packet.RawData, 11); - if (peerId < 0) - return null; - - return new NetConnectAcceptPacket(connectionId, connectionNumber, peerId, isReused == 1); - } - - public static NetPacket Make(long connectTime, byte connectNum, int localPeerId) - { - var packet = new NetPacket(PacketProperty.ConnectAccept, 0); - FastBitConverter.GetBytes(packet.RawData, 1, connectTime); - packet.RawData[9] = connectNum; - FastBitConverter.GetBytes(packet.RawData, 11, localPeerId); - return packet; - } - - public static NetPacket MakeNetworkChanged(NetPeer peer) - { - var packet = new NetPacket(PacketProperty.PeerNotFound, Size-1); - FastBitConverter.GetBytes(packet.RawData, 1, peer.ConnectTime); - packet.RawData[9] = peer.ConnectionNum; - packet.RawData[10] = 1; - FastBitConverter.GetBytes(packet.RawData, 11, peer.RemoteId); - return packet; - } - } -} \ No newline at end of file diff --git a/Plugins/LiteNetLib/InternalPackets.cs.meta b/Plugins/LiteNetLib/InternalPackets.cs.meta deleted file mode 100644 index 3ecae4a5..00000000 --- a/Plugins/LiteNetLib/InternalPackets.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 33d628e0ff7b77a4bbe88a5406469ff7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Layers.meta b/Plugins/LiteNetLib/Layers.meta deleted file mode 100644 index 5d1644b3..00000000 --- a/Plugins/LiteNetLib/Layers.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9e44ccf572af50040939ee1193977576 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Layers/Crc32cLayer.cs b/Plugins/LiteNetLib/Layers/Crc32cLayer.cs deleted file mode 100644 index 3ee97d6c..00000000 --- a/Plugins/LiteNetLib/Layers/Crc32cLayer.cs +++ /dev/null @@ -1,41 +0,0 @@ -using LiteNetLib.Utils; -using System; -using System.Net; - -namespace LiteNetLib.Layers -{ - public sealed class Crc32cLayer : PacketLayerBase - { - public Crc32cLayer() : base(CRC32C.ChecksumSize) - { - - } - - public override void ProcessInboundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length) - { - if (length < NetConstants.HeaderSize + CRC32C.ChecksumSize) - { - NetDebug.WriteError("[NM] DataReceived size: bad!"); - //Set length to 0 to have netManager drop the packet. - length = 0; - return; - } - - int checksumPoint = length - CRC32C.ChecksumSize; - if (CRC32C.Compute(data, offset, checksumPoint) != BitConverter.ToUInt32(data, checksumPoint)) - { - NetDebug.Write("[NM] DataReceived checksum: bad!"); - //Set length to 0 to have netManager drop the packet. - length = 0; - return; - } - length -= CRC32C.ChecksumSize; - } - - public override void ProcessOutBoundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length) - { - FastBitConverter.GetBytes(data, length, CRC32C.Compute(data, offset, length)); - length += CRC32C.ChecksumSize; - } - } -} diff --git a/Plugins/LiteNetLib/Layers/Crc32cLayer.cs.meta b/Plugins/LiteNetLib/Layers/Crc32cLayer.cs.meta deleted file mode 100644 index bd6b0285..00000000 --- a/Plugins/LiteNetLib/Layers/Crc32cLayer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 61c40f604e1ebbf49ad4a15921ab08b5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Layers/PacketLayerBase.cs b/Plugins/LiteNetLib/Layers/PacketLayerBase.cs deleted file mode 100644 index b3d9b3a7..00000000 --- a/Plugins/LiteNetLib/Layers/PacketLayerBase.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Net; - -namespace LiteNetLib.Layers -{ - public abstract class PacketLayerBase - { - public readonly int ExtraPacketSizeForLayer; - - protected PacketLayerBase(int extraPacketSizeForLayer) - { - ExtraPacketSizeForLayer = extraPacketSizeForLayer; - } - - public abstract void ProcessInboundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length); - public abstract void ProcessOutBoundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length); - } -} diff --git a/Plugins/LiteNetLib/Layers/PacketLayerBase.cs.meta b/Plugins/LiteNetLib/Layers/PacketLayerBase.cs.meta deleted file mode 100644 index 72be04e0..00000000 --- a/Plugins/LiteNetLib/Layers/PacketLayerBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e713b515d972788408064cb7a3cbb1db -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Layers/XorEncryptLayer.cs b/Plugins/LiteNetLib/Layers/XorEncryptLayer.cs deleted file mode 100644 index 9b671969..00000000 --- a/Plugins/LiteNetLib/Layers/XorEncryptLayer.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Net; -using System.Text; - -namespace LiteNetLib.Layers -{ - public class XorEncryptLayer : PacketLayerBase - { - private byte[] _byteKey; - - public XorEncryptLayer() : base(0) - { - - } - - public XorEncryptLayer(byte[] key) : this() - { - SetKey(key); - } - - public XorEncryptLayer(string key) : this() - { - SetKey(key); - } - - public void SetKey(string key) - { - _byteKey = Encoding.UTF8.GetBytes(key); - } - - public void SetKey(byte[] key) - { - if (_byteKey == null || _byteKey.Length != key.Length) - _byteKey = new byte[key.Length]; - Buffer.BlockCopy(key, 0, _byteKey, 0, key.Length); - } - - public override void ProcessInboundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length) - { - if (_byteKey == null) - return; - var cur = offset; - for (var i = 0; i < length; i++, cur++) - { - data[cur] = (byte)(data[cur] ^ _byteKey[i % _byteKey.Length]); - } - } - - public override void ProcessOutBoundPacket(ref IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length) - { - if (_byteKey == null) - return; - var cur = offset; - for (var i = 0; i < length; i++, cur++) - { - data[cur] = (byte)(data[cur] ^ _byteKey[i % _byteKey.Length]); - } - } - } -} diff --git a/Plugins/LiteNetLib/Layers/XorEncryptLayer.cs.meta b/Plugins/LiteNetLib/Layers/XorEncryptLayer.cs.meta deleted file mode 100644 index 1aa29cd6..00000000 --- a/Plugins/LiteNetLib/Layers/XorEncryptLayer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9e37bcdc5fcaf6444a9110a6a8024063 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/LiteNetLib.asmdef b/Plugins/LiteNetLib/LiteNetLib.asmdef deleted file mode 100644 index 530c72ed..00000000 --- a/Plugins/LiteNetLib/LiteNetLib.asmdef +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "LiteNetLib", - "references": [], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": true, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/Plugins/LiteNetLib/LiteNetLib.asmdef.meta b/Plugins/LiteNetLib/LiteNetLib.asmdef.meta deleted file mode 100644 index cb597c74..00000000 --- a/Plugins/LiteNetLib/LiteNetLib.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 31f70a8aefd57b049ae8e786e7ddac5f -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/LiteNetLib.csproj b/Plugins/LiteNetLib/LiteNetLib.csproj deleted file mode 100644 index 4a58e9ea..00000000 --- a/Plugins/LiteNetLib/LiteNetLib.csproj +++ /dev/null @@ -1,62 +0,0 @@ - - - - LiteNetLib - LiteNetLib - net6.0;net5.0;netcoreapp3.1;netstandard2.0;netstandard2.1 - net471;net6.0;net5.0;netstandard2.0;netstandard2.1;netcoreapp3.1 - true - Library - 7.3 - - true - 1701;1702;1705;1591 - 1.1.0 - Lite reliable UDP library for Mono and .NET - - - - TRACE;DEBUG - - - - TRACE - - - - true - $(DefineConstants);LITENETLIB_UNSAFE - udp reliable-udp network - https://github.com/RevenantX/LiteNetLib/releases/tag/v1.1.0 - git - https://github.com/RevenantX/LiteNetLib - https://github.com/RevenantX/LiteNetLib - MIT - True - 1.1.0 - Ruslan Pyrch - Copyright 2023 Ruslan Pyrch - Lite reliable UDP library for .NET, Mono, and .NET Core - LNL.png - README.md - - - - - - - - - - - - True - \ - - - True - \ - - - - \ No newline at end of file diff --git a/Plugins/LiteNetLib/LiteNetLib.csproj.meta b/Plugins/LiteNetLib/LiteNetLib.csproj.meta deleted file mode 100644 index 86d69fbf..00000000 --- a/Plugins/LiteNetLib/LiteNetLib.csproj.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 9e582c5b0276eb7408ce90f0a12b05d7 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NatPunchModule.cs b/Plugins/LiteNetLib/NatPunchModule.cs deleted file mode 100644 index 2310452c..00000000 --- a/Plugins/LiteNetLib/NatPunchModule.cs +++ /dev/null @@ -1,258 +0,0 @@ -using System.Collections.Concurrent; -using System.Net; -using LiteNetLib.Utils; - -namespace LiteNetLib -{ - public enum NatAddressType - { - Internal, - External - } - - public interface INatPunchListener - { - void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token); - void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token); - } - - public class EventBasedNatPunchListener : INatPunchListener - { - public delegate void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token); - public delegate void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token); - - public event OnNatIntroductionRequest NatIntroductionRequest; - public event OnNatIntroductionSuccess NatIntroductionSuccess; - - void INatPunchListener.OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token) - { - if(NatIntroductionRequest != null) - NatIntroductionRequest(localEndPoint, remoteEndPoint, token); - } - - void INatPunchListener.OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token) - { - if (NatIntroductionSuccess != null) - NatIntroductionSuccess(targetEndPoint, type, token); - } - } - - /// - /// Module for UDP NAT Hole punching operations. Can be accessed from NetManager - /// - public sealed class NatPunchModule - { - struct RequestEventData - { - public IPEndPoint LocalEndPoint; - public IPEndPoint RemoteEndPoint; - public string Token; - } - - struct SuccessEventData - { - public IPEndPoint TargetEndPoint; - public NatAddressType Type; - public string Token; - } - - class NatIntroduceRequestPacket - { - public IPEndPoint Internal { get; set; } - public string Token { get; set; } - } - - class NatIntroduceResponsePacket - { - public IPEndPoint Internal { get; set; } - public IPEndPoint External { get; set; } - public string Token { get; set; } - } - - class NatPunchPacket - { - public string Token { get; set; } - public bool IsExternal { get; set; } - } - - private readonly NetManager _socket; - private readonly ConcurrentQueue _requestEvents = new ConcurrentQueue(); - private readonly ConcurrentQueue _successEvents = new ConcurrentQueue(); - private readonly NetDataReader _cacheReader = new NetDataReader(); - private readonly NetDataWriter _cacheWriter = new NetDataWriter(); - private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(MaxTokenLength); - private INatPunchListener _natPunchListener; - public const int MaxTokenLength = 256; - - /// - /// Events automatically will be called without PollEvents method from another thread - /// - public bool UnsyncedEvents = false; - - internal NatPunchModule(NetManager socket) - { - _socket = socket; - _netPacketProcessor.SubscribeReusable(OnNatIntroductionResponse); - _netPacketProcessor.SubscribeReusable(OnNatIntroductionRequest); - _netPacketProcessor.SubscribeReusable(OnNatPunch); - } - - internal void ProcessMessage(IPEndPoint senderEndPoint, NetPacket packet) - { - lock (_cacheReader) - { - _cacheReader.SetSource(packet.RawData, NetConstants.HeaderSize, packet.Size); - _netPacketProcessor.ReadAllPackets(_cacheReader, senderEndPoint); - } - } - - public void Init(INatPunchListener listener) - { - _natPunchListener = listener; - } - - private void Send(T packet, IPEndPoint target) where T : class, new() - { - _cacheWriter.Reset(); - _cacheWriter.Put((byte)PacketProperty.NatMessage); - _netPacketProcessor.Write(_cacheWriter, packet); - _socket.SendRaw(_cacheWriter.Data, 0, _cacheWriter.Length, target); - } - - public void NatIntroduce( - IPEndPoint hostInternal, - IPEndPoint hostExternal, - IPEndPoint clientInternal, - IPEndPoint clientExternal, - string additionalInfo) - { - var req = new NatIntroduceResponsePacket - { - Token = additionalInfo - }; - - //First packet (server) send to client - req.Internal = hostInternal; - req.External = hostExternal; - Send(req, clientExternal); - - //Second packet (client) send to server - req.Internal = clientInternal; - req.External = clientExternal; - Send(req, hostExternal); - } - - public void PollEvents() - { - if (UnsyncedEvents) - return; - - if (_natPunchListener == null || (_successEvents.IsEmpty && _requestEvents.IsEmpty)) - return; - - while (_successEvents.TryDequeue(out var evt)) - { - _natPunchListener.OnNatIntroductionSuccess( - evt.TargetEndPoint, - evt.Type, - evt.Token); - } - - while (_requestEvents.TryDequeue(out var evt)) - { - _natPunchListener.OnNatIntroductionRequest(evt.LocalEndPoint, evt.RemoteEndPoint, evt.Token); - } - } - - public void SendNatIntroduceRequest(string host, int port, string additionalInfo) - { - SendNatIntroduceRequest(NetUtils.MakeEndPoint(host, port), additionalInfo); - } - - public void SendNatIntroduceRequest(IPEndPoint masterServerEndPoint, string additionalInfo) - { - //prepare outgoing data - string networkIp = NetUtils.GetLocalIp(LocalAddrType.IPv4); - if (string.IsNullOrEmpty(networkIp)) - { - networkIp = NetUtils.GetLocalIp(LocalAddrType.IPv6); - } - - Send( - new NatIntroduceRequestPacket - { - Internal = NetUtils.MakeEndPoint(networkIp, _socket.LocalPort), - Token = additionalInfo - }, - masterServerEndPoint); - } - - //We got request and must introduce - private void OnNatIntroductionRequest(NatIntroduceRequestPacket req, IPEndPoint senderEndPoint) - { - if (UnsyncedEvents) - { - _natPunchListener.OnNatIntroductionRequest( - req.Internal, - senderEndPoint, - req.Token); - } - else - { - _requestEvents.Enqueue(new RequestEventData - { - LocalEndPoint = req.Internal, - RemoteEndPoint = senderEndPoint, - Token = req.Token - }); - } - } - - //We got introduce and must punch - private void OnNatIntroductionResponse(NatIntroduceResponsePacket req) - { - NetDebug.Write(NetLogLevel.Trace, "[NAT] introduction received"); - - // send internal punch - var punchPacket = new NatPunchPacket {Token = req.Token}; - Send(punchPacket, req.Internal); - NetDebug.Write(NetLogLevel.Trace, $"[NAT] internal punch sent to {req.Internal}"); - - // hack for some routers - _socket.Ttl = 2; - _socket.SendRaw(new[] { (byte)PacketProperty.Empty }, 0, 1, req.External); - - // send external punch - _socket.Ttl = NetConstants.SocketTTL; - punchPacket.IsExternal = true; - Send(punchPacket, req.External); - NetDebug.Write(NetLogLevel.Trace, $"[NAT] external punch sent to {req.External}"); - } - - //We got punch and can connect - private void OnNatPunch(NatPunchPacket req, IPEndPoint senderEndPoint) - { - //Read info - NetDebug.Write(NetLogLevel.Trace, $"[NAT] punch received from {senderEndPoint} - additional info: {req.Token}"); - - //Release punch success to client; enabling him to Connect() to Sender if token is ok - if(UnsyncedEvents) - { - _natPunchListener.OnNatIntroductionSuccess( - senderEndPoint, - req.IsExternal ? NatAddressType.External : NatAddressType.Internal, - req.Token - ); - } - else - { - _successEvents.Enqueue(new SuccessEventData - { - TargetEndPoint = senderEndPoint, - Type = req.IsExternal ? NatAddressType.External : NatAddressType.Internal, - Token = req.Token - }); - } - } - } -} diff --git a/Plugins/LiteNetLib/NatPunchModule.cs.meta b/Plugins/LiteNetLib/NatPunchModule.cs.meta deleted file mode 100644 index d7147e77..00000000 --- a/Plugins/LiteNetLib/NatPunchModule.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f3ab6e1d42a247c499d0e14ee4106d02 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NativeSocket.cs b/Plugins/LiteNetLib/NativeSocket.cs deleted file mode 100644 index fc846c8b..00000000 --- a/Plugins/LiteNetLib/NativeSocket.cs +++ /dev/null @@ -1,301 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace LiteNetLib -{ - internal readonly struct NativeAddr : IEquatable - { - //common parts - private readonly long _part1; //family, port, etc - private readonly long _part2; - //ipv6 parts - private readonly long _part3; - private readonly int _part4; - - private readonly int _hash; - - public NativeAddr(byte[] address, int len) - { - _part1 = BitConverter.ToInt64(address, 0); - _part2 = BitConverter.ToInt64(address, 8); - if (len > 16) - { - _part3 = BitConverter.ToInt64(address, 16); - _part4 = BitConverter.ToInt32(address, 24); - } - else - { - _part3 = 0; - _part4 = 0; - } - _hash = (int)(_part1 >> 32) ^ (int)_part1 ^ - (int)(_part2 >> 32) ^ (int)_part2 ^ - (int)(_part3 >> 32) ^ (int)_part3 ^ - _part4; - } - - public override int GetHashCode() - { - return _hash; - } - - public bool Equals(NativeAddr other) - { - return _part1 == other._part1 && - _part2 == other._part2 && - _part3 == other._part3 && - _part4 == other._part4; - } - - public override bool Equals(object obj) - { - return obj is NativeAddr other && Equals(other); - } - - public static bool operator ==(NativeAddr left, NativeAddr right) - { - return left.Equals(right); - } - - public static bool operator !=(NativeAddr left, NativeAddr right) - { - return !left.Equals(right); - } - } - - internal class NativeEndPoint : IPEndPoint - { - public readonly byte[] NativeAddress; - - public NativeEndPoint(byte[] address) : base(IPAddress.Any, 0) - { - NativeAddress = new byte[address.Length]; - Buffer.BlockCopy(address, 0, NativeAddress, 0, address.Length); - - short family = (short)((address[1] << 8) | address[0]); - Port =(ushort)((address[2] << 8) | address[3]); - - if ((NativeSocket.UnixMode && family == NativeSocket.AF_INET6) || (!NativeSocket.UnixMode && (AddressFamily)family == AddressFamily.InterNetworkV6)) - { - uint scope = unchecked((uint)( - (address[27] << 24) + - (address[26] << 16) + - (address[25] << 8) + - (address[24]))); -#if NETCOREAPP || NETSTANDARD2_1 || NETSTANDARD2_1_OR_GREATER - Address = new IPAddress(new ReadOnlySpan(address, 8, 16), scope); -#else - byte[] addrBuffer = new byte[16]; - Buffer.BlockCopy(address, 8, addrBuffer, 0, 16); - Address = new IPAddress(addrBuffer, scope); -#endif - } - else //IPv4 - { - long ipv4Addr = unchecked((uint)((address[4] & 0x000000FF) | - (address[5] << 8 & 0x0000FF00) | - (address[6] << 16 & 0x00FF0000) | - (address[7] << 24))); - Address = new IPAddress(ipv4Addr); - } - } - } - - internal static class NativeSocket - { - static -#if LITENETLIB_UNSAFE - unsafe -#endif - class WinSock - { - private const string LibName = "ws2_32.dll"; - - [DllImport(LibName, SetLastError = true)] - public static extern int recvfrom( - IntPtr socketHandle, - [In, Out] byte[] pinnedBuffer, - [In] int len, - [In] SocketFlags socketFlags, - [Out] byte[] socketAddress, - [In, Out] ref int socketAddressSize); - - [DllImport(LibName, SetLastError = true)] - internal static extern int sendto( - IntPtr socketHandle, -#if LITENETLIB_UNSAFE - byte* pinnedBuffer, -#else - [In] byte[] pinnedBuffer, -#endif - [In] int len, - [In] SocketFlags socketFlags, - [In] byte[] socketAddress, - [In] int socketAddressSize); - } - - static -#if LITENETLIB_UNSAFE - unsafe -#endif - class UnixSock - { - private const string LibName = "libc"; - - [DllImport(LibName, SetLastError = true)] - public static extern int recvfrom( - IntPtr socketHandle, - [In, Out] byte[] pinnedBuffer, - [In] int len, - [In] SocketFlags socketFlags, - [Out] byte[] socketAddress, - [In, Out] ref int socketAddressSize); - - [DllImport(LibName, SetLastError = true)] - internal static extern int sendto( - IntPtr socketHandle, -#if LITENETLIB_UNSAFE - byte* pinnedBuffer, -#else - [In] byte[] pinnedBuffer, -#endif - [In] int len, - [In] SocketFlags socketFlags, - [In] byte[] socketAddress, - [In] int socketAddressSize); - } - - public static readonly bool IsSupported = false; - public static readonly bool UnixMode = false; - - public const int IPv4AddrSize = 16; - public const int IPv6AddrSize = 28; - public const int AF_INET = 2; - public const int AF_INET6 = 10; - - private static readonly Dictionary NativeErrorToSocketError = new Dictionary - { - { 13, SocketError.AccessDenied }, //EACCES - { 98, SocketError.AddressAlreadyInUse }, //EADDRINUSE - { 99, SocketError.AddressNotAvailable }, //EADDRNOTAVAIL - { 97, SocketError.AddressFamilyNotSupported }, //EAFNOSUPPORT - { 11, SocketError.WouldBlock }, //EAGAIN - { 114, SocketError.AlreadyInProgress }, //EALREADY - { 9, SocketError.OperationAborted }, //EBADF - { 125, SocketError.OperationAborted }, //ECANCELED - { 103, SocketError.ConnectionAborted }, //ECONNABORTED - { 111, SocketError.ConnectionRefused }, //ECONNREFUSED - { 104, SocketError.ConnectionReset }, //ECONNRESET - { 89, SocketError.DestinationAddressRequired }, //EDESTADDRREQ - { 14, SocketError.Fault }, //EFAULT - { 112, SocketError.HostDown }, //EHOSTDOWN - { 6, SocketError.HostNotFound }, //ENXIO - { 113, SocketError.HostUnreachable }, //EHOSTUNREACH - { 115, SocketError.InProgress }, //EINPROGRESS - { 4, SocketError.Interrupted }, //EINTR - { 22, SocketError.InvalidArgument }, //EINVAL - { 106, SocketError.IsConnected }, //EISCONN - { 24, SocketError.TooManyOpenSockets }, //EMFILE - { 90, SocketError.MessageSize }, //EMSGSIZE - { 100, SocketError.NetworkDown }, //ENETDOWN - { 102, SocketError.NetworkReset }, //ENETRESET - { 101, SocketError.NetworkUnreachable }, //ENETUNREACH - { 23, SocketError.TooManyOpenSockets }, //ENFILE - { 105, SocketError.NoBufferSpaceAvailable }, //ENOBUFS - { 61, SocketError.NoData }, //ENODATA - { 2, SocketError.AddressNotAvailable }, //ENOENT - { 92, SocketError.ProtocolOption }, //ENOPROTOOPT - { 107, SocketError.NotConnected }, //ENOTCONN - { 88, SocketError.NotSocket }, //ENOTSOCK - { 3440, SocketError.OperationNotSupported }, //ENOTSUP - { 1, SocketError.AccessDenied }, //EPERM - { 32, SocketError.Shutdown }, //EPIPE - { 96, SocketError.ProtocolFamilyNotSupported }, //EPFNOSUPPORT - { 93, SocketError.ProtocolNotSupported }, //EPROTONOSUPPORT - { 91, SocketError.ProtocolType }, //EPROTOTYPE - { 94, SocketError.SocketNotSupported }, //ESOCKTNOSUPPORT - { 108, SocketError.Disconnecting }, //ESHUTDOWN - { 110, SocketError.TimedOut }, //ETIMEDOUT - { 0, SocketError.Success } - }; - - static NativeSocket() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - IsSupported = true; - UnixMode = true; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - IsSupported = true; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int RecvFrom( - IntPtr socketHandle, - byte[] pinnedBuffer, - int len, - byte[] socketAddress, - ref int socketAddressSize) - { - return UnixMode - ? UnixSock.recvfrom(socketHandle, pinnedBuffer, len, 0, socketAddress, ref socketAddressSize) - : WinSock.recvfrom(socketHandle, pinnedBuffer, len, 0, socketAddress, ref socketAddressSize); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public -#if LITENETLIB_UNSAFE - unsafe -#endif - static int SendTo( - IntPtr socketHandle, -#if LITENETLIB_UNSAFE - byte* pinnedBuffer, -#else - byte[] pinnedBuffer, -#endif - int len, - byte[] socketAddress, - int socketAddressSize) - { - return UnixMode - ? UnixSock.sendto(socketHandle, pinnedBuffer, len, 0, socketAddress, socketAddressSize) - : WinSock.sendto(socketHandle, pinnedBuffer, len, 0, socketAddress, socketAddressSize); - } - - public static SocketError GetSocketError() - { - int error = Marshal.GetLastWin32Error(); - if (UnixMode) - return NativeErrorToSocketError.TryGetValue(error, out var err) - ? err - : SocketError.SocketError; - return (SocketError)error; - } - - public static SocketException GetSocketException() - { - int error = Marshal.GetLastWin32Error(); - if (UnixMode) - return NativeErrorToSocketError.TryGetValue(error, out var err) - ? new SocketException((int)err) - : new SocketException((int)SocketError.SocketError); - return new SocketException(error); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short GetNativeAddressFamily(IPEndPoint remoteEndPoint) - { - return UnixMode - ? (short)(remoteEndPoint.AddressFamily == AddressFamily.InterNetwork ? AF_INET : AF_INET6) - : (short)remoteEndPoint.AddressFamily; - } - } -} diff --git a/Plugins/LiteNetLib/NativeSocket.cs.meta b/Plugins/LiteNetLib/NativeSocket.cs.meta deleted file mode 100644 index 16c94163..00000000 --- a/Plugins/LiteNetLib/NativeSocket.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e15ffd38c77258945ab40da92f2abb25 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetConstants.cs b/Plugins/LiteNetLib/NetConstants.cs deleted file mode 100644 index ca7dfbcd..00000000 --- a/Plugins/LiteNetLib/NetConstants.cs +++ /dev/null @@ -1,75 +0,0 @@ -namespace LiteNetLib -{ - /// - /// Sending method type - /// - public enum DeliveryMethod : byte - { - /// - /// Unreliable. Packets can be dropped, can be duplicated, can arrive without order. - /// - Unreliable = 4, - - /// - /// Reliable. Packets won't be dropped, won't be duplicated, can arrive without order. - /// - ReliableUnordered = 0, - - /// - /// Unreliable. Packets can be dropped, won't be duplicated, will arrive in order. - /// - Sequenced = 1, - - /// - /// Reliable and ordered. Packets won't be dropped, won't be duplicated, will arrive in order. - /// - ReliableOrdered = 2, - - /// - /// Reliable only last packet. Packets can be dropped (except the last one), won't be duplicated, will arrive in order. - /// Cannot be fragmented - /// - ReliableSequenced = 3 - } - - /// - /// Network constants. Can be tuned from sources for your purposes. - /// - public static class NetConstants - { - //can be tuned - public const int DefaultWindowSize = 64; - public const int SocketBufferSize = 1024 * 1024; //1mb - public const int SocketTTL = 255; - - public const int HeaderSize = 1; - public const int ChanneledHeaderSize = 4; - public const int FragmentHeaderSize = 6; - public const int FragmentedHeaderTotalSize = ChanneledHeaderSize + FragmentHeaderSize; - public const ushort MaxSequence = 32768; - public const ushort HalfMaxSequence = MaxSequence / 2; - - //protocol - internal const int ProtocolId = 13; - internal const int MaxUdpHeaderSize = 68; - internal const int ChannelTypeCount = 4; - - internal static readonly int[] PossibleMtu = - { - 576 - MaxUdpHeaderSize, //minimal (RFC 1191) - 1024, //most games standard - 1232 - MaxUdpHeaderSize, - 1460 - MaxUdpHeaderSize, //google cloud - 1472 - MaxUdpHeaderSize, //VPN - 1492 - MaxUdpHeaderSize, //Ethernet with LLC and SNAP, PPPoE (RFC 1042) - 1500 - MaxUdpHeaderSize //Ethernet II (RFC 1191) - }; - - //Max possible single packet size - public static readonly int MaxPacketSize = PossibleMtu[PossibleMtu.Length - 1]; - public static readonly int MaxUnreliableDataSize = MaxPacketSize - HeaderSize; - - //peer specific - public const byte MaxConnectionNumber = 4; - } -} diff --git a/Plugins/LiteNetLib/NetConstants.cs.meta b/Plugins/LiteNetLib/NetConstants.cs.meta deleted file mode 100644 index 06d813ad..00000000 --- a/Plugins/LiteNetLib/NetConstants.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a0ea28c584481764793945d25f894681 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetDebug.cs b/Plugins/LiteNetLib/NetDebug.cs deleted file mode 100644 index 44cb6f3e..00000000 --- a/Plugins/LiteNetLib/NetDebug.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Diagnostics; - -namespace LiteNetLib -{ - public class InvalidPacketException : ArgumentException - { - public InvalidPacketException(string message) : base(message) - { - } - } - - public class TooBigPacketException : InvalidPacketException - { - public TooBigPacketException(string message) : base(message) - { - } - } - - public enum NetLogLevel - { - Warning, - Error, - Trace, - Info - } - - /// - /// Interface to implement for your own logger - /// - public interface INetLogger - { - void WriteNet(NetLogLevel level, string str, params object[] args); - } - - /// - /// Static class for defining your own LiteNetLib logger instead of Console.WriteLine - /// or Debug.Log if compiled with UNITY flag - /// - public static class NetDebug - { - public static INetLogger Logger = null; - private static readonly object DebugLogLock = new object(); - private static void WriteLogic(NetLogLevel logLevel, string str, params object[] args) - { - lock (DebugLogLock) - { - if (Logger == null) - { -#if UNITY_5_3_OR_NEWER - UnityEngine.Debug.Log(string.Format(str, args)); -#else - Console.WriteLine(str, args); -#endif - } - else - { - Logger.WriteNet(logLevel, str, args); - } - } - } - - [Conditional("DEBUG_MESSAGES")] - internal static void Write(string str) - { - WriteLogic(NetLogLevel.Trace, str); - } - - [Conditional("DEBUG_MESSAGES")] - internal static void Write(NetLogLevel level, string str) - { - WriteLogic(level, str); - } - - [Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")] - internal static void WriteForce(string str) - { - WriteLogic(NetLogLevel.Trace, str); - } - - [Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")] - internal static void WriteForce(NetLogLevel level, string str) - { - WriteLogic(level, str); - } - - internal static void WriteError(string str) - { - WriteLogic(NetLogLevel.Error, str); - } - } -} diff --git a/Plugins/LiteNetLib/NetDebug.cs.meta b/Plugins/LiteNetLib/NetDebug.cs.meta deleted file mode 100644 index a007520a..00000000 --- a/Plugins/LiteNetLib/NetDebug.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 05e8d90ba46876441832487c42fb51f0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetManager.PacketPool.cs b/Plugins/LiteNetLib/NetManager.PacketPool.cs deleted file mode 100644 index 08312209..00000000 --- a/Plugins/LiteNetLib/NetManager.PacketPool.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; - -namespace LiteNetLib -{ - public partial class NetManager - { - private NetPacket _poolHead; - private int _poolCount; - private readonly object _poolLock = new object(); - - /// - /// Maximum packet pool size (increase if you have tons of packets sending) - /// - public int PacketPoolSize = 1000; - - public int PoolCount => _poolCount; - - private NetPacket PoolGetWithData(PacketProperty property, byte[] data, int start, int length) - { - int headerSize = NetPacket.GetHeaderSize(property); - NetPacket packet = PoolGetPacket(length + headerSize); - packet.Property = property; - Buffer.BlockCopy(data, start, packet.RawData, headerSize, length); - return packet; - } - - //Get packet with size - private NetPacket PoolGetWithProperty(PacketProperty property, int size) - { - NetPacket packet = PoolGetPacket(size + NetPacket.GetHeaderSize(property)); - packet.Property = property; - return packet; - } - - private NetPacket PoolGetWithProperty(PacketProperty property) - { - NetPacket packet = PoolGetPacket(NetPacket.GetHeaderSize(property)); - packet.Property = property; - return packet; - } - - internal NetPacket PoolGetPacket(int size) - { - if (size > NetConstants.MaxPacketSize) - return new NetPacket(size); - - NetPacket packet; - lock (_poolLock) - { - packet = _poolHead; - if (packet == null) - return new NetPacket(size); - - _poolHead = _poolHead.Next; - _poolCount--; - } - - packet.Size = size; - if (packet.RawData.Length < size) - packet.RawData = new byte[size]; - return packet; - } - - internal void PoolRecycle(NetPacket packet) - { - if (packet.RawData.Length > NetConstants.MaxPacketSize || _poolCount >= PacketPoolSize) - { - //Don't pool big packets. Save memory - return; - } - - //Clean fragmented flag - packet.RawData[0] = 0; - lock (_poolLock) - { - packet.Next = _poolHead; - _poolHead = packet; - _poolCount++; - } - } - } -} diff --git a/Plugins/LiteNetLib/NetManager.PacketPool.cs.meta b/Plugins/LiteNetLib/NetManager.PacketPool.cs.meta deleted file mode 100644 index 384b838c..00000000 --- a/Plugins/LiteNetLib/NetManager.PacketPool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8a5763b52c5b7684cbc54c2366e195be -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetManager.Socket.cs b/Plugins/LiteNetLib/NetManager.Socket.cs deleted file mode 100644 index 1adc2ac2..00000000 --- a/Plugins/LiteNetLib/NetManager.Socket.cs +++ /dev/null @@ -1,728 +0,0 @@ -using System.Runtime.InteropServices; -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Threading; -using LiteNetLib.Utils; - -namespace LiteNetLib -{ - public partial class NetManager - { - private const int ReceivePollingTime = 500000; //0.5 second - - private Socket _udpSocketv4; - private Socket _udpSocketv6; - private Thread _receiveThread; - private IPEndPoint _bufferEndPointv4; - private IPEndPoint _bufferEndPointv6; -#if UNITY_2018_3_OR_NEWER - private PausedSocketFix _pausedSocketFix; -#endif - -#if !LITENETLIB_UNSAFE - [ThreadStatic] private static byte[] _sendToBuffer; -#endif - [ThreadStatic] private static byte[] _endPointBuffer; - - private readonly Dictionary _nativeAddrMap = new Dictionary(); - - private const int SioUdpConnreset = -1744830452; //SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 - private static readonly IPAddress MulticastAddressV6 = IPAddress.Parse("ff02::1"); - public static readonly bool IPv6Support; - - /// - /// Maximum packets count that will be processed in Manual PollEvents - /// - public int MaxPacketsReceivePerUpdate = 0; - - // special case in iOS (and possibly android that should be resolved in unity) - internal bool NotConnected; - - public short Ttl - { - get - { -#if UNITY_SWITCH - return 0; -#else - return _udpSocketv4.Ttl; -#endif - } - internal set - { -#if !UNITY_SWITCH - _udpSocketv4.Ttl = value; -#endif - } - } - - static NetManager() - { -#if DISABLE_IPV6 - IPv6Support = false; -#elif !UNITY_2019_1_OR_NEWER && !UNITY_2018_4_OR_NEWER && (!UNITY_EDITOR && ENABLE_IL2CPP) - string version = UnityEngine.Application.unityVersion; - IPv6Support = Socket.OSSupportsIPv6 && int.Parse(version.Remove(version.IndexOf('f')).Split('.')[2]) >= 6; -#else - IPv6Support = Socket.OSSupportsIPv6; -#endif - } - - private void RegisterEndPoint(IPEndPoint ep) - { - if (UseNativeSockets && ep is NativeEndPoint nep) - { - _nativeAddrMap.Add(new NativeAddr(nep.NativeAddress, nep.NativeAddress.Length), nep); - } - } - - private void UnregisterEndPoint(IPEndPoint ep) - { - if (UseNativeSockets && ep is NativeEndPoint nep) - { - var nativeAddr = new NativeAddr(nep.NativeAddress, nep.NativeAddress.Length); - _nativeAddrMap.Remove(nativeAddr); - } - } - - private bool ProcessError(SocketException ex) - { - switch (ex.SocketErrorCode) - { - case SocketError.NotConnected: - NotConnected = true; - return true; - case SocketError.Interrupted: - case SocketError.NotSocket: - case SocketError.OperationAborted: - return true; - case SocketError.ConnectionReset: - case SocketError.MessageSize: - case SocketError.TimedOut: - case SocketError.NetworkReset: - //NetDebug.Write($"[R]Ignored error: {(int)ex.SocketErrorCode} - {ex}"); - break; - default: - NetDebug.WriteError($"[R]Error code: {(int)ex.SocketErrorCode} - {ex}"); - CreateEvent(NetEvent.EType.Error, errorCode: ex.SocketErrorCode); - break; - } - return false; - } - - private void ManualReceive(Socket socket, EndPoint bufferEndPoint) - { - //Reading data - try - { - int packetsReceived = 0; - while (socket.Available > 0) - { - ReceiveFrom(socket, ref bufferEndPoint); - packetsReceived++; - if (packetsReceived == MaxPacketsReceivePerUpdate) - break; - } - } - catch (SocketException ex) - { - ProcessError(ex); - } - catch (ObjectDisposedException) - { - - } - catch (Exception e) - { - //protects socket receive thread - NetDebug.WriteError("[NM] SocketReceiveThread error: " + e ); - } - } - - private bool NativeReceiveFrom(ref NetPacket packet, IntPtr s, byte[] addrBuffer, int addrSize) - { - //Reading data - packet.Size = NativeSocket.RecvFrom(s, packet.RawData, NetConstants.MaxPacketSize, addrBuffer, ref addrSize); - if (packet.Size == 0) - return false; //socket closed - if (packet.Size == -1) - { - var errorCode = NativeSocket.GetSocketError(); - //Linux timeout EAGAIN - return errorCode == SocketError.WouldBlock || errorCode == SocketError.TimedOut || ProcessError(new SocketException((int)errorCode)) == false; - } - - var nativeAddr = new NativeAddr(addrBuffer, addrSize); - if (!_nativeAddrMap.TryGetValue(nativeAddr, out var endPoint)) - endPoint = new NativeEndPoint(addrBuffer); - - //All ok! - //NetDebug.WriteForce($"[R]Received data from {endPoint}, result: {packet.Size}"); - OnMessageReceived(packet, endPoint); - packet = PoolGetPacket(NetConstants.MaxPacketSize); - return true; - } - - private void NativeReceiveLogic() - { - IntPtr socketHandle4 = _udpSocketv4.Handle; - IntPtr socketHandle6 = _udpSocketv6?.Handle ?? IntPtr.Zero; - byte[] addrBuffer4 = new byte[NativeSocket.IPv4AddrSize]; - byte[] addrBuffer6 = new byte[NativeSocket.IPv6AddrSize]; - int addrSize4 = addrBuffer4.Length; - int addrSize6 = addrBuffer6.Length; - var selectReadList = new List(2); - var socketv4 = _udpSocketv4; - var socketV6 = _udpSocketv6; - var packet = PoolGetPacket(NetConstants.MaxPacketSize); - - while (IsRunning) - { - if (socketV6 == null) - { - if (NativeReceiveFrom(ref packet, socketHandle4, addrBuffer4, addrSize4) == false) - return; - continue; - } - bool messageReceived = false; - if (socketv4.Available != 0) - { - if (NativeReceiveFrom(ref packet, socketHandle4, addrBuffer4, addrSize4) == false) - return; - messageReceived = true; - } - if (socketV6.Available != 0) - { - if (NativeReceiveFrom(ref packet, socketHandle6, addrBuffer6, addrSize6) == false) - return; - messageReceived = true; - } - if (messageReceived) - continue; - selectReadList.Clear(); - selectReadList.Add(socketv4); - selectReadList.Add(socketV6); - try - { - Socket.Select(selectReadList, null, null, ReceivePollingTime); - } - catch (SocketException ex) - { - if (ProcessError(ex)) - return; - } - catch (ObjectDisposedException) - { - //socket closed - return; - } - catch (ThreadAbortException) - { - //thread closed - return; - } - catch (Exception e) - { - //protects socket receive thread - NetDebug.WriteError("[NM] SocketReceiveThread error: " + e ); - } - } - } - - private void ReceiveFrom(Socket s, ref EndPoint bufferEndPoint) - { - var packet = PoolGetPacket(NetConstants.MaxPacketSize); - packet.Size = s.ReceiveFrom(packet.RawData, 0, NetConstants.MaxPacketSize, SocketFlags.None, ref bufferEndPoint); - OnMessageReceived(packet, (IPEndPoint)bufferEndPoint); - } - - private void ReceiveLogic() - { - EndPoint bufferEndPoint4 = new IPEndPoint(IPAddress.Any, 0); - EndPoint bufferEndPoint6 = new IPEndPoint(IPAddress.IPv6Any, 0); - var selectReadList = new List(2); - var socketv4 = _udpSocketv4; - var socketV6 = _udpSocketv6; - - while (IsRunning) - { - //Reading data - try - { - if (socketV6 == null) - { - if (socketv4.Available == 0 && !socketv4.Poll(ReceivePollingTime, SelectMode.SelectRead)) - continue; - ReceiveFrom(socketv4, ref bufferEndPoint4); - } - else - { - bool messageReceived = false; - if (socketv4.Available != 0) - { - ReceiveFrom(socketv4, ref bufferEndPoint4); - messageReceived = true; - } - if (socketV6.Available != 0) - { - ReceiveFrom(socketV6, ref bufferEndPoint6); - messageReceived = true; - } - if (messageReceived) - continue; - - selectReadList.Clear(); - selectReadList.Add(socketv4); - selectReadList.Add(socketV6); - Socket.Select(selectReadList, null, null, ReceivePollingTime); - } - //NetDebug.Write(NetLogLevel.Trace, $"[R]Received data from {bufferEndPoint}, result: {packet.Size}"); - } - catch (SocketException ex) - { - if (ProcessError(ex)) - return; - } - catch (ObjectDisposedException) - { - //socket closed - return; - } - catch (ThreadAbortException) - { - //thread closed - return; - } - catch (Exception e) - { - //protects socket receive thread - NetDebug.WriteError("[NM] SocketReceiveThread error: " + e ); - } - } - } - - /// - /// Start logic thread and listening on selected port - /// - /// bind to specific ipv4 address - /// bind to specific ipv6 address - /// port to listen - /// mode of library - public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode) - { - if (IsRunning && NotConnected == false) - return false; - - NotConnected = false; - _manualMode = manualMode; - UseNativeSockets = UseNativeSockets && NativeSocket.IsSupported; - _udpSocketv4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - if (!BindSocket(_udpSocketv4, new IPEndPoint(addressIPv4, port))) - return false; - - LocalPort = ((IPEndPoint) _udpSocketv4.LocalEndPoint).Port; - -#if UNITY_2018_3_OR_NEWER - if (_pausedSocketFix == null) - _pausedSocketFix = new PausedSocketFix(this, addressIPv4, addressIPv6, port, manualMode); -#endif - - IsRunning = true; - if (_manualMode) - { - _bufferEndPointv4 = new IPEndPoint(IPAddress.Any, 0); - } - - //Check IPv6 support - if (IPv6Support && IPv6Enabled) - { - _udpSocketv6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); - //Use one port for two sockets - if (BindSocket(_udpSocketv6, new IPEndPoint(addressIPv6, LocalPort))) - { - if (_manualMode) - { - _bufferEndPointv6 = new IPEndPoint(IPAddress.IPv6Any, 0); - } - } - else - { - _udpSocketv6 = null; - } - } - - if (!manualMode) - { - ThreadStart ts = ReceiveLogic; - if (UseNativeSockets) - ts = NativeReceiveLogic; - _receiveThread = new Thread(ts) - { - Name = $"ReceiveThread({LocalPort})", - IsBackground = true - }; - _receiveThread.Start(); - if (_logicThread == null) - { - _logicThread = new Thread(UpdateLogic) { Name = "LogicThread", IsBackground = true }; - _logicThread.Start(); - } - } - - return true; - } - - private bool BindSocket(Socket socket, IPEndPoint ep) - { - //Setup socket - socket.ReceiveTimeout = 500; - socket.SendTimeout = 500; - socket.ReceiveBufferSize = NetConstants.SocketBufferSize; - socket.SendBufferSize = NetConstants.SocketBufferSize; - socket.Blocking = true; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - try - { - socket.IOControl(SioUdpConnreset, new byte[] {0}, null); - } - catch - { - //ignored - } - } - - try - { - socket.ExclusiveAddressUse = !ReuseAddress; - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, ReuseAddress); - } - catch - { - //Unity with IL2CPP throws an exception here, it doesn't matter in most cases so just ignore it - } - if (ep.AddressFamily == AddressFamily.InterNetwork) - { - Ttl = NetConstants.SocketTTL; - - try { socket.EnableBroadcast = true; } - catch (SocketException e) - { - NetDebug.WriteError($"[B]Broadcast error: {e.SocketErrorCode}"); - } - - if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - try { socket.DontFragment = true; } - catch (SocketException e) - { - NetDebug.WriteError($"[B]DontFragment error: {e.SocketErrorCode}"); - } - } - } - //Bind - try - { - socket.Bind(ep); - NetDebug.Write(NetLogLevel.Trace, $"[B]Successfully binded to port: {((IPEndPoint)socket.LocalEndPoint).Port}, AF: {socket.AddressFamily}"); - - //join multicast - if (ep.AddressFamily == AddressFamily.InterNetworkV6) - { - try - { -#if !UNITY_2018_3_OR_NEWER - socket.SetSocketOption( - SocketOptionLevel.IPv6, - SocketOptionName.AddMembership, - new IPv6MulticastOption(MulticastAddressV6)); -#endif - } - catch (Exception) - { - // Unity3d throws exception - ignored - } - } - } - catch (SocketException bindException) - { - switch (bindException.SocketErrorCode) - { - //IPv6 bind fix - case SocketError.AddressAlreadyInUse: - if (socket.AddressFamily == AddressFamily.InterNetworkV6) - { - try - { - //Set IPv6Only - socket.DualMode = false; - socket.Bind(ep); - } - catch (SocketException ex) - { - //because its fixed in 2018_3 - NetDebug.WriteError($"[B]Bind exception: {ex}, errorCode: {ex.SocketErrorCode}"); - return false; - } - return true; - } - break; - //hack for iOS (Unity3D) - case SocketError.AddressFamilyNotSupported: - return true; - } - NetDebug.WriteError($"[B]Bind exception: {bindException}, errorCode: {bindException.SocketErrorCode}"); - return false; - } - return true; - } - - internal int SendRawAndRecycle(NetPacket packet, IPEndPoint remoteEndPoint) - { - int result = SendRaw(packet.RawData, 0, packet.Size, remoteEndPoint); - PoolRecycle(packet); - return result; - } - - internal int SendRaw(NetPacket packet, IPEndPoint remoteEndPoint) - { - return SendRaw(packet.RawData, 0, packet.Size, remoteEndPoint); - } - - internal int SendRaw(byte[] message, int start, int length, IPEndPoint remoteEndPoint) - { - if (!IsRunning) - return 0; - - NetPacket expandedPacket = null; - if (_extraPacketLayer != null) - { - expandedPacket = PoolGetPacket(length + _extraPacketLayer.ExtraPacketSizeForLayer); - Buffer.BlockCopy(message, start, expandedPacket.RawData, 0, length); - start = 0; - _extraPacketLayer.ProcessOutBoundPacket(ref remoteEndPoint, ref expandedPacket.RawData, ref start, ref length); - message = expandedPacket.RawData; - } - - var socket = _udpSocketv4; - if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6 && IPv6Support) - { - socket = _udpSocketv6; - if (socket == null) - return 0; - } - - int result; - try - { - if (UseNativeSockets) - { - byte[] socketAddress; - - if (remoteEndPoint is NativeEndPoint nep) - { - socketAddress = nep.NativeAddress; - } - else //Convert endpoint to raw - { - if (_endPointBuffer == null) - _endPointBuffer = new byte[NativeSocket.IPv6AddrSize]; - socketAddress = _endPointBuffer; - - bool ipv4 = remoteEndPoint.AddressFamily == AddressFamily.InterNetwork; - short addressFamily = NativeSocket.GetNativeAddressFamily(remoteEndPoint); - - socketAddress[0] = (byte) (addressFamily); - socketAddress[1] = (byte) (addressFamily >> 8); - socketAddress[2] = (byte) (remoteEndPoint.Port >> 8); - socketAddress[3] = (byte) (remoteEndPoint.Port); - - if (ipv4) - { -#pragma warning disable 618 - long addr = remoteEndPoint.Address.Address; -#pragma warning restore 618 - socketAddress[4] = (byte) (addr); - socketAddress[5] = (byte) (addr >> 8); - socketAddress[6] = (byte) (addr >> 16); - socketAddress[7] = (byte) (addr >> 24); - } - else - { -#if NETCOREAPP || NETSTANDARD2_1 || NETSTANDARD2_1_OR_GREATER - remoteEndPoint.Address.TryWriteBytes(new Span(socketAddress, 8, 16), out _); -#else - byte[] addrBytes = remoteEndPoint.Address.GetAddressBytes(); - Buffer.BlockCopy(addrBytes, 0, socketAddress, 8, 16); -#endif - } - } - -#if LITENETLIB_UNSAFE - unsafe - { - fixed (byte* dataWithOffset = &message[start]) - { - result = - NativeSocket.SendTo(socket.Handle, dataWithOffset, length, socketAddress, socketAddress.Length); - } - } -#else - if (start > 0) - { - if (_sendToBuffer == null) - _sendToBuffer = new byte[NetConstants.MaxPacketSize]; - Buffer.BlockCopy(message, start, _sendToBuffer, 0, length); - message = _sendToBuffer; - } - - result = NativeSocket.SendTo(socket.Handle, message, length, socketAddress, socketAddress.Length); -#endif - if (result == -1) - throw NativeSocket.GetSocketException(); - } - else - { - result = socket.SendTo(message, start, length, SocketFlags.None, remoteEndPoint); - } - //NetDebug.WriteForce("[S]Send packet to {0}, result: {1}", remoteEndPoint, result); - } - catch (SocketException ex) - { - switch (ex.SocketErrorCode) - { - case SocketError.NoBufferSpaceAvailable: - case SocketError.Interrupted: - return 0; - case SocketError.MessageSize: - NetDebug.Write(NetLogLevel.Trace, $"[SRD] 10040, datalen: {length}"); - return 0; - - case SocketError.HostUnreachable: - case SocketError.NetworkUnreachable: - if (DisconnectOnUnreachable && TryGetPeer(remoteEndPoint, out var fromPeer)) - { - DisconnectPeerForce( - fromPeer, - ex.SocketErrorCode == SocketError.HostUnreachable - ? DisconnectReason.HostUnreachable - : DisconnectReason.NetworkUnreachable, - ex.SocketErrorCode, - null); - } - - CreateEvent(NetEvent.EType.Error, remoteEndPoint: remoteEndPoint, errorCode: ex.SocketErrorCode); - return -1; - - default: - NetDebug.WriteError($"[S] {ex}"); - return -1; - } - } - catch (Exception ex) - { - NetDebug.WriteError($"[S] {ex}"); - return 0; - } - finally - { - if (expandedPacket != null) - { - PoolRecycle(expandedPacket); - } - } - - if (result <= 0) - return 0; - - if (EnableStatistics) - { - Statistics.IncrementPacketsSent(); - Statistics.AddBytesSent(length); - } - - return result; - } - - public bool SendBroadcast(NetDataWriter writer, int port) - { - return SendBroadcast(writer.Data, 0, writer.Length, port); - } - - public bool SendBroadcast(byte[] data, int port) - { - return SendBroadcast(data, 0, data.Length, port); - } - - public bool SendBroadcast(byte[] data, int start, int length, int port) - { - if (!IsRunning) - return false; - - NetPacket packet; - if (_extraPacketLayer != null) - { - var headerSize = NetPacket.GetHeaderSize(PacketProperty.Broadcast); - packet = PoolGetPacket(headerSize + length + _extraPacketLayer.ExtraPacketSizeForLayer); - packet.Property = PacketProperty.Broadcast; - Buffer.BlockCopy(data, start, packet.RawData, headerSize, length); - var checksumComputeStart = 0; - int preCrcLength = length + headerSize; - IPEndPoint emptyEp = null; - _extraPacketLayer.ProcessOutBoundPacket(ref emptyEp, ref packet.RawData, ref checksumComputeStart, ref preCrcLength); - } - else - { - packet = PoolGetWithData(PacketProperty.Broadcast, data, start, length); - } - - bool broadcastSuccess = false; - bool multicastSuccess = false; - try - { - broadcastSuccess = _udpSocketv4.SendTo( - packet.RawData, - 0, - packet.Size, - SocketFlags.None, - new IPEndPoint(IPAddress.Broadcast, port)) > 0; - - if (_udpSocketv6 != null) - { - multicastSuccess = _udpSocketv6.SendTo( - packet.RawData, - 0, - packet.Size, - SocketFlags.None, - new IPEndPoint(MulticastAddressV6, port)) > 0; - } - } - catch (Exception ex) - { - NetDebug.WriteError($"[S][MCAST] {ex}"); - return broadcastSuccess; - } - finally - { - PoolRecycle(packet); - } - - return broadcastSuccess || multicastSuccess; - } - - private void CloseSocket() - { - IsRunning = false; - _udpSocketv4?.Close(); - _udpSocketv6?.Close(); - _udpSocketv4 = null; - _udpSocketv6 = null; - if (_receiveThread != null && _receiveThread != Thread.CurrentThread) - _receiveThread.Join(); - _receiveThread = null; - } - } -} diff --git a/Plugins/LiteNetLib/NetManager.Socket.cs.meta b/Plugins/LiteNetLib/NetManager.Socket.cs.meta deleted file mode 100644 index c63a1bf2..00000000 --- a/Plugins/LiteNetLib/NetManager.Socket.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4f361f46e03301d45a6c9cd2bc867960 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetManager.cs b/Plugins/LiteNetLib/NetManager.cs deleted file mode 100644 index 752dfb7c..00000000 --- a/Plugins/LiteNetLib/NetManager.cs +++ /dev/null @@ -1,1821 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net; -using System.Net.Sockets; -using System.Threading; -using LiteNetLib.Layers; -using LiteNetLib.Utils; - -namespace LiteNetLib -{ - public sealed class NetPacketReader : NetDataReader - { - private NetPacket _packet; - private readonly NetManager _manager; - private readonly NetEvent _evt; - - internal NetPacketReader(NetManager manager, NetEvent evt) - { - _manager = manager; - _evt = evt; - } - - internal void SetSource(NetPacket packet, int headerSize) - { - if (packet == null) - return; - _packet = packet; - SetSource(packet.RawData, headerSize, packet.Size); - } - - internal void RecycleInternal() - { - Clear(); - if (_packet != null) - _manager.PoolRecycle(_packet); - _packet = null; - _manager.RecycleEvent(_evt); - } - - public void Recycle() - { - if (_manager.AutoRecycle) - return; - RecycleInternal(); - } - } - - internal sealed class NetEvent - { - public NetEvent Next; - - public enum EType - { - Connect, - Disconnect, - Receive, - ReceiveUnconnected, - Error, - ConnectionLatencyUpdated, - Broadcast, - ConnectionRequest, - MessageDelivered, - PeerAddressChanged - } - public EType Type; - - public NetPeer Peer; - public IPEndPoint RemoteEndPoint; - public object UserData; - public int Latency; - public SocketError ErrorCode; - public DisconnectReason DisconnectReason; - public ConnectionRequest ConnectionRequest; - public DeliveryMethod DeliveryMethod; - public byte ChannelNumber; - public readonly NetPacketReader DataReader; - - public NetEvent(NetManager manager) - { - DataReader = new NetPacketReader(manager, this); - } - } - - /// - /// Main class for all network operations. Can be used as client and/or server. - /// - public partial class NetManager : IEnumerable - { - private class IPEndPointComparer : IEqualityComparer - { - public bool Equals(IPEndPoint x, IPEndPoint y) - { - return x.Address.Equals(y.Address) && x.Port == y.Port; - } - - public int GetHashCode(IPEndPoint obj) - { - return obj.GetHashCode(); - } - } - - public struct NetPeerEnumerator : IEnumerator - { - private readonly NetPeer _initialPeer; - private NetPeer _p; - - public NetPeerEnumerator(NetPeer p) - { - _initialPeer = p; - _p = null; - } - - public void Dispose() - { - - } - - public bool MoveNext() - { - _p = _p == null ? _initialPeer : _p.NextPeer; - return _p != null; - } - - public void Reset() - { - throw new NotSupportedException(); - } - - public NetPeer Current => _p; - object IEnumerator.Current => _p; - } - -#if DEBUG - private struct IncomingData - { - public NetPacket Data; - public IPEndPoint EndPoint; - public DateTime TimeWhenGet; - } - private readonly List _pingSimulationList = new List(); - private readonly Random _randomGenerator = new Random(); - private const int MinLatencyThreshold = 5; -#endif - - private Thread _logicThread; - private bool _manualMode; - private readonly AutoResetEvent _updateTriggerEvent = new AutoResetEvent(true); - - private NetEvent _pendingEventHead; - private NetEvent _pendingEventTail; - - private NetEvent _netEventPoolHead; - private readonly INetEventListener _netEventListener; - private readonly IDeliveryEventListener _deliveryEventListener; - private readonly INtpEventListener _ntpEventListener; - private readonly IPeerAddressChangedListener _peerAddressChangedListener; - - private readonly Dictionary _peersDict = new Dictionary(new IPEndPointComparer()); - private readonly Dictionary _requestsDict = new Dictionary(new IPEndPointComparer()); - private readonly Dictionary _ntpRequests = new Dictionary(new IPEndPointComparer()); - private readonly ReaderWriterLockSlim _peersLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); - private volatile NetPeer _headPeer; - private int _connectedPeersCount; - private readonly List _connectedPeerListCache = new List(); - private NetPeer[] _peersArray = new NetPeer[32]; - private readonly PacketLayerBase _extraPacketLayer; - private int _lastPeerId; - private ConcurrentQueue _peerIds = new ConcurrentQueue(); - private byte _channelsCount = 1; - private readonly object _eventLock = new object(); - - //config section - /// - /// Enable messages receiving without connection. (with SendUnconnectedMessage method) - /// - public bool UnconnectedMessagesEnabled = false; - - /// - /// Enable nat punch messages - /// - public bool NatPunchEnabled = false; - - /// - /// Library logic update and send period in milliseconds - /// Lowest values in Windows doesn't change much because of Thread.Sleep precision - /// To more frequent sends (or sends tied to your game logic) use - /// - public int UpdateTime = 15; - - /// - /// Interval for latency detection and checking connection (in milliseconds) - /// - public int PingInterval = 1000; - - /// - /// If NetManager doesn't receive any packet from remote peer during this time (in milliseconds) then connection will be closed - /// (including library internal keepalive packets) - /// - public int DisconnectTimeout = 5000; - - /// - /// Simulate packet loss by dropping random amount of packets. (Works only in DEBUG mode) - /// - public bool SimulatePacketLoss = false; - - /// - /// Simulate latency by holding packets for random time. (Works only in DEBUG mode) - /// - public bool SimulateLatency = false; - - /// - /// Chance of packet loss when simulation enabled. value in percents (1 - 100). - /// - public int SimulationPacketLossChance = 10; - - /// - /// Minimum simulated latency (in milliseconds) - /// - public int SimulationMinLatency = 30; - - /// - /// Maximum simulated latency (in milliseconds) - /// - public int SimulationMaxLatency = 100; - - /// - /// Events automatically will be called without PollEvents method from another thread - /// - public bool UnsyncedEvents = false; - - /// - /// If true - receive event will be called from "receive" thread immediately otherwise on PollEvents call - /// - public bool UnsyncedReceiveEvent = false; - - /// - /// If true - delivery event will be called from "receive" thread immediately otherwise on PollEvents call - /// - public bool UnsyncedDeliveryEvent = false; - - /// - /// Allows receive broadcast packets - /// - public bool BroadcastReceiveEnabled = false; - - /// - /// Delay between initial connection attempts (in milliseconds) - /// - public int ReconnectDelay = 500; - - /// - /// Maximum connection attempts before client stops and call disconnect event. - /// - public int MaxConnectAttempts = 10; - - /// - /// Enables socket option "ReuseAddress" for specific purposes - /// - public bool ReuseAddress = false; - - /// - /// Statistics of all connections - /// - public readonly NetStatistics Statistics = new NetStatistics(); - - /// - /// Toggles the collection of network statistics for the instance and all known peers - /// - public bool EnableStatistics = false; - - /// - /// NatPunchModule for NAT hole punching operations - /// - public readonly NatPunchModule NatPunchModule; - - /// - /// Returns true if socket listening and update thread is running - /// - public bool IsRunning { get; private set; } - - /// - /// Local EndPoint (host and port) - /// - public int LocalPort { get; private set; } - - /// - /// Automatically recycle NetPacketReader after OnReceive event - /// - public bool AutoRecycle; - - /// - /// IPv6 support - /// - public bool IPv6Enabled = true; - - /// - /// Override MTU for all new peers registered in this NetManager, will ignores MTU Discovery! - /// - public int MtuOverride = 0; - - /// - /// Sets initial MTU to lowest possible value according to RFC1191 (576 bytes) - /// - public bool UseSafeMtu = false; - - /// - /// First peer. Useful for Client mode - /// - public NetPeer FirstPeer => _headPeer; - - /// - /// Experimental feature mostly for servers. Only for Windows/Linux - /// use direct socket calls for send/receive to drastically increase speed and reduce GC pressure - /// - public bool UseNativeSockets = false; - - /// - /// Disconnect peers if HostUnreachable or NetworkUnreachable spawned (old behaviour 0.9.x was true) - /// - public bool DisconnectOnUnreachable = false; - - /// - /// Allows peer change it's ip (lte to wifi, wifi to lte, etc). Use only on server - /// - public bool AllowPeerAddressChange = false; - - /// - /// QoS channel count per message type (value must be between 1 and 64 channels) - /// - public byte ChannelsCount - { - get => _channelsCount; - set - { - if (value < 1 || value > 64) - throw new ArgumentException("Channels count must be between 1 and 64"); - _channelsCount = value; - } - } - - /// - /// Returns connected peers list (with internal cached list) - /// - public List ConnectedPeerList - { - get - { - GetPeersNonAlloc(_connectedPeerListCache, ConnectionState.Connected); - return _connectedPeerListCache; - } - } - - /// - /// Gets peer by peer id - /// - /// id of peer - /// Peer if peer with id exist, otherwise null - public NetPeer GetPeerById(int id) - { - if (id >= 0 && id < _peersArray.Length) - { - return _peersArray[id]; - } - - return null; - } - - /// - /// Gets peer by peer id - /// - /// id of peer - /// resulting peer - /// True if peer with id exist, otherwise false - public bool TryGetPeerById(int id, out NetPeer peer) - { - peer = GetPeerById(id); - - return peer != null; - } - - /// - /// Returns connected peers count - /// - public int ConnectedPeersCount => Interlocked.CompareExchange(ref _connectedPeersCount,0,0); - - public int ExtraPacketSizeForLayer => _extraPacketLayer?.ExtraPacketSizeForLayer ?? 0; - - private bool TryGetPeer(IPEndPoint endPoint, out NetPeer peer) - { - _peersLock.EnterReadLock(); - bool result = _peersDict.TryGetValue(endPoint, out peer); - _peersLock.ExitReadLock(); - return result; - } - - private void AddPeer(NetPeer peer) - { - _peersLock.EnterWriteLock(); - if (_headPeer != null) - { - peer.NextPeer = _headPeer; - _headPeer.PrevPeer = peer; - } - _headPeer = peer; - _peersDict.Add(peer.EndPoint, peer); - if (peer.Id >= _peersArray.Length) - { - int newSize = _peersArray.Length * 2; - while (peer.Id >= newSize) - newSize *= 2; - Array.Resize(ref _peersArray, newSize); - } - _peersArray[peer.Id] = peer; - RegisterEndPoint(peer.EndPoint); - _peersLock.ExitWriteLock(); - } - - private void RemovePeer(NetPeer peer) - { - _peersLock.EnterWriteLock(); - RemovePeerInternal(peer); - _peersLock.ExitWriteLock(); - } - - private void RemovePeerInternal(NetPeer peer) - { - if (!_peersDict.Remove(peer.EndPoint)) - return; - if (peer == _headPeer) - _headPeer = peer.NextPeer; - - if (peer.PrevPeer != null) - peer.PrevPeer.NextPeer = peer.NextPeer; - if (peer.NextPeer != null) - peer.NextPeer.PrevPeer = peer.PrevPeer; - peer.PrevPeer = null; - - _peersArray[peer.Id] = null; - _peerIds.Enqueue(peer.Id); - UnregisterEndPoint(peer.EndPoint); - } - - /// - /// NetManager constructor - /// - /// Network events listener (also can implement IDeliveryEventListener) - /// Extra processing of packages, like CRC checksum or encryption. All connected NetManagers must have same layer. - public NetManager(INetEventListener listener, PacketLayerBase extraPacketLayer = null) - { - _netEventListener = listener; - _deliveryEventListener = listener as IDeliveryEventListener; - _ntpEventListener = listener as INtpEventListener; - _peerAddressChangedListener = listener as IPeerAddressChangedListener; - NatPunchModule = new NatPunchModule(this); - _extraPacketLayer = extraPacketLayer; - } - - internal void ConnectionLatencyUpdated(NetPeer fromPeer, int latency) - { - CreateEvent(NetEvent.EType.ConnectionLatencyUpdated, fromPeer, latency: latency); - } - - internal void MessageDelivered(NetPeer fromPeer, object userData) - { - if(_deliveryEventListener != null) - CreateEvent(NetEvent.EType.MessageDelivered, fromPeer, userData: userData); - } - - internal void DisconnectPeerForce(NetPeer peer, - DisconnectReason reason, - SocketError socketErrorCode, - NetPacket eventData) - { - DisconnectPeer(peer, reason, socketErrorCode, true, null, 0, 0, eventData); - } - - private void DisconnectPeer( - NetPeer peer, - DisconnectReason reason, - SocketError socketErrorCode, - bool force, - byte[] data, - int start, - int count, - NetPacket eventData) - { - var shutdownResult = peer.Shutdown(data, start, count, force); - if (shutdownResult == ShutdownResult.None) - return; - if(shutdownResult == ShutdownResult.WasConnected) - Interlocked.Decrement(ref _connectedPeersCount); - CreateEvent( - NetEvent.EType.Disconnect, - peer, - errorCode: socketErrorCode, - disconnectReason: reason, - readerSource: eventData); - } - - private void CreateEvent( - NetEvent.EType type, - NetPeer peer = null, - IPEndPoint remoteEndPoint = null, - SocketError errorCode = 0, - int latency = 0, - DisconnectReason disconnectReason = DisconnectReason.ConnectionFailed, - ConnectionRequest connectionRequest = null, - DeliveryMethod deliveryMethod = DeliveryMethod.Unreliable, - byte channelNumber = 0, - NetPacket readerSource = null, - object userData = null) - { - NetEvent evt; - bool unsyncEvent = UnsyncedEvents; - - if (type == NetEvent.EType.Connect) - Interlocked.Increment(ref _connectedPeersCount); - else if (type == NetEvent.EType.MessageDelivered) - unsyncEvent = UnsyncedDeliveryEvent; - - lock(_eventLock) - { - evt = _netEventPoolHead; - if (evt == null) - evt = new NetEvent(this); - else - _netEventPoolHead = evt.Next; - } - - evt.Next = null; - evt.Type = type; - evt.DataReader.SetSource(readerSource, readerSource?.GetHeaderSize() ?? 0); - evt.Peer = peer; - evt.RemoteEndPoint = remoteEndPoint; - evt.Latency = latency; - evt.ErrorCode = errorCode; - evt.DisconnectReason = disconnectReason; - evt.ConnectionRequest = connectionRequest; - evt.DeliveryMethod = deliveryMethod; - evt.ChannelNumber = channelNumber; - evt.UserData = userData; - - if (unsyncEvent || _manualMode) - { - ProcessEvent(evt); - } - else - { - lock (_eventLock) - { - if (_pendingEventTail == null) - _pendingEventHead = evt; - else - _pendingEventTail.Next = evt; - _pendingEventTail = evt; - } - } - } - - private void ProcessEvent(NetEvent evt) - { - NetDebug.Write("[NM] Processing event: " + evt.Type); - bool emptyData = evt.DataReader.IsNull; - switch (evt.Type) - { - case NetEvent.EType.Connect: - _netEventListener.OnPeerConnected(evt.Peer); - break; - case NetEvent.EType.Disconnect: - var info = new DisconnectInfo - { - Reason = evt.DisconnectReason, - AdditionalData = evt.DataReader, - SocketErrorCode = evt.ErrorCode - }; - _netEventListener.OnPeerDisconnected(evt.Peer, info); - break; - case NetEvent.EType.Receive: - _netEventListener.OnNetworkReceive(evt.Peer, evt.DataReader, evt.ChannelNumber, evt.DeliveryMethod); - break; - case NetEvent.EType.ReceiveUnconnected: - _netEventListener.OnNetworkReceiveUnconnected(evt.RemoteEndPoint, evt.DataReader, UnconnectedMessageType.BasicMessage); - break; - case NetEvent.EType.Broadcast: - _netEventListener.OnNetworkReceiveUnconnected(evt.RemoteEndPoint, evt.DataReader, UnconnectedMessageType.Broadcast); - break; - case NetEvent.EType.Error: - _netEventListener.OnNetworkError(evt.RemoteEndPoint, evt.ErrorCode); - break; - case NetEvent.EType.ConnectionLatencyUpdated: - _netEventListener.OnNetworkLatencyUpdate(evt.Peer, evt.Latency); - break; - case NetEvent.EType.ConnectionRequest: - _netEventListener.OnConnectionRequest(evt.ConnectionRequest); - break; - case NetEvent.EType.MessageDelivered: - _deliveryEventListener.OnMessageDelivered(evt.Peer, evt.UserData); - break; - case NetEvent.EType.PeerAddressChanged: - _peersLock.EnterUpgradeableReadLock(); - IPEndPoint previousAddress = null; - if (_peersDict.ContainsKey(evt.Peer.EndPoint)) - { - _peersLock.EnterWriteLock(); - _peersDict.Remove(evt.Peer.EndPoint); - previousAddress = evt.Peer.EndPoint; - evt.Peer.FinishEndPointChange(evt.RemoteEndPoint); - _peersDict.Add(evt.Peer.EndPoint, evt.Peer); - _peersLock.ExitWriteLock(); - } - _peersLock.ExitUpgradeableReadLock(); - if(previousAddress != null) - _peerAddressChangedListener.OnPeerAddressChanged(evt.Peer, previousAddress); - break; - } - //Recycle if not message - if (emptyData) - RecycleEvent(evt); - else if (AutoRecycle) - evt.DataReader.RecycleInternal(); - } - - internal void RecycleEvent(NetEvent evt) - { - evt.Peer = null; - evt.ErrorCode = 0; - evt.RemoteEndPoint = null; - evt.ConnectionRequest = null; - lock(_eventLock) - { - evt.Next = _netEventPoolHead; - _netEventPoolHead = evt; - } - } - - //Update function - private void UpdateLogic() - { - var peersToRemove = new List(); - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - while (IsRunning) - { - try - { - ProcessDelayedPackets(); - int elapsed = (int)stopwatch.ElapsedMilliseconds; - elapsed = elapsed <= 0 ? 1 : elapsed; - stopwatch.Restart(); - - for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - { - if (netPeer.ConnectionState == ConnectionState.Disconnected && - netPeer.TimeSinceLastPacket > DisconnectTimeout) - { - peersToRemove.Add(netPeer); - } - else - { - netPeer.Update(elapsed); - } - } - - if (peersToRemove.Count > 0) - { - _peersLock.EnterWriteLock(); - for (int i = 0; i < peersToRemove.Count; i++) - RemovePeerInternal(peersToRemove[i]); - _peersLock.ExitWriteLock(); - peersToRemove.Clear(); - } - - ProcessNtpRequests(elapsed); - - int sleepTime = UpdateTime - (int)stopwatch.ElapsedMilliseconds; - if (sleepTime > 0) - _updateTriggerEvent.WaitOne(sleepTime); - } - catch (ThreadAbortException) - { - return; - } - catch (Exception e) - { - NetDebug.WriteError("[NM] LogicThread error: " + e); - } - } - stopwatch.Stop(); - } - - [Conditional("DEBUG")] - private void ProcessDelayedPackets() - { -#if DEBUG - if (!SimulateLatency) - return; - - var time = DateTime.UtcNow; - lock (_pingSimulationList) - { - for (int i = 0; i < _pingSimulationList.Count; i++) - { - var incomingData = _pingSimulationList[i]; - if (incomingData.TimeWhenGet <= time) - { - DebugMessageReceived(incomingData.Data, incomingData.EndPoint); - _pingSimulationList.RemoveAt(i); - i--; - } - } - } -#endif - } - - private void ProcessNtpRequests(int elapsedMilliseconds) - { - List requestsToRemove = null; - foreach (var ntpRequest in _ntpRequests) - { - ntpRequest.Value.Send(_udpSocketv4, elapsedMilliseconds); - if(ntpRequest.Value.NeedToKill) - { - if (requestsToRemove == null) - requestsToRemove = new List(); - requestsToRemove.Add(ntpRequest.Key); - } - } - - if (requestsToRemove != null) - { - foreach (var ipEndPoint in requestsToRemove) - { - _ntpRequests.Remove(ipEndPoint); - } - } - } - - /// - /// Update and send logic. Use this only when NetManager started in manual mode - /// - /// elapsed milliseconds since last update call - public void ManualUpdate(int elapsedMilliseconds) - { - if (!_manualMode) - return; - - for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - { - if (netPeer.ConnectionState == ConnectionState.Disconnected && netPeer.TimeSinceLastPacket > DisconnectTimeout) - { - RemovePeerInternal(netPeer); - } - else - { - netPeer.Update(elapsedMilliseconds); - } - } - ProcessNtpRequests(elapsedMilliseconds); - } - - internal NetPeer OnConnectionSolved(ConnectionRequest request, byte[] rejectData, int start, int length) - { - NetPeer netPeer = null; - - if (request.Result == ConnectionRequestResult.RejectForce) - { - NetDebug.Write(NetLogLevel.Trace, "[NM] Peer connect reject force."); - if (rejectData != null && length > 0) - { - var shutdownPacket = PoolGetWithProperty(PacketProperty.Disconnect, length); - shutdownPacket.ConnectionNumber = request.InternalPacket.ConnectionNumber; - FastBitConverter.GetBytes(shutdownPacket.RawData, 1, request.InternalPacket.ConnectionTime); - if (shutdownPacket.Size >= NetConstants.PossibleMtu[0]) - NetDebug.WriteError("[Peer] Disconnect additional data size more than MTU!"); - else - Buffer.BlockCopy(rejectData, start, shutdownPacket.RawData, 9, length); - SendRawAndRecycle(shutdownPacket, request.RemoteEndPoint); - } - } - else - { - _peersLock.EnterUpgradeableReadLock(); - if (_peersDict.TryGetValue(request.RemoteEndPoint, out netPeer)) - { - //already have peer - _peersLock.ExitUpgradeableReadLock(); - } - else if (request.Result == ConnectionRequestResult.Reject) - { - netPeer = new NetPeer(this, request.RemoteEndPoint, GetNextPeerId()); - netPeer.Reject(request.InternalPacket, rejectData, start, length); - AddPeer(netPeer); - _peersLock.ExitUpgradeableReadLock(); - NetDebug.Write(NetLogLevel.Trace, "[NM] Peer connect reject."); - } - else //Accept - { - netPeer = new NetPeer(this, request, GetNextPeerId()); - AddPeer(netPeer); - _peersLock.ExitUpgradeableReadLock(); - CreateEvent(NetEvent.EType.Connect, netPeer); - NetDebug.Write(NetLogLevel.Trace, $"[NM] Received peer connection Id: {netPeer.ConnectTime}, EP: {netPeer.EndPoint}"); - } - } - - lock(_requestsDict) - _requestsDict.Remove(request.RemoteEndPoint); - - return netPeer; - } - - private int GetNextPeerId() - { - return _peerIds.TryDequeue(out int id) ? id : _lastPeerId++; - } - - private void ProcessConnectRequest( - IPEndPoint remoteEndPoint, - NetPeer netPeer, - NetConnectRequestPacket connRequest) - { - //if we have peer - if (netPeer != null) - { - var processResult = netPeer.ProcessConnectRequest(connRequest); - NetDebug.Write($"ConnectRequest LastId: {netPeer.ConnectTime}, NewId: {connRequest.ConnectionTime}, EP: {remoteEndPoint}, Result: {processResult}"); - - switch (processResult) - { - case ConnectRequestResult.Reconnection: - DisconnectPeerForce(netPeer, DisconnectReason.Reconnect, 0, null); - RemovePeer(netPeer); - //go to new connection - break; - case ConnectRequestResult.NewConnection: - RemovePeer(netPeer); - //go to new connection - break; - case ConnectRequestResult.P2PLose: - DisconnectPeerForce(netPeer, DisconnectReason.PeerToPeerConnection, 0, null); - RemovePeer(netPeer); - //go to new connection - break; - default: - //no operations needed - return; - } - //ConnectRequestResult.NewConnection - //Set next connection number - if(processResult != ConnectRequestResult.P2PLose) - connRequest.ConnectionNumber = (byte)((netPeer.ConnectionNum + 1) % NetConstants.MaxConnectionNumber); - //To reconnect peer - } - else - { - NetDebug.Write($"ConnectRequest Id: {connRequest.ConnectionTime}, EP: {remoteEndPoint}"); - } - - ConnectionRequest req; - lock (_requestsDict) - { - if (_requestsDict.TryGetValue(remoteEndPoint, out req)) - { - req.UpdateRequest(connRequest); - return; - } - req = new ConnectionRequest(remoteEndPoint, connRequest, this); - _requestsDict.Add(remoteEndPoint, req); - } - NetDebug.Write($"[NM] Creating request event: {connRequest.ConnectionTime}"); - CreateEvent(NetEvent.EType.ConnectionRequest, connectionRequest: req); - } - - private void OnMessageReceived(NetPacket packet, IPEndPoint remoteEndPoint) - { -#if DEBUG - if (SimulatePacketLoss && _randomGenerator.NextDouble() * 100 < SimulationPacketLossChance) - { - //drop packet - return; - } - if (SimulateLatency) - { - int latency = _randomGenerator.Next(SimulationMinLatency, SimulationMaxLatency); - if (latency > MinLatencyThreshold) - { - lock (_pingSimulationList) - { - _pingSimulationList.Add(new IncomingData - { - Data = packet, - EndPoint = remoteEndPoint, - TimeWhenGet = DateTime.UtcNow.AddMilliseconds(latency) - }); - } - //hold packet - return; - } - } - - //ProcessEvents - DebugMessageReceived(packet, remoteEndPoint); - } - - private void DebugMessageReceived(NetPacket packet, IPEndPoint remoteEndPoint) - { -#endif - var originalPacketSize = packet.Size; - if (EnableStatistics) - { - Statistics.IncrementPacketsReceived(); - Statistics.AddBytesReceived(originalPacketSize); - } - - if (_ntpRequests.Count > 0) - { - if (_ntpRequests.TryGetValue(remoteEndPoint, out var request)) - { - if (packet.Size < 48) - { - NetDebug.Write(NetLogLevel.Trace, $"NTP response too short: {packet.Size}"); - return; - } - - byte[] copiedData = new byte[packet.Size]; - Buffer.BlockCopy(packet.RawData, 0, copiedData, 0, packet.Size); - NtpPacket ntpPacket = NtpPacket.FromServerResponse(copiedData, DateTime.UtcNow); - try - { - ntpPacket.ValidateReply(); - } - catch (InvalidOperationException ex) - { - NetDebug.Write(NetLogLevel.Trace, $"NTP response error: {ex.Message}"); - ntpPacket = null; - } - - if (ntpPacket != null) - { - _ntpRequests.Remove(remoteEndPoint); - _ntpEventListener?.OnNtpResponse(ntpPacket); - } - return; - } - } - - if (_extraPacketLayer != null) - { - int start = 0; - _extraPacketLayer.ProcessInboundPacket(ref remoteEndPoint, ref packet.RawData, ref start, ref packet.Size); - if (packet.Size == 0) - return; - } - - if (!packet.Verify()) - { - NetDebug.WriteError("[NM] DataReceived: bad!"); - PoolRecycle(packet); - return; - } - - switch (packet.Property) - { - //special case connect request - case PacketProperty.ConnectRequest: - if (NetConnectRequestPacket.GetProtocolId(packet) != NetConstants.ProtocolId) - { - SendRawAndRecycle(PoolGetWithProperty(PacketProperty.InvalidProtocol), remoteEndPoint); - return; - } - break; - //unconnected messages - case PacketProperty.Broadcast: - if (!BroadcastReceiveEnabled) - return; - CreateEvent(NetEvent.EType.Broadcast, remoteEndPoint: remoteEndPoint, readerSource: packet); - return; - case PacketProperty.UnconnectedMessage: - if (!UnconnectedMessagesEnabled) - return; - CreateEvent(NetEvent.EType.ReceiveUnconnected, remoteEndPoint: remoteEndPoint, readerSource: packet); - return; - case PacketProperty.NatMessage: - if (NatPunchEnabled) - NatPunchModule.ProcessMessage(remoteEndPoint, packet); - return; - } - - //Check normal packets - _peersLock.EnterReadLock(); - bool peerFound = _peersDict.TryGetValue(remoteEndPoint, out var netPeer); - _peersLock.ExitReadLock(); - - if (peerFound && EnableStatistics) - { - netPeer.Statistics.IncrementPacketsReceived(); - netPeer.Statistics.AddBytesReceived(originalPacketSize); - } - - switch (packet.Property) - { - case PacketProperty.ConnectRequest: - var connRequest = NetConnectRequestPacket.FromData(packet); - if (connRequest != null) - ProcessConnectRequest(remoteEndPoint, netPeer, connRequest); - break; - case PacketProperty.PeerNotFound: - if (peerFound) //local - { - if (netPeer.ConnectionState != ConnectionState.Connected) - return; - if (packet.Size == 1) - { - //first reply - //send NetworkChanged packet - netPeer.ResetMtu(); - SendRaw(NetConnectAcceptPacket.MakeNetworkChanged(netPeer), remoteEndPoint); - NetDebug.Write($"PeerNotFound sending connection info: {remoteEndPoint}"); - } - else if (packet.Size == 2 && packet.RawData[1] == 1) - { - //second reply - DisconnectPeerForce(netPeer, DisconnectReason.PeerNotFound, 0, null); - } - } - else if (packet.Size > 1) //remote - { - //check if this is old peer - bool isOldPeer = false; - - if (AllowPeerAddressChange) - { - NetDebug.Write($"[NM] Looks like address change: {packet.Size}"); - var remoteData = NetConnectAcceptPacket.FromData(packet); - if (remoteData != null && - remoteData.PeerNetworkChanged && - remoteData.PeerId < _peersArray.Length) - { - _peersLock.EnterUpgradeableReadLock(); - var peer = _peersArray[remoteData.PeerId]; - if (peer != null && - peer.ConnectTime == remoteData.ConnectionTime && - peer.ConnectionNum == remoteData.ConnectionNumber) - { - if (peer.ConnectionState == ConnectionState.Connected) - { - peer.InitiateEndPointChange(); - if (_peerAddressChangedListener != null) - { - CreateEvent(NetEvent.EType.PeerAddressChanged, peer, remoteEndPoint); - } - NetDebug.Write("[NM] PeerNotFound change address of remote peer"); - } - isOldPeer = true; - } - _peersLock.ExitUpgradeableReadLock(); - } - } - - PoolRecycle(packet); - - //else peer really not found - if (!isOldPeer) - { - var secondResponse = PoolGetWithProperty(PacketProperty.PeerNotFound, 1); - secondResponse.RawData[1] = 1; - SendRawAndRecycle(secondResponse, remoteEndPoint); - } - } - break; - case PacketProperty.InvalidProtocol: - if (peerFound && netPeer.ConnectionState == ConnectionState.Outgoing) - DisconnectPeerForce(netPeer, DisconnectReason.InvalidProtocol, 0, null); - break; - case PacketProperty.Disconnect: - if (peerFound) - { - var disconnectResult = netPeer.ProcessDisconnect(packet); - if (disconnectResult == DisconnectResult.None) - { - PoolRecycle(packet); - return; - } - DisconnectPeerForce( - netPeer, - disconnectResult == DisconnectResult.Disconnect - ? DisconnectReason.RemoteConnectionClose - : DisconnectReason.ConnectionRejected, - 0, packet); - } - else - { - PoolRecycle(packet); - } - //Send shutdown - SendRawAndRecycle(PoolGetWithProperty(PacketProperty.ShutdownOk), remoteEndPoint); - break; - case PacketProperty.ConnectAccept: - if (!peerFound) - return; - var connAccept = NetConnectAcceptPacket.FromData(packet); - if (connAccept != null && netPeer.ProcessConnectAccept(connAccept)) - CreateEvent(NetEvent.EType.Connect, netPeer); - break; - default: - if(peerFound) - netPeer.ProcessPacket(packet); - else - SendRawAndRecycle(PoolGetWithProperty(PacketProperty.PeerNotFound), remoteEndPoint); - break; - } - } - - internal void CreateReceiveEvent(NetPacket packet, DeliveryMethod method, byte channelNumber, int headerSize, NetPeer fromPeer) - { - NetEvent evt; - - if (UnsyncedEvents || UnsyncedReceiveEvent || _manualMode) - { - lock (_eventLock) - { - evt = _netEventPoolHead; - if (evt == null) - evt = new NetEvent(this); - else - _netEventPoolHead = evt.Next; - } - evt.Next = null; - evt.Type = NetEvent.EType.Receive; - evt.DataReader.SetSource(packet, headerSize); - evt.Peer = fromPeer; - evt.DeliveryMethod = method; - evt.ChannelNumber = channelNumber; - ProcessEvent(evt); - } - else - { - lock (_eventLock) - { - evt = _netEventPoolHead; - if (evt == null) - evt = new NetEvent(this); - else - _netEventPoolHead = evt.Next; - - evt.Next = null; - evt.Type = NetEvent.EType.Receive; - evt.DataReader.SetSource(packet, headerSize); - evt.Peer = fromPeer; - evt.DeliveryMethod = method; - evt.ChannelNumber = channelNumber; - - if (_pendingEventTail == null) - _pendingEventHead = evt; - else - _pendingEventTail.Next = evt; - _pendingEventTail = evt; - } - } - } - - /// - /// Send data to all connected peers (channel - 0) - /// - /// DataWriter with data - /// Send options (reliable, unreliable, etc.) - public void SendToAll(NetDataWriter writer, DeliveryMethod options) - { - SendToAll(writer.Data, 0, writer.Length, options); - } - - /// - /// Send data to all connected peers (channel - 0) - /// - /// Data - /// Send options (reliable, unreliable, etc.) - public void SendToAll(byte[] data, DeliveryMethod options) - { - SendToAll(data, 0, data.Length, options); - } - - /// - /// Send data to all connected peers (channel - 0) - /// - /// Data - /// Start of data - /// Length of data - /// Send options (reliable, unreliable, etc.) - public void SendToAll(byte[] data, int start, int length, DeliveryMethod options) - { - SendToAll(data, start, length, 0, options); - } - - /// - /// Send data to all connected peers - /// - /// DataWriter with data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - public void SendToAll(NetDataWriter writer, byte channelNumber, DeliveryMethod options) - { - SendToAll(writer.Data, 0, writer.Length, channelNumber, options); - } - - /// - /// Send data to all connected peers - /// - /// Data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - public void SendToAll(byte[] data, byte channelNumber, DeliveryMethod options) - { - SendToAll(data, 0, data.Length, channelNumber, options); - } - - /// - /// Send data to all connected peers - /// - /// Data - /// Start of data - /// Length of data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - public void SendToAll(byte[] data, int start, int length, byte channelNumber, DeliveryMethod options) - { - try - { - _peersLock.EnterReadLock(); - for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - netPeer.Send(data, start, length, channelNumber, options); - } - finally - { - _peersLock.ExitReadLock(); - } - } - - /// - /// Send data to all connected peers (channel - 0) - /// - /// DataWriter with data - /// Send options (reliable, unreliable, etc.) - /// Excluded peer - public void SendToAll(NetDataWriter writer, DeliveryMethod options, NetPeer excludePeer) - { - SendToAll(writer.Data, 0, writer.Length, 0, options, excludePeer); - } - - /// - /// Send data to all connected peers (channel - 0) - /// - /// Data - /// Send options (reliable, unreliable, etc.) - /// Excluded peer - public void SendToAll(byte[] data, DeliveryMethod options, NetPeer excludePeer) - { - SendToAll(data, 0, data.Length, 0, options, excludePeer); - } - - /// - /// Send data to all connected peers (channel - 0) - /// - /// Data - /// Start of data - /// Length of data - /// Send options (reliable, unreliable, etc.) - /// Excluded peer - public void SendToAll(byte[] data, int start, int length, DeliveryMethod options, NetPeer excludePeer) - { - SendToAll(data, start, length, 0, options, excludePeer); - } - - /// - /// Send data to all connected peers - /// - /// DataWriter with data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - /// Excluded peer - public void SendToAll(NetDataWriter writer, byte channelNumber, DeliveryMethod options, NetPeer excludePeer) - { - SendToAll(writer.Data, 0, writer.Length, channelNumber, options, excludePeer); - } - - /// - /// Send data to all connected peers - /// - /// Data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - /// Excluded peer - public void SendToAll(byte[] data, byte channelNumber, DeliveryMethod options, NetPeer excludePeer) - { - SendToAll(data, 0, data.Length, channelNumber, options, excludePeer); - } - - - /// - /// Send data to all connected peers - /// - /// Data - /// Start of data - /// Length of data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - /// Excluded peer - public void SendToAll(byte[] data, int start, int length, byte channelNumber, DeliveryMethod options, NetPeer excludePeer) - { - try - { - _peersLock.EnterReadLock(); - for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - { - if (netPeer != excludePeer) - netPeer.Send(data, start, length, channelNumber, options); - } - } - finally - { - _peersLock.ExitReadLock(); - } - } - - /// - /// Start logic thread and listening on available port - /// - public bool Start() - { - return Start(0); - } - - /// - /// Start logic thread and listening on selected port - /// - /// bind to specific ipv4 address - /// bind to specific ipv6 address - /// port to listen - public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port) - { - return Start(addressIPv4, addressIPv6, port, false); - } - - /// - /// Start logic thread and listening on selected port - /// - /// bind to specific ipv4 address - /// bind to specific ipv6 address - /// port to listen - public bool Start(string addressIPv4, string addressIPv6, int port) - { - IPAddress ipv4 = NetUtils.ResolveAddress(addressIPv4); - IPAddress ipv6 = NetUtils.ResolveAddress(addressIPv6); - return Start(ipv4, ipv6, port); - } - - /// - /// Start logic thread and listening on selected port - /// - /// port to listen - public bool Start(int port) - { - return Start(IPAddress.Any, IPAddress.IPv6Any, port); - } - - /// - /// Start in manual mode and listening on selected port - /// In this mode you should use ManualReceive (without PollEvents) for receive packets - /// and ManualUpdate(...) for update and send packets - /// This mode useful mostly for single-threaded servers - /// - /// bind to specific ipv4 address - /// bind to specific ipv6 address - /// port to listen - public bool StartInManualMode(IPAddress addressIPv4, IPAddress addressIPv6, int port) - { - return Start(addressIPv4, addressIPv6, port, true); - } - - /// - /// Start in manual mode and listening on selected port - /// In this mode you should use ManualReceive (without PollEvents) for receive packets - /// and ManualUpdate(...) for update and send packets - /// This mode useful mostly for single-threaded servers - /// - /// bind to specific ipv4 address - /// bind to specific ipv6 address - /// port to listen - public bool StartInManualMode(string addressIPv4, string addressIPv6, int port) - { - IPAddress ipv4 = NetUtils.ResolveAddress(addressIPv4); - IPAddress ipv6 = NetUtils.ResolveAddress(addressIPv6); - return StartInManualMode(ipv4, ipv6, port); - } - - /// - /// Start in manual mode and listening on selected port - /// In this mode you should use ManualReceive (without PollEvents) for receive packets - /// and ManualUpdate(...) for update and send packets - /// This mode useful mostly for single-threaded servers - /// - /// port to listen - public bool StartInManualMode(int port) - { - return StartInManualMode(IPAddress.Any, IPAddress.IPv6Any, port); - } - - /// - /// Send message without connection - /// - /// Raw data - /// Packet destination - /// Operation result - public bool SendUnconnectedMessage(byte[] message, IPEndPoint remoteEndPoint) - { - return SendUnconnectedMessage(message, 0, message.Length, remoteEndPoint); - } - - /// - /// Send message without connection. WARNING This method allocates a new IPEndPoint object and - /// synchronously makes a DNS request. If you're calling this method every frame it will be - /// much faster to just cache the IPEndPoint. - /// - /// Data serializer - /// Packet destination IP or hostname - /// Packet destination port - /// Operation result - public bool SendUnconnectedMessage(NetDataWriter writer, string address, int port) - { - IPEndPoint remoteEndPoint = NetUtils.MakeEndPoint(address, port); - - return SendUnconnectedMessage(writer.Data, 0, writer.Length, remoteEndPoint); - } - - /// - /// Send message without connection - /// - /// Data serializer - /// Packet destination - /// Operation result - public bool SendUnconnectedMessage(NetDataWriter writer, IPEndPoint remoteEndPoint) - { - return SendUnconnectedMessage(writer.Data, 0, writer.Length, remoteEndPoint); - } - - /// - /// Send message without connection - /// - /// Raw data - /// data start - /// data length - /// Packet destination - /// Operation result - public bool SendUnconnectedMessage(byte[] message, int start, int length, IPEndPoint remoteEndPoint) - { - //No need for CRC here, SendRaw does that - NetPacket packet = PoolGetWithData(PacketProperty.UnconnectedMessage, message, start, length); - return SendRawAndRecycle(packet, remoteEndPoint) > 0; - } - - /// - /// Triggers update and send logic immediately (works asynchronously) - /// - public void TriggerUpdate() - { - _updateTriggerEvent.Set(); - } - - /// - /// Receive all pending events. Call this in game update code - /// In Manual mode it will call also socket Receive (which can be slow) - /// - public void PollEvents() - { - if (_manualMode) - { - if (_udpSocketv4 != null) - ManualReceive(_udpSocketv4, _bufferEndPointv4); - if (_udpSocketv6 != null && _udpSocketv6 != _udpSocketv4) - ManualReceive(_udpSocketv6, _bufferEndPointv6); - ProcessDelayedPackets(); - return; - } - if (UnsyncedEvents) - return; - NetEvent pendingEvent; - lock (_eventLock) - { - pendingEvent = _pendingEventHead; - _pendingEventHead = null; - _pendingEventTail = null; - } - - while (pendingEvent != null) - { - var next = pendingEvent.Next; - ProcessEvent(pendingEvent); - pendingEvent = next; - } - } - - /// - /// Connect to remote host - /// - /// Server IP or hostname - /// Server Port - /// Connection key - /// New NetPeer if new connection, Old NetPeer if already connected, null peer if there is ConnectionRequest awaiting - /// Manager is not running. Call - public NetPeer Connect(string address, int port, string key) - { - return Connect(address, port, NetDataWriter.FromString(key)); - } - - /// - /// Connect to remote host - /// - /// Server IP or hostname - /// Server Port - /// Additional data for remote peer - /// New NetPeer if new connection, Old NetPeer if already connected, null peer if there is ConnectionRequest awaiting - /// Manager is not running. Call - public NetPeer Connect(string address, int port, NetDataWriter connectionData) - { - IPEndPoint ep; - try - { - ep = NetUtils.MakeEndPoint(address, port); - } - catch - { - CreateEvent(NetEvent.EType.Disconnect, disconnectReason: DisconnectReason.UnknownHost); - return null; - } - return Connect(ep, connectionData); - } - - /// - /// Connect to remote host - /// - /// Server end point (ip and port) - /// Connection key - /// New NetPeer if new connection, Old NetPeer if already connected, null peer if there is ConnectionRequest awaiting - /// Manager is not running. Call - public NetPeer Connect(IPEndPoint target, string key) - { - return Connect(target, NetDataWriter.FromString(key)); - } - - /// - /// Connect to remote host - /// - /// Server end point (ip and port) - /// Additional data for remote peer - /// New NetPeer if new connection, Old NetPeer if already connected, null peer if there is ConnectionRequest awaiting - /// Manager is not running. Call - public NetPeer Connect(IPEndPoint target, NetDataWriter connectionData) - { - if (!IsRunning) - throw new InvalidOperationException("Client is not running"); - - lock(_requestsDict) - { - if (_requestsDict.ContainsKey(target)) - return null; - } - - byte connectionNumber = 0; - _peersLock.EnterUpgradeableReadLock(); - if (_peersDict.TryGetValue(target, out var peer)) - { - switch (peer.ConnectionState) - { - //just return already connected peer - case ConnectionState.Connected: - case ConnectionState.Outgoing: - _peersLock.ExitUpgradeableReadLock(); - return peer; - } - //else reconnect - connectionNumber = (byte)((peer.ConnectionNum + 1) % NetConstants.MaxConnectionNumber); - RemovePeer(peer); - } - - //Create reliable connection - //And send connection request - peer = new NetPeer(this, target, GetNextPeerId(), connectionNumber, connectionData); - AddPeer(peer); - _peersLock.ExitUpgradeableReadLock(); - - return peer; - } - - /// - /// Force closes connection and stop all threads. - /// - public void Stop() - { - Stop(true); - } - - /// - /// Force closes connection and stop all threads. - /// - /// Send disconnect messages - public void Stop(bool sendDisconnectMessages) - { - if (!IsRunning) - return; - NetDebug.Write("[NM] Stop"); - -#if UNITY_2018_3_OR_NEWER - _pausedSocketFix.Deinitialize(); - _pausedSocketFix = null; -#endif - - //Send last disconnect - for(var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - netPeer.Shutdown(null, 0, 0, !sendDisconnectMessages); - - //Stop - CloseSocket(); - _updateTriggerEvent.Set(); - if (!_manualMode) - { - _logicThread.Join(); - _logicThread = null; - } - - //clear peers - _peersLock.EnterWriteLock(); - _headPeer = null; - _peersDict.Clear(); - _peersArray = new NetPeer[32]; - _peersLock.ExitWriteLock(); - _peerIds = new ConcurrentQueue(); - _lastPeerId = 0; -#if DEBUG - lock (_pingSimulationList) - _pingSimulationList.Clear(); -#endif - _connectedPeersCount = 0; - _pendingEventHead = null; - _pendingEventTail = null; - } - - /// - /// Return peers count with connection state - /// - /// peer connection state (you can use as bit flags) - /// peers count - public int GetPeersCount(ConnectionState peerState) - { - int count = 0; - _peersLock.EnterReadLock(); - for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - { - if ((netPeer.ConnectionState & peerState) != 0) - count++; - } - _peersLock.ExitReadLock(); - return count; - } - - /// - /// Get copy of peers (without allocations) - /// - /// List that will contain result - /// State of peers - public void GetPeersNonAlloc(List peers, ConnectionState peerState) - { - peers.Clear(); - _peersLock.EnterReadLock(); - for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - { - if ((netPeer.ConnectionState & peerState) != 0) - peers.Add(netPeer); - } - _peersLock.ExitReadLock(); - } - - /// - /// Disconnect all peers without any additional data - /// - public void DisconnectAll() - { - DisconnectAll(null, 0, 0); - } - - /// - /// Disconnect all peers with shutdown message - /// - /// Data to send (must be less or equal MTU) - /// Data start - /// Data count - public void DisconnectAll(byte[] data, int start, int count) - { - //Send disconnect packets - _peersLock.EnterReadLock(); - for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - { - DisconnectPeer( - netPeer, - DisconnectReason.DisconnectPeerCalled, - 0, - false, - data, - start, - count, - null); - } - _peersLock.ExitReadLock(); - } - - /// - /// Immediately disconnect peer from server without additional data - /// - /// peer to disconnect - public void DisconnectPeerForce(NetPeer peer) - { - DisconnectPeerForce(peer, DisconnectReason.DisconnectPeerCalled, 0, null); - } - - /// - /// Disconnect peer from server - /// - /// peer to disconnect - public void DisconnectPeer(NetPeer peer) - { - DisconnectPeer(peer, null, 0, 0); - } - - /// - /// Disconnect peer from server and send additional data (Size must be less or equal MTU - 8) - /// - /// peer to disconnect - /// additional data - public void DisconnectPeer(NetPeer peer, byte[] data) - { - DisconnectPeer(peer, data, 0, data.Length); - } - - /// - /// Disconnect peer from server and send additional data (Size must be less or equal MTU - 8) - /// - /// peer to disconnect - /// additional data - public void DisconnectPeer(NetPeer peer, NetDataWriter writer) - { - DisconnectPeer(peer, writer.Data, 0, writer.Length); - } - - /// - /// Disconnect peer from server and send additional data (Size must be less or equal MTU - 8) - /// - /// peer to disconnect - /// additional data - /// data start - /// data length - public void DisconnectPeer(NetPeer peer, byte[] data, int start, int count) - { - DisconnectPeer( - peer, - DisconnectReason.DisconnectPeerCalled, - 0, - false, - data, - start, - count, - null); - } - - /// - /// Create the requests for NTP server - /// - /// NTP Server address. - public void CreateNtpRequest(IPEndPoint endPoint) - { - _ntpRequests.Add(endPoint, new NtpRequest(endPoint)); - } - - /// - /// Create the requests for NTP server - /// - /// NTP Server address. - /// port - public void CreateNtpRequest(string ntpServerAddress, int port) - { - IPEndPoint endPoint = NetUtils.MakeEndPoint(ntpServerAddress, port); - _ntpRequests.Add(endPoint, new NtpRequest(endPoint)); - } - - /// - /// Create the requests for NTP server (default port) - /// - /// NTP Server address. - public void CreateNtpRequest(string ntpServerAddress) - { - IPEndPoint endPoint = NetUtils.MakeEndPoint(ntpServerAddress, NtpRequest.DefaultPort); - _ntpRequests.Add(endPoint, new NtpRequest(endPoint)); - } - - public NetPeerEnumerator GetEnumerator() - { - return new NetPeerEnumerator(_headPeer); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return new NetPeerEnumerator(_headPeer); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return new NetPeerEnumerator(_headPeer); - } - } -} diff --git a/Plugins/LiteNetLib/NetManager.cs.meta b/Plugins/LiteNetLib/NetManager.cs.meta deleted file mode 100644 index 081c2bbb..00000000 --- a/Plugins/LiteNetLib/NetManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9380ddabc17c8724bae7311162b25f8a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetPacket.cs b/Plugins/LiteNetLib/NetPacket.cs deleted file mode 100644 index 4b403084..00000000 --- a/Plugins/LiteNetLib/NetPacket.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using LiteNetLib.Utils; - -namespace LiteNetLib -{ - internal enum PacketProperty : byte - { - Unreliable, - Channeled, - Ack, - Ping, - Pong, - ConnectRequest, - ConnectAccept, - Disconnect, - UnconnectedMessage, - MtuCheck, - MtuOk, - Broadcast, - Merged, - ShutdownOk, - PeerNotFound, - InvalidProtocol, - NatMessage, - Empty - } - - internal sealed class NetPacket - { - private static readonly int PropertiesCount = Enum.GetValues(typeof(PacketProperty)).Length; - private static readonly int[] HeaderSizes; - - static NetPacket() - { - HeaderSizes = NetUtils.AllocatePinnedUninitializedArray(PropertiesCount); - for (int i = 0; i < HeaderSizes.Length; i++) - { - switch ((PacketProperty)i) - { - case PacketProperty.Channeled: - case PacketProperty.Ack: - HeaderSizes[i] = NetConstants.ChanneledHeaderSize; - break; - case PacketProperty.Ping: - HeaderSizes[i] = NetConstants.HeaderSize + 2; - break; - case PacketProperty.ConnectRequest: - HeaderSizes[i] = NetConnectRequestPacket.HeaderSize; - break; - case PacketProperty.ConnectAccept: - HeaderSizes[i] = NetConnectAcceptPacket.Size; - break; - case PacketProperty.Disconnect: - HeaderSizes[i] = NetConstants.HeaderSize + 8; - break; - case PacketProperty.Pong: - HeaderSizes[i] = NetConstants.HeaderSize + 10; - break; - default: - HeaderSizes[i] = NetConstants.HeaderSize; - break; - } - } - } - - //Header - public PacketProperty Property - { - get => (PacketProperty)(RawData[0] & 0x1F); - set => RawData[0] = (byte)((RawData[0] & 0xE0) | (byte)value); - } - - public byte ConnectionNumber - { - get => (byte)((RawData[0] & 0x60) >> 5); - set => RawData[0] = (byte) ((RawData[0] & 0x9F) | (value << 5)); - } - - public ushort Sequence - { - get => BitConverter.ToUInt16(RawData, 1); - set => FastBitConverter.GetBytes(RawData, 1, value); - } - - public bool IsFragmented => (RawData[0] & 0x80) != 0; - - public void MarkFragmented() - { - RawData[0] |= 0x80; //set first bit - } - - public byte ChannelId - { - get => RawData[3]; - set => RawData[3] = value; - } - - public ushort FragmentId - { - get => BitConverter.ToUInt16(RawData, 4); - set => FastBitConverter.GetBytes(RawData, 4, value); - } - - public ushort FragmentPart - { - get => BitConverter.ToUInt16(RawData, 6); - set => FastBitConverter.GetBytes(RawData, 6, value); - } - - public ushort FragmentsTotal - { - get => BitConverter.ToUInt16(RawData, 8); - set => FastBitConverter.GetBytes(RawData, 8, value); - } - - //Data - public byte[] RawData; - public int Size; - - //Delivery - public object UserData; - - //Pool node - public NetPacket Next; - - public NetPacket(int size) - { - RawData = new byte[size]; - Size = size; - } - - public NetPacket(PacketProperty property, int size) - { - size += GetHeaderSize(property); - RawData = new byte[size]; - Property = property; - Size = size; - } - - public static int GetHeaderSize(PacketProperty property) - { - return HeaderSizes[(int)property]; - } - - public int GetHeaderSize() - { - return HeaderSizes[RawData[0] & 0x1F]; - } - - public bool Verify() - { - byte property = (byte)(RawData[0] & 0x1F); - if (property >= PropertiesCount) - return false; - int headerSize = HeaderSizes[property]; - bool fragmented = (RawData[0] & 0x80) != 0; - return Size >= headerSize && (!fragmented || Size >= headerSize + NetConstants.FragmentHeaderSize); - } - } -} diff --git a/Plugins/LiteNetLib/NetPacket.cs.meta b/Plugins/LiteNetLib/NetPacket.cs.meta deleted file mode 100644 index 92a5e725..00000000 --- a/Plugins/LiteNetLib/NetPacket.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7434346045bfad94c93976fdf3036c53 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetPeer.cs b/Plugins/LiteNetLib/NetPeer.cs deleted file mode 100644 index 66906789..00000000 --- a/Plugins/LiteNetLib/NetPeer.cs +++ /dev/null @@ -1,1398 +0,0 @@ -#if DEBUG -#define STATS_ENABLED -#endif -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net; -using System.Threading; -using LiteNetLib.Utils; - -namespace LiteNetLib -{ - /// - /// Peer connection state - /// - [Flags] - public enum ConnectionState : byte - { - Outgoing = 1 << 1, - Connected = 1 << 2, - ShutdownRequested = 1 << 3, - Disconnected = 1 << 4, - EndPointChange = 1 << 5, - Any = Outgoing | Connected | ShutdownRequested | EndPointChange - } - - internal enum ConnectRequestResult - { - None, - P2PLose, //when peer connecting - Reconnection, //when peer was connected - NewConnection //when peer was disconnected - } - - internal enum DisconnectResult - { - None, - Reject, - Disconnect - } - - internal enum ShutdownResult - { - None, - Success, - WasConnected - } - - /// - /// Network peer. Main purpose is sending messages to specific peer. - /// - public class NetPeer - { - //Ping and RTT - private int _rtt; - private int _avgRtt; - private int _rttCount; - private double _resendDelay = 27.0; - private int _pingSendTimer; - private int _rttResetTimer; - private readonly Stopwatch _pingTimer = new Stopwatch(); - private int _timeSinceLastPacket; - private long _remoteDelta; - - //Common - private readonly object _shutdownLock = new object(); - - internal volatile NetPeer NextPeer; - internal NetPeer PrevPeer; - - internal byte ConnectionNum - { - get => _connectNum; - private set - { - _connectNum = value; - _mergeData.ConnectionNumber = value; - _pingPacket.ConnectionNumber = value; - _pongPacket.ConnectionNumber = value; - } - } - - //Channels - private readonly Queue _unreliableChannel; - private readonly ConcurrentQueue _channelSendQueue; - private readonly BaseChannel[] _channels; - - //MTU - private int _mtu; - private int _mtuIdx; - private bool _finishMtu; - private int _mtuCheckTimer; - private int _mtuCheckAttempts; - private const int MtuCheckDelay = 1000; - private const int MaxMtuCheckAttempts = 4; - private readonly object _mtuMutex = new object(); - - //Fragment - private class IncomingFragments - { - public NetPacket[] Fragments; - public int ReceivedCount; - public int TotalSize; - public byte ChannelId; - } - private int _fragmentId; - private readonly Dictionary _holdedFragments; - private readonly Dictionary _deliveredFragments; - - //Merging - private readonly NetPacket _mergeData; - private int _mergePos; - private int _mergeCount; - - //Connection - private IPEndPoint _remoteEndPoint; - private int _connectAttempts; - private int _connectTimer; - private long _connectTime; - private byte _connectNum; - private ConnectionState _connectionState; - private NetPacket _shutdownPacket; - private const int ShutdownDelay = 300; - private int _shutdownTimer; - private readonly NetPacket _pingPacket; - private readonly NetPacket _pongPacket; - private readonly NetPacket _connectRequestPacket; - private readonly NetPacket _connectAcceptPacket; - - /// - /// Peer ip address and port - /// - public IPEndPoint EndPoint => _remoteEndPoint; - - /// - /// Peer parent NetManager - /// - public readonly NetManager NetManager; - - /// - /// Current connection state - /// - public ConnectionState ConnectionState => _connectionState; - - /// - /// Connection time for internal purposes - /// - internal long ConnectTime => _connectTime; - - /// - /// Peer id can be used as key in your dictionary of peers - /// - public readonly int Id; - - /// - /// Id assigned from server - /// - public int RemoteId { get; private set; } - - /// - /// Current one-way ping (RTT/2) in milliseconds - /// - public int Ping => _avgRtt/2; - - /// - /// Round trip time in milliseconds - /// - public int RoundTripTime => _avgRtt; - - /// - /// Current MTU - Maximum Transfer Unit ( maximum udp packet size without fragmentation ) - /// - public int Mtu => _mtu; - - /// - /// Delta with remote time in ticks (not accurate) - /// positive - remote time > our time - /// - public long RemoteTimeDelta => _remoteDelta; - - /// - /// Remote UTC time (not accurate) - /// - public DateTime RemoteUtcTime => new DateTime(DateTime.UtcNow.Ticks + _remoteDelta); - - /// - /// Time since last packet received (including internal library packets) - /// - public int TimeSinceLastPacket => _timeSinceLastPacket; - - internal double ResendDelay => _resendDelay; - - /// - /// Application defined object containing data about the connection - /// - public object Tag; - - /// - /// Statistics of peer connection - /// - public readonly NetStatistics Statistics; - - //incoming connection constructor - internal NetPeer(NetManager netManager, IPEndPoint remoteEndPoint, int id) - { - Id = id; - Statistics = new NetStatistics(); - NetManager = netManager; - ResetMtu(); - _remoteEndPoint = remoteEndPoint; - _connectionState = ConnectionState.Connected; - _mergeData = new NetPacket(PacketProperty.Merged, NetConstants.MaxPacketSize); - _pongPacket = new NetPacket(PacketProperty.Pong, 0); - _pingPacket = new NetPacket(PacketProperty.Ping, 0) {Sequence = 1}; - - _unreliableChannel = new Queue(); - _holdedFragments = new Dictionary(); - _deliveredFragments = new Dictionary(); - - _channels = new BaseChannel[netManager.ChannelsCount * NetConstants.ChannelTypeCount]; - _channelSendQueue = new ConcurrentQueue(); - } - - internal void InitiateEndPointChange() - { - ResetMtu(); - _connectionState = ConnectionState.EndPointChange; - } - - internal void FinishEndPointChange(IPEndPoint newEndPoint) - { - if (_connectionState != ConnectionState.EndPointChange) - return; - _connectionState = ConnectionState.Connected; - _remoteEndPoint = newEndPoint; - } - - internal void ResetMtu() - { - _finishMtu = false; - if (NetManager.MtuOverride > 0) - OverrideMtu(NetManager.MtuOverride); - else if (NetManager.UseSafeMtu) - SetMtu(0); - else - SetMtu(1); - } - - private void SetMtu(int mtuIdx) - { - _mtuIdx = mtuIdx; - _mtu = NetConstants.PossibleMtu[mtuIdx] - NetManager.ExtraPacketSizeForLayer; - } - - private void OverrideMtu(int mtuValue) - { - _mtu = mtuValue; - _finishMtu = true; - } - - /// - /// Returns packets count in queue for reliable channel - /// - /// number of channel 0-63 - /// type of channel ReliableOrdered or ReliableUnordered - /// packets count in channel queue - public int GetPacketsCountInReliableQueue(byte channelNumber, bool ordered) - { - int idx = channelNumber * NetConstants.ChannelTypeCount + - (byte) (ordered ? DeliveryMethod.ReliableOrdered : DeliveryMethod.ReliableUnordered); - var channel = _channels[idx]; - return channel != null ? ((ReliableChannel)channel).PacketsInQueue : 0; - } - - /// - /// Create temporary packet (maximum size MTU - headerSize) to send later without additional copies - /// - /// Delivery method (reliable, unreliable, etc.) - /// Number of channel (from 0 to channelsCount - 1) - /// PooledPacket that you can use to write data starting from UserDataOffset - public PooledPacket CreatePacketFromPool(DeliveryMethod deliveryMethod, byte channelNumber) - { - //multithreaded variable - int mtu = _mtu; - var packet = NetManager.PoolGetPacket(mtu); - if (deliveryMethod == DeliveryMethod.Unreliable) - { - packet.Property = PacketProperty.Unreliable; - return new PooledPacket(packet, mtu, 0); - } - else - { - packet.Property = PacketProperty.Channeled; - return new PooledPacket(packet, mtu, (byte)(channelNumber * NetConstants.ChannelTypeCount + (byte)deliveryMethod)); - } - } - - /// - /// Sends pooled packet without data copy - /// - /// packet to send - /// size of user data you want to send - public void SendPooledPacket(PooledPacket packet, int userDataSize) - { - if (_connectionState != ConnectionState.Connected) - return; - packet._packet.Size = packet.UserDataOffset + userDataSize; - if (packet._packet.Property == PacketProperty.Channeled) - { - CreateChannel(packet._channelNumber).AddToQueue(packet._packet); - } - else - { - lock(_unreliableChannel) - _unreliableChannel.Enqueue(packet._packet); - } - } - - private BaseChannel CreateChannel(byte idx) - { - BaseChannel newChannel = _channels[idx]; - if (newChannel != null) - return newChannel; - switch ((DeliveryMethod)(idx % NetConstants.ChannelTypeCount)) - { - case DeliveryMethod.ReliableUnordered: - newChannel = new ReliableChannel(this, false, idx); - break; - case DeliveryMethod.Sequenced: - newChannel = new SequencedChannel(this, false, idx); - break; - case DeliveryMethod.ReliableOrdered: - newChannel = new ReliableChannel(this, true, idx); - break; - case DeliveryMethod.ReliableSequenced: - newChannel = new SequencedChannel(this, true, idx); - break; - } - BaseChannel prevChannel = Interlocked.CompareExchange(ref _channels[idx], newChannel, null); - if (prevChannel != null) - return prevChannel; - - return newChannel; - } - - //"Connect to" constructor - internal NetPeer(NetManager netManager, IPEndPoint remoteEndPoint, int id, byte connectNum, NetDataWriter connectData) - : this(netManager, remoteEndPoint, id) - { - _connectTime = DateTime.UtcNow.Ticks; - _connectionState = ConnectionState.Outgoing; - ConnectionNum = connectNum; - - //Make initial packet - _connectRequestPacket = NetConnectRequestPacket.Make(connectData, remoteEndPoint.Serialize(), _connectTime, id); - _connectRequestPacket.ConnectionNumber = connectNum; - - //Send request - NetManager.SendRaw(_connectRequestPacket, _remoteEndPoint); - - NetDebug.Write(NetLogLevel.Trace, $"[CC] ConnectId: {_connectTime}, ConnectNum: {connectNum}"); - } - - //"Accept" incoming constructor - internal NetPeer(NetManager netManager, ConnectionRequest request, int id) - : this(netManager, request.RemoteEndPoint, id) - { - _connectTime = request.InternalPacket.ConnectionTime; - ConnectionNum = request.InternalPacket.ConnectionNumber; - RemoteId = request.InternalPacket.PeerId; - - //Make initial packet - _connectAcceptPacket = NetConnectAcceptPacket.Make(_connectTime, ConnectionNum, id); - - //Make Connected - _connectionState = ConnectionState.Connected; - - //Send - NetManager.SendRaw(_connectAcceptPacket, _remoteEndPoint); - - NetDebug.Write(NetLogLevel.Trace, $"[CC] ConnectId: {_connectTime}"); - } - - //Reject - internal void Reject(NetConnectRequestPacket requestData, byte[] data, int start, int length) - { - _connectTime = requestData.ConnectionTime; - _connectNum = requestData.ConnectionNumber; - Shutdown(data, start, length, false); - } - - internal bool ProcessConnectAccept(NetConnectAcceptPacket packet) - { - if (_connectionState != ConnectionState.Outgoing) - return false; - - //check connection id - if (packet.ConnectionTime != _connectTime) - { - NetDebug.Write(NetLogLevel.Trace, $"[NC] Invalid connectId: {packet.ConnectionTime} != our({_connectTime})"); - return false; - } - //check connect num - ConnectionNum = packet.ConnectionNumber; - RemoteId = packet.PeerId; - - NetDebug.Write(NetLogLevel.Trace, "[NC] Received connection accept"); - Interlocked.Exchange(ref _timeSinceLastPacket, 0); - _connectionState = ConnectionState.Connected; - return true; - } - - /// - /// Gets maximum size of packet that will be not fragmented. - /// - /// Type of packet that you want send - /// size in bytes - public int GetMaxSinglePacketSize(DeliveryMethod options) - { - return _mtu - NetPacket.GetHeaderSize(options == DeliveryMethod.Unreliable ? PacketProperty.Unreliable : PacketProperty.Channeled); - } - - /// - /// Send data to peer with delivery event called - /// - /// Data - /// Number of channel (from 0 to channelsCount - 1) - /// Delivery method (reliable, unreliable, etc.) - /// User data that will be received in DeliveryEvent - /// - /// If you trying to send unreliable packet type - /// - public void SendWithDeliveryEvent(byte[] data, byte channelNumber, DeliveryMethod deliveryMethod, object userData) - { - if (deliveryMethod != DeliveryMethod.ReliableOrdered && deliveryMethod != DeliveryMethod.ReliableUnordered) - throw new ArgumentException("Delivery event will work only for ReliableOrdered/Unordered packets"); - SendInternal(data, 0, data.Length, channelNumber, deliveryMethod, userData); - } - - /// - /// Send data to peer with delivery event called - /// - /// Data - /// Start of data - /// Length of data - /// Number of channel (from 0 to channelsCount - 1) - /// Delivery method (reliable, unreliable, etc.) - /// User data that will be received in DeliveryEvent - /// - /// If you trying to send unreliable packet type - /// - public void SendWithDeliveryEvent(byte[] data, int start, int length, byte channelNumber, DeliveryMethod deliveryMethod, object userData) - { - if (deliveryMethod != DeliveryMethod.ReliableOrdered && deliveryMethod != DeliveryMethod.ReliableUnordered) - throw new ArgumentException("Delivery event will work only for ReliableOrdered/Unordered packets"); - SendInternal(data, start, length, channelNumber, deliveryMethod, userData); - } - - /// - /// Send data to peer with delivery event called - /// - /// Data - /// Number of channel (from 0 to channelsCount - 1) - /// Delivery method (reliable, unreliable, etc.) - /// User data that will be received in DeliveryEvent - /// - /// If you trying to send unreliable packet type - /// - public void SendWithDeliveryEvent(NetDataWriter dataWriter, byte channelNumber, DeliveryMethod deliveryMethod, object userData) - { - if (deliveryMethod != DeliveryMethod.ReliableOrdered && deliveryMethod != DeliveryMethod.ReliableUnordered) - throw new ArgumentException("Delivery event will work only for ReliableOrdered/Unordered packets"); - SendInternal(dataWriter.Data, 0, dataWriter.Length, channelNumber, deliveryMethod, userData); - } - - /// - /// Send data to peer (channel - 0) - /// - /// Data - /// Send options (reliable, unreliable, etc.) - /// - /// If size exceeds maximum limit: - /// MTU - headerSize bytes for Unreliable - /// Fragment count exceeded ushort.MaxValue - /// - public void Send(byte[] data, DeliveryMethod deliveryMethod) - { - SendInternal(data, 0, data.Length, 0, deliveryMethod, null); - } - - /// - /// Send data to peer (channel - 0) - /// - /// DataWriter with data - /// Send options (reliable, unreliable, etc.) - /// - /// If size exceeds maximum limit: - /// MTU - headerSize bytes for Unreliable - /// Fragment count exceeded ushort.MaxValue - /// - public void Send(NetDataWriter dataWriter, DeliveryMethod deliveryMethod) - { - SendInternal(dataWriter.Data, 0, dataWriter.Length, 0, deliveryMethod, null); - } - - /// - /// Send data to peer (channel - 0) - /// - /// Data - /// Start of data - /// Length of data - /// Send options (reliable, unreliable, etc.) - /// - /// If size exceeds maximum limit: - /// MTU - headerSize bytes for Unreliable - /// Fragment count exceeded ushort.MaxValue - /// - public void Send(byte[] data, int start, int length, DeliveryMethod options) - { - SendInternal(data, start, length, 0, options, null); - } - - /// - /// Send data to peer - /// - /// Data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - /// - /// If size exceeds maximum limit: - /// MTU - headerSize bytes for Unreliable - /// Fragment count exceeded ushort.MaxValue - /// - public void Send(byte[] data, byte channelNumber, DeliveryMethod deliveryMethod) - { - SendInternal(data, 0, data.Length, channelNumber, deliveryMethod, null); - } - - /// - /// Send data to peer - /// - /// DataWriter with data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - /// - /// If size exceeds maximum limit: - /// MTU - headerSize bytes for Unreliable - /// Fragment count exceeded ushort.MaxValue - /// - public void Send(NetDataWriter dataWriter, byte channelNumber, DeliveryMethod deliveryMethod) - { - SendInternal(dataWriter.Data, 0, dataWriter.Length, channelNumber, deliveryMethod, null); - } - - /// - /// Send data to peer - /// - /// Data - /// Start of data - /// Length of data - /// Number of channel (from 0 to channelsCount - 1) - /// Delivery method (reliable, unreliable, etc.) - /// - /// If size exceeds maximum limit: - /// MTU - headerSize bytes for Unreliable - /// Fragment count exceeded ushort.MaxValue - /// - public void Send(byte[] data, int start, int length, byte channelNumber, DeliveryMethod deliveryMethod) - { - SendInternal(data, start, length, channelNumber, deliveryMethod, null); - } - - private void SendInternal( - byte[] data, - int start, - int length, - byte channelNumber, - DeliveryMethod deliveryMethod, - object userData) - { - if (_connectionState != ConnectionState.Connected || channelNumber >= _channels.Length) - return; - - //Select channel - PacketProperty property; - BaseChannel channel = null; - - if (deliveryMethod == DeliveryMethod.Unreliable) - { - property = PacketProperty.Unreliable; - } - else - { - property = PacketProperty.Channeled; - channel = CreateChannel((byte)(channelNumber * NetConstants.ChannelTypeCount + (byte)deliveryMethod)); - } - - //Prepare - NetDebug.Write("[RS]Packet: " + property); - - //Check fragmentation - int headerSize = NetPacket.GetHeaderSize(property); - //Save mtu for multithread - int mtu = _mtu; - if (length + headerSize > mtu) - { - //if cannot be fragmented - if (deliveryMethod != DeliveryMethod.ReliableOrdered && deliveryMethod != DeliveryMethod.ReliableUnordered) - throw new TooBigPacketException("Unreliable or ReliableSequenced packet size exceeded maximum of " + (mtu - headerSize) + " bytes, Check allowed size by GetMaxSinglePacketSize()"); - - int packetFullSize = mtu - headerSize; - int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize; - int totalPackets = length / packetDataSize + (length % packetDataSize == 0 ? 0 : 1); - - NetDebug.Write($@"FragmentSend: - MTU: {mtu} - headerSize: {headerSize} - packetFullSize: {packetFullSize} - packetDataSize: {packetDataSize} - totalPackets: {totalPackets}"); - - if (totalPackets > ushort.MaxValue) - throw new TooBigPacketException("Data was split in " + totalPackets + " fragments, which exceeds " + ushort.MaxValue); - - ushort currentFragmentId = (ushort)Interlocked.Increment(ref _fragmentId); - - for(ushort partIdx = 0; partIdx < totalPackets; partIdx++) - { - int sendLength = length > packetDataSize ? packetDataSize : length; - - NetPacket p = NetManager.PoolGetPacket(headerSize + sendLength + NetConstants.FragmentHeaderSize); - p.Property = property; - p.UserData = userData; - p.FragmentId = currentFragmentId; - p.FragmentPart = partIdx; - p.FragmentsTotal = (ushort)totalPackets; - p.MarkFragmented(); - - Buffer.BlockCopy(data, start + partIdx * packetDataSize, p.RawData, NetConstants.FragmentedHeaderTotalSize, sendLength); - channel.AddToQueue(p); - - length -= sendLength; - } - return; - } - - //Else just send - NetPacket packet = NetManager.PoolGetPacket(headerSize + length); - packet.Property = property; - Buffer.BlockCopy(data, start, packet.RawData, headerSize, length); - packet.UserData = userData; - - if (channel == null) //unreliable - { - lock(_unreliableChannel) - _unreliableChannel.Enqueue(packet); - } - else - { - channel.AddToQueue(packet); - } - } - -#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1 - /// - /// Send data to peer with delivery event called - /// - /// Data - /// Number of channel (from 0 to channelsCount - 1) - /// Delivery method (reliable, unreliable, etc.) - /// User data that will be received in DeliveryEvent - /// - /// If you trying to send unreliable packet type - /// - public void SendWithDeliveryEvent(ReadOnlySpan data, byte channelNumber, DeliveryMethod deliveryMethod, object userData) - { - if (deliveryMethod != DeliveryMethod.ReliableOrdered && deliveryMethod != DeliveryMethod.ReliableUnordered) - throw new ArgumentException("Delivery event will work only for ReliableOrdered/Unordered packets"); - SendInternal(data, channelNumber, deliveryMethod, userData); - } - - /// - /// Send data to peer (channel - 0) - /// - /// Data - /// Send options (reliable, unreliable, etc.) - /// - /// If size exceeds maximum limit: - /// MTU - headerSize bytes for Unreliable - /// Fragment count exceeded ushort.MaxValue - /// - public void Send(ReadOnlySpan data, DeliveryMethod deliveryMethod) - { - SendInternal(data, 0, deliveryMethod, null); - } - - /// - /// Send data to peer - /// - /// Data - /// Number of channel (from 0 to channelsCount - 1) - /// Send options (reliable, unreliable, etc.) - /// - /// If size exceeds maximum limit: - /// MTU - headerSize bytes for Unreliable - /// Fragment count exceeded ushort.MaxValue - /// - public void Send(ReadOnlySpan data, byte channelNumber, DeliveryMethod deliveryMethod) - { - SendInternal(data, channelNumber, deliveryMethod, null); - } - - private void SendInternal( - ReadOnlySpan data, - byte channelNumber, - DeliveryMethod deliveryMethod, - object userData) - { - if (_connectionState != ConnectionState.Connected || channelNumber >= _channels.Length) - return; - - //Select channel - PacketProperty property; - BaseChannel channel = null; - - if (deliveryMethod == DeliveryMethod.Unreliable) - { - property = PacketProperty.Unreliable; - } - else - { - property = PacketProperty.Channeled; - channel = CreateChannel((byte)(channelNumber * NetConstants.ChannelTypeCount + (byte)deliveryMethod)); - } - - //Prepare - NetDebug.Write("[RS]Packet: " + property); - - //Check fragmentation - int headerSize = NetPacket.GetHeaderSize(property); - //Save mtu for multithread - int mtu = _mtu; - int length = data.Length; - if (length + headerSize > mtu) - { - //if cannot be fragmented - if (deliveryMethod != DeliveryMethod.ReliableOrdered && deliveryMethod != DeliveryMethod.ReliableUnordered) - throw new TooBigPacketException("Unreliable or ReliableSequenced packet size exceeded maximum of " + (mtu - headerSize) + " bytes, Check allowed size by GetMaxSinglePacketSize()"); - - int packetFullSize = mtu - headerSize; - int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize; - int totalPackets = length / packetDataSize + (length % packetDataSize == 0 ? 0 : 1); - - if (totalPackets > ushort.MaxValue) - throw new TooBigPacketException("Data was split in " + totalPackets + " fragments, which exceeds " + ushort.MaxValue); - - ushort currentFragmentId = (ushort)Interlocked.Increment(ref _fragmentId); - - for (ushort partIdx = 0; partIdx < totalPackets; partIdx++) - { - int sendLength = length > packetDataSize ? packetDataSize : length; - - NetPacket p = NetManager.PoolGetPacket(headerSize + sendLength + NetConstants.FragmentHeaderSize); - p.Property = property; - p.UserData = userData; - p.FragmentId = currentFragmentId; - p.FragmentPart = partIdx; - p.FragmentsTotal = (ushort)totalPackets; - p.MarkFragmented(); - - data.Slice(partIdx * packetDataSize, sendLength).CopyTo(new Span(p.RawData, NetConstants.FragmentedHeaderTotalSize, sendLength)); - channel.AddToQueue(p); - - length -= sendLength; - } - return; - } - - //Else just send - NetPacket packet = NetManager.PoolGetPacket(headerSize + length); - packet.Property = property; - data.CopyTo(new Span(packet.RawData, headerSize, length)); - packet.UserData = userData; - - if (channel == null) //unreliable - { - lock(_unreliableChannel) - _unreliableChannel.Enqueue(packet); - } - else - { - channel.AddToQueue(packet); - } - } -#endif - - public void Disconnect(byte[] data) - { - NetManager.DisconnectPeer(this, data); - } - - public void Disconnect(NetDataWriter writer) - { - NetManager.DisconnectPeer(this, writer); - } - - public void Disconnect(byte[] data, int start, int count) - { - NetManager.DisconnectPeer(this, data, start, count); - } - - public void Disconnect() - { - NetManager.DisconnectPeer(this); - } - - internal DisconnectResult ProcessDisconnect(NetPacket packet) - { - if ((_connectionState == ConnectionState.Connected || _connectionState == ConnectionState.Outgoing) && - packet.Size >= 9 && - BitConverter.ToInt64(packet.RawData, 1) == _connectTime && - packet.ConnectionNumber == _connectNum) - { - return _connectionState == ConnectionState.Connected - ? DisconnectResult.Disconnect - : DisconnectResult.Reject; - } - return DisconnectResult.None; - } - - internal void AddToReliableChannelSendQueue(BaseChannel channel) - { - _channelSendQueue.Enqueue(channel); - } - - internal ShutdownResult Shutdown(byte[] data, int start, int length, bool force) - { - lock (_shutdownLock) - { - //trying to shutdown already disconnected - if (_connectionState == ConnectionState.Disconnected || - _connectionState == ConnectionState.ShutdownRequested) - { - return ShutdownResult.None; - } - - var result = _connectionState == ConnectionState.Connected - ? ShutdownResult.WasConnected - : ShutdownResult.Success; - - //don't send anything - if (force) - { - _connectionState = ConnectionState.Disconnected; - return result; - } - - //reset time for reconnect protection - Interlocked.Exchange(ref _timeSinceLastPacket, 0); - - //send shutdown packet - _shutdownPacket = new NetPacket(PacketProperty.Disconnect, length) {ConnectionNumber = _connectNum}; - FastBitConverter.GetBytes(_shutdownPacket.RawData, 1, _connectTime); - if (_shutdownPacket.Size >= _mtu) - { - //Drop additional data - NetDebug.WriteError("[Peer] Disconnect additional data size more than MTU - 8!"); - } - else if (data != null && length > 0) - { - Buffer.BlockCopy(data, start, _shutdownPacket.RawData, 9, length); - } - _connectionState = ConnectionState.ShutdownRequested; - NetDebug.Write("[Peer] Send disconnect"); - NetManager.SendRaw(_shutdownPacket, _remoteEndPoint); - return result; - } - } - - private void UpdateRoundTripTime(int roundTripTime) - { - _rtt += roundTripTime; - _rttCount++; - _avgRtt = _rtt/_rttCount; - _resendDelay = 25.0 + _avgRtt * 2.1; // 25 ms + double rtt - } - - internal void AddReliablePacket(DeliveryMethod method, NetPacket p) - { - if (p.IsFragmented) - { - NetDebug.Write($"Fragment. Id: {p.FragmentId}, Part: {p.FragmentPart}, Total: {p.FragmentsTotal}"); - //Get needed array from dictionary - ushort packetFragId = p.FragmentId; - byte packetChannelId = p.ChannelId; - if (!_holdedFragments.TryGetValue(packetFragId, out var incomingFragments)) - { - incomingFragments = new IncomingFragments - { - Fragments = new NetPacket[p.FragmentsTotal], - ChannelId = p.ChannelId - }; - _holdedFragments.Add(packetFragId, incomingFragments); - } - - //Cache - var fragments = incomingFragments.Fragments; - - //Error check - if (p.FragmentPart >= fragments.Length || - fragments[p.FragmentPart] != null || - p.ChannelId != incomingFragments.ChannelId) - { - NetManager.PoolRecycle(p); - NetDebug.WriteError("Invalid fragment packet"); - return; - } - //Fill array - fragments[p.FragmentPart] = p; - - //Increase received fragments count - incomingFragments.ReceivedCount++; - - //Increase total size - incomingFragments.TotalSize += p.Size - NetConstants.FragmentedHeaderTotalSize; - - //Check for finish - if (incomingFragments.ReceivedCount != fragments.Length) - return; - - //just simple packet - NetPacket resultingPacket = NetManager.PoolGetPacket(incomingFragments.TotalSize); - - int pos = 0; - for (int i = 0; i < incomingFragments.ReceivedCount; i++) - { - var fragment = fragments[i]; - int writtenSize = fragment.Size - NetConstants.FragmentedHeaderTotalSize; - - if (pos+writtenSize > resultingPacket.RawData.Length) - { - _holdedFragments.Remove(packetFragId); - NetDebug.WriteError($"Fragment error pos: {pos + writtenSize} >= resultPacketSize: {resultingPacket.RawData.Length} , totalSize: {incomingFragments.TotalSize}"); - return; - } - if (fragment.Size > fragment.RawData.Length) - { - _holdedFragments.Remove(packetFragId); - NetDebug.WriteError($"Fragment error size: {fragment.Size} > fragment.RawData.Length: {fragment.RawData.Length}"); - return; - } - - //Create resulting big packet - Buffer.BlockCopy( - fragment.RawData, - NetConstants.FragmentedHeaderTotalSize, - resultingPacket.RawData, - pos, - writtenSize); - pos += writtenSize; - - //Free memory - NetManager.PoolRecycle(fragment); - fragments[i] = null; - } - - //Clear memory - _holdedFragments.Remove(packetFragId); - - //Send to process - NetManager.CreateReceiveEvent(resultingPacket, method, (byte)(packetChannelId / NetConstants.ChannelTypeCount), 0, this); - } - else //Just simple packet - { - NetManager.CreateReceiveEvent(p, method, (byte)(p.ChannelId / NetConstants.ChannelTypeCount), NetConstants.ChanneledHeaderSize, this); - } - } - - private void ProcessMtuPacket(NetPacket packet) - { - //header + int - if (packet.Size < NetConstants.PossibleMtu[0]) - return; - - //first stage check (mtu check and mtu ok) - int receivedMtu = BitConverter.ToInt32(packet.RawData, 1); - int endMtuCheck = BitConverter.ToInt32(packet.RawData, packet.Size - 4); - if (receivedMtu != packet.Size || receivedMtu != endMtuCheck || receivedMtu > NetConstants.MaxPacketSize) - { - NetDebug.WriteError($"[MTU] Broken packet. RMTU {receivedMtu}, EMTU {endMtuCheck}, PSIZE {packet.Size}"); - return; - } - - if (packet.Property == PacketProperty.MtuCheck) - { - _mtuCheckAttempts = 0; - NetDebug.Write("[MTU] check. send back: " + receivedMtu); - packet.Property = PacketProperty.MtuOk; - NetManager.SendRawAndRecycle(packet, _remoteEndPoint); - } - else if(receivedMtu > _mtu && !_finishMtu) //MtuOk - { - //invalid packet - if (receivedMtu != NetConstants.PossibleMtu[_mtuIdx + 1] - NetManager.ExtraPacketSizeForLayer) - return; - - lock (_mtuMutex) - { - SetMtu(_mtuIdx+1); - } - //if maxed - finish. - if (_mtuIdx == NetConstants.PossibleMtu.Length - 1) - _finishMtu = true; - NetManager.PoolRecycle(packet); - NetDebug.Write("[MTU] ok. Increase to: " + _mtu); - } - } - - private void UpdateMtuLogic(int deltaTime) - { - if (_finishMtu) - return; - - _mtuCheckTimer += deltaTime; - if (_mtuCheckTimer < MtuCheckDelay) - return; - - _mtuCheckTimer = 0; - _mtuCheckAttempts++; - if (_mtuCheckAttempts >= MaxMtuCheckAttempts) - { - _finishMtu = true; - return; - } - - lock (_mtuMutex) - { - if (_mtuIdx >= NetConstants.PossibleMtu.Length - 1) - return; - - //Send increased packet - int newMtu = NetConstants.PossibleMtu[_mtuIdx + 1] - NetManager.ExtraPacketSizeForLayer; - var p = NetManager.PoolGetPacket(newMtu); - p.Property = PacketProperty.MtuCheck; - FastBitConverter.GetBytes(p.RawData, 1, newMtu); //place into start - FastBitConverter.GetBytes(p.RawData, p.Size - 4, newMtu);//and end of packet - - //Must check result for MTU fix - if (NetManager.SendRawAndRecycle(p, _remoteEndPoint) <= 0) - _finishMtu = true; - } - } - - internal ConnectRequestResult ProcessConnectRequest(NetConnectRequestPacket connRequest) - { - //current or new request - switch (_connectionState) - { - //P2P case - case ConnectionState.Outgoing: - //fast check - if (connRequest.ConnectionTime < _connectTime) - { - return ConnectRequestResult.P2PLose; - } - //slow rare case check - if (connRequest.ConnectionTime == _connectTime) - { - var remoteBytes = _remoteEndPoint.Serialize(); - var localBytes = connRequest.TargetAddress; - for (int i = remoteBytes.Size-1; i >= 0; i--) - { - byte rb = remoteBytes[i]; - if (rb == localBytes[i]) - continue; - if (rb < localBytes[i]) - return ConnectRequestResult.P2PLose; - } - } - break; - - case ConnectionState.Connected: - //Old connect request - if (connRequest.ConnectionTime == _connectTime) - { - //just reply accept - NetManager.SendRaw(_connectAcceptPacket, _remoteEndPoint); - } - //New connect request - else if (connRequest.ConnectionTime > _connectTime) - { - return ConnectRequestResult.Reconnection; - } - break; - - case ConnectionState.Disconnected: - case ConnectionState.ShutdownRequested: - if (connRequest.ConnectionTime >= _connectTime) - return ConnectRequestResult.NewConnection; - break; - } - return ConnectRequestResult.None; - } - - //Process incoming packet - internal void ProcessPacket(NetPacket packet) - { - //not initialized - if (_connectionState == ConnectionState.Outgoing || _connectionState == ConnectionState.Disconnected) - { - NetManager.PoolRecycle(packet); - return; - } - if (packet.Property == PacketProperty.ShutdownOk) - { - if (_connectionState == ConnectionState.ShutdownRequested) - _connectionState = ConnectionState.Disconnected; - NetManager.PoolRecycle(packet); - return; - } - if (packet.ConnectionNumber != _connectNum) - { - NetDebug.Write(NetLogLevel.Trace, "[RR]Old packet"); - NetManager.PoolRecycle(packet); - return; - } - Interlocked.Exchange(ref _timeSinceLastPacket, 0); - - NetDebug.Write($"[RR]PacketProperty: {packet.Property}"); - switch (packet.Property) - { - case PacketProperty.Merged: - int pos = NetConstants.HeaderSize; - while (pos < packet.Size) - { - ushort size = BitConverter.ToUInt16(packet.RawData, pos); - pos += 2; - if (packet.RawData.Length - pos < size) - break; - - NetPacket mergedPacket = NetManager.PoolGetPacket(size); - Buffer.BlockCopy(packet.RawData, pos, mergedPacket.RawData, 0, size); - mergedPacket.Size = size; - - if (!mergedPacket.Verify()) - break; - - pos += size; - ProcessPacket(mergedPacket); - } - NetManager.PoolRecycle(packet); - break; - //If we get ping, send pong - case PacketProperty.Ping: - if (NetUtils.RelativeSequenceNumber(packet.Sequence, _pongPacket.Sequence) > 0) - { - NetDebug.Write("[PP]Ping receive, send pong"); - FastBitConverter.GetBytes(_pongPacket.RawData, 3, DateTime.UtcNow.Ticks); - _pongPacket.Sequence = packet.Sequence; - NetManager.SendRaw(_pongPacket, _remoteEndPoint); - } - NetManager.PoolRecycle(packet); - break; - - //If we get pong, calculate ping time and rtt - case PacketProperty.Pong: - if (packet.Sequence == _pingPacket.Sequence) - { - _pingTimer.Stop(); - int elapsedMs = (int)_pingTimer.ElapsedMilliseconds; - _remoteDelta = BitConverter.ToInt64(packet.RawData, 3) + (elapsedMs * TimeSpan.TicksPerMillisecond ) / 2 - DateTime.UtcNow.Ticks; - UpdateRoundTripTime(elapsedMs); - NetManager.ConnectionLatencyUpdated(this, elapsedMs / 2); - NetDebug.Write($"[PP]Ping: {packet.Sequence} - {elapsedMs} - {_remoteDelta}"); - } - NetManager.PoolRecycle(packet); - break; - - case PacketProperty.Ack: - case PacketProperty.Channeled: - if (packet.ChannelId > _channels.Length) - { - NetManager.PoolRecycle(packet); - break; - } - var channel = _channels[packet.ChannelId] ?? (packet.Property == PacketProperty.Ack ? null : CreateChannel(packet.ChannelId)); - if (channel != null) - { - if (!channel.ProcessPacket(packet)) - NetManager.PoolRecycle(packet); - } - break; - - //Simple packet without acks - case PacketProperty.Unreliable: - NetManager.CreateReceiveEvent(packet, DeliveryMethod.Unreliable, 0, NetConstants.HeaderSize, this); - return; - - case PacketProperty.MtuCheck: - case PacketProperty.MtuOk: - ProcessMtuPacket(packet); - break; - - default: - NetDebug.WriteError("Error! Unexpected packet type: " + packet.Property); - break; - } - } - - private void SendMerged() - { - if (_mergeCount == 0) - return; - int bytesSent; - if (_mergeCount > 1) - { - NetDebug.Write("[P]Send merged: " + _mergePos + ", count: " + _mergeCount); - bytesSent = NetManager.SendRaw(_mergeData.RawData, 0, NetConstants.HeaderSize + _mergePos, _remoteEndPoint); - } - else - { - //Send without length information and merging - bytesSent = NetManager.SendRaw(_mergeData.RawData, NetConstants.HeaderSize + 2, _mergePos - 2, _remoteEndPoint); - } - - if (NetManager.EnableStatistics) - { - Statistics.IncrementPacketsSent(); - Statistics.AddBytesSent(bytesSent); - } - - _mergePos = 0; - _mergeCount = 0; - } - - internal void SendUserData(NetPacket packet) - { - packet.ConnectionNumber = _connectNum; - int mergedPacketSize = NetConstants.HeaderSize + packet.Size + 2; - const int sizeTreshold = 20; - if (mergedPacketSize + sizeTreshold >= _mtu) - { - NetDebug.Write(NetLogLevel.Trace, "[P]SendingPacket: " + packet.Property); - int bytesSent = NetManager.SendRaw(packet, _remoteEndPoint); - - if (NetManager.EnableStatistics) - { - Statistics.IncrementPacketsSent(); - Statistics.AddBytesSent(bytesSent); - } - - return; - } - if (_mergePos + mergedPacketSize > _mtu) - SendMerged(); - - FastBitConverter.GetBytes(_mergeData.RawData, _mergePos + NetConstants.HeaderSize, (ushort)packet.Size); - Buffer.BlockCopy(packet.RawData, 0, _mergeData.RawData, _mergePos + NetConstants.HeaderSize + 2, packet.Size); - _mergePos += packet.Size + 2; - _mergeCount++; - //DebugWriteForce("Merged: " + _mergePos + "/" + (_mtu - 2) + ", count: " + _mergeCount); - } - - internal void Update(int deltaTime) - { - Interlocked.Add(ref _timeSinceLastPacket, deltaTime); - switch (_connectionState) - { - case ConnectionState.Connected: - if (_timeSinceLastPacket > NetManager.DisconnectTimeout) - { - NetDebug.Write($"[UPDATE] Disconnect by timeout: {_timeSinceLastPacket} > {NetManager.DisconnectTimeout}"); - NetManager.DisconnectPeerForce(this, DisconnectReason.Timeout, 0, null); - return; - } - break; - - case ConnectionState.ShutdownRequested: - if (_timeSinceLastPacket > NetManager.DisconnectTimeout) - { - _connectionState = ConnectionState.Disconnected; - } - else - { - _shutdownTimer += deltaTime; - if (_shutdownTimer >= ShutdownDelay) - { - _shutdownTimer = 0; - NetManager.SendRaw(_shutdownPacket, _remoteEndPoint); - } - } - return; - - case ConnectionState.Outgoing: - _connectTimer += deltaTime; - if (_connectTimer > NetManager.ReconnectDelay) - { - _connectTimer = 0; - _connectAttempts++; - if (_connectAttempts > NetManager.MaxConnectAttempts) - { - NetManager.DisconnectPeerForce(this, DisconnectReason.ConnectionFailed, 0, null); - return; - } - - //else send connect again - NetManager.SendRaw(_connectRequestPacket, _remoteEndPoint); - } - return; - - case ConnectionState.Disconnected: - return; - } - - //Send ping - _pingSendTimer += deltaTime; - if (_pingSendTimer >= NetManager.PingInterval) - { - NetDebug.Write("[PP] Send ping..."); - //reset timer - _pingSendTimer = 0; - //send ping - _pingPacket.Sequence++; - //ping timeout - if (_pingTimer.IsRunning) - UpdateRoundTripTime((int)_pingTimer.ElapsedMilliseconds); - _pingTimer.Restart(); - NetManager.SendRaw(_pingPacket, _remoteEndPoint); - } - - //RTT - round trip time - _rttResetTimer += deltaTime; - if (_rttResetTimer >= NetManager.PingInterval * 3) - { - _rttResetTimer = 0; - _rtt = _avgRtt; - _rttCount = 1; - } - - UpdateMtuLogic(deltaTime); - - //Pending send - int count = _channelSendQueue.Count; - while (count-- > 0) - { - if (!_channelSendQueue.TryDequeue(out var channel)) - break; - if (channel.SendAndCheckQueue()) - { - // still has something to send, re-add it to the send queue - _channelSendQueue.Enqueue(channel); - } - } - - lock (_unreliableChannel) - { - int unreliableCount = _unreliableChannel.Count; - for (int i = 0; i < unreliableCount; i++) - { - var packet = _unreliableChannel.Dequeue(); - SendUserData(packet); - NetManager.PoolRecycle(packet); - } - } - - SendMerged(); - } - - //For reliable channel - internal void RecycleAndDeliver(NetPacket packet) - { - if (packet.UserData != null) - { - if (packet.IsFragmented) - { - _deliveredFragments.TryGetValue(packet.FragmentId, out ushort fragCount); - fragCount++; - if (fragCount == packet.FragmentsTotal) - { - NetManager.MessageDelivered(this, packet.UserData); - _deliveredFragments.Remove(packet.FragmentId); - } - else - { - _deliveredFragments[packet.FragmentId] = fragCount; - } - } - else - { - NetManager.MessageDelivered(this, packet.UserData); - } - packet.UserData = null; - } - NetManager.PoolRecycle(packet); - } - } -} diff --git a/Plugins/LiteNetLib/NetPeer.cs.meta b/Plugins/LiteNetLib/NetPeer.cs.meta deleted file mode 100644 index 3b6e8980..00000000 --- a/Plugins/LiteNetLib/NetPeer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9c65d87475d35ff4e9f0be7545811e31 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetStatistics.cs b/Plugins/LiteNetLib/NetStatistics.cs deleted file mode 100644 index 032e2754..00000000 --- a/Plugins/LiteNetLib/NetStatistics.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Threading; - -namespace LiteNetLib -{ - public sealed class NetStatistics - { - private long _packetsSent; - private long _packetsReceived; - private long _bytesSent; - private long _bytesReceived; - private long _packetLoss; - - public long PacketsSent => Interlocked.Read(ref _packetsSent); - public long PacketsReceived => Interlocked.Read(ref _packetsReceived); - public long BytesSent => Interlocked.Read(ref _bytesSent); - public long BytesReceived => Interlocked.Read(ref _bytesReceived); - public long PacketLoss => Interlocked.Read(ref _packetLoss); - - public long PacketLossPercent - { - get - { - long sent = PacketsSent, loss = PacketLoss; - - return sent == 0 ? 0 : loss * 100 / sent; - } - } - - public void Reset() - { - Interlocked.Exchange(ref _packetsSent, 0); - Interlocked.Exchange(ref _packetsReceived, 0); - Interlocked.Exchange(ref _bytesSent, 0); - Interlocked.Exchange(ref _bytesReceived, 0); - Interlocked.Exchange(ref _packetLoss, 0); - } - - public void IncrementPacketsSent() - { - Interlocked.Increment(ref _packetsSent); - } - - public void IncrementPacketsReceived() - { - Interlocked.Increment(ref _packetsReceived); - } - - public void AddBytesSent(long bytesSent) - { - Interlocked.Add(ref _bytesSent, bytesSent); - } - - public void AddBytesReceived(long bytesReceived) - { - Interlocked.Add(ref _bytesReceived, bytesReceived); - } - - public void IncrementPacketLoss() - { - Interlocked.Increment(ref _packetLoss); - } - - public void AddPacketLoss(long packetLoss) - { - Interlocked.Add(ref _packetLoss, packetLoss); - } - - public override string ToString() - { - return - string.Format( - "BytesReceived: {0}\nPacketsReceived: {1}\nBytesSent: {2}\nPacketsSent: {3}\nPacketLoss: {4}\nPacketLossPercent: {5}\n", - BytesReceived, - PacketsReceived, - BytesSent, - PacketsSent, - PacketLoss, - PacketLossPercent); - } - } -} diff --git a/Plugins/LiteNetLib/NetStatistics.cs.meta b/Plugins/LiteNetLib/NetStatistics.cs.meta deleted file mode 100644 index d14fbb8e..00000000 --- a/Plugins/LiteNetLib/NetStatistics.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7ceec5b44fa316a4a902adf9d7417985 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/NetUtils.cs b/Plugins/LiteNetLib/NetUtils.cs deleted file mode 100644 index 3b752e96..00000000 --- a/Plugins/LiteNetLib/NetUtils.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Net.NetworkInformation; - -namespace LiteNetLib -{ - /// - /// Address type that you want to receive from NetUtils.GetLocalIp method - /// - [Flags] - public enum LocalAddrType - { - IPv4 = 1, - IPv6 = 2, - All = IPv4 | IPv6 - } - - /// - /// Some specific network utilities - /// - public static class NetUtils - { - public static IPEndPoint MakeEndPoint(string hostStr, int port) - { - return new IPEndPoint(ResolveAddress(hostStr), port); - } - - public static IPAddress ResolveAddress(string hostStr) - { - if(hostStr == "localhost") - return IPAddress.Loopback; - - if (!IPAddress.TryParse(hostStr, out var ipAddress)) - { - if (NetManager.IPv6Support) - ipAddress = ResolveAddress(hostStr, AddressFamily.InterNetworkV6); - if (ipAddress == null) - ipAddress = ResolveAddress(hostStr, AddressFamily.InterNetwork); - } - if (ipAddress == null) - throw new ArgumentException("Invalid address: " + hostStr); - - return ipAddress; - } - - public static IPAddress ResolveAddress(string hostStr, AddressFamily addressFamily) - { - IPAddress[] addresses = Dns.GetHostEntry(hostStr).AddressList; - foreach (IPAddress ip in addresses) - { - if (ip.AddressFamily == addressFamily) - { - return ip; - } - } - return null; - } - - /// - /// Get all local ip addresses - /// - /// type of address (IPv4, IPv6 or both) - /// List with all local ip addresses - public static List GetLocalIpList(LocalAddrType addrType) - { - List targetList = new List(); - GetLocalIpList(targetList, addrType); - return targetList; - } - - /// - /// Get all local ip addresses (non alloc version) - /// - /// result list - /// type of address (IPv4, IPv6 or both) - public static void GetLocalIpList(IList targetList, LocalAddrType addrType) - { - bool ipv4 = (addrType & LocalAddrType.IPv4) == LocalAddrType.IPv4; - bool ipv6 = (addrType & LocalAddrType.IPv6) == LocalAddrType.IPv6; - try - { - foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) - { - //Skip loopback and disabled network interfaces - if (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback || - ni.OperationalStatus != OperationalStatus.Up) - continue; - - var ipProps = ni.GetIPProperties(); - - //Skip address without gateway - if (ipProps.GatewayAddresses.Count == 0) - continue; - - foreach (UnicastIPAddressInformation ip in ipProps.UnicastAddresses) - { - var address = ip.Address; - if ((ipv4 && address.AddressFamily == AddressFamily.InterNetwork) || - (ipv6 && address.AddressFamily == AddressFamily.InterNetworkV6)) - targetList.Add(address.ToString()); - } - } - - //Fallback mode (unity android) - if (targetList.Count == 0) - { - IPAddress[] addresses = Dns.GetHostEntry(Dns.GetHostName()).AddressList; - foreach (IPAddress ip in addresses) - { - if((ipv4 && ip.AddressFamily == AddressFamily.InterNetwork) || - (ipv6 && ip.AddressFamily == AddressFamily.InterNetworkV6)) - targetList.Add(ip.ToString()); - } - } - } - catch - { - //ignored - } - - if (targetList.Count == 0) - { - if(ipv4) - targetList.Add("127.0.0.1"); - if(ipv6) - targetList.Add("::1"); - } - } - - private static readonly List IpList = new List(); - /// - /// Get first detected local ip address - /// - /// type of address (IPv4, IPv6 or both) - /// IP address if available. Else - string.Empty - public static string GetLocalIp(LocalAddrType addrType) - { - lock (IpList) - { - IpList.Clear(); - GetLocalIpList(IpList, addrType); - return IpList.Count == 0 ? string.Empty : IpList[0]; - } - } - - // =========================================== - // Internal and debug log related stuff - // =========================================== - internal static void PrintInterfaceInfos() - { - NetDebug.WriteForce(NetLogLevel.Info, $"IPv6Support: { NetManager.IPv6Support}"); - try - { - foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) - { - foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) - { - if (ip.Address.AddressFamily == AddressFamily.InterNetwork || - ip.Address.AddressFamily == AddressFamily.InterNetworkV6) - { - NetDebug.WriteForce( - NetLogLevel.Info, - $"Interface: {ni.Name}, Type: {ni.NetworkInterfaceType}, Ip: {ip.Address}, OpStatus: {ni.OperationalStatus}"); - } - } - } - } - catch (Exception e) - { - NetDebug.WriteForce(NetLogLevel.Info, $"Error while getting interface infos: {e}"); - } - } - - internal static int RelativeSequenceNumber(int number, int expected) - { - return (number - expected + NetConstants.MaxSequence + NetConstants.HalfMaxSequence) % NetConstants.MaxSequence - NetConstants.HalfMaxSequence; - } - - internal static T[] AllocatePinnedUninitializedArray(int count) where T : unmanaged - { -#if NET5_0_OR_GREATER || NET5_0 - return GC.AllocateUninitializedArray(count, true); -#else - return new T[count]; -#endif - } - } -} diff --git a/Plugins/LiteNetLib/NetUtils.cs.meta b/Plugins/LiteNetLib/NetUtils.cs.meta deleted file mode 100644 index ef94789d..00000000 --- a/Plugins/LiteNetLib/NetUtils.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 44e25bdb2d99d6647965ccc7957fc2fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/PausedSocketFix.cs b/Plugins/LiteNetLib/PausedSocketFix.cs deleted file mode 100644 index dc92122a..00000000 --- a/Plugins/LiteNetLib/PausedSocketFix.cs +++ /dev/null @@ -1,57 +0,0 @@ -#if UNITY_2018_3_OR_NEWER -using System.Net; - -namespace LiteNetLib -{ - public class PausedSocketFix - { - private readonly NetManager _netManager; - private readonly IPAddress _ipv4; - private readonly IPAddress _ipv6; - private readonly int _port; - private readonly bool _manualMode; - private bool _initialized; - - public PausedSocketFix(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) - { - _netManager = netManager; - _ipv4 = ipv4; - _ipv6 = ipv6; - _port = port; - _manualMode = manualMode; - UnityEngine.Application.focusChanged += Application_focusChanged; - _initialized = true; - } - - public void Deinitialize() - { - if (_initialized) - UnityEngine.Application.focusChanged -= Application_focusChanged; - _initialized = false; - } - - private void Application_focusChanged(bool focused) - { - //If coming back into focus see if a reconnect is needed. - if (focused) - { - //try reconnect - if (!_initialized) - return; - //Was intentionally disconnected at some point. - if (!_netManager.IsRunning) - return; - //Socket is in working state. - if (_netManager.NotConnected == false) - return; - - //Socket isn't running but should be. Try to start again. - if (!_netManager.Start(_ipv4, _ipv6, _port, _manualMode)) - { - NetDebug.WriteError($"[S] Cannot restore connection. Ipv4 {_ipv4}, Ipv6 {_ipv6}, Port {_port}, ManualMode {_manualMode}"); - } - } - } - } -} -#endif diff --git a/Plugins/LiteNetLib/PausedSocketFix.cs.meta b/Plugins/LiteNetLib/PausedSocketFix.cs.meta deleted file mode 100644 index fda02f14..00000000 --- a/Plugins/LiteNetLib/PausedSocketFix.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dfc08189ca743bf4287e5a22a5c7b605 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/PooledPacket.cs b/Plugins/LiteNetLib/PooledPacket.cs deleted file mode 100644 index 26ef7bd8..00000000 --- a/Plugins/LiteNetLib/PooledPacket.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace LiteNetLib -{ - public readonly ref struct PooledPacket - { - internal readonly NetPacket _packet; - internal readonly byte _channelNumber; - - /// - /// Maximum data size that you can put into such packet - /// - public readonly int MaxUserDataSize; - - /// - /// Offset for user data when writing to Data array - /// - public readonly int UserDataOffset; - - /// - /// Raw packet data. Do not modify header! Use UserDataOffset as start point for your data - /// - public byte[] Data => _packet.RawData; - - internal PooledPacket(NetPacket packet, int maxDataSize, byte channelNumber) - { - _packet = packet; - UserDataOffset = _packet.GetHeaderSize(); - _packet.Size = UserDataOffset; - MaxUserDataSize = maxDataSize - UserDataOffset; - _channelNumber = channelNumber; - } - } -} diff --git a/Plugins/LiteNetLib/PooledPacket.cs.meta b/Plugins/LiteNetLib/PooledPacket.cs.meta deleted file mode 100644 index 00d971cc..00000000 --- a/Plugins/LiteNetLib/PooledPacket.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e0da76c0bff2bdc4bb2ba34fc8f99421 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/ReliableChannel.cs b/Plugins/LiteNetLib/ReliableChannel.cs deleted file mode 100644 index 4a10d170..00000000 --- a/Plugins/LiteNetLib/ReliableChannel.cs +++ /dev/null @@ -1,337 +0,0 @@ -using System; - -namespace LiteNetLib -{ - internal sealed class ReliableChannel : BaseChannel - { - private struct PendingPacket - { - private NetPacket _packet; - private long _timeStamp; - private bool _isSent; - - public override string ToString() - { - return _packet == null ? "Empty" : _packet.Sequence.ToString(); - } - - public void Init(NetPacket packet) - { - _packet = packet; - _isSent = false; - } - - //Returns true if there is a pending packet inside - public bool TrySend(long currentTime, NetPeer peer) - { - if (_packet == null) - return false; - - if (_isSent) //check send time - { - double resendDelay = peer.ResendDelay * TimeSpan.TicksPerMillisecond; - double packetHoldTime = currentTime - _timeStamp; - if (packetHoldTime < resendDelay) - return true; - NetDebug.Write($"[RC]Resend: {packetHoldTime} > {resendDelay}"); - } - _timeStamp = currentTime; - _isSent = true; - peer.SendUserData(_packet); - return true; - } - - public bool Clear(NetPeer peer) - { - if (_packet != null) - { - peer.RecycleAndDeliver(_packet); - _packet = null; - return true; - } - return false; - } - } - - private readonly NetPacket _outgoingAcks; //for send acks - private readonly PendingPacket[] _pendingPackets; //for unacked packets and duplicates - private readonly NetPacket[] _receivedPackets; //for order - private readonly bool[] _earlyReceived; //for unordered - - private int _localSeqence; - private int _remoteSequence; - private int _localWindowStart; - private int _remoteWindowStart; - - private bool _mustSendAcks; - - private readonly DeliveryMethod _deliveryMethod; - private readonly bool _ordered; - private readonly int _windowSize; - private const int BitsInByte = 8; - private readonly byte _id; - - public ReliableChannel(NetPeer peer, bool ordered, byte id) : base(peer) - { - _id = id; - _windowSize = NetConstants.DefaultWindowSize; - _ordered = ordered; - _pendingPackets = new PendingPacket[_windowSize]; - for (int i = 0; i < _pendingPackets.Length; i++) - _pendingPackets[i] = new PendingPacket(); - - if (_ordered) - { - _deliveryMethod = DeliveryMethod.ReliableOrdered; - _receivedPackets = new NetPacket[_windowSize]; - } - else - { - _deliveryMethod = DeliveryMethod.ReliableUnordered; - _earlyReceived = new bool[_windowSize]; - } - - _localWindowStart = 0; - _localSeqence = 0; - _remoteSequence = 0; - _remoteWindowStart = 0; - _outgoingAcks = new NetPacket(PacketProperty.Ack, (_windowSize - 1) / BitsInByte + 2) {ChannelId = id}; - } - - //ProcessAck in packet - private void ProcessAck(NetPacket packet) - { - if (packet.Size != _outgoingAcks.Size) - { - NetDebug.Write("[PA]Invalid acks packet size"); - return; - } - - ushort ackWindowStart = packet.Sequence; - int windowRel = NetUtils.RelativeSequenceNumber(_localWindowStart, ackWindowStart); - if (ackWindowStart >= NetConstants.MaxSequence || windowRel < 0) - { - NetDebug.Write("[PA]Bad window start"); - return; - } - - //check relevance - if (windowRel >= _windowSize) - { - NetDebug.Write("[PA]Old acks"); - return; - } - - byte[] acksData = packet.RawData; - lock (_pendingPackets) - { - for (int pendingSeq = _localWindowStart; - pendingSeq != _localSeqence; - pendingSeq = (pendingSeq + 1) % NetConstants.MaxSequence) - { - int rel = NetUtils.RelativeSequenceNumber(pendingSeq, ackWindowStart); - if (rel >= _windowSize) - { - NetDebug.Write("[PA]REL: " + rel); - break; - } - - int pendingIdx = pendingSeq % _windowSize; - int currentByte = NetConstants.ChanneledHeaderSize + pendingIdx / BitsInByte; - int currentBit = pendingIdx % BitsInByte; - if ((acksData[currentByte] & (1 << currentBit)) == 0) - { - if (Peer.NetManager.EnableStatistics) - { - Peer.Statistics.IncrementPacketLoss(); - Peer.NetManager.Statistics.IncrementPacketLoss(); - } - - //Skip false ack - NetDebug.Write($"[PA]False ack: {pendingSeq}"); - continue; - } - - if (pendingSeq == _localWindowStart) - { - //Move window - _localWindowStart = (_localWindowStart + 1) % NetConstants.MaxSequence; - } - - //clear packet - if (_pendingPackets[pendingIdx].Clear(Peer)) - NetDebug.Write($"[PA]Removing reliableInOrder ack: {pendingSeq} - true"); - } - } - } - - protected override bool SendNextPackets() - { - if (_mustSendAcks) - { - _mustSendAcks = false; - NetDebug.Write("[RR]SendAcks"); - lock(_outgoingAcks) - Peer.SendUserData(_outgoingAcks); - } - - long currentTime = DateTime.UtcNow.Ticks; - bool hasPendingPackets = false; - - lock (_pendingPackets) - { - //get packets from queue - lock (OutgoingQueue) - { - while (OutgoingQueue.Count > 0) - { - int relate = NetUtils.RelativeSequenceNumber(_localSeqence, _localWindowStart); - if (relate >= _windowSize) - break; - - var netPacket = OutgoingQueue.Dequeue(); - netPacket.Sequence = (ushort) _localSeqence; - netPacket.ChannelId = _id; - _pendingPackets[_localSeqence % _windowSize].Init(netPacket); - _localSeqence = (_localSeqence + 1) % NetConstants.MaxSequence; - } - } - - //send - for (int pendingSeq = _localWindowStart; pendingSeq != _localSeqence; pendingSeq = (pendingSeq + 1) % NetConstants.MaxSequence) - { - // Please note: TrySend is invoked on a mutable struct, it's important to not extract it into a variable here - if (_pendingPackets[pendingSeq % _windowSize].TrySend(currentTime, Peer)) - hasPendingPackets = true; - } - } - - return hasPendingPackets || _mustSendAcks || OutgoingQueue.Count > 0; - } - - //Process incoming packet - public override bool ProcessPacket(NetPacket packet) - { - if (packet.Property == PacketProperty.Ack) - { - ProcessAck(packet); - return false; - } - int seq = packet.Sequence; - if (seq >= NetConstants.MaxSequence) - { - NetDebug.Write("[RR]Bad sequence"); - return false; - } - - int relate = NetUtils.RelativeSequenceNumber(seq, _remoteWindowStart); - int relateSeq = NetUtils.RelativeSequenceNumber(seq, _remoteSequence); - - if (relateSeq > _windowSize) - { - NetDebug.Write("[RR]Bad sequence"); - return false; - } - - //Drop bad packets - if (relate < 0) - { - //Too old packet doesn't ack - NetDebug.Write("[RR]ReliableInOrder too old"); - return false; - } - if (relate >= _windowSize * 2) - { - //Some very new packet - NetDebug.Write("[RR]ReliableInOrder too new"); - return false; - } - - //If very new - move window - int ackIdx; - int ackByte; - int ackBit; - lock (_outgoingAcks) - { - if (relate >= _windowSize) - { - //New window position - int newWindowStart = (_remoteWindowStart + relate - _windowSize + 1) % NetConstants.MaxSequence; - _outgoingAcks.Sequence = (ushort) newWindowStart; - - //Clean old data - while (_remoteWindowStart != newWindowStart) - { - ackIdx = _remoteWindowStart % _windowSize; - ackByte = NetConstants.ChanneledHeaderSize + ackIdx / BitsInByte; - ackBit = ackIdx % BitsInByte; - _outgoingAcks.RawData[ackByte] &= (byte) ~(1 << ackBit); - _remoteWindowStart = (_remoteWindowStart + 1) % NetConstants.MaxSequence; - } - } - - //Final stage - process valid packet - //trigger acks send - _mustSendAcks = true; - - ackIdx = seq % _windowSize; - ackByte = NetConstants.ChanneledHeaderSize + ackIdx / BitsInByte; - ackBit = ackIdx % BitsInByte; - if ((_outgoingAcks.RawData[ackByte] & (1 << ackBit)) != 0) - { - NetDebug.Write("[RR]ReliableInOrder duplicate"); - //because _mustSendAcks == true - AddToPeerChannelSendQueue(); - return false; - } - - //save ack - _outgoingAcks.RawData[ackByte] |= (byte) (1 << ackBit); - } - - AddToPeerChannelSendQueue(); - - //detailed check - if (seq == _remoteSequence) - { - NetDebug.Write("[RR]ReliableInOrder packet succes"); - Peer.AddReliablePacket(_deliveryMethod, packet); - _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence; - - if (_ordered) - { - NetPacket p; - while ((p = _receivedPackets[_remoteSequence % _windowSize]) != null) - { - //process holden packet - _receivedPackets[_remoteSequence % _windowSize] = null; - Peer.AddReliablePacket(_deliveryMethod, p); - _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence; - } - } - else - { - while (_earlyReceived[_remoteSequence % _windowSize]) - { - //process early packet - _earlyReceived[_remoteSequence % _windowSize] = false; - _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence; - } - } - return true; - } - - //holden packet - if (_ordered) - { - _receivedPackets[ackIdx] = packet; - } - else - { - _earlyReceived[ackIdx] = true; - Peer.AddReliablePacket(_deliveryMethod, packet); - } - return true; - } - } -} diff --git a/Plugins/LiteNetLib/ReliableChannel.cs.meta b/Plugins/LiteNetLib/ReliableChannel.cs.meta deleted file mode 100644 index db1fa036..00000000 --- a/Plugins/LiteNetLib/ReliableChannel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7fe127c80c0a52a439d991e9dea1be59 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/SequencedChannel.cs b/Plugins/LiteNetLib/SequencedChannel.cs deleted file mode 100644 index bc47f86d..00000000 --- a/Plugins/LiteNetLib/SequencedChannel.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; - -namespace LiteNetLib -{ - internal sealed class SequencedChannel : BaseChannel - { - private int _localSequence; - private ushort _remoteSequence; - private readonly bool _reliable; - private NetPacket _lastPacket; - private readonly NetPacket _ackPacket; - private bool _mustSendAck; - private readonly byte _id; - private long _lastPacketSendTime; - - public SequencedChannel(NetPeer peer, bool reliable, byte id) : base(peer) - { - _id = id; - _reliable = reliable; - if (_reliable) - _ackPacket = new NetPacket(PacketProperty.Ack, 0) {ChannelId = id}; - } - - protected override bool SendNextPackets() - { - if (_reliable && OutgoingQueue.Count == 0) - { - long currentTime = DateTime.UtcNow.Ticks; - long packetHoldTime = currentTime - _lastPacketSendTime; - if (packetHoldTime >= Peer.ResendDelay * TimeSpan.TicksPerMillisecond) - { - var packet = _lastPacket; - if (packet != null) - { - _lastPacketSendTime = currentTime; - Peer.SendUserData(packet); - } - } - } - else - { - lock (OutgoingQueue) - { - while (OutgoingQueue.Count > 0) - { - NetPacket packet = OutgoingQueue.Dequeue(); - _localSequence = (_localSequence + 1) % NetConstants.MaxSequence; - packet.Sequence = (ushort)_localSequence; - packet.ChannelId = _id; - Peer.SendUserData(packet); - - if (_reliable && OutgoingQueue.Count == 0) - { - _lastPacketSendTime = DateTime.UtcNow.Ticks; - _lastPacket = packet; - } - else - { - Peer.NetManager.PoolRecycle(packet); - } - } - } - } - - if (_reliable && _mustSendAck) - { - _mustSendAck = false; - _ackPacket.Sequence = _remoteSequence; - Peer.SendUserData(_ackPacket); - } - - return _lastPacket != null; - } - - public override bool ProcessPacket(NetPacket packet) - { - if (packet.IsFragmented) - return false; - if (packet.Property == PacketProperty.Ack) - { - if (_reliable && _lastPacket != null && packet.Sequence == _lastPacket.Sequence) - _lastPacket = null; - return false; - } - int relative = NetUtils.RelativeSequenceNumber(packet.Sequence, _remoteSequence); - bool packetProcessed = false; - if (packet.Sequence < NetConstants.MaxSequence && relative > 0) - { - if (Peer.NetManager.EnableStatistics) - { - Peer.Statistics.AddPacketLoss(relative - 1); - Peer.NetManager.Statistics.AddPacketLoss(relative - 1); - } - - _remoteSequence = packet.Sequence; - Peer.NetManager.CreateReceiveEvent( - packet, - _reliable ? DeliveryMethod.ReliableSequenced : DeliveryMethod.Sequenced, - (byte)(packet.ChannelId / NetConstants.ChannelTypeCount), - NetConstants.ChanneledHeaderSize, - Peer); - packetProcessed = true; - } - - if (_reliable) - { - _mustSendAck = true; - AddToPeerChannelSendQueue(); - } - - return packetProcessed; - } - } -} diff --git a/Plugins/LiteNetLib/SequencedChannel.cs.meta b/Plugins/LiteNetLib/SequencedChannel.cs.meta deleted file mode 100644 index 913beb33..00000000 --- a/Plugins/LiteNetLib/SequencedChannel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: afc0ff99f5eb1414183b29dfe2a3d660 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils.meta b/Plugins/LiteNetLib/Utils.meta deleted file mode 100644 index bf720016..00000000 --- a/Plugins/LiteNetLib/Utils.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8d65d12d8875cef48a8532b4f3d53896 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/CRC32C.cs b/Plugins/LiteNetLib/Utils/CRC32C.cs deleted file mode 100644 index 7e85680c..00000000 --- a/Plugins/LiteNetLib/Utils/CRC32C.cs +++ /dev/null @@ -1,150 +0,0 @@ -#if NETCOREAPP3_0_OR_GREATER || NETCOREAPP3_1 || NET5_0 -using System; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics.X86; -#endif -#if NET5_0_OR_GREATER || NET5_0 -using System.Runtime.Intrinsics.Arm; -#endif - -namespace LiteNetLib.Utils -{ - //Implementation from Crc32.NET - public static class CRC32C - { - public const int ChecksumSize = 4; - private const uint Poly = 0x82F63B78u; - private static readonly uint[] Table; - - static CRC32C() - { -#if NETCOREAPP3_0_OR_GREATER || NETCOREAPP3_1 || NET5_0 - if (Sse42.IsSupported) - return; -#endif -#if NET5_0_OR_GREATER || NET5_0 - if (Crc32.IsSupported) - return; -#endif - Table = NetUtils.AllocatePinnedUninitializedArray(16 * 256); - for (uint i = 0; i < 256; i++) - { - uint res = i; - for (int t = 0; t < 16; t++) - { - for (int k = 0; k < 8; k++) - res = (res & 1) == 1 ? Poly ^ (res >> 1) : (res >> 1); - Table[t * 256 + i] = res; - } - } - } - - /// - /// Compute CRC32C for data - /// - /// input data - /// offset - /// length - /// CRC32C checksum - public static uint Compute(byte[] input, int offset, int length) - { - uint crcLocal = uint.MaxValue; -#if NETCOREAPP3_0_OR_GREATER || NETCOREAPP3_1 || NET5_0 - if (Sse42.IsSupported) - { - var data = new ReadOnlySpan(input, offset, length); - int processed = 0; - if (Sse42.X64.IsSupported && data.Length > sizeof(ulong)) - { - processed = data.Length / sizeof(ulong) * sizeof(ulong); - var ulongs = MemoryMarshal.Cast(data.Slice(0, processed)); - ulong crclong = crcLocal; - for (int i = 0; i < ulongs.Length; i++) - { - crclong = Sse42.X64.Crc32(crclong, ulongs[i]); - } - - crcLocal = (uint)crclong; - } - else if (data.Length > sizeof(uint)) - { - processed = data.Length / sizeof(uint) * sizeof(uint); - var uints = MemoryMarshal.Cast(data.Slice(0, processed)); - for (int i = 0; i < uints.Length; i++) - { - crcLocal = Sse42.Crc32(crcLocal, uints[i]); - } - } - - for (int i = processed; i < data.Length; i++) - { - crcLocal = Sse42.Crc32(crcLocal, data[i]); - } - - return crcLocal ^ uint.MaxValue; - } -#endif -#if NET5_0_OR_GREATER || NET5_0 - if (Crc32.IsSupported) - { - var data = new ReadOnlySpan(input, offset, length); - int processed = 0; - if (Crc32.Arm64.IsSupported && data.Length > sizeof(ulong)) - { - processed = data.Length / sizeof(ulong) * sizeof(ulong); - var ulongs = MemoryMarshal.Cast(data.Slice(0, processed)); - for (int i = 0; i < ulongs.Length; i++) - { - crcLocal = Crc32.Arm64.ComputeCrc32C(crcLocal, ulongs[i]); - } - } - else if (data.Length > sizeof(uint)) - { - processed = data.Length / sizeof(uint) * sizeof(uint); - var uints = MemoryMarshal.Cast(data.Slice(0, processed)); - for (int i = 0; i < uints.Length; i++) - { - crcLocal = Crc32.ComputeCrc32C(crcLocal, uints[i]); - } - } - - for (int i = processed; i < data.Length; i++) - { - crcLocal = Crc32.ComputeCrc32C(crcLocal, data[i]); - } - - return crcLocal ^ uint.MaxValue; - } -#endif - while (length >= 16) - { - var a = Table[(3 * 256) + input[offset + 12]] - ^ Table[(2 * 256) + input[offset + 13]] - ^ Table[(1 * 256) + input[offset + 14]] - ^ Table[(0 * 256) + input[offset + 15]]; - - var b = Table[(7 * 256) + input[offset + 8]] - ^ Table[(6 * 256) + input[offset + 9]] - ^ Table[(5 * 256) + input[offset + 10]] - ^ Table[(4 * 256) + input[offset + 11]]; - - var c = Table[(11 * 256) + input[offset + 4]] - ^ Table[(10 * 256) + input[offset + 5]] - ^ Table[(9 * 256) + input[offset + 6]] - ^ Table[(8 * 256) + input[offset + 7]]; - - var d = Table[(15 * 256) + ((byte)crcLocal ^ input[offset])] - ^ Table[(14 * 256) + ((byte)(crcLocal >> 8) ^ input[offset + 1])] - ^ Table[(13 * 256) + ((byte)(crcLocal >> 16) ^ input[offset + 2])] - ^ Table[(12 * 256) + ((crcLocal >> 24) ^ input[offset + 3])]; - - crcLocal = d ^ c ^ b ^ a; - offset += 16; - length -= 16; - } - while (--length >= 0) - crcLocal = Table[(byte)(crcLocal ^ input[offset++])] ^ crcLocal >> 8; - return crcLocal ^ uint.MaxValue; - } - } -} diff --git a/Plugins/LiteNetLib/Utils/CRC32C.cs.meta b/Plugins/LiteNetLib/Utils/CRC32C.cs.meta deleted file mode 100644 index 6551baf0..00000000 --- a/Plugins/LiteNetLib/Utils/CRC32C.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 66ee12ebb39d4c8488f0f1baaf4ac6e8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/FastBitConverter.cs b/Plugins/LiteNetLib/Utils/FastBitConverter.cs deleted file mode 100644 index 3ecd10c7..00000000 --- a/Plugins/LiteNetLib/Utils/FastBitConverter.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace LiteNetLib.Utils -{ - public static class FastBitConverter - { -#if (LITENETLIB_UNSAFE || LITENETLIB_UNSAFELIB || NETCOREAPP3_1 || NET5_0 || NETCOREAPP3_0_OR_GREATER) && !BIGENDIAN -#if LITENETLIB_UNSAFE - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void GetBytes(byte[] bytes, int startIndex, T value) where T : unmanaged - { - int size = sizeof(T); - if (bytes.Length < startIndex + size) - ThrowIndexOutOfRangeException(); -#if LITENETLIB_UNSAFELIB || NETCOREAPP3_1 || NET5_0 || NETCOREAPP3_0_OR_GREATER - Unsafe.As(ref bytes[startIndex]) = value; -#else - fixed (byte* ptr = &bytes[startIndex]) - { -#if UNITY_ANDROID - // On some android systems, assigning *(T*)ptr throws a NRE if - // the ptr isn't aligned (i.e. if Position is 1,2,3,5, etc.). - // Here we have to use memcpy. - // - // => we can't get a pointer of a struct in C# without - // marshalling allocations - // => instead, we stack allocate an array of type T and use that - // => stackalloc avoids GC and is very fast. it only works for - // value types, but all blittable types are anyway. - T* valueBuffer = stackalloc T[1] { value }; - UnsafeUtility.MemCpy(ptr, valueBuffer, size); -#else - *(T*)ptr = value; -#endif - } -#endif - } -#else - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, T value) where T : unmanaged - { - if (bytes.Length < startIndex + Unsafe.SizeOf()) - ThrowIndexOutOfRangeException(); - Unsafe.As(ref bytes[startIndex]) = value; - } -#endif - - private static void ThrowIndexOutOfRangeException() => throw new IndexOutOfRangeException(); -#else - [StructLayout(LayoutKind.Explicit)] - private struct ConverterHelperDouble - { - [FieldOffset(0)] - public ulong Along; - - [FieldOffset(0)] - public double Adouble; - } - - [StructLayout(LayoutKind.Explicit)] - private struct ConverterHelperFloat - { - [FieldOffset(0)] - public int Aint; - - [FieldOffset(0)] - public float Afloat; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteLittleEndian(byte[] buffer, int offset, ulong data) - { -#if BIGENDIAN - buffer[offset + 7] = (byte)(data); - buffer[offset + 6] = (byte)(data >> 8); - buffer[offset + 5] = (byte)(data >> 16); - buffer[offset + 4] = (byte)(data >> 24); - buffer[offset + 3] = (byte)(data >> 32); - buffer[offset + 2] = (byte)(data >> 40); - buffer[offset + 1] = (byte)(data >> 48); - buffer[offset ] = (byte)(data >> 56); -#else - buffer[offset] = (byte)(data); - buffer[offset + 1] = (byte)(data >> 8); - buffer[offset + 2] = (byte)(data >> 16); - buffer[offset + 3] = (byte)(data >> 24); - buffer[offset + 4] = (byte)(data >> 32); - buffer[offset + 5] = (byte)(data >> 40); - buffer[offset + 6] = (byte)(data >> 48); - buffer[offset + 7] = (byte)(data >> 56); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteLittleEndian(byte[] buffer, int offset, int data) - { -#if BIGENDIAN - buffer[offset + 3] = (byte)(data); - buffer[offset + 2] = (byte)(data >> 8); - buffer[offset + 1] = (byte)(data >> 16); - buffer[offset ] = (byte)(data >> 24); -#else - buffer[offset] = (byte)(data); - buffer[offset + 1] = (byte)(data >> 8); - buffer[offset + 2] = (byte)(data >> 16); - buffer[offset + 3] = (byte)(data >> 24); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteLittleEndian(byte[] buffer, int offset, short data) - { -#if BIGENDIAN - buffer[offset + 1] = (byte)(data); - buffer[offset ] = (byte)(data >> 8); -#else - buffer[offset] = (byte)(data); - buffer[offset + 1] = (byte)(data >> 8); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, double value) - { - ConverterHelperDouble ch = new ConverterHelperDouble { Adouble = value }; - WriteLittleEndian(bytes, startIndex, ch.Along); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, float value) - { - ConverterHelperFloat ch = new ConverterHelperFloat { Afloat = value }; - WriteLittleEndian(bytes, startIndex, ch.Aint); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, short value) - { - WriteLittleEndian(bytes, startIndex, value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, ushort value) - { - WriteLittleEndian(bytes, startIndex, (short)value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, int value) - { - WriteLittleEndian(bytes, startIndex, value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, uint value) - { - WriteLittleEndian(bytes, startIndex, (int)value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, long value) - { - WriteLittleEndian(bytes, startIndex, (ulong)value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, ulong value) - { - WriteLittleEndian(bytes, startIndex, value); - } -#endif - } -} diff --git a/Plugins/LiteNetLib/Utils/FastBitConverter.cs.meta b/Plugins/LiteNetLib/Utils/FastBitConverter.cs.meta deleted file mode 100644 index ac246a0d..00000000 --- a/Plugins/LiteNetLib/Utils/FastBitConverter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4e9bc937cb014ff48a6f689029c117fd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/INetSerializable.cs b/Plugins/LiteNetLib/Utils/INetSerializable.cs deleted file mode 100644 index 92f14bee..00000000 --- a/Plugins/LiteNetLib/Utils/INetSerializable.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace LiteNetLib.Utils -{ - public interface INetSerializable - { - void Serialize(NetDataWriter writer); - void Deserialize(NetDataReader reader); - } -} diff --git a/Plugins/LiteNetLib/Utils/INetSerializable.cs.meta b/Plugins/LiteNetLib/Utils/INetSerializable.cs.meta deleted file mode 100644 index 4faa5bc4..00000000 --- a/Plugins/LiteNetLib/Utils/INetSerializable.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f32a9f3c6cd025044b0ff1b86dd6f2b1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/NetDataReader.cs b/Plugins/LiteNetLib/Utils/NetDataReader.cs deleted file mode 100644 index 6ddab0e5..00000000 --- a/Plugins/LiteNetLib/Utils/NetDataReader.cs +++ /dev/null @@ -1,673 +0,0 @@ -using System; -using System.Net; -using System.Runtime.CompilerServices; - -namespace LiteNetLib.Utils -{ - public class NetDataReader - { - protected byte[] _data; - protected int _position; - protected int _dataSize; - private int _offset; - - public byte[] RawData - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _data; - } - public int RawDataSize - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _dataSize; - } - public int UserDataOffset - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _offset; - } - public int UserDataSize - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _dataSize - _offset; - } - public bool IsNull - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _data == null; - } - public int Position - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _position; - } - public bool EndOfData - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _position == _dataSize; - } - public int AvailableBytes - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _dataSize - _position; - } - - public void SkipBytes(int count) - { - _position += count; - } - - public void SetPosition(int position) - { - _position = position; - } - - public void SetSource(NetDataWriter dataWriter) - { - _data = dataWriter.Data; - _position = 0; - _offset = 0; - _dataSize = dataWriter.Length; - } - - public void SetSource(byte[] source) - { - _data = source; - _position = 0; - _offset = 0; - _dataSize = source.Length; - } - - public void SetSource(byte[] source, int offset, int maxSize) - { - _data = source; - _position = offset; - _offset = offset; - _dataSize = maxSize; - } - - public NetDataReader() - { - - } - - public NetDataReader(NetDataWriter writer) - { - SetSource(writer); - } - - public NetDataReader(byte[] source) - { - SetSource(source); - } - - public NetDataReader(byte[] source, int offset, int maxSize) - { - SetSource(source, offset, maxSize); - } - - #region GetMethods - public IPEndPoint GetNetEndPoint() - { - string host = GetString(1000); - int port = GetInt(); - return NetUtils.MakeEndPoint(host, port); - } - - public byte GetByte() - { - byte res = _data[_position]; - _position++; - return res; - } - - public sbyte GetSByte() - { - return (sbyte)GetByte(); - } - - public T[] GetArray(ushort size) - { - ushort length = BitConverter.ToUInt16(_data, _position); - _position += 2; - T[] result = new T[length]; - length *= size; - Buffer.BlockCopy(_data, _position, result, 0, length); - _position += length; - return result; - } - - public bool[] GetBoolArray() - { - return GetArray(1); - } - - public ushort[] GetUShortArray() - { - return GetArray(2); - } - - public short[] GetShortArray() - { - return GetArray(2); - } - - public int[] GetIntArray() - { - return GetArray(4); - } - - public uint[] GetUIntArray() - { - return GetArray(4); - } - - public float[] GetFloatArray() - { - return GetArray(4); - } - - public double[] GetDoubleArray() - { - return GetArray(8); - } - - public long[] GetLongArray() - { - return GetArray(8); - } - - public ulong[] GetULongArray() - { - return GetArray(8); - } - - public string[] GetStringArray() - { - ushort length = GetUShort(); - string[] arr = new string[length]; - for (int i = 0; i < length; i++) - { - arr[i] = GetString(); - } - return arr; - } - - /// - /// Note that "maxStringLength" only limits the number of characters in a string, not its size in bytes. - /// Strings that exceed this parameter are returned as empty - /// - public string[] GetStringArray(int maxStringLength) - { - ushort length = GetUShort(); - string[] arr = new string[length]; - for (int i = 0; i < length; i++) - { - arr[i] = GetString(maxStringLength); - } - return arr; - } - - public bool GetBool() - { - return GetByte() == 1; - } - - public char GetChar() - { - return (char)GetUShort(); - } - - public ushort GetUShort() - { - ushort result = BitConverter.ToUInt16(_data, _position); - _position += 2; - return result; - } - - public short GetShort() - { - short result = BitConverter.ToInt16(_data, _position); - _position += 2; - return result; - } - - public long GetLong() - { - long result = BitConverter.ToInt64(_data, _position); - _position += 8; - return result; - } - - public ulong GetULong() - { - ulong result = BitConverter.ToUInt64(_data, _position); - _position += 8; - return result; - } - - public int GetInt() - { - int result = BitConverter.ToInt32(_data, _position); - _position += 4; - return result; - } - - public uint GetUInt() - { - uint result = BitConverter.ToUInt32(_data, _position); - _position += 4; - return result; - } - - public float GetFloat() - { - float result = BitConverter.ToSingle(_data, _position); - _position += 4; - return result; - } - - public double GetDouble() - { - double result = BitConverter.ToDouble(_data, _position); - _position += 8; - return result; - } - - /// - /// Note that "maxLength" only limits the number of characters in a string, not its size in bytes. - /// - /// "string.Empty" if value > "maxLength" - public string GetString(int maxLength) - { - ushort size = GetUShort(); - if (size == 0) - { - return string.Empty; - } - - int actualSize = size - 1; - if (actualSize >= NetDataWriter.StringBufferMaxLength) - { - return null; - } - - ArraySegment data = GetBytesSegment(actualSize); - - return (maxLength > 0 && NetDataWriter.uTF8Encoding.Value.GetCharCount(data.Array, data.Offset, data.Count) > maxLength) ? - string.Empty : - NetDataWriter.uTF8Encoding.Value.GetString(data.Array, data.Offset, data.Count); - } - - public string GetString() - { - ushort size = GetUShort(); - if (size == 0) - { - return string.Empty; - } - - int actualSize = size - 1; - if (actualSize >= NetDataWriter.StringBufferMaxLength) - { - return null; - } - - ArraySegment data = GetBytesSegment(actualSize); - - return NetDataWriter.uTF8Encoding.Value.GetString(data.Array, data.Offset, data.Count); - } - - public ArraySegment GetBytesSegment(int count) - { - ArraySegment segment = new ArraySegment(_data, _position, count); - _position += count; - return segment; - } - - public ArraySegment GetRemainingBytesSegment() - { - ArraySegment segment = new ArraySegment(_data, _position, AvailableBytes); - _position = _data.Length; - return segment; - } - - public T Get() where T : struct, INetSerializable - { - var obj = default(T); - obj.Deserialize(this); - return obj; - } - - public T Get(Func constructor) where T : class, INetSerializable - { - var obj = constructor(); - obj.Deserialize(this); - return obj; - } - - public byte[] GetRemainingBytes() - { - byte[] outgoingData = new byte[AvailableBytes]; - Buffer.BlockCopy(_data, _position, outgoingData, 0, AvailableBytes); - _position = _data.Length; - return outgoingData; - } - - public void GetBytes(byte[] destination, int start, int count) - { - Buffer.BlockCopy(_data, _position, destination, start, count); - _position += count; - } - - public void GetBytes(byte[] destination, int count) - { - Buffer.BlockCopy(_data, _position, destination, 0, count); - _position += count; - } - - public sbyte[] GetSBytesWithLength() - { - return GetArray(1); - } - - public byte[] GetBytesWithLength() - { - return GetArray(1); - } - #endregion - - #region PeekMethods - - public byte PeekByte() - { - return _data[_position]; - } - - public sbyte PeekSByte() - { - return (sbyte)_data[_position]; - } - - public bool PeekBool() - { - return _data[_position] == 1; - } - - public char PeekChar() - { - return (char)PeekUShort(); - } - - public ushort PeekUShort() - { - return BitConverter.ToUInt16(_data, _position); - } - - public short PeekShort() - { - return BitConverter.ToInt16(_data, _position); - } - - public long PeekLong() - { - return BitConverter.ToInt64(_data, _position); - } - - public ulong PeekULong() - { - return BitConverter.ToUInt64(_data, _position); - } - - public int PeekInt() - { - return BitConverter.ToInt32(_data, _position); - } - - public uint PeekUInt() - { - return BitConverter.ToUInt32(_data, _position); - } - - public float PeekFloat() - { - return BitConverter.ToSingle(_data, _position); - } - - public double PeekDouble() - { - return BitConverter.ToDouble(_data, _position); - } - - /// - /// Note that "maxLength" only limits the number of characters in a string, not its size in bytes. - /// - public string PeekString(int maxLength) - { - ushort size = PeekUShort(); - if (size == 0) - { - return string.Empty; - } - - int actualSize = size - 1; - if (actualSize >= NetDataWriter.StringBufferMaxLength) - { - return null; - } - - return (maxLength > 0 && NetDataWriter.uTF8Encoding.Value.GetCharCount(_data, _position + 2, actualSize) > maxLength) ? - string.Empty : - NetDataWriter.uTF8Encoding.Value.GetString(_data, _position + 2, actualSize); - } - - public string PeekString() - { - ushort size = PeekUShort(); - if (size == 0) - { - return string.Empty; - } - - int actualSize = size - 1; - if (actualSize >= NetDataWriter.StringBufferMaxLength) - { - return null; - } - - return NetDataWriter.uTF8Encoding.Value.GetString(_data, _position + 2, actualSize); - } - #endregion - - #region TryGetMethods - public bool TryGetByte(out byte result) - { - if (AvailableBytes >= 1) - { - result = GetByte(); - return true; - } - result = 0; - return false; - } - - public bool TryGetSByte(out sbyte result) - { - if (AvailableBytes >= 1) - { - result = GetSByte(); - return true; - } - result = 0; - return false; - } - - public bool TryGetBool(out bool result) - { - if (AvailableBytes >= 1) - { - result = GetBool(); - return true; - } - result = false; - return false; - } - - public bool TryGetChar(out char result) - { - if (!TryGetUShort(out ushort uShortValue)) - { - result = '\0'; - return false; - } - result = (char)uShortValue; - return true; - } - - public bool TryGetShort(out short result) - { - if (AvailableBytes >= 2) - { - result = GetShort(); - return true; - } - result = 0; - return false; - } - - public bool TryGetUShort(out ushort result) - { - if (AvailableBytes >= 2) - { - result = GetUShort(); - return true; - } - result = 0; - return false; - } - - public bool TryGetInt(out int result) - { - if (AvailableBytes >= 4) - { - result = GetInt(); - return true; - } - result = 0; - return false; - } - - public bool TryGetUInt(out uint result) - { - if (AvailableBytes >= 4) - { - result = GetUInt(); - return true; - } - result = 0; - return false; - } - - public bool TryGetLong(out long result) - { - if (AvailableBytes >= 8) - { - result = GetLong(); - return true; - } - result = 0; - return false; - } - - public bool TryGetULong(out ulong result) - { - if (AvailableBytes >= 8) - { - result = GetULong(); - return true; - } - result = 0; - return false; - } - - public bool TryGetFloat(out float result) - { - if (AvailableBytes >= 4) - { - result = GetFloat(); - return true; - } - result = 0; - return false; - } - - public bool TryGetDouble(out double result) - { - if (AvailableBytes >= 8) - { - result = GetDouble(); - return true; - } - result = 0; - return false; - } - - public bool TryGetString(out string result) - { - if (AvailableBytes >= 2) - { - ushort strSize = PeekUShort(); - if (AvailableBytes >= strSize + 1) - { - result = GetString(); - return true; - } - } - result = null; - return false; - } - - public bool TryGetStringArray(out string[] result) - { - if (!TryGetUShort(out ushort strArrayLength)) { - result = null; - return false; - } - - result = new string[strArrayLength]; - for (int i = 0; i < strArrayLength; i++) - { - if (!TryGetString(out result[i])) - { - result = null; - return false; - } - } - - return true; - } - - public bool TryGetBytesWithLength(out byte[] result) - { - if (AvailableBytes >= 2) - { - ushort length = PeekUShort(); - if (length >= 0 && AvailableBytes >= 2 + length) - { - result = GetBytesWithLength(); - return true; - } - } - result = null; - return false; - } - #endregion - - public void Clear() - { - _position = 0; - _dataSize = 0; - _data = null; - } - } -} diff --git a/Plugins/LiteNetLib/Utils/NetDataReader.cs.meta b/Plugins/LiteNetLib/Utils/NetDataReader.cs.meta deleted file mode 100644 index 4d15cb8c..00000000 --- a/Plugins/LiteNetLib/Utils/NetDataReader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4f9b78b3d36571849914c107ac33938b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/NetDataWriter.cs b/Plugins/LiteNetLib/Utils/NetDataWriter.cs deleted file mode 100644 index baa8351a..00000000 --- a/Plugins/LiteNetLib/Utils/NetDataWriter.cs +++ /dev/null @@ -1,381 +0,0 @@ -using System; -using System.Net; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; - -namespace LiteNetLib.Utils -{ - public class NetDataWriter - { - protected byte[] _data; - protected int _position; - private const int InitialSize = 64; - private readonly bool _autoResize; - - public int Capacity - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _data.Length; - } - public byte[] Data - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _data; - } - public int Length - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _position; - } - - public static readonly ThreadLocal uTF8Encoding = new ThreadLocal(() => new UTF8Encoding(false, true)); - public const int StringBufferMaxLength = 65535; - private readonly byte[] _stringBuffer = new byte[StringBufferMaxLength]; - - public NetDataWriter() : this(true, InitialSize) - { - } - - public NetDataWriter(bool autoResize) : this(autoResize, InitialSize) - { - } - - public NetDataWriter(bool autoResize, int initialSize) - { - _data = new byte[initialSize]; - _autoResize = autoResize; - } - - /// - /// Creates NetDataWriter from existing ByteArray - /// - /// Source byte array - /// Copy array to new location or use existing - public static NetDataWriter FromBytes(byte[] bytes, bool copy) - { - if (copy) - { - var netDataWriter = new NetDataWriter(true, bytes.Length); - netDataWriter.Put(bytes); - return netDataWriter; - } - return new NetDataWriter(true, 0) {_data = bytes, _position = bytes.Length}; - } - - /// - /// Creates NetDataWriter from existing ByteArray (always copied data) - /// - /// Source byte array - /// Offset of array - /// Length of array - public static NetDataWriter FromBytes(byte[] bytes, int offset, int length) - { - var netDataWriter = new NetDataWriter(true, bytes.Length); - netDataWriter.Put(bytes, offset, length); - return netDataWriter; - } - - public static NetDataWriter FromString(string value) - { - var netDataWriter = new NetDataWriter(); - netDataWriter.Put(value); - return netDataWriter; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ResizeIfNeed(int newSize) - { - if (_data.Length < newSize) - { - Array.Resize(ref _data, Math.Max(newSize, _data.Length * 2)); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void EnsureFit(int additionalSize) - { - if (_data.Length < _position + additionalSize) - { - Array.Resize(ref _data, Math.Max(_position + additionalSize, _data.Length * 2)); - } - } - - public void Reset(int size) - { - ResizeIfNeed(size); - _position = 0; - } - - public void Reset() - { - _position = 0; - } - - public byte[] CopyData() - { - byte[] resultData = new byte[_position]; - Buffer.BlockCopy(_data, 0, resultData, 0, _position); - return resultData; - } - - /// - /// Sets position of NetDataWriter to rewrite previous values - /// - /// new byte position - /// previous position of data writer - public int SetPosition(int position) - { - int prevPosition = _position; - _position = position; - return prevPosition; - } - - public void Put(float value) - { - if (_autoResize) - ResizeIfNeed(_position + 4); - FastBitConverter.GetBytes(_data, _position, value); - _position += 4; - } - - public void Put(double value) - { - if (_autoResize) - ResizeIfNeed(_position + 8); - FastBitConverter.GetBytes(_data, _position, value); - _position += 8; - } - - public void Put(long value) - { - if (_autoResize) - ResizeIfNeed(_position + 8); - FastBitConverter.GetBytes(_data, _position, value); - _position += 8; - } - - public void Put(ulong value) - { - if (_autoResize) - ResizeIfNeed(_position + 8); - FastBitConverter.GetBytes(_data, _position, value); - _position += 8; - } - - public void Put(int value) - { - if (_autoResize) - ResizeIfNeed(_position + 4); - FastBitConverter.GetBytes(_data, _position, value); - _position += 4; - } - - public void Put(uint value) - { - if (_autoResize) - ResizeIfNeed(_position + 4); - FastBitConverter.GetBytes(_data, _position, value); - _position += 4; - } - - public void Put(char value) - { - Put((ushort)value); - } - - public void Put(ushort value) - { - if (_autoResize) - ResizeIfNeed(_position + 2); - FastBitConverter.GetBytes(_data, _position, value); - _position += 2; - } - - public void Put(short value) - { - if (_autoResize) - ResizeIfNeed(_position + 2); - FastBitConverter.GetBytes(_data, _position, value); - _position += 2; - } - - public void Put(sbyte value) - { - if (_autoResize) - ResizeIfNeed(_position + 1); - _data[_position] = (byte)value; - _position++; - } - - public void Put(byte value) - { - if (_autoResize) - ResizeIfNeed(_position + 1); - _data[_position] = value; - _position++; - } - - public void Put(byte[] data, int offset, int length) - { - if (_autoResize) - ResizeIfNeed(_position + length); - Buffer.BlockCopy(data, offset, _data, _position, length); - _position += length; - } - - public void Put(byte[] data) - { - if (_autoResize) - ResizeIfNeed(_position + data.Length); - Buffer.BlockCopy(data, 0, _data, _position, data.Length); - _position += data.Length; - } - - public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) - { - if (_autoResize) - ResizeIfNeed(_position + 2 + length); - FastBitConverter.GetBytes(_data, _position, length); - Buffer.BlockCopy(data, offset, _data, _position + 2, length); - _position += 2 + length; - } - - public void PutSBytesWithLength(sbyte[] data) - { - PutArray(data, 1); - } - - public void PutBytesWithLength(byte[] data, int offset, ushort length) - { - if (_autoResize) - ResizeIfNeed(_position + 2 + length); - FastBitConverter.GetBytes(_data, _position, length); - Buffer.BlockCopy(data, offset, _data, _position + 2, length); - _position += 2 + length; - } - - public void PutBytesWithLength(byte[] data) - { - PutArray(data, 1); - } - - public void Put(bool value) - { - Put((byte)(value ? 1 : 0)); - } - - public void PutArray(Array arr, int sz) - { - ushort length = arr == null ? (ushort) 0 : (ushort)arr.Length; - sz *= length; - if (_autoResize) - ResizeIfNeed(_position + sz + 2); - FastBitConverter.GetBytes(_data, _position, length); - if (arr != null) - Buffer.BlockCopy(arr, 0, _data, _position + 2, sz); - _position += sz + 2; - } - - public void PutArray(float[] value) - { - PutArray(value, 4); - } - - public void PutArray(double[] value) - { - PutArray(value, 8); - } - - public void PutArray(long[] value) - { - PutArray(value, 8); - } - - public void PutArray(ulong[] value) - { - PutArray(value, 8); - } - - public void PutArray(int[] value) - { - PutArray(value, 4); - } - - public void PutArray(uint[] value) - { - PutArray(value, 4); - } - - public void PutArray(ushort[] value) - { - PutArray(value, 2); - } - - public void PutArray(short[] value) - { - PutArray(value, 2); - } - - public void PutArray(bool[] value) - { - PutArray(value, 1); - } - - public void PutArray(string[] value) - { - ushort strArrayLength = value == null ? (ushort)0 : (ushort)value.Length; - Put(strArrayLength); - for (int i = 0; i < strArrayLength; i++) - Put(value[i]); - } - - public void PutArray(string[] value, int strMaxLength) - { - ushort strArrayLength = value == null ? (ushort)0 : (ushort)value.Length; - Put(strArrayLength); - for (int i = 0; i < strArrayLength; i++) - Put(value[i], strMaxLength); - } - - public void Put(IPEndPoint endPoint) - { - Put(endPoint.Address.ToString()); - Put(endPoint.Port); - } - - public void Put(string value) - { - Put(value, 0); - } - - /// - /// Note that "maxLength" only limits the number of characters in a string, not its size in bytes. - /// - public void Put(string value, int maxLength) - { - if (string.IsNullOrEmpty(value)) - { - Put((ushort)0); - return; - } - - int length = maxLength > 0 && value.Length > maxLength ? maxLength : value.Length; - int size = uTF8Encoding.Value.GetBytes(value, 0, length, _stringBuffer, 0); - - if (size == 0 || size >= StringBufferMaxLength) - { - Put((ushort)0); - return; - } - - Put(checked((ushort)(size + 1))); - Put(_stringBuffer, 0, size); - } - - public void Put(T obj) where T : INetSerializable - { - obj.Serialize(this); - } - } -} diff --git a/Plugins/LiteNetLib/Utils/NetDataWriter.cs.meta b/Plugins/LiteNetLib/Utils/NetDataWriter.cs.meta deleted file mode 100644 index 74282a88..00000000 --- a/Plugins/LiteNetLib/Utils/NetDataWriter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a36e850e0d8b7804587ec8541a608d66 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/NetPacketProcessor.cs b/Plugins/LiteNetLib/Utils/NetPacketProcessor.cs deleted file mode 100644 index f3d1493e..00000000 --- a/Plugins/LiteNetLib/Utils/NetPacketProcessor.cs +++ /dev/null @@ -1,267 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace LiteNetLib.Utils -{ - public class NetPacketProcessor - { - private static class HashCache - { - public static readonly ulong Id; - - //FNV-1 64 bit hash - static HashCache() - { - ulong hash = 14695981039346656037UL; //offset - string typeName = typeof(T).ToString(); - for (var i = 0; i < typeName.Length; i++) - { - hash ^= typeName[i]; - hash *= 1099511628211UL; //prime - } - Id = hash; - } - } - - protected delegate void SubscribeDelegate(NetDataReader reader, object userData); - private readonly NetSerializer _netSerializer; - private readonly Dictionary _callbacks = new Dictionary(); - - public NetPacketProcessor() - { - _netSerializer = new NetSerializer(); - } - - public NetPacketProcessor(int maxStringLength) - { - _netSerializer = new NetSerializer(maxStringLength); - } - - protected virtual ulong GetHash() - { - return HashCache.Id; - } - - protected virtual SubscribeDelegate GetCallbackFromData(NetDataReader reader) - { - ulong hash = reader.GetULong(); - if (!_callbacks.TryGetValue(hash, out var action)) - { - throw new ParseException("Undefined packet in NetDataReader"); - } - return action; - } - - protected virtual void WriteHash(NetDataWriter writer) - { - writer.Put(GetHash()); - } - - /// - /// Register nested property type - /// - /// INetSerializable structure - public void RegisterNestedType() where T : struct, INetSerializable - { - _netSerializer.RegisterNestedType(); - } - - /// - /// Register nested property type - /// - /// - /// - public void RegisterNestedType(Action writeDelegate, Func readDelegate) - { - _netSerializer.RegisterNestedType(writeDelegate, readDelegate); - } - - /// - /// Register nested property type - /// - /// INetSerializable class - public void RegisterNestedType(Func constructor) where T : class, INetSerializable - { - _netSerializer.RegisterNestedType(constructor); - } - - /// - /// Reads all available data from NetDataReader and calls OnReceive delegates - /// - /// NetDataReader with packets data - public void ReadAllPackets(NetDataReader reader) - { - while (reader.AvailableBytes > 0) - ReadPacket(reader); - } - - /// - /// Reads all available data from NetDataReader and calls OnReceive delegates - /// - /// NetDataReader with packets data - /// Argument that passed to OnReceivedEvent - /// Malformed packet - public void ReadAllPackets(NetDataReader reader, object userData) - { - while (reader.AvailableBytes > 0) - ReadPacket(reader, userData); - } - - /// - /// Reads one packet from NetDataReader and calls OnReceive delegate - /// - /// NetDataReader with packet - /// Malformed packet - public void ReadPacket(NetDataReader reader) - { - ReadPacket(reader, null); - } - - public void Write(NetDataWriter writer, T packet) where T : class, new() - { - WriteHash(writer); - _netSerializer.Serialize(writer, packet); - } - - public void WriteNetSerializable(NetDataWriter writer, ref T packet) where T : INetSerializable - { - WriteHash(writer); - packet.Serialize(writer); - } - - /// - /// Reads one packet from NetDataReader and calls OnReceive delegate - /// - /// NetDataReader with packet - /// Argument that passed to OnReceivedEvent - /// Malformed packet - public void ReadPacket(NetDataReader reader, object userData) - { - GetCallbackFromData(reader)(reader, userData); - } - - /// - /// Register and subscribe to packet receive event - /// - /// event that will be called when packet deserialized with ReadPacket method - /// Method that constructs packet instead of slow Activator.CreateInstance - /// 's fields are not supported, or it has no fields - public void Subscribe(Action onReceive, Func packetConstructor) where T : class, new() - { - _netSerializer.Register(); - _callbacks[GetHash()] = (reader, userData) => - { - var reference = packetConstructor(); - _netSerializer.Deserialize(reader, reference); - onReceive(reference); - }; - } - - /// - /// Register and subscribe to packet receive event (with userData) - /// - /// event that will be called when packet deserialized with ReadPacket method - /// Method that constructs packet instead of slow Activator.CreateInstance - /// 's fields are not supported, or it has no fields - public void Subscribe(Action onReceive, Func packetConstructor) where T : class, new() - { - _netSerializer.Register(); - _callbacks[GetHash()] = (reader, userData) => - { - var reference = packetConstructor(); - _netSerializer.Deserialize(reader, reference); - onReceive(reference, (TUserData)userData); - }; - } - - /// - /// Register and subscribe to packet receive event - /// This method will overwrite last received packet class on receive (less garbage) - /// - /// event that will be called when packet deserialized with ReadPacket method - /// 's fields are not supported, or it has no fields - public void SubscribeReusable(Action onReceive) where T : class, new() - { - _netSerializer.Register(); - var reference = new T(); - _callbacks[GetHash()] = (reader, userData) => - { - _netSerializer.Deserialize(reader, reference); - onReceive(reference); - }; - } - - /// - /// Register and subscribe to packet receive event - /// This method will overwrite last received packet class on receive (less garbage) - /// - /// event that will be called when packet deserialized with ReadPacket method - /// 's fields are not supported, or it has no fields - public void SubscribeReusable(Action onReceive) where T : class, new() - { - _netSerializer.Register(); - var reference = new T(); - _callbacks[GetHash()] = (reader, userData) => - { - _netSerializer.Deserialize(reader, reference); - onReceive(reference, (TUserData)userData); - }; - } - - public void SubscribeNetSerializable( - Action onReceive, - Func packetConstructor) where T : INetSerializable - { - _callbacks[GetHash()] = (reader, userData) => - { - var pkt = packetConstructor(); - pkt.Deserialize(reader); - onReceive(pkt, (TUserData)userData); - }; - } - - public void SubscribeNetSerializable( - Action onReceive, - Func packetConstructor) where T : INetSerializable - { - _callbacks[GetHash()] = (reader, userData) => - { - var pkt = packetConstructor(); - pkt.Deserialize(reader); - onReceive(pkt); - }; - } - - public void SubscribeNetSerializable( - Action onReceive) where T : INetSerializable, new() - { - var reference = new T(); - _callbacks[GetHash()] = (reader, userData) => - { - reference.Deserialize(reader); - onReceive(reference, (TUserData)userData); - }; - } - - public void SubscribeNetSerializable( - Action onReceive) where T : INetSerializable, new() - { - var reference = new T(); - _callbacks[GetHash()] = (reader, userData) => - { - reference.Deserialize(reader); - onReceive(reference); - }; - } - - /// - /// Remove any subscriptions by type - /// - /// Packet type - /// true if remove is success - public bool RemoveSubscription() - { - return _callbacks.Remove(GetHash()); - } - } -} diff --git a/Plugins/LiteNetLib/Utils/NetPacketProcessor.cs.meta b/Plugins/LiteNetLib/Utils/NetPacketProcessor.cs.meta deleted file mode 100644 index 0412f276..00000000 --- a/Plugins/LiteNetLib/Utils/NetPacketProcessor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0f768ca4116d8f04bb3e156ec6552355 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/NetSerializer.cs b/Plugins/LiteNetLib/Utils/NetSerializer.cs deleted file mode 100644 index 63f6cd67..00000000 --- a/Plugins/LiteNetLib/Utils/NetSerializer.cs +++ /dev/null @@ -1,738 +0,0 @@ -using System; -using System.Reflection; -using System.Collections.Generic; -using System.Net; -using System.Runtime.Serialization; - -namespace LiteNetLib.Utils -{ - public class InvalidTypeException : ArgumentException - { - public InvalidTypeException(string message) : base(message) { } - } - - public class ParseException : Exception - { - public ParseException(string message) : base(message) { } - } - - public class NetSerializer - { - private enum CallType - { - Basic, - Array, - List - } - - private abstract class FastCall - { - public CallType Type; - public virtual void Init(MethodInfo getMethod, MethodInfo setMethod, CallType type) { Type = type; } - public abstract void Read(T inf, NetDataReader r); - public abstract void Write(T inf, NetDataWriter w); - public abstract void ReadArray(T inf, NetDataReader r); - public abstract void WriteArray(T inf, NetDataWriter w); - public abstract void ReadList(T inf, NetDataReader r); - public abstract void WriteList(T inf, NetDataWriter w); - } - - private abstract class FastCallSpecific : FastCall - { - protected Func Getter; - protected Action Setter; - protected Func GetterArr; - protected Action SetterArr; - protected Func> GetterList; - protected Action> SetterList; - - public override void ReadArray(TClass inf, NetDataReader r) { throw new InvalidTypeException("Unsupported type: " + typeof(TProperty) + "[]"); } - public override void WriteArray(TClass inf, NetDataWriter w) { throw new InvalidTypeException("Unsupported type: " + typeof(TProperty) + "[]"); } - public override void ReadList(TClass inf, NetDataReader r) { throw new InvalidTypeException("Unsupported type: List<" + typeof(TProperty) + ">"); } - public override void WriteList(TClass inf, NetDataWriter w) { throw new InvalidTypeException("Unsupported type: List<" + typeof(TProperty) + ">"); } - - protected TProperty[] ReadArrayHelper(TClass inf, NetDataReader r) - { - ushort count = r.GetUShort(); - var arr = GetterArr(inf); - arr = arr == null || arr.Length != count ? new TProperty[count] : arr; - SetterArr(inf, arr); - return arr; - } - - protected TProperty[] WriteArrayHelper(TClass inf, NetDataWriter w) - { - var arr = GetterArr(inf); - w.Put((ushort)arr.Length); - return arr; - } - - protected List ReadListHelper(TClass inf, NetDataReader r, out int len) - { - len = r.GetUShort(); - var list = GetterList(inf); - if (list == null) - { - list = new List(len); - SetterList(inf, list); - } - return list; - } - - protected List WriteListHelper(TClass inf, NetDataWriter w, out int len) - { - var list = GetterList(inf); - if (list == null) - { - len = 0; - w.Put(0); - return null; - } - len = list.Count; - w.Put((ushort)len); - return list; - } - - public override void Init(MethodInfo getMethod, MethodInfo setMethod, CallType type) - { - base.Init(getMethod, setMethod, type); - switch (type) - { - case CallType.Array: - GetterArr = (Func)Delegate.CreateDelegate(typeof(Func), getMethod); - SetterArr = (Action)Delegate.CreateDelegate(typeof(Action), setMethod); - break; - case CallType.List: - GetterList = (Func>)Delegate.CreateDelegate(typeof(Func>), getMethod); - SetterList = (Action>)Delegate.CreateDelegate(typeof(Action>), setMethod); - break; - default: - Getter = (Func)Delegate.CreateDelegate(typeof(Func), getMethod); - Setter = (Action)Delegate.CreateDelegate(typeof(Action), setMethod); - break; - } - } - } - - private abstract class FastCallSpecificAuto : FastCallSpecific - { - protected abstract void ElementRead(NetDataReader r, out TProperty prop); - protected abstract void ElementWrite(NetDataWriter w, ref TProperty prop); - - public override void Read(TClass inf, NetDataReader r) - { - ElementRead(r, out var elem); - Setter(inf, elem); - } - - public override void Write(TClass inf, NetDataWriter w) - { - var elem = Getter(inf); - ElementWrite(w, ref elem); - } - - public override void ReadArray(TClass inf, NetDataReader r) - { - var arr = ReadArrayHelper(inf, r); - for (int i = 0; i < arr.Length; i++) - ElementRead(r, out arr[i]); - } - - public override void WriteArray(TClass inf, NetDataWriter w) - { - var arr = WriteArrayHelper(inf, w); - for (int i = 0; i < arr.Length; i++) - ElementWrite(w, ref arr[i]); - } - } - - private sealed class FastCallStatic : FastCallSpecific - { - private readonly Action _writer; - private readonly Func _reader; - - public FastCallStatic(Action write, Func read) - { - _writer = write; - _reader = read; - } - - public override void Read(TClass inf, NetDataReader r) { Setter(inf, _reader(r)); } - public override void Write(TClass inf, NetDataWriter w) { _writer(w, Getter(inf)); } - - public override void ReadList(TClass inf, NetDataReader r) - { - var list = ReadListHelper(inf, r, out int len); - int listCount = list.Count; - for (int i = 0; i < len; i++) - { - if (i < listCount) - list[i] = _reader(r); - else - list.Add(_reader(r)); - } - if (len < listCount) - list.RemoveRange(len, listCount - len); - } - - public override void WriteList(TClass inf, NetDataWriter w) - { - var list = WriteListHelper(inf, w, out int len); - for (int i = 0; i < len; i++) - _writer(w, list[i]); - } - - public override void ReadArray(TClass inf, NetDataReader r) - { - var arr = ReadArrayHelper(inf, r); - int len = arr.Length; - for (int i = 0; i < len; i++) - arr[i] = _reader(r); - } - - public override void WriteArray(TClass inf, NetDataWriter w) - { - var arr = WriteArrayHelper(inf, w); - int len = arr.Length; - for (int i = 0; i < len; i++) - _writer(w, arr[i]); - } - } - - private sealed class FastCallStruct : FastCallSpecific where TProperty : struct, INetSerializable - { - private TProperty _p; - - public override void Read(TClass inf, NetDataReader r) - { - _p.Deserialize(r); - Setter(inf, _p); - } - - public override void Write(TClass inf, NetDataWriter w) - { - _p = Getter(inf); - _p.Serialize(w); - } - - public override void ReadList(TClass inf, NetDataReader r) - { - var list = ReadListHelper(inf, r, out int len); - int listCount = list.Count; - for (int i = 0; i < len; i++) - { - var itm = default(TProperty); - itm.Deserialize(r); - if(i < listCount) - list[i] = itm; - else - list.Add(itm); - } - if (len < listCount) - list.RemoveRange(len, listCount - len); - } - - public override void WriteList(TClass inf, NetDataWriter w) - { - var list = WriteListHelper(inf, w, out int len); - for (int i = 0; i < len; i++) - list[i].Serialize(w); - } - - public override void ReadArray(TClass inf, NetDataReader r) - { - var arr = ReadArrayHelper(inf, r); - int len = arr.Length; - for (int i = 0; i < len; i++) - arr[i].Deserialize(r); - } - - public override void WriteArray(TClass inf, NetDataWriter w) - { - var arr = WriteArrayHelper(inf, w); - int len = arr.Length; - for (int i = 0; i < len; i++) - arr[i].Serialize(w); - } - } - - private sealed class FastCallClass : FastCallSpecific where TProperty : class, INetSerializable - { - private readonly Func _constructor; - public FastCallClass(Func constructor) { _constructor = constructor; } - - public override void Read(TClass inf, NetDataReader r) - { - var p = _constructor(); - p.Deserialize(r); - Setter(inf, p); - } - - public override void Write(TClass inf, NetDataWriter w) - { - var p = Getter(inf); - p?.Serialize(w); - } - - public override void ReadList(TClass inf, NetDataReader r) - { - var list = ReadListHelper(inf, r, out int len); - int listCount = list.Count; - for (int i = 0; i < len; i++) - { - if (i < listCount) - { - list[i].Deserialize(r); - } - else - { - var itm = _constructor(); - itm.Deserialize(r); - list.Add(itm); - } - } - if (len < listCount) - list.RemoveRange(len, listCount - len); - } - - public override void WriteList(TClass inf, NetDataWriter w) - { - var list = WriteListHelper(inf, w, out int len); - for (int i = 0; i < len; i++) - list[i].Serialize(w); - } - - public override void ReadArray(TClass inf, NetDataReader r) - { - var arr = ReadArrayHelper(inf, r); - int len = arr.Length; - for (int i = 0; i < len; i++) - { - arr[i] = _constructor(); - arr[i].Deserialize(r); - } - } - - public override void WriteArray(TClass inf, NetDataWriter w) - { - var arr = WriteArrayHelper(inf, w); - int len = arr.Length; - for (int i = 0; i < len; i++) - arr[i].Serialize(w); - } - } - - private class IntSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetInt()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetIntArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class UIntSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetUInt()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetUIntArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class ShortSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetShort()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetShortArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class UShortSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetUShort()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetUShortArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class LongSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetLong()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetLongArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class ULongSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetULong()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetULongArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class ByteSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetByte()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetBytesWithLength()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutBytesWithLength(GetterArr(inf)); } - } - - private class SByteSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetSByte()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetSBytesWithLength()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutSBytesWithLength(GetterArr(inf)); } - } - - private class FloatSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetFloat()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetFloatArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class DoubleSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetDouble()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetDoubleArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class BoolSerializer : FastCallSpecific - { - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetBool()); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf)); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetBoolArray()); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf)); } - } - - private class CharSerializer : FastCallSpecificAuto - { - protected override void ElementWrite(NetDataWriter w, ref char prop) { w.Put(prop); } - protected override void ElementRead(NetDataReader r, out char prop) { prop = r.GetChar(); } - } - - private class IPEndPointSerializer : FastCallSpecificAuto - { - protected override void ElementWrite(NetDataWriter w, ref IPEndPoint prop) { w.Put(prop); } - protected override void ElementRead(NetDataReader r, out IPEndPoint prop) { prop = r.GetNetEndPoint(); } - } - - private class StringSerializer : FastCallSpecific - { - private readonly int _maxLength; - public StringSerializer(int maxLength) { _maxLength = maxLength > 0 ? maxLength : short.MaxValue; } - public override void Read(T inf, NetDataReader r) { Setter(inf, r.GetString(_maxLength)); } - public override void Write(T inf, NetDataWriter w) { w.Put(Getter(inf), _maxLength); } - public override void ReadArray(T inf, NetDataReader r) { SetterArr(inf, r.GetStringArray(_maxLength)); } - public override void WriteArray(T inf, NetDataWriter w) { w.PutArray(GetterArr(inf), _maxLength); } - } - - private class EnumByteSerializer : FastCall - { - protected readonly PropertyInfo Property; - protected readonly Type PropertyType; - public EnumByteSerializer(PropertyInfo property, Type propertyType) - { - Property = property; - PropertyType = propertyType; - } - public override void Read(T inf, NetDataReader r) { Property.SetValue(inf, Enum.ToObject(PropertyType, r.GetByte()), null); } - public override void Write(T inf, NetDataWriter w) { w.Put((byte)Property.GetValue(inf, null)); } - public override void ReadArray(T inf, NetDataReader r) { throw new InvalidTypeException("Unsupported type: Enum[]"); } - public override void WriteArray(T inf, NetDataWriter w) { throw new InvalidTypeException("Unsupported type: Enum[]"); } - public override void ReadList(T inf, NetDataReader r) { throw new InvalidTypeException("Unsupported type: List"); } - public override void WriteList(T inf, NetDataWriter w) { throw new InvalidTypeException("Unsupported type: List"); } - } - - private class EnumIntSerializer : EnumByteSerializer - { - public EnumIntSerializer(PropertyInfo property, Type propertyType) : base(property, propertyType) { } - public override void Read(T inf, NetDataReader r) { Property.SetValue(inf, Enum.ToObject(PropertyType, r.GetInt()), null); } - public override void Write(T inf, NetDataWriter w) { w.Put((int)Property.GetValue(inf, null)); } - } - - private sealed class ClassInfo - { - public static ClassInfo Instance; - private readonly FastCall[] _serializers; - private readonly int _membersCount; - - public ClassInfo(List> serializers) - { - _membersCount = serializers.Count; - _serializers = serializers.ToArray(); - } - - public void Write(T obj, NetDataWriter writer) - { - for (int i = 0; i < _membersCount; i++) - { - var s = _serializers[i]; - if (s.Type == CallType.Basic) - s.Write(obj, writer); - else if (s.Type == CallType.Array) - s.WriteArray(obj, writer); - else - s.WriteList(obj, writer); - } - } - - public void Read(T obj, NetDataReader reader) - { - for (int i = 0; i < _membersCount; i++) - { - var s = _serializers[i]; - if (s.Type == CallType.Basic) - s.Read(obj, reader); - else if(s.Type == CallType.Array) - s.ReadArray(obj, reader); - else - s.ReadList(obj, reader); - } - } - } - - private abstract class CustomType - { - public abstract FastCall Get(); - } - - private sealed class CustomTypeStruct : CustomType where TProperty : struct, INetSerializable - { - public override FastCall Get() { return new FastCallStruct(); } - } - - private sealed class CustomTypeClass : CustomType where TProperty : class, INetSerializable - { - private readonly Func _constructor; - public CustomTypeClass(Func constructor) { _constructor = constructor; } - public override FastCall Get() { return new FastCallClass(_constructor); } - } - - private sealed class CustomTypeStatic : CustomType - { - private readonly Action _writer; - private readonly Func _reader; - public CustomTypeStatic(Action writer, Func reader) - { - _writer = writer; - _reader = reader; - } - public override FastCall Get() { return new FastCallStatic(_writer, _reader); } - } - - /// - /// Register custom property type - /// - /// INetSerializable structure - public void RegisterNestedType() where T : struct, INetSerializable - { - _registeredTypes.Add(typeof(T), new CustomTypeStruct()); - } - - /// - /// Register custom property type - /// - /// INetSerializable class - public void RegisterNestedType(Func constructor) where T : class, INetSerializable - { - _registeredTypes.Add(typeof(T), new CustomTypeClass(constructor)); - } - - /// - /// Register custom property type - /// - /// Any packet - /// custom type writer - /// custom type reader - public void RegisterNestedType(Action writer, Func reader) - { - _registeredTypes.Add(typeof(T), new CustomTypeStatic(writer, reader)); - } - - private NetDataWriter _writer; - private readonly int _maxStringLength; - private readonly Dictionary _registeredTypes = new Dictionary(); - - public NetSerializer() : this(0) - { - } - - public NetSerializer(int maxStringLength) - { - _maxStringLength = maxStringLength; - } - - private ClassInfo RegisterInternal() - { - if (ClassInfo.Instance != null) - return ClassInfo.Instance; - - Type t = typeof(T); - var props = t.GetProperties( - BindingFlags.Instance | - BindingFlags.Public | - BindingFlags.GetProperty | - BindingFlags.SetProperty); - var serializers = new List>(); - for (int i = 0; i < props.Length; i++) - { - var property = props[i]; - var propertyType = property.PropertyType; - - var elementType = propertyType.IsArray ? propertyType.GetElementType() : propertyType; - var callType = propertyType.IsArray ? CallType.Array : CallType.Basic; - - if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>)) - { - elementType = propertyType.GetGenericArguments()[0]; - callType = CallType.List; - } - - if (Attribute.IsDefined(property, typeof(IgnoreDataMemberAttribute))) - continue; - - var getMethod = property.GetGetMethod(); - var setMethod = property.GetSetMethod(); - if (getMethod == null || setMethod == null) - continue; - - FastCall serialzer = null; - if (propertyType.IsEnum) - { - var underlyingType = Enum.GetUnderlyingType(propertyType); - if (underlyingType == typeof(byte)) - serialzer = new EnumByteSerializer(property, propertyType); - else if (underlyingType == typeof(int)) - serialzer = new EnumIntSerializer(property, propertyType); - else - throw new InvalidTypeException("Not supported enum underlying type: " + underlyingType.Name); - } - else if (elementType == typeof(string)) - serialzer = new StringSerializer(_maxStringLength); - else if (elementType == typeof(bool)) - serialzer = new BoolSerializer(); - else if (elementType == typeof(byte)) - serialzer = new ByteSerializer(); - else if (elementType == typeof(sbyte)) - serialzer = new SByteSerializer(); - else if (elementType == typeof(short)) - serialzer = new ShortSerializer(); - else if (elementType == typeof(ushort)) - serialzer = new UShortSerializer(); - else if (elementType == typeof(int)) - serialzer = new IntSerializer(); - else if (elementType == typeof(uint)) - serialzer = new UIntSerializer(); - else if (elementType == typeof(long)) - serialzer = new LongSerializer(); - else if (elementType == typeof(ulong)) - serialzer = new ULongSerializer(); - else if (elementType == typeof(float)) - serialzer = new FloatSerializer(); - else if (elementType == typeof(double)) - serialzer = new DoubleSerializer(); - else if (elementType == typeof(char)) - serialzer = new CharSerializer(); - else if (elementType == typeof(IPEndPoint)) - serialzer = new IPEndPointSerializer(); - else - { - _registeredTypes.TryGetValue(elementType, out var customType); - if (customType != null) - serialzer = customType.Get(); - } - - if (serialzer != null) - { - serialzer.Init(getMethod, setMethod, callType); - serializers.Add(serialzer); - } - else - { - throw new InvalidTypeException("Unknown property type: " + propertyType.FullName); - } - } - ClassInfo.Instance = new ClassInfo(serializers); - return ClassInfo.Instance; - } - - /// 's fields are not supported, or it has no fields - public void Register() - { - RegisterInternal(); - } - - /// - /// Reads packet with known type - /// - /// NetDataReader with packet - /// Returns packet if packet in reader is matched type - /// 's fields are not supported, or it has no fields - public T Deserialize(NetDataReader reader) where T : class, new() - { - var info = RegisterInternal(); - var result = new T(); - try - { - info.Read(result, reader); - } - catch - { - return null; - } - return result; - } - - /// - /// Reads packet with known type (non alloc variant) - /// - /// NetDataReader with packet - /// Deserialization target - /// Returns true if packet in reader is matched type - /// 's fields are not supported, or it has no fields - public bool Deserialize(NetDataReader reader, T target) where T : class, new() - { - var info = RegisterInternal(); - try - { - info.Read(target, reader); - } - catch - { - return false; - } - return true; - } - - /// - /// Serialize object to NetDataWriter (fast) - /// - /// Serialization target NetDataWriter - /// Object to serialize - /// 's fields are not supported, or it has no fields - public void Serialize(NetDataWriter writer, T obj) where T : class, new() - { - RegisterInternal().Write(obj, writer); - } - - /// - /// Serialize object to byte array - /// - /// Object to serialize - /// byte array with serialized data - public byte[] Serialize(T obj) where T : class, new() - { - if (_writer == null) - _writer = new NetDataWriter(); - _writer.Reset(); - Serialize(_writer, obj); - return _writer.CopyData(); - } - } -} diff --git a/Plugins/LiteNetLib/Utils/NetSerializer.cs.meta b/Plugins/LiteNetLib/Utils/NetSerializer.cs.meta deleted file mode 100644 index e48ae5f0..00000000 --- a/Plugins/LiteNetLib/Utils/NetSerializer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7e1ebe631dc04e94885c546f0ce411a6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/NtpPacket.cs b/Plugins/LiteNetLib/Utils/NtpPacket.cs deleted file mode 100644 index 1ba52107..00000000 --- a/Plugins/LiteNetLib/Utils/NtpPacket.cs +++ /dev/null @@ -1,423 +0,0 @@ -using System; - -namespace LiteNetLib.Utils -{ - /// - /// Represents RFC4330 SNTP packet used for communication to and from a network time server. - /// - /// - /// - /// Most applications should just use the property. - /// - /// - /// The same data structure represents both request and reply packets. - /// Request and reply differ in which properties are set and to what values. - /// - /// - /// The only real property is . - /// All other properties read from and write to the underlying byte array - /// with the exception of , - /// which is not part of the packet on network and it is instead set locally after receiving the packet. - /// - /// - /// Copied from GuerrillaNtp project - /// with permission from Robert Vazan (@robertvazan) under MIT license, see https://github.com/RevenantX/LiteNetLib/pull/236 - /// - /// - public class NtpPacket - { - private static readonly DateTime Epoch = new DateTime(1900, 1, 1); - - /// - /// Gets RFC4330-encoded SNTP packet. - /// - /// - /// Byte array containing RFC4330-encoded SNTP packet. It is at least 48 bytes long. - /// - /// - /// This is the only real property. All other properties except - /// read from or write to this byte array. - /// - public byte[] Bytes { get; } - - /// - /// Gets the leap second indicator. - /// - /// - /// Leap second warning, if any. Special value - /// indicates unsynchronized server clock. - /// Default is . - /// - /// - /// Only servers fill in this property. Clients can consult this property for possible leap second warning. - /// - public NtpLeapIndicator LeapIndicator => (NtpLeapIndicator)((Bytes[0] & 0xC0) >> 6); - - /// - /// Gets or sets protocol version number. - /// - /// - /// SNTP protocol version. Default is 4, which is the latest version at the time of this writing. - /// - /// - /// In request packets, clients should leave this property at default value 4. - /// Servers usually reply with the same protocol version. - /// - public int VersionNumber - { - get => (Bytes[0] & 0x38) >> 3; - private set => Bytes[0] = (byte)((Bytes[0] & ~0x38) | value << 3); - } - - /// - /// Gets or sets SNTP packet mode, i.e. whether this is client or server packet. - /// - /// - /// SNTP packet mode. Default is in newly created packets. - /// Server reply should have this property set to . - /// - public NtpMode Mode - { - get => (NtpMode)(Bytes[0] & 0x07); - private set => Bytes[0] = (byte)((Bytes[0] & ~0x07) | (int)value); - } - - /// - /// Gets server's distance from the reference clock. - /// - /// - /// - /// Distance from the reference clock. This property is set only in server reply packets. - /// Servers connected directly to reference clock hardware set this property to 1. - /// Statum number is incremented by 1 on every hop down the NTP server hierarchy. - /// - /// - /// Special value 0 indicates that this packet is a Kiss-o'-Death message - /// with kiss code stored in . - /// - /// - public int Stratum => Bytes[1]; - - /// - /// Gets server's preferred polling interval. - /// - /// - /// Polling interval in log2 seconds, e.g. 4 stands for 16s and 17 means 131,072s. - /// - public int Poll => Bytes[2]; - - /// - /// Gets the precision of server clock. - /// - /// - /// Clock precision in log2 seconds, e.g. -20 for microsecond precision. - /// - public int Precision => (sbyte)Bytes[3]; - - /// - /// Gets the total round-trip delay from the server to the reference clock. - /// - /// - /// Round-trip delay to the reference clock. Normally a positive value smaller than one second. - /// - public TimeSpan RootDelay => GetTimeSpan32(4); - - /// - /// Gets the estimated error in time reported by the server. - /// - /// - /// Estimated error in time reported by the server. Normally a positive value smaller than one second. - /// - public TimeSpan RootDispersion => GetTimeSpan32(8); - - /// - /// Gets the ID of the time source used by the server or Kiss-o'-Death code sent by the server. - /// - /// - /// - /// ID of server's time source or Kiss-o'-Death code. - /// Purpose of this property depends on value of property. - /// - /// - /// Stratum 1 servers write here one of several special values that describe the kind of hardware clock they use. - /// - /// - /// Stratum 2 and lower servers set this property to IPv4 address of their upstream server. - /// If upstream server has IPv6 address, the address is hashed, because it doesn't fit in this property. - /// - /// - /// When server sets to special value 0, - /// this property contains so called kiss code that instructs the client to stop querying the server. - /// - /// - public uint ReferenceId => GetUInt32BE(12); - - /// - /// Gets or sets the time when the server clock was last set or corrected. - /// - /// - /// Time when the server clock was last set or corrected or null when not specified. - /// - /// - /// This Property is usually set only by servers. It usually lags server's current time by several minutes, - /// so don't use this property for time synchronization. - /// - public DateTime? ReferenceTimestamp => GetDateTime64(16); - - /// - /// Gets or sets the time when the client sent its request. - /// - /// - /// This property is null in request packets. - /// In reply packets, it is the time when the client sent its request. - /// Servers copy this value from - /// that they find in received request packet. - /// - /// - /// - public DateTime? OriginTimestamp => GetDateTime64(24); - - /// - /// Gets or sets the time when the request was received by the server. - /// - /// - /// This property is null in request packets. - /// In reply packets, it is the time when the server received client request. - /// - /// - /// - public DateTime? ReceiveTimestamp => GetDateTime64(32); - - /// - /// Gets or sets the time when the packet was sent. - /// - /// - /// Time when the packet was sent. It should never be null. - /// Default value is . - /// - /// - /// This property must be set by both clients and servers. - /// - /// - /// - public DateTime? TransmitTimestamp { get { return GetDateTime64(40); } private set { SetDateTime64(40, value); } } - - /// - /// Gets or sets the time of reception of response SNTP packet on the client. - /// - /// - /// Time of reception of response SNTP packet on the client. It is null in request packets. - /// - /// - /// This property is not part of the protocol and has to be set when reply packet is received. - /// - /// - /// - public DateTime? DestinationTimestamp { get; private set; } - - /// - /// Gets the round-trip time to the server. - /// - /// - /// Time the request spent traveling to the server plus the time the reply spent traveling back. - /// This is calculated from timestamps in the packet as (t1 - t0) + (t3 - t2) - /// where t0 is , - /// t1 is , - /// t2 is , - /// and t3 is . - /// This property throws an exception in request packets. - /// - public TimeSpan RoundTripTime - { - get - { - CheckTimestamps(); - return (ReceiveTimestamp.Value - OriginTimestamp.Value) + (DestinationTimestamp.Value - TransmitTimestamp.Value); - } - } - - /// - /// Gets the offset that should be added to local time to synchronize it with server time. - /// - /// - /// Time difference between server and client. It should be added to local time to get server time. - /// It is calculated from timestamps in the packet as 0.5 * ((t1 - t0) - (t3 - t2)) - /// where t0 is , - /// t1 is , - /// t2 is , - /// and t3 is . - /// This property throws an exception in request packets. - /// - public TimeSpan CorrectionOffset - { - get - { - CheckTimestamps(); - return TimeSpan.FromTicks(((ReceiveTimestamp.Value - OriginTimestamp.Value) - (DestinationTimestamp.Value - TransmitTimestamp.Value)).Ticks / 2); - } - } - - /// - /// Initializes default request packet. - /// - /// - /// Properties and - /// are set appropriately for request packet. Property - /// is set to . - /// - public NtpPacket() : this(new byte[48]) - { - Mode = NtpMode.Client; - VersionNumber = 4; - TransmitTimestamp = DateTime.UtcNow; - } - - /// - /// Initializes packet from received data. - /// - internal NtpPacket(byte[] bytes) - { - if (bytes.Length < 48) - throw new ArgumentException("SNTP reply packet must be at least 48 bytes long.", "bytes"); - Bytes = bytes; - } - - /// - /// Initializes packet from data received from a server. - /// - /// Data received from the server. - /// Utc time of reception of response SNTP packet on the client. - /// - public static NtpPacket FromServerResponse(byte[] bytes, DateTime destinationTimestamp) - { - return new NtpPacket(bytes) { DestinationTimestamp = destinationTimestamp }; - } - - internal void ValidateRequest() - { - if (Mode != NtpMode.Client) - throw new InvalidOperationException("This is not a request SNTP packet."); - if (VersionNumber == 0) - throw new InvalidOperationException("Protocol version of the request is not specified."); - if (TransmitTimestamp == null) - throw new InvalidOperationException("TransmitTimestamp must be set in request packet."); - } - - internal void ValidateReply() - { - if (Mode != NtpMode.Server) - throw new InvalidOperationException("This is not a reply SNTP packet."); - if (VersionNumber == 0) - throw new InvalidOperationException("Protocol version of the reply is not specified."); - if (Stratum == 0) - throw new InvalidOperationException(string.Format("Received Kiss-o'-Death SNTP packet with code 0x{0:x}.", ReferenceId)); - if (LeapIndicator == NtpLeapIndicator.AlarmCondition) - throw new InvalidOperationException("SNTP server has unsynchronized clock."); - CheckTimestamps(); - } - - private void CheckTimestamps() - { - if (OriginTimestamp == null) - throw new InvalidOperationException("Origin timestamp is missing."); - if (ReceiveTimestamp == null) - throw new InvalidOperationException("Receive timestamp is missing."); - if (TransmitTimestamp == null) - throw new InvalidOperationException("Transmit timestamp is missing."); - if (DestinationTimestamp == null) - throw new InvalidOperationException("Destination timestamp is missing."); - } - - private DateTime? GetDateTime64(int offset) - { - var field = GetUInt64BE(offset); - if (field == 0) - return null; - return new DateTime(Epoch.Ticks + Convert.ToInt64(field * (1.0 / (1L << 32) * 10000000.0))); - } - - private void SetDateTime64(int offset, DateTime? value) - { - SetUInt64BE(offset, value == null ? 0 : Convert.ToUInt64((value.Value.Ticks - Epoch.Ticks) * (0.0000001 * (1L << 32)))); - } - - private TimeSpan GetTimeSpan32(int offset) - { - return TimeSpan.FromSeconds(GetInt32BE(offset) / (double)(1 << 16)); - } - - private ulong GetUInt64BE(int offset) - { - return SwapEndianness(BitConverter.ToUInt64(Bytes, offset)); - } - - private void SetUInt64BE(int offset, ulong value) - { - FastBitConverter.GetBytes(Bytes, offset, SwapEndianness(value)); - } - - private int GetInt32BE(int offset) - { - return (int)GetUInt32BE(offset); - } - - private uint GetUInt32BE(int offset) - { - return SwapEndianness(BitConverter.ToUInt32(Bytes, offset)); - } - - private static uint SwapEndianness(uint x) - { - return ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24); - } - - private static ulong SwapEndianness(ulong x) - { - return ((ulong)SwapEndianness((uint)x) << 32) | SwapEndianness((uint)(x >> 32)); - } - } - - /// - /// Represents leap second warning from the server that instructs the client to add or remove leap second. - /// - /// - public enum NtpLeapIndicator - { - /// - /// No leap second warning. No action required. - /// - NoWarning, - - /// - /// Warns the client that the last minute of the current day has 61 seconds. - /// - LastMinuteHas61Seconds, - - /// - /// Warns the client that the last minute of the current day has 59 seconds. - /// - LastMinuteHas59Seconds, - - /// - /// Special value indicating that the server clock is unsynchronized and the returned time is unreliable. - /// - AlarmCondition - } - - /// - /// Describes SNTP packet mode, i.e. client or server. - /// - /// - public enum NtpMode - { - /// - /// Identifies client-to-server SNTP packet. - /// - Client = 3, - - /// - /// Identifies server-to-client SNTP packet. - /// - Server = 4, - } -} diff --git a/Plugins/LiteNetLib/Utils/NtpPacket.cs.meta b/Plugins/LiteNetLib/Utils/NtpPacket.cs.meta deleted file mode 100644 index fc264493..00000000 --- a/Plugins/LiteNetLib/Utils/NtpPacket.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5e26e26980b7ffb4783c2202db2bfa75 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/Utils/NtpRequest.cs b/Plugins/LiteNetLib/Utils/NtpRequest.cs deleted file mode 100644 index bd7f74fe..00000000 --- a/Plugins/LiteNetLib/Utils/NtpRequest.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Net; -using System.Net.Sockets; - -namespace LiteNetLib.Utils -{ - internal sealed class NtpRequest - { - private const int ResendTimer = 1000; - private const int KillTimer = 10000; - public const int DefaultPort = 123; - private readonly IPEndPoint _ntpEndPoint; - private int _resendTime = ResendTimer; - private int _killTime = 0; - - public NtpRequest(IPEndPoint endPoint) - { - _ntpEndPoint = endPoint; - } - - public bool NeedToKill => _killTime >= KillTimer; - - public bool Send(Socket socket, int time) - { - _resendTime += time; - _killTime += time; - if (_resendTime < ResendTimer) - { - return false; - } - var packet = new NtpPacket(); - try - { - int sendCount = socket.SendTo(packet.Bytes, 0, packet.Bytes.Length, SocketFlags.None, _ntpEndPoint); - return sendCount == packet.Bytes.Length; - } - catch - { - return false; - } - } - } -} diff --git a/Plugins/LiteNetLib/Utils/NtpRequest.cs.meta b/Plugins/LiteNetLib/Utils/NtpRequest.cs.meta deleted file mode 100644 index b3d0380c..00000000 --- a/Plugins/LiteNetLib/Utils/NtpRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e3ccd85aa19ab9a499844a3c59f1364a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/LiteNetLib/package.json b/Plugins/LiteNetLib/package.json deleted file mode 100644 index e5011459..00000000 --- a/Plugins/LiteNetLib/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "com.revenantx.litenetlib", - "version": "1.0.1-1", - "displayName": "LiteNetLib", - "description": "Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework)", - "unity": "2018.3", - "author": { - "name": "RevenantX", - "url": "https://github.com/RevenantX" - } -} \ No newline at end of file diff --git a/Plugins/LiteNetLib/package.json.meta b/Plugins/LiteNetLib/package.json.meta deleted file mode 100644 index 1c363160..00000000 --- a/Plugins/LiteNetLib/package.json.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 7e879b021586eaf4bb79e8caceaa1852 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/Microsoft.Bcl.AsyncInterfaces.dll b/Plugins/Microsoft.Bcl.AsyncInterfaces.dll deleted file mode 100644 index 73223c80491ba1ced9d4427acbe58f105293c22b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21064 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 QK}*$>dbFMF8Rv!mAG$TM$^ZZW diff --git a/Plugins/Microsoft.Bcl.AsyncInterfaces.dll.meta b/Plugins/Microsoft.Bcl.AsyncInterfaces.dll.meta deleted file mode 100644 index 010cffd2..00000000 --- a/Plugins/Microsoft.Bcl.AsyncInterfaces.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 67f455c3dca87624d8ecc28fbeeadf85 -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/Plugins/Microsoft.Extensions.Configuration.Abstractions.dll b/Plugins/Microsoft.Extensions.Configuration.Abstractions.dll deleted file mode 100644 index 2ce4c756ef555c6522fb1ee103285b7e2229e81a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21368 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 XvrUU5DWihrx~~3fn-}B%XXgI_bL>KG diff --git a/Plugins/Microsoft.Extensions.Configuration.Binder.dll.meta b/Plugins/Microsoft.Extensions.Configuration.Binder.dll.meta deleted file mode 100644 index 3e6d3a4a..00000000 --- a/Plugins/Microsoft.Extensions.Configuration.Binder.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 263c0dc25d3acc24d97ef482ff5a3e25 -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/Plugins/Microsoft.Extensions.Configuration.dll b/Plugins/Microsoft.Extensions.Configuration.dll deleted file mode 100644 index 1b99e0a9b271e7f496ce46d446d0e15fed1711ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27000 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 Q{p$X7Ptb450=O{wUkjSlqW}N^ diff --git a/Plugins/Microsoft.Extensions.Configuration.dll.meta b/Plugins/Microsoft.Extensions.Configuration.dll.meta deleted file mode 100644 index fcf89852..00000000 --- a/Plugins/Microsoft.Extensions.Configuration.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: c966b2500a2ece7418c65814005eceb6 -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/Plugins/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/Plugins/Microsoft.Extensions.DependencyInjection.Abstractions.dll deleted file mode 100644 index 6a1b454f5972d150fb0ea818b1e2f049248ccd32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37752 zcmeHw2YeGp^XT54bdu#N+1M1@2(Ur8$dbFM?qI-RV}t2NmSiKaB_qjzX|YWSC3G-7 zm=*$r7D7S@HIx7WVju-lsDXqegwO&60&jNjR16N`EC2Vs_x=8Yo7SXoh^5g zGyBa(3_?f%*Ry8`?Swo2Bog>?PyyKq_gqdk+evjh*(`U6!6Gj;n~Kbu61i4m zG@7jP0=?W^W|SL@^3)zV@)DCyuXJ~p1o5J?(h%xKF{su$^fy~=mr!%LE2Tn62NVfM z4XlE@9IhI;5b`2vn$sH-u>Rz82_VqL1`66WcoJsC{~dQ8#U%KAT8U5(oTx!4h{Xy1 zQ;N{27LeYLkQ>};DiF$r`zwFspo0^$81T+cxYDX0Wd%H_0088Xwu0WyA2~vUm1c`s z3q+z@4J5G8Lb#khiO^k2v%c5_j96E!GqwRT!sYZyL@3z_CCO*de*D3@(MX8I?GRej z5g`{sg?5iYr~-^DuYfyGd)cjtia{R&1BH;(&z14XrcK_^iINM-GU!k$I9$-uH?&bp z+T;V&S~ZXq4IriP1>pOXc`9w`C-HT?fY`86qA)Q-oBSXno5>1q%oQ;;1U$?gGOz$e zBQ7_rE1%mK=XT(cCV-3wMFd28SS!AaKakzTK8gU$D-)Xn@m<1*nJh(9NM^GkSby*t z3hdz$gG3&H2hs{TWQHWyHn-_qfkk6pZ;h5G4K)+d{>fzlkf%}*>#FI4NHdPDj=%iK;{kcSjOwY2!s|8=p^{X z{GdAdS7=742nJGpA)?+uCKw002||w3jPG9;1l2d%TT2VZL3koXUQ!nn+2dRUrfNY* zZ!Rc<1TeFJX2vm?8c2`9D8Acpq7&exBDj;%U>hM?2ett&sre*GZ#)CW5f$ufz6;2z zU_V;X3fjIZxS`pV!h}Y&q9qXCfJjEKQa~R`B(y>S6n--CXUze?XpR8DWhlU&5^M-b z2(5tbV8fd6JiQ1HCYeB{#EFq-s3Z)nfx#({_*FXSj6Zei7I7FcwB0ecK-JGrV9t|OLj|l5*pMphmX4Xo5$oxOio{o9 z*j#U&b)?b^FD%fH)3YVb`2Ah|et%a#&+tn1^Spt+|FE5W|4vWeztfXvaMIHeG@hGk zVZafizeT?o9-O*{iw^B^_iS)jzphkAD54n>ib9MI368}C%{31?L_p$72ua}x5;7ON z#y-0nIfW+^xTj<-49F%SI7W5_KL&)vNC$s?;f5{~fy+zSFfq%RU=_@U&VQ0H16b|K=%)=J@X(AR42qh<0koM5`8=+~ z#0UWHp~GBEu!@#=3#0;*8WQ3CAQ1_Puxy!7Do{)Tp;AGuJB|%_S?z0z!tAU}C{Rp= zJa3Vd4U>t&go+%@DQXZURKTu=m9pVNKqKIiNQG{|HQ3d~6pd?`aY5n|#=4kd0Qr_} z5G6IAhHhmPv4C?1m(jFh8VCu&Yi1gSqmgU4T^qJ#0ki{}Eu|S5l2HoSYO%F2p>jqe z9-@c?Np7_+U>BmZS;nAJLUdaU=-~7Kw#^qy)H;cs0&=gXDrHl2r;=O-NRS_G-*?2(T$?vC|Q&VQ-Vb zOhubgAn^jdkyP*oa8L>&%NqAiuaCP6h>hGY3a5QTSie3JmH~8?Ux?EDtpJt+A;3IZX@=z!pT_>qqP3ta zh>$uB=+q`%7Wl<-=opmuILYX(24;7O%S~#U<(}AzSD3h9)qg zC1xFN3XB2?p+M+^!69)_P2k89iO8>ys|efr6E-B$JOqkx;z9Q>5*!L+*CvQOEWPyo+75(UKk&~P`J<0C4BkTyVs zLjQOh6h;tSUmN(i<*YxABB2iYMLX5ElxGx5+(uZL;2MY@(+C3lE0(Wsy9d)?Ju(wt zT_#u+#)Zuz1PWNxI5Z>&S`LSCn#UchQN?iFmX~k}!JoJpl5oa?H^ST#>TH95$cC_> za%hNS!N0+V^~n4eYzQkehlVe)3|@nCmKpiVHYA+bhLV59hVjlC{+n!AkIa9;hHafS zd?g#gp6M0+kZ@wZfmL69W6!pI+h`vc4tM7dcVJoS=wjR*FvZzj8hnyLTR}D~$EB88 zm=)rhHy_tv;mHp-b_}M~iEAuJGlfB+ad5ycV8>usE442(eIek5H{{4Xb1Puxj=7t? zNFN57T$t|*B}dZ`IA;Utxxk4P;Q}X){myaIp)TI;zAW}DCV<>mjGGMV2ljzhNiB1r z6t)knKVFFYm{!L=SpB(n^IzROVBUd6f}|zP0JsD{k)=DuE5++ji0pS^xsA`` zr1kD_O|Z(4`1O^9Hie_Vfsn>WH7vs!R|GUzYDidMV0|OLqeI?>6E6>}Ha!O4$dYp$ zOlFvXZ?ICt9XAgA!2XpQ5Gt|t9W|xHP7_KnOsX%uBuA=Z%8x{5k z;4f^rg6z?3RH80#BD^_r+PU$P#j8SH_@rnRS^wIVoPfBJT(&76%DZ1sm$e4Fa?i3n z$!2^o(0!gV+!HL=lVe<=0bnWs@U*cDZWs4VsS5dQM?TenD=lw;wiVDvWO*tFPP|Md z_dyKldz!30NRoJgJ^x)>J{dZWAt+`R zw&>I=1N(a^;5b6HNG`_aARkz>PeN!j6qGLrB= zb_oJGvk`_R5)3^F3@1Fzhz|2zu?`Q2gv*37gJ{@-$nWNkb&hpADq+z#uDF)hi9VeO z+~Q8OVlW&}ayN@{`X?f1Gof7f#PUxGG3-O?UEq#e_cPH@D8u|;5IwIGs3IDkB(-Oe zbRvPx35+83-XUc#5crf>$zQO}4P=rU?-H2oR)V`7{fPneI__UD)KuKYC5>P!0dMH~ z9V}C5IA6rr0pyImFW@ki3^%B@EeBp5IB*K#B{<^+NF;9M&9BP~~!v zQU>Q+Nrdw-;dJG(a31SK$~6~#Cs_|3*_)Ib3H5CPEDu#c4aYs&d8Gl?pGbM?Y4l73 zpDsqOkY|KV=1Rb(Af}lY@`F0lVBVUJ7{~(zFd3RbFc?69d81hbgW(8R12hMz(OZm< zpc%SKH3ax4h0~2`3_qg$0p`(71uQG36oTFrj9Wv1MZnp+Vym>FK#iKXg$kr-fO`bM z4s`tjbrP_si$_;G94qwU(^+y*1XZI9aSs87@B=@DCO7=h z9lxESBG{aU``q&c494B=-`xP8d&1A!9tv16YI zRA{XoJ1vMpmk2fo`XS81BD61np6t9TNx>(KI{eDojRu2v!N4 zjfH9GESD#qEod(6gudaiJA!!B30>u}9zu-$%ws7`CSZ4Ytdp!2lzT$3BWRU)A>9dW zh4~Ai38;{iqZJsdMq8z7;FQ?0IKbN3u|#188feG53%j84c5HyKE84(gMU+~YiQcti zae(c%V~N5Z=sP>sU6_TQ+OYw`Y!m{k1FQ?n9hzR3VWeRcC5RwH+svC z4G`v`Gj?pKurGRI$IQZhs1=^Fp;wmCqlE)d3c;!Ys}c@GnRaZ3a4^c_u?Ea?p%#th zvG?hn!;LO2W!z@Y|O zn;`pAXhg?(ESk9_EJas%OaZl<(IY#yR%k)8a9nNLJ*xW_62Rjj!@N1E<20QJ3`H22C%SoAe=|2*O{U00(6^5nJ4b- zKAf#aQZ>$gr&JTzN82`xm?BySF26WPUR8qax6Je^&N7IGM3 zTxJ2bh0mKJna(alyZO9zlKFsr!RKA3r?YROD}3G`^nAb`^LaZ!W(^WY63x&F@hrgP z940nW)7h0MoX?v~%>pcq&pXLXXIG(~eBL8wK48NLRt=G13A+Z(w_~f>x6l(F%c8cj zZ=*g@xV~zXMeSrapxr#SL3)UN2R*T4C)mv>3s#DlbA$9tb{kq|$F8yOp(A$e7j_5w z&5qq=-$w`n6)vZt4zW8?q8&TI?n3kJ*q7`cbjglgWA`ITtgYNH>;V*Q$L_Kpqf{RI z)AbO02u-wOC)gwCoE`g;J%)nfI4OU+USm(7?sn`K_9Pl*$7sVK=jr{T$unv9MHsM{lZ}= zz(pqd7R|@YU^E#;GYv)Gp|NnP0V9t1`~@_HV4TliK(p&$iwHIWUKb1$T|ir%@-CvC zeBMCFyNIqiQa8M{zKb=M%MCL9pY(1Q&Q4iSb+4y<7ljQZlL!n;8SMd`v8es~9ewJcu*HAb& zjQHL{$Ys#400roG$aTo4f$rylcOIC>LC5@lQ1k})TRmJnzlHmy?&cGk6+G>lgOg5x138DeUy2hiGRC`#x&OwWTa}N60B^up8M(H3lmB?IAVLg3d)lh=AQGKK% z2^ zx<5jxXqVKDI!&ce(dabQ1mJlpkCIZCsdK=244oHJq^^ckYpT*+4bY2fPvxT51a8y- zRLzW}Zd2=I71SfjRW_ZXXspR;YNOXWN{1-0Lu+cK^gSr`lh;Q8S4xjk=c!Q8vo%%V zavCV(nePDBN^bzXEWJm$P>W^0bON=_r6a9_wwHjkzJgvf<{w07LyIUh9N;*5IJHqc zfyNe?O()TKce9OJOD_f3N4k>04YWULV=-x?6{LMZXVY@oH*{b6L-!|;9xruae2_`( z5AcYzCF6!xx`Y7iEQNR2VeOj6Xy~J^T^R#?M3@cmnv{ZfRpdx05ThU@0jNNpu)EdJ zLf9X=0!0aD3E3hgYJ&O!Y=O!FhQdjh5=Eg80k%bLU6d#V^#<4#X#wV-g#h~_Ux^ZF zQ3$|cXb?aP8V7I;+9^qblM9JJLtrI=D+xS6AVcAL}NX)Q@tkn{wSt|95wB)y-cFA<0sq7Q+I1P&&! zg1{OA_Y-)DOABxjY|=HqA2r=x$L;>t7iv!rrJqh4mVJCntE|~x~NiakVhG)bW zzCmI53@9{-oHQI>2%(l%Pzw$IjcaTTzD=VLcz1&aPxS;i0HP@c(NzlR!Qk^WoHaK9 zs6&1L3n9wV(5fZ?hoS(;@rSVx0+Dzxx(z37ZKwfMF|~=>PoJa(6?k5Q1p<69)H3bJ zJWdD%^kZg2gy%k(<8zorrEu~mgUcIE7k%Jr02lsHcKtJ$uZt!w$@b&!6)9>>4`+WX=KK}tvf5zV_it8VW;_S}=j{8SQ?(min#ZqHo zUpE=O4c8$w9QB|^qSvY6sDxew*EV#M9*pkLL*cT*wF7Yc&b|mP7r5Nv@`TG9E?>AB z!qo(>0J!9EHHWJuToG_Z!4(G=eA;!;=I5sxETzSo@|0qY#S)pXs)ra=FEs{JbIs*R zI$ei?e2nzegCMP*$GEICV_AvbtSKnw$)zgPy{xzx69%hMh9euWv{9vIy~ScM8F5yM zskm6LwelFxXf>H}UN?iqitjmk^9X}hpJg_UFzEE=bd44m$|0u|GL6=#NR(b?)DGrv zQ5+TnO-w-TGEKTN&H$qcfrq9nu-83ZyIt?}eD$-l?Gb~wU1;qv}$|<*4^(9J& zLKbBwy-{z5ERHY7s<8sXwHResQuT!fqh7}oa~l<@O3j3>aB*7dUAM8a?4BW$*e2Bex4N2tjzqkh51f-K{afTOuco8Nr#|q_-52w zaWixpvks-|En2goK#zE*Lb<%YsFU7mGlPwkkyBP$YBIk-$5o_|ZU50UlX_y`* zgI7RblC*7@HUCw)GjN13 zS+FG3v&@LSiR-t{&{qx`u7#(7!8nd|v#G>E!yHbO6jMp50m`R>L32SUX@bpP5pQuj zUd%hPebAF(g}DCU(wUlJdVXNys<_UvJWt^T6Ar$IN!q}7j8oCxI561pRK2!XgCAxS z3be785n@hpxs6hUV@91$w=vd3t?M23I_x9eR+QYWw$|`N4q32cbHfj%XiD)gM4ZKw zH5RZa=`bJxi$SZgSX1@I`XVqhI32OMnHU8Kx+E(+pD!qbtnT_Ut65WwM@pGltG9I1 zfCp)c^bU?xeL-1K5%vQIEy-fhmlPD2=NhceKi< ziAV=$=&d)`pP6ASBykc-YKs4oE5&3iG!&JYNl<*T1}>8kkdhSq;Sot3hvp8Z1_G8J=exY@Ag|r9Jhr;RtqLtV89?)S*En>7)lIBa;X;l2&kYaW|6|&#rZX zDBra&Vc^$io#4$OO|fA#8GWy8b-O?63;E@yeTH!?_>k7V7{y-dG^K#k8;lScOh%MD z#B3T#LM|-LQXoKBGBxI5dR?BuI>bIy(?)6aBmki#a}g|!jaEF-JE&aX#A^Vs1W0w{ z01aBF>ro2J>AE?@O^mQ0bue=?yaTsY=Adx1e-4bhV!ai#hh}jz2#&NE)1Y5ba??%n|A%sP7ol)>4^UaFMeMDROnXosk9U}F*sy6=kTRS6a*h|&MLtj`5Y}@>*zY$(#$rSf+{+)S}(;~ z>0uLR>#|gXrpRc5wW!u&BiX{f-E;WPdx62WQnBYdT+(9eOGhEwqUDu`ecfPd>pctn zL<+zBfgK25?SLI%qo}tytZ!cmAZ|qhtB3Be%&{O?@{j?IM~VgI+ufK>Xgn=FO#WPZ1oYu3Qh8Kw+w#w>%;ZcCeBUxwL7=*?D? z3CpbRdid!en7+B@fTo2VAnl;-_*x zLfSCg19hitTTb0gj*ZHh!G;xb>L62Te%kOdnBlDDIGtexjX5l>q!eiQBelSpsu_(y z26%R$hf`$aSC^8D%26rgpkM8Lwo6mvKFBgO~BXU<1#(eS@T>&=M2rJsoKks_d8q&9=K>|2z#o}I| zti!0-ljTGq3#5vnA8>=}HpHQ5{U#m>hB81|&J)OKMCs@i5P=#wU_6e>8 z_NOwwM{xrjC7eAA`%5nI5YAgHkal<)_S9mqx6Riu&Y1^RvXFy&(9sF?dp4M)V);K} zl95mar%VY5H=|*IV>cTK)nR9r!~5lU*w}gi51U>D#|mLOj-Dydj2DMl66E87X8;E* zgOnb63{{-2pIHu`_dlUBra;;V|8U&t2GAC7UKTP@Yv)ouNegX5 zvu@x=!QDY-{e9r1MJvozw)L z1?f0)a`6Vo87^X@2H3B059p!Y*uAi0p$0h2!-|eL6AlvC4Uu1cRG7*UnzAii)-5qG zbHlfb_n!L_-mGTih=OPRlvoHr+5jg#*aos}N)`mSUfiuO+~`2~LJmXIvJ5Cf3*eDg zh6quz3~9wNc&rO#lHm`Jl>KEHEY86<8W4XvkP?VM1g^pxF(Rk|(H-$of)&2xA!{IRM}jVw%4|LdhC75Q)XKG_`@O zqLPwTOoIQ?R9cKRtXM9~aFHX-3RDq)CluiIMq*nTP{13pa@-bp4GvWDmx%;WB%pz` zVk#w;Rm_0@VnpLah6f$sFZH5mC_D$$l2t4S0JWLDm8>sNs(jvWmsTESW5)2sUoTVt+T#q*BOLynv{+ z7_0@4)n#CTa$Jz4-HC(+5=@ukbOtF1x=g}6J|YH^HkZ3Y@Nygp-h9FgN7DUq%*{w}?<(R|3X%mucVgv&uv>Hk#6W|mLP^TM zA?_Vu#7=|hf#9^@C_w-?FUrDf9v-ZSmgUNVWWbFXo!CJ==p%4fF{p#b2l$Fa#EQk> z3d?D+i%2N;_xG1oti^sBK>DvzjoV%sBZI_=G2YKkhJTk`Q3G%GAVCE}^I-t8GyuSR z<|L`%=`_5cK%u*BS_^ut|0?m=_GWG7T^l>`J@e7-uG2gke?PNm{lnicEYE+feb0AV zd_V1QL+bXo3nY7I2dvHvd9&??Z+sg2eKP*;Vf}Z5t_i!&`Aqv!yP-Qfnm4xDa-+TH z!H=V-kLa;w>$d%t_Sby+Zr+&QhncuQC;kAUN3dimqG z48b?xS-BhBWEyXTN4Ew8A9#^Y<_7=31w3s@z7~-eP2oK3&4fkd1s(z^Pv{+d=lBAV zrx(=Yz$q7-Ab%I0GZ0?o5O6{uMk%B=gs(}eaFH|Md^it=Jf!?R2*I8&B2=jYbjHlY zhrkd*c!g6IgcS_JrQNZ{LA+X&J66|*;dfgw6EBf8B`6TT1B0plq^&_x_y#}2iIOU? zIUEI~3S0z2iw27L<1yn3IOm}<4UBD^By=1Qd}JCh0zm^{tkAM}5+SiUu!sPEH>_JZ z3>O@(BuGG5VH7q1%fJA23Uh!g@Bx1y0=yu{iw_GxgxCmi*O@3q3{4_dhK&s@2f_pV z-Q^&88&1h8cKCxIzGzl*}|4`R|D4EHc%cq0?P&xb#Ocx30&zIkR%X?LeX zW^#mWp@0vMHH2a*)JWMqEf-#JAdlt4_@_1PM?@-BAi=}O{)mr%PKA%cP-O*$Do4Na zbB|oT#cBzYb8lO~!9#nMDl%GyKhg2zmcU^uRjewK5cvF<$e5^Tb(9)&5;{)7RTvee ziA+#MM;B@mbaBxtZ9+j*q&iBI5T%ca)5b>^M8`$KO|L45*QoSrjXpYF9~-AhD2y+R z)#(#-F@>tj?g(FF-=ZDDLwK|z!@R#OlkRTvkkDTvZ&3iSz5I#r=I z3aW^XFNli;T?-3T1!}D-E-Ff=k5Na*Bxv-Sg6PZjn+rTt7D@J;&w^j^wmr~tm%u4* ziOE=8E-$m_b#nY1+tS8eVz18m@mYOO#B4A4I1UWqmkHoi`6wmyvQnL(1XHV`xn=-O zsS1tOs|)mzg#|Iuv2ihK=#Z#{*mzxBLA0t6IyJf=HZndwP8|c^D1tH2$gYSSd%4`{ z+!M8-P>enM@APyw2Yf>xeiT}742N&IqXKwq(Dn+0yuEykEj=zw&Y#rc(_)rg&$$HhT*>qf|bHSJG&JF`}(5r0Fz;{v0SKFiQ0M_pR-fh}75J^p;Y>z1A zPDkw)xdu+h;lZS_NDfbm<>XXeZad=U2CjUFW`rJos$Xw}5npE1;h*crBU;{SjA~pf zr95{Cyw4`L3^A1z>*Qq67wF-xmuu`#pq#5zQt|Kr86Hc?ttL7AEmDfEm<^+@Q zf`bpd=m!)vR7G`jl!U;9-|UjxIB+m>XeA#x1l}r4=w7}~(a_bPdur=VX8-NV08Q#~E!>nmj3@i*> zX8U`8L^w8esqJy6MQ$pTYviTmrNg?GQg%1l!(_+@Y2 zShttstxz}#BovNTNZ0XYP<0!AOob6-@8sLU)JYPQ04uL3TZ2yGu68@=Ib1=pHN zxU{w$?(S6=g)LBO&IiTmp<55;ciHf?(}ETY<{iT_BJv|NW~%`|wXj6MlbncuYL1BD zC*TODR~}(S_0I`Ymg)*nPUob^m{`QCylW`0GB(RctIj=MTogFF>%=3g??TgUANMLq z$!%EOyX{XtaMXNQK%^EIXToD}M5YeCp1hwza-Ri*kmt=;SK9w#|3wzSzi7KB_BjgQ4MV6m99ZT9OhY{(l>vWgr90pm0Mog@x`Ory zZau|^5jyzh#LjQMA;l08__xvU2OkmOaqs*|1%v{r_;5NM4kYo>BtGcGNB;N|L`vcL z6(8GLARiy)@&}iMW2-;`x>BGMcN&hLZ@ef8|F{SRPx5U4qTxssYyhk5(Ll!swk7Zn zKW?x>EeMWW3*e3=+MbbcXYh_EFZg&AKf}a_vKVT~!v%aWI}~uo@v0K`@Dh6sSPJ(T z0v}g%PXlbva4hhY5%Xq3`|x3`2{`bhCM%rmr@=4n;xm411FrQJpr!)lc^$Czp4T7) ztmFKA61Vq-V_-NA_qE#sKln02i@L*|Jhud!yr`F)w95=S;3H$_o|%tgL6)r_u%6Bb z%#QwhQRcte*1zgGggU@?FC04cCKj<-6T4CrSX50s1m6C%bld)M|1c|7WP^EoSS<Ia^;($K}c=0D5PKPMyBY3|G z`5SjMjZ{@F46IAY7*>BF6l{kF0M-pxWm5s&n%2KYN(s;G2%7tZm!H<^Gy>isvDk(<9 z-jY0x1;6hKZ$YcQR34Zp@`fW)9h_Y1)PX90Op$okf1avVs9NHD#=EI~CkW@QI=wsx zUew3ODOo8=@<^3htqSyWS0|`qRFQBL9Ty$j&(9qWvmL0)`ahx{uRrq_`m3s_=FWzK zzGJE=Pv~n(LRZ1>7cS^`WU`@CKy={kUIz=yelN&v*vF@+)o-gqjxe2fU+*3LT84)H zb>gVPR`Yu|3)`{smk&<1-S+nT-}{RSORlwx&QV-Fd+Sz?yjeu&Cbz>kGOz#oQ@<5A zI&WOv-QtnocJ(`t2hKU|zB@|2?(x`<{0!4PMz`*LGfeiwovX_)ebRn()RFxMXU!h; z^W#VN#`TZRI2V%pbFo+JDU%XExo~i;=Gx;~E6az(mA851V!0LX-(#|LssHU?qZ+Jv z_UrD=@96grPbsSr-CuKT_@%>d#oViiQf`_(<>A8f)9y?SOx;#7^y2IuH#5sUdY7yX zjom-ldv4-^Bi_g4k%L#W#_x+)27JBo-S1A#Or1l6qf)D@sPSNt(W<7<*8#zThALmX zH+K_LtQdSphX8K0@LaJE#Cq3X0I zO_icK$VNDY%0i9bya25bgD_4oHE2}Eo~DKF>>Tc zWr_WZELu}ZMCmYtsnimoH5cQP2=HR?VQ^pUz4;h~tKz~{@k+>7X>4t#C_yh(jw;)R ztLVvTe_H`G%kno>SXFLVac_!xCZJ(=Rd+BmRWybAc~)#vqBl1m-#jI3{=`-_2hI#k z`T5VrGn>ou9*>)8ydJ0O|J?#OzMK2*@L%qCo^IZeb|!E7pYFY`ebj8_o|)Zy z4?XkFnGxHW@FLCe9UezUj9(QyCj0Yqm-~LaYf6)%FN=RaG1cgCK0BgkZ#HPPpt#>t zZQj)W>s3$RGYU_6ZyoNVD%)Fex6O#yk>j`T7$~_e+&V;jwf{2DiI}gHF zrFU%oR@sK@_hK@x$FF>Pv4Q02;@&}9s03D-vr{s7{JBrRn5#J743)5 z0S(gujJb`!{bBa_)$=4LjNR#)6DpuN`y?{4Q?T z5!pG{-{L=B%x*oJ@CD_gPCh%;yL1!*5&3RW6c5uu2^`V$lXs%?zS1Q()V8au1oQ{ zcZ|B2QE$~~J;To?&U<+Eg2?@g0p)8mTL0j_x5j(q-udlsJ-!;+&#P%>Z^f$7=1a0R zA7l(Vck^b-oC)X0ygO!clk*+6y)p2|sXZn(zOyo-@AtFYhHsAQbNGV}Pb1H6XWDOj zcgx)P@n@D-gx&Andrq^M;DZT9-D^3!mU(V!)MDbN_jWOpXFSONt+waBH|D>-dw(-) zaDGF@`zKl{;)53@bcy|J?6$d^{adVCU-*lr>CnrHjOF=Lt^^M}+pKGco`-hibqr#D zJ3YF8#1}2DmJamHP9M4bA-cT#9l9$2oBa*8?`iURudY8Ntn|FmB4c;MovCBfzCUo# zJo=LPhoFo5(ib1T^|626Hxp+3l9{1ew{hmhU;3}u^5na%g;x$NtQ>Rm%bQ()$Y{OJ zTk+PqaYYr^rxlFKe>Y;{S9!|@>>H_2+`d_IP%$fPR$^R_1D7YIPCew(?eOPoQzEPj z9vB~vlJ^Po9yoZxk`6thCVstjirf&2y@JT^-e~O>;-&ifm@&i&X4em&M7EK<%+|-rvQtYtn#$SexZtiDWJ|Y zXAW;et7oTt=p*cY`KNWCs86?;8m;PwOEeY0Or+{jlUdVsat1#O!EE*7G)Lw*_{JCh zIxd-sVBEr}g~4i{?DADn`H_)ivKwTZ++ecnsmfAyx8X3^CBJO4i_qF;x|hhesw!7t z<>i9Pg{sQ=s>(TbBPkhGlH&a_`Q4X<|s1of0 zXjODzq&&dsU?-m(vT^Szm&3s;KAgk{ZjLWbDCGgq1ynNo7TuY=cG0EW^2W-u=d4A| zm%3I1VqvUwoeVx{?zH9hKyRUi7+Jyu4 z6K9W`o}Sg~oZH;7XBv0)zuPW(de7Ree-69aL8NTG^m_XyYd_x+Fmisvl^eQasqIIN zZgJOp+*`A)6K34|v?ZM$^6@mUkJhXgx-Gpq@ZayK+gZ z%O}?^to?PMHtA}A(X!V&up`;i?6$I|K6^Eq9lw2hq={hf#iUO>6u(~3NBpwz_mu;x z&!I0@rtj%{ci~!>uARLWS2V3ftq*Toy0&B5$iSE*XI8CRF?w|KKRPdHy76(R78Up3 ze7JAe2VECl`MGRV<6nM?TU_3->$5Mnw-{1(eajzDrvL0(@spwLmM5y4f^IV}UMwro z&S`&odGGE$_EqFHUpYz|*=+Q!B+0gpkKaDAX5fL9Q~K3bce_3OaT#(ll@`}2{DJ3Yz{R(`!yH^r}_ z|Mq(cua6ycIOm+TL2%Pg9|gSGBPsm6v~~6UWfwex`+gDcvFr1YDQmm=Z)`ic;Fxr5 zi`h+@oc-}&A7%9iZb1c?*PhN>{jFeeh-}GwQ``&7?wre7$ZoaZgc1=|!yKFZu!%*rf*=eAiwD%A`n~?1V(k_}}UObzqqOw_6n-_S&@kAAs z2)1npQ(8QDGcS5#UkO9ib2zc_$k`@72lS77XTV zFX^8+i3nGP!ZZS#$sosaG{X$PM*%M(IBhDs8A=TB!yoFFsvwR%Aa@A+iOfURUTkJ!EHE_Iq!5N zKMEh zSHsR)&7=QS{R6)J;=v$^lR@Rm2 z`+qu!W-MzT)zbg*iVMCwh8*5@s!PO!v^#Wlw?m!2Kb$jc;c)TNUA?~?Qu5h5r_Oe$ zop<6|-({w!2OqkmNu}^!@8m4gscHV9;VZ5j==|2nbzi;Vy|$VA>8=gXtc%gr zp%q7KH_rNa;I83wE|m35f0D6dXl~)7&OP66cxmhPpryjCv*g>3j#PfoY|(?txo;Hj zQ=VS)_J9P}9L+lB>Zf;aJ~?~-=&~tGD)N0xZa&uBIT{iY?2{U7?2_lxx-@U;p96pO7pE~6?rOOEau3?Y%|75z6 z9sK3!{4Oq=Za$co9ewkUSkYUa4U6Y>_&Imf{Auj{H46(Lsmi-FjP=O5@g;_FTUn`~HY^2fGiPFui))f&GI$Zoi}Z;K0)BlXrc$ zC2MffgxnUYbw4EzeIux)YQXK~fyL6eUhdx?@1EModr9U5seW~OiEC^3*UAS;3W5`c z4`N+=JbAk1t6Kw_Y!R887Mk}4yd}Tf;c~}9{i#oC!_MCp4ed5^#NqeOey*F5_QRrr zzGvqclBXnJEl6$^(CN2bgLkY6U95g8?)Gilkhqx*pG_hnv-9dyX~`i-R2%R^wz-B8gHZGNaIJ7D?YlYd6IshRX|XY%-p!yv@KnAQ?m-T z4g7Ot)AqmRmA$iPT5@J$_G!;$Y=@%P?icQ7s#C|`s_pux@!FE(+upu2Iz*!W?d$IB zocE`QV}2avzxBrAlkI+pNZqyW-nY6vYp4TqmwBU3KH0thSn9w*zRM_KkLH=SNOc_| z)s>fS!Rrl8|CTNI7r*!Zbk>in1{4fA-G2V;{$HJ1((ur~8uaX2WIpJ{hDS#IyMo?d z$cC+V4UTj0?TTjt*u+%MRaMTav-_@8wYSAT*nO-2GQ?(e&EU4)DOouY{EuI~!rnWJ zyfA}b%fWkZ{HoC_?Y%|Ur)0ZdIdW-H$I9VM`{k=wHZyJi`K=T8)q6h^URnS2kGzsb zs_h>iE<85$;{6|f8@1?z5ZB+Ui+-Tkn4VPr>EV6_H(9{n=|v#MAe$&5Zh}Ab-g>d5Je} zpITfv`;BKq3ts!~a2MA(Ew3c}(x}UD?ea0rN)9ety{g?GuZ^o7I(yVxC1)-#dlc{_ z{@na~N7hQJC$HJ_X5-C*R4i>CFW(V-P4~-#d;7*~`v!ZCRwm?)ST%eDJI!;d z?=H8DH1d30J*ak%#6y4qXgCj54}?QoZi1Fegii#1%XafcU|(TW1lrj%DgoB zQOJ_j(n8hQkF1ehFKWl!Upy_M$tTUW^xd)f+thXovxa}Q^3360R}B~P4xGNA+W+T? z>zR+;_YLfEV|ies_=w$~^${v>xz}XHe0|HMmH!vp$HxSUcYPiE&Ds1}7pzk<_$d^`@d*aR7^iRAx;%V2&$0~T(~m^*lY?Y zbp$N+B)kB8m?{B4)4pHOZ~!VIY3W6dVf1HFm?74wIE^1g+Yc@9?v<{QsKmG!BU&k6 zX-iX+Yn+!RpfXcgiPl`1^!tnxBd>nrV;*y4(y_@GM0C^lhfhvu`$fU-L)TCB*}vlF zo6mAuPfW}n9(!)(k6Tw=3s{)wk}xA__Pt-f={qP>y=lxHHh0yczUc?Nn=To9;rLCL zj-RJ|ef~)CUg1~zfr%R*cbS>DNaJlPk6rxk)I)Y{3FKXHJ=B=DUVtSPkB#3wUK?+vPs zh`4p&`kFWQj%;?xyUm8^PRmEBD*td2Ku4%6e^OQcpsM^{Rk=qXkDgU~N}ki9P0+&I zr9lIPSN8Z=!*1`taX9yhV88bO%M?}RqW=emLj8t=!?HC#UrZd-E#rjf$AzDCJ6Kuy z?UZJzKF#NCh^+eXM^)NhFK35@a{+wN)wN=7fZ*dcmsaWDf7s_{t^SWT-?eBRR;*>- znRm_Il5F^0+wstyaov)X6J{&!T#mhF^8Z}ccv!FEnU~k=I+!1Zx4YDL$-$uw)~`%r z4=aA8=U(n7{bj(?18w&NkNNt}sNY4Fvz~$G!H0#~*57X^-+2u!T6b^Kv7tu}$H(k! zeebK*MQ7HJ*>~XK4}S5l#|7jhjOqV%(|~PzYcI5Z;Fc8g&hgvhEEoJU))jwPTb)r_ z`GX?R)$7A_`?_za)gHaSzAS0do8j9OE?YaSoZRc-mAtjXTkhAq*T1%Pr*+=Z uGrJsG?yl?K`_TP%pQsttDA%vrx@_v!BJbLTyKX5{-yO0&Vf#KfF!?_VA2Wmi diff --git a/Plugins/Microsoft.Extensions.DependencyInjection.Abstractions.dll.meta b/Plugins/Microsoft.Extensions.DependencyInjection.Abstractions.dll.meta deleted file mode 100644 index 60a0f281..00000000 --- a/Plugins/Microsoft.Extensions.DependencyInjection.Abstractions.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: e17227739bbf1a743a3973d6a6872afc -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/Plugins/Microsoft.Extensions.DependencyInjection.dll b/Plugins/Microsoft.Extensions.DependencyInjection.dll deleted file mode 100644 index f6dc5d16a2b284742e949d2f668b65248fcaf680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64888 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 diff --git a/Plugins/Microsoft.Extensions.DependencyInjection.dll.meta b/Plugins/Microsoft.Extensions.DependencyInjection.dll.meta deleted file mode 100644 index afcf6c74..00000000 --- a/Plugins/Microsoft.Extensions.DependencyInjection.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: b675a68415e5d5d478075997188970b3 -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/Plugins/Microsoft.Extensions.Logging.Abstractions.dll b/Plugins/Microsoft.Extensions.Logging.Abstractions.dll deleted file mode 100644 index 82e0698974b07f39df55667333b60f2386e8b624..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48504 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 diff --git a/Plugins/Microsoft.Extensions.Logging.Abstractions.dll.meta b/Plugins/Microsoft.Extensions.Logging.Abstractions.dll.meta deleted file mode 100644 index 859e0f10..00000000 --- a/Plugins/Microsoft.Extensions.Logging.Abstractions.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 9d8b067f96d495a429bbd0e26b6cf343 -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/Plugins/Microsoft.Extensions.Logging.Configuration.dll b/Plugins/Microsoft.Extensions.Logging.Configuration.dll deleted file mode 100644 index 3fe08331f76e1d23c7724b04fecab3e6a45d3beb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20344 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 C#Ek*~ diff --git a/Plugins/Microsoft.Extensions.Logging.Configuration.dll.meta b/Plugins/Microsoft.Extensions.Logging.Configuration.dll.meta deleted file mode 100644 index a53e905c..00000000 --- a/Plugins/Microsoft.Extensions.Logging.Configuration.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: d44b8285870fb6e47b69c367be160f5a -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/Plugins/Microsoft.Extensions.Logging.dll b/Plugins/Microsoft.Extensions.Logging.dll deleted file mode 100644 index 9f6e94b9b81a80b4f540bbba6d6b7cbf5f2b2398..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34168 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 diff --git a/Plugins/Microsoft.Extensions.Logging.dll.meta b/Plugins/Microsoft.Extensions.Logging.dll.meta deleted file mode 100644 index 579f0276..00000000 --- a/Plugins/Microsoft.Extensions.Logging.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 81d91924403053d4fa39be9fda1ccdcb -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/Plugins/Microsoft.Extensions.Options.ConfigurationExtensions.dll b/Plugins/Microsoft.Extensions.Options.ConfigurationExtensions.dll deleted file mode 100644 index a6f0946ea59c458a775a82de3a9599e45a6ff017..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18296 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 - /// Dynamic byte buffer - /// - public class Buffer - { - private byte[] _data; - private long _size; - private long _offset; - - ///

- /// Is the buffer empty? - /// - public bool IsEmpty => (_data == null) || (_size == 0); - /// - /// Bytes memory buffer - /// - public byte[] Data => _data; - /// - /// Bytes memory buffer capacity - /// - public long Capacity => _data.Length; - /// - /// Bytes memory buffer size - /// - public long Size => _size; - /// - /// Bytes memory buffer offset - /// - public long Offset => _offset; - - /// - /// Buffer indexer operator - /// - public byte this[int index] => _data[index]; - - /// - /// Initialize a new expandable buffer with zero capacity - /// - public Buffer() { _data = new byte[0]; _size = 0; _offset = 0; } - /// - /// Initialize a new expandable buffer with the given capacity - /// - public Buffer(long capacity) { _data = new byte[capacity]; _size = 0; _offset = 0; } - /// - /// Initialize a new expandable buffer with the given data - /// - public Buffer(byte[] data) { _data = data; _size = data.Length; _offset = 0; } - - #region Memory buffer methods - - /// - /// Get string from the current buffer - /// - public override string ToString() - { - return ExtractString(0, _size); - } - - // Clear the current buffer and its offset - public void Clear() - { - _size = 0; - _offset = 0; - } - - /// - /// Extract the string from buffer of the given offset and size - /// - public string ExtractString(long offset, long size) - { - Debug.Assert(((offset + size) <= Size), "Invalid offset & size!"); - if ((offset + size) > Size) - throw new ArgumentException("Invalid offset & size!", nameof(offset)); - - return Encoding.UTF8.GetString(_data, (int)offset, (int)size); - } - - /// - /// Remove the buffer of the given offset and size - /// - public void Remove(long offset, long size) - { - Debug.Assert(((offset + size) <= Size), "Invalid offset & size!"); - if ((offset + size) > Size) - throw new ArgumentException("Invalid offset & size!", nameof(offset)); - - Array.Copy(_data, offset + size, _data, offset, _size - size - offset); - _size -= size; - if (_offset >= (offset + size)) - _offset -= size; - else if (_offset >= offset) - { - _offset -= _offset - offset; - if (_offset > Size) - _offset = Size; - } - } - - /// - /// Reserve the buffer of the given capacity - /// - public void Reserve(long capacity) - { - Debug.Assert((capacity >= 0), "Invalid reserve capacity!"); - if (capacity < 0) - throw new ArgumentException("Invalid reserve capacity!", nameof(capacity)); - - if (capacity > Capacity) - { - byte[] data = new byte[Math.Max(capacity, 2 * Capacity)]; - Array.Copy(_data, 0, data, 0, _size); - _data = data; - } - } - - // Resize the current buffer - public void Resize(long size) - { - Reserve(size); - _size = size; - if (_offset > _size) - _offset = _size; - } - - // Shift the current buffer offset - public void Shift(long offset) { _offset += offset; } - // Unshift the current buffer offset - public void Unshift(long offset) { _offset -= offset; } - - #endregion - - #region Buffer I/O methods - - /// - /// Append the given buffer - /// - /// Buffer to append - /// Count of append bytes - public long Append(byte[] buffer) - { - Reserve(_size + buffer.Length); - Array.Copy(buffer, 0, _data, _size, buffer.Length); - _size += buffer.Length; - return buffer.Length; - } - - /// - /// Append the given buffer fragment - /// - /// Buffer to append - /// Buffer offset - /// Buffer size - /// Count of append bytes - public long Append(byte[] buffer, long offset, long size) - { - Reserve(_size + size); - Array.Copy(buffer, offset, _data, _size, size); - _size += size; - return size; - } - - /// - /// Append the given text in UTF-8 encoding - /// - /// Text to append - /// Count of append bytes - public long Append(string text) - { - Reserve(_size + Encoding.UTF8.GetMaxByteCount(text.Length)); - long result = Encoding.UTF8.GetBytes(text, 0, text.Length, _data, (int)_size); - _size += result; - return result; - } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/Buffer.cs.meta b/Plugins/NetCoreServer/Buffer.cs.meta deleted file mode 100644 index 37918311..00000000 --- a/Plugins/NetCoreServer/Buffer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 32df20dbcf5527a489c1eeb443489be5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/FileCache.cs b/Plugins/NetCoreServer/FileCache.cs deleted file mode 100644 index 7b883e7a..00000000 --- a/Plugins/NetCoreServer/FileCache.cs +++ /dev/null @@ -1,491 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading; -using System.Web; - -namespace NetCoreServer -{ - /// - /// File cache is used to cache files in memory with optional timeouts. - /// FileSystemWatcher is used to monitor file system changes in cached - /// directories. - /// - /// Thread-safe. - public class FileCache : IDisposable - { - public delegate bool InsertHandler(FileCache cache, string key, byte[] value, TimeSpan timeout); - - #region Cache items access - - /// - /// Is the file cache empty? - /// - public bool Empty => _entriesByKey.Count == 0; - - /// - /// Get the file cache size - /// - public int Size => _entriesByKey.Count; - - /// - /// Add a new cache value with the given timeout into the file cache - /// - /// Key to add - /// Value to add - /// Cache timeout (default is 0 - no timeout) - /// 'true' if the cache value was added, 'false' if the given key was not added - public bool Add(string key, byte[] value, TimeSpan timeout = new TimeSpan()) - { - using (new WriteLock(_lockEx)) - { - // Try to find and remove the previous key - _entriesByKey.Remove(key); - - // Update the cache entry - _entriesByKey.Add(key, new MemCacheEntry(value, timeout)); - - return true; - } - } - - /// - /// Try to find the cache value by the given key - /// - /// Key to find - /// 'true' and cache value if the cache value was found, 'false' if the given key was not found - public (bool, byte[]) Find(string key) - { - using (new ReadLock(_lockEx)) - { - // Try to find the given key - if (!_entriesByKey.TryGetValue(key, out var cacheValue)) - return (false, new byte[0]); - - return (true, cacheValue.Value); - } - } - - /// - /// Remove the cache value with the given key from the file cache - /// - /// Key to remove - /// 'true' if the cache value was removed, 'false' if the given key was not found - public bool Remove(string key) - { - using (new WriteLock(_lockEx)) - { - return _entriesByKey.Remove(key); - } - } - - #endregion - - #region Cache management methods - - /// - /// Insert a new cache path with the given timeout into the file cache - /// - /// Path to insert - /// Cache prefix (default is "/") - /// Cache filter (default is "*.*") - /// Cache timeout (default is 0 - no timeout) - /// Cache insert handler (default is 'return cache.Add(key, value, timeout)') - /// 'true' if the cache path was setup, 'false' if failed to setup the cache path - public bool InsertPath(string path, string prefix = "/", string filter = "*.*", TimeSpan timeout = new TimeSpan(), InsertHandler handler = null) - { - if (handler == null) - handler = (FileCache cache, string key, byte[] value, TimeSpan timespan) => cache.Add(key, value, timespan); - - // Try to find and remove the previous path - RemovePathInternal(path); - - using (new WriteLock(_lockEx)) - { - // Add the given path to the cache - _pathsByKey.Add(path, new FileCacheEntry(this, prefix, path, filter, handler, timeout)); - // Create entries by path map - _entriesByPath[path] = new HashSet(); - } - - // Insert the cache path - if (!InsertPathInternal(path, path, prefix, timeout, handler)) - return false; - - return true; - } - - /// - /// Try to find the cache path - /// - /// Path to find - /// 'true' if the cache path was found, 'false' if the given path was not found - public bool FindPath(string path) - { - using (new ReadLock(_lockEx)) - { - // Try to find the given key - return _pathsByKey.ContainsKey(path); - } - } - - /// - /// Remove the cache path from the file cache - /// - /// Path to remove - /// 'true' if the cache path was removed, 'false' if the given path was not found - public bool RemovePath(string path) - { - return RemovePathInternal(path); - } - - /// - /// Clear the memory cache - /// - public void Clear() - { - using (new WriteLock(_lockEx)) - { - // Stop all file system watchers - foreach (var fileCacheEntry in _pathsByKey) - fileCacheEntry.Value.StopWatcher(); - - // Clear all cache entries - _entriesByKey.Clear(); - _entriesByPath.Clear(); - _pathsByKey.Clear(); - } - } - - #endregion - - #region Cache implementation - - private readonly ReaderWriterLockSlim _lockEx = new ReaderWriterLockSlim(); - private Dictionary _entriesByKey = new Dictionary(); - private Dictionary> _entriesByPath = new Dictionary>(); - private Dictionary _pathsByKey = new Dictionary(); - - private class MemCacheEntry - { - private readonly byte[] _value; - private readonly TimeSpan _timespan; - - public byte[] Value => _value; - public TimeSpan Timespan => _timespan; - - public MemCacheEntry(byte[] value, TimeSpan timespan = new TimeSpan()) - { - _value = value; - _timespan = timespan; - } - - public MemCacheEntry(string value, TimeSpan timespan = new TimeSpan()) - { - _value = Encoding.UTF8.GetBytes(value); - _timespan = timespan; - } - }; - - private class FileCacheEntry - { - private readonly string _prefix; - private readonly string _path; - private readonly InsertHandler _handler; - private readonly TimeSpan _timespan; - private readonly FileSystemWatcher _watcher; - - public FileCacheEntry(FileCache cache, string prefix, string path, string filter, InsertHandler handler, TimeSpan timespan) - { - _prefix = prefix; - _path = path; - _handler = handler; - _timespan = timespan; - _watcher = new FileSystemWatcher(); - - // Start the filesystem watcher - StartWatcher(cache, path, filter); - } - private void StartWatcher(FileCache cache, string path, string filter) - { - FileCacheEntry entry = this; - - // Initialize a new filesystem watcher - _watcher.Created += (sender, e) => OnCreated(sender, e, cache, entry); - _watcher.Changed += (sender, e) => OnChanged(sender, e, cache, entry); - _watcher.Deleted += (sender, e) => OnDeleted(sender, e, cache, entry); - _watcher.Renamed += (sender, e) => OnRenamed(sender, e, cache, entry); - _watcher.Path = path; - _watcher.IncludeSubdirectories = true; - _watcher.Filter = filter; - _watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite; - _watcher.EnableRaisingEvents = true; - } - - public void StopWatcher() - { - _watcher.Dispose(); - } - - private static bool IsDirectory(string path) - { - try - { - // Skip directory updates - if (File.GetAttributes(path).HasFlag(FileAttributes.Directory)) - return true; - } - catch (Exception) {} - - return false; - } - - private static void OnCreated(object sender, FileSystemEventArgs e, FileCache cache, FileCacheEntry entry) - { - var key = e.FullPath.Replace(entry._path, entry._prefix); - var file = e.FullPath; - - // Skip missing files - if (!File.Exists(file)) - return; - // Skip directory updates - if (IsDirectory(file)) - return; - - cache.InsertFileInternal(entry._path, file, key, entry._timespan, entry._handler); - } - - private static void OnChanged(object sender, FileSystemEventArgs e, FileCache cache, FileCacheEntry entry) - { - if (e.ChangeType != WatcherChangeTypes.Changed) - return; - - var key = e.FullPath.Replace(entry._path, entry._prefix); - var file = e.FullPath; - - // Skip missing files - if (!File.Exists(file)) - return; - // Skip directory updates - if (IsDirectory(file)) - return; - - cache.InsertFileInternal(entry._path, file, key, entry._timespan, entry._handler); - } - - private static void OnDeleted(object sender, FileSystemEventArgs e, FileCache cache, FileCacheEntry entry) - { - var key = e.FullPath.Replace(entry._path, entry._prefix); - var file = e.FullPath; - - cache.RemoveFileInternal(entry._path, key); - } - - private static void OnRenamed(object sender, RenamedEventArgs e, FileCache cache, FileCacheEntry entry) - { - var oldKey = e.OldFullPath.Replace(entry._path, entry._prefix); - var oldFile = e.OldFullPath; - var newKey = e.FullPath.Replace(entry._path, entry._prefix); - var newFile = e.FullPath; - - // Skip missing files - if (!File.Exists(newFile)) - return; - // Skip directory updates - if (IsDirectory(newFile)) - return; - - cache.RemoveFileInternal(entry._path, oldKey); - cache.InsertFileInternal(entry._path, newFile, newKey, entry._timespan, entry._handler); - } - }; - - private bool InsertFileInternal(string path, string file, string key, TimeSpan timeout, InsertHandler handler) - { - try - { - key = key.Replace('\\', '/'); - file = file.Replace('\\', '/'); - - // Load the cache file content - var content = File.ReadAllBytes(file); - if (!handler(this, key, content, timeout)) - return false; - - using (new WriteLock(_lockEx)) - { - // Update entries by path map - _entriesByPath[path].Add(key); - } - - return true; - } - catch (Exception) { return false; } - } - - private bool RemoveFileInternal(string path, string key) - { - try - { - key = key.Replace('\\', '/'); - - using (new WriteLock(_lockEx)) - { - // Update entries by path map - _entriesByPath[path].Remove(key); - } - - return Remove(key); - } - catch (Exception) { return false; } - } - - private bool InsertPathInternal(string root, string path, string prefix, TimeSpan timeout, InsertHandler handler) - { - try - { - string keyPrefix = (string.IsNullOrEmpty(prefix) || (prefix == "/")) ? "/" : (prefix + "/"); - - // Iterate through all directory entries - foreach (var item in Directory.GetDirectories(path)) - { - string key = keyPrefix + Uri.UnescapeDataString(Path.GetFileName(item)); - - // Recursively insert sub-directory - if (!InsertPathInternal(root, item, key, timeout, handler)) - return false; - } - - foreach (var item in Directory.GetFiles(path)) - { - string key = keyPrefix + Uri.UnescapeDataString(Path.GetFileName(item)); - - // Insert file into the cache - if (!InsertFileInternal(root, item, key, timeout, handler)) - return false; - } - - return true; - } - catch (Exception) { return false; } - } - - private bool RemovePathInternal(string path) - { - using (new WriteLock(_lockEx)) - { - // Try to find the given path - if (!_pathsByKey.TryGetValue(path, out var cacheValue)) - return false; - - // Stop the file system watcher - cacheValue.StopWatcher(); - - // Remove path entries - foreach (var entryKey in _entriesByPath[path]) - _entriesByKey.Remove(entryKey); - _entriesByPath.Remove(path); - - // Remove cache path - _pathsByKey.Remove(path); - - return true; - } - } - - #endregion - - #region IDisposable implementation - - // Disposed flag. - private bool _disposed; - - // Implement IDisposable. - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposingManagedResources) - { - // The idea here is that Dispose(Boolean) knows whether it is - // being called to do explicit cleanup (the Boolean is true) - // versus being called due to a garbage collection (the Boolean - // is false). This distinction is useful because, when being - // disposed explicitly, the Dispose(Boolean) method can safely - // execute code using reference type fields that refer to other - // objects knowing for sure that these other objects have not been - // finalized or disposed of yet. When the Boolean is false, - // the Dispose(Boolean) method should not execute code that - // refer to reference type fields because those objects may - // have already been finalized." - - if (!_disposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - Clear(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - _disposed = true; - } - } - - // Use C# destructor syntax for finalization code. - ~FileCache() - { - // Simply call Dispose(false). - Dispose(false); - } - - #endregion - } - - /// - /// Disposable lock class performs exit action on dispose operation. - /// - public class DisposableLock : IDisposable - { - private readonly Action _exitLock; - - public DisposableLock(Action exitLock) - { - _exitLock = exitLock; - } - - public void Dispose() - { - _exitLock(); - } - } - - /// - /// Read lock class enters read lock on construction and performs exit read lock on dispose. - /// - public class ReadLock : DisposableLock - { - public ReadLock(ReaderWriterLockSlim locker) : base(locker.ExitReadLock) - { - locker.EnterReadLock(); - } - } - - /// - /// Write lock class enters write lock on construction and performs exit write lock on dispose. - /// - public class WriteLock : DisposableLock - { - public WriteLock(ReaderWriterLockSlim locker) : base(locker.ExitWriteLock) - { - locker.EnterWriteLock(); - } - } -} diff --git a/Plugins/NetCoreServer/FileCache.cs.meta b/Plugins/NetCoreServer/FileCache.cs.meta deleted file mode 100644 index 3cd2f263..00000000 --- a/Plugins/NetCoreServer/FileCache.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 714b67c4f5697394cae061193549efbb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/HttpClient.cs b/Plugins/NetCoreServer/HttpClient.cs deleted file mode 100644 index 4f0588be..00000000 --- a/Plugins/NetCoreServer/HttpClient.cs +++ /dev/null @@ -1,417 +0,0 @@ -using System; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace NetCoreServer -{ - /// - /// HTTP client is used to communicate with HTTP Web server. It allows to send GET, POST, PUT, DELETE requests and receive HTTP result. - /// - /// Thread-safe. - public class HttpClient : TcpClient - { - /// - /// Initialize HTTP client with a given IP address and port number - /// - /// IP address - /// Port number - public HttpClient(IPAddress address, int port) : base(address, port) { Request = new HttpRequest(); Response = new HttpResponse(); } - /// - /// Initialize HTTP client with a given IP address and port number - /// - /// IP address - /// Port number - public HttpClient(string address, int port) : base(address, port) { Request = new HttpRequest(); Response = new HttpResponse(); } - /// - /// Initialize HTTP client with a given IP endpoint - /// - /// IP endpoint - public HttpClient(IPEndPoint endpoint) : base(endpoint) { Request = new HttpRequest(); Response = new HttpResponse(); } - - /// - /// Get the HTTP request - /// - public HttpRequest Request { get; protected set; } - - /// - /// Get the HTTP response - /// - protected HttpResponse Response { get; set; } - - #region Send request / Send request body - - /// - /// Send the current HTTP request (synchronous) - /// - /// Size of sent data - public long SendRequest() { return SendRequest(Request); } - /// - /// Send the HTTP request (synchronous) - /// - /// HTTP request - /// Size of sent data - public long SendRequest(HttpRequest request) { return Send(request.Cache.Data, request.Cache.Offset, request.Cache.Size); } - - /// - /// Send the HTTP request body (synchronous) - /// - /// HTTP request body - /// Size of sent data - public long SendRequestBody(string body) { return Send(body); } - /// - /// Send the HTTP request body (synchronous) - /// - /// HTTP request body buffer - /// Size of sent data - public long SendRequestBody(byte[] buffer) { return Send(buffer); } - /// - /// Send the HTTP request body (synchronous) - /// - /// HTTP request body buffer - /// HTTP request body buffer offset - /// HTTP request body size - /// Size of sent data - public long SendRequestBody(byte[] buffer, long offset, long size) { return Send(buffer, offset, size); } - - /// - /// Send the current HTTP request (asynchronous) - /// - /// 'true' if the current HTTP request was successfully sent, 'false' if the session is not connected - public bool SendRequestAsync() { return SendRequestAsync(Request); } - /// - /// Send the HTTP request (asynchronous) - /// - /// HTTP request - /// 'true' if the current HTTP request was successfully sent, 'false' if the session is not connected - public bool SendRequestAsync(HttpRequest request) { return SendAsync(request.Cache.Data, request.Cache.Offset, request.Cache.Size); } - - /// - /// Send the HTTP request body (asynchronous) - /// - /// HTTP request body - /// 'true' if the HTTP request body was successfully sent, 'false' if the session is not connected - public bool SendRequestBodyAsync(string body) { return SendAsync(body); } - /// - /// Send the HTTP request body (asynchronous) - /// - /// HTTP request body buffer - /// 'true' if the HTTP request body was successfully sent, 'false' if the session is not connected - public bool SendRequestBodyAsync(byte[] buffer) { return SendAsync(buffer); } - /// - /// Send the HTTP request body (asynchronous) - /// - /// HTTP request body buffer - /// HTTP request body buffer offset - /// HTTP request body size - /// 'true' if the HTTP request body was successfully sent, 'false' if the session is not connected - public bool SendRequestBodyAsync(byte[] buffer, long offset, long size) { return SendAsync(buffer, offset, size); } - - #endregion - - #region Session handlers - - protected override void OnReceived(byte[] buffer, long offset, long size) - { - // Receive HTTP response header - if (Response.IsPendingHeader()) - { - if (Response.ReceiveHeader(buffer, (int)offset, (int)size)) - OnReceivedResponseHeader(Response); - - size = 0; - } - - // Check for HTTP response error - if (Response.IsErrorSet) - { - OnReceivedResponseError(Response, "Invalid HTTP response!"); - Response.Clear(); - Disconnect(); - return; - } - - // Receive HTTP response body - if (Response.ReceiveBody(buffer, (int)offset, (int)size)) - { - OnReceivedResponse(Response); - Response.Clear(); - return; - } - - // Check for HTTP response error - if (Response.IsErrorSet) - { - OnReceivedResponseError(Response, "Invalid HTTP response!"); - Response.Clear(); - Disconnect(); - return; - } - } - - protected override void OnDisconnected() - { - // Receive HTTP response body - if (Response.IsPendingBody()) - { - OnReceivedResponse(Response); - Response.Clear(); - return; - } - } - - /// - /// Handle HTTP response header received notification - /// - /// Notification is called when HTTP response header was received from the server. - /// HTTP request - protected virtual void OnReceivedResponseHeader(HttpResponse response) { } - - /// - /// Handle HTTP response received notification - /// - /// Notification is called when HTTP response was received from the server. - /// HTTP response - protected virtual void OnReceivedResponse(HttpResponse response) { } - - /// - /// Handle HTTP response error notification - /// - /// Notification is called when HTTP response error was received from the server. - /// HTTP response - /// HTTP response error - protected virtual void OnReceivedResponseError(HttpResponse response, string error) { } - - #endregion - } - - /// - /// HTTP extended client make requests to HTTP Web server with returning Task as a synchronization primitive. - /// - /// Thread-safe. - public class HttpClientEx : HttpClient - { - /// - /// Initialize HTTP client with a given IP address and port number - /// - /// IP address - /// Port number - public HttpClientEx(IPAddress address, int port) : base(address, port) {} - /// - /// Initialize HTTP client with a given IP address and port number - /// - /// IP address - /// Port number - public HttpClientEx(string address, int port) : base(address, port) {} - /// - /// Initialize HTTP client with a given IP endpoint - /// - /// IP endpoint - public HttpClientEx(IPEndPoint endpoint) : base(endpoint) {} - - #region Send request - - /// - /// Send current HTTP request - /// - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendRequest(TimeSpan? timeout = null) { return SendRequest(Request, timeout); } - /// - /// Send HTTP request - /// - /// HTTP request - /// HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendRequest(HttpRequest request, TimeSpan? timeout = null) - { - if (timeout == null) - timeout = TimeSpan.FromMinutes(1); - - _tcs = new TaskCompletionSource(); - Request = request; - - // Check if the HTTP request is valid - if (Request.IsEmpty || Request.IsErrorSet) - { - SetPromiseError("Invalid HTTP request!"); - return _tcs.Task; - } - - if (!IsConnected) - { - // Connect to the Web server - if (!ConnectAsync()) - { - SetPromiseError("Connection failed!"); - return _tcs.Task; - } - } - else - { - // Send prepared HTTP request - if (!SendRequestAsync()) - { - SetPromiseError("Failed to send HTTP request!"); - return _tcs.Task; - } - } - - void TimeoutHandler(object state) - { - // Disconnect on timeout - OnReceivedResponseError(Response, "Timeout!"); - Response.Clear(); - DisconnectAsync(); - } - - // Create a new timeout timer - if (_timer == null) - _timer = new Timer(TimeoutHandler, null, Timeout.Infinite, Timeout.Infinite); - - // Start the timeout timer - _timer.Change((int)timeout.Value.TotalMilliseconds, Timeout.Infinite); - - return _tcs.Task; - } - - /// - /// Send HEAD request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendHeadRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeHeadRequest(url), timeout); } - /// - /// Send GET request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendGetRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeGetRequest(url), timeout); } - /// - /// Send POST request - /// - /// URL to request - /// Content - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendPostRequest(string url, string content, TimeSpan? timeout = null) { return SendRequest(Request.MakePostRequest(url, content), timeout); } - /// - /// Send PUT request - /// - /// URL to request - /// Content - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendPutRequest(string url, string content, TimeSpan? timeout = null) { return SendRequest(Request.MakePutRequest(url, content), timeout); } - /// - /// Send DELETE request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendDeleteRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeDeleteRequest(url), timeout); } - /// - /// Send OPTIONS request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendOptionsRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeOptionsRequest(url), timeout); } - /// - /// Send TRACE request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendTraceRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeTraceRequest(url), timeout); } - - #endregion - - #region Session handlers - - protected override void OnConnected() - { - // Send prepared HTTP request on connect - if (!Request.IsEmpty && !Request.IsErrorSet) - if (!SendRequestAsync()) - SetPromiseError("Failed to send HTTP request!"); - } - - protected override void OnDisconnected() - { - // Cancel timeout check timer - _timer?.Change(Timeout.Infinite, Timeout.Infinite); - - base.OnDisconnected(); - } - - protected override void OnReceivedResponse(HttpResponse response) - { - // Cancel timeout check timer - _timer?.Change(Timeout.Infinite, Timeout.Infinite); - - SetPromiseValue(response); - } - - protected override void OnReceivedResponseError(HttpResponse response, string error) - { - // Cancel timeout check timer - _timer?.Change(Timeout.Infinite, Timeout.Infinite); - - SetPromiseError(error); - } - - #endregion - - private TaskCompletionSource _tcs = new TaskCompletionSource(); - private Timer _timer; - - private void SetPromiseValue(HttpResponse response) - { - Response = new HttpResponse(); - _tcs.SetResult(response); - Request.Clear(); - } - - private void SetPromiseError(string error) - { - _tcs.SetException(new Exception(error)); - Request.Clear(); - } - - #region IDisposable implementation - - // Disposed flag. - private bool _disposed; - - protected override void Dispose(bool disposingManagedResources) - { - if (!_disposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - _timer?.Dispose(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - _disposed = true; - } - - // Call Dispose in the base class. - base.Dispose(disposingManagedResources); - } - - // The derived class does not have a Finalize method - // or a Dispose method without parameters because it inherits - // them from the base class. - - #endregion - } -} diff --git a/Plugins/NetCoreServer/HttpClient.cs.meta b/Plugins/NetCoreServer/HttpClient.cs.meta deleted file mode 100644 index 2d73f4ed..00000000 --- a/Plugins/NetCoreServer/HttpClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cf8b0366e18758340bca8b210d3c542c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/HttpRequest.cs b/Plugins/NetCoreServer/HttpRequest.cs deleted file mode 100644 index 0636f888..00000000 --- a/Plugins/NetCoreServer/HttpRequest.cs +++ /dev/null @@ -1,849 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; - -namespace NetCoreServer -{ - /// - /// HTTP request is used to create or process parameters of HTTP protocol request(method, URL, headers, etc). - /// - /// Not thread-safe. - public class HttpRequest - { - /// - /// Initialize an empty HTTP request - /// - public HttpRequest() - { - Clear(); - } - /// - /// Initialize a new HTTP request with a given method, URL and protocol - /// - /// HTTP method - /// Requested URL - /// Protocol version (default is "HTTP/1.1") - public HttpRequest(string method, string url, string protocol = "HTTP/1.1") - { - SetBegin(method, url, protocol); - } - - /// - /// Is the HTTP request empty? - /// - public bool IsEmpty { get { return (_cache.Size == 0); } } - /// - /// Is the HTTP request error flag set? - /// - public bool IsErrorSet { get; private set; } - - /// - /// Get the HTTP request method - /// - public string Method { get { return _method; } } - /// - /// Get the HTTP request URL - /// - public string Url { get { return _url; } } - /// - /// Get the HTTP request protocol version - /// - public string Protocol { get { return _protocol; } } - /// - /// Get the HTTP request headers count - /// - public long Headers { get { return _headers.Count; } } - /// - /// Get the HTTP request header by index - /// - public (string, string) Header(int i) - { - Debug.Assert((i < _headers.Count), "Index out of bounds!"); - if (i >= _headers.Count) - return ("", ""); - - return _headers[i]; - } - /// - /// Get the HTTP request cookies count - /// - public long Cookies { get { return _cookies.Count; } } - /// - /// Get the HTTP request cookie by index - /// - public (string, string) Cookie(int i) - { - Debug.Assert((i < _cookies.Count), "Index out of bounds!"); - if (i >= _cookies.Count) - return ("", ""); - - return _cookies[i]; - } - /// - /// Get the HTTP request body as string - /// - public string Body { get { return _cache.ExtractString(_bodyIndex, _bodySize); } } - /// - /// Get the HTTP request body as byte array - /// - public byte[] BodyBytes - { - get - { - byte[] bodyBytes = new byte[_bodySize]; - Array.Copy(_cache.Data, _bodyIndex, bodyBytes, 0, _bodySize); - return bodyBytes; - } - } - /// - /// Get the HTTP request body as byte span - /// - public Span BodySpan { get { return new Span(_cache.Data, _bodyIndex, _bodySize); } } - /// - /// Get the HTTP request body length - /// - public long BodyLength { get { return _bodyLength; } } - - /// - /// Get the HTTP request cache content - /// - public Buffer Cache { get { return _cache; } } - - /// - /// Get string from the current HTTP request - /// - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine($"Request method: {Method}"); - sb.AppendLine($"Request URL: {Url}"); - sb.AppendLine($"Request protocol: {Protocol}"); - sb.AppendLine($"Request headers: {Headers}"); - for (int i = 0; i < Headers; i++) - { - var header = Header(i); - sb.AppendLine($"{header.Item1} : {header.Item2}"); - } - sb.AppendLine($"Request body: {BodyLength}"); - sb.AppendLine(Body); - return sb.ToString(); - } - - /// - /// Clear the HTTP request cache - /// - public HttpRequest Clear() - { - IsErrorSet = false; - _method = ""; - _url = ""; - _protocol = ""; - _headers.Clear(); - _cookies.Clear(); - _bodyIndex = 0; - _bodySize = 0; - _bodyLength = 0; - _bodyLengthProvided = false; - - _cache.Clear(); - _cacheSize = 0; - return this; - } - - /// - /// Set the HTTP request begin with a given method, URL and protocol - /// - /// HTTP method - /// Requested URL - /// Protocol version (default is "HTTP/1.1") - public HttpRequest SetBegin(string method, string url, string protocol = "HTTP/1.1") - { - // Clear the HTTP request cache - Clear(); - - // Append the HTTP request method - _cache.Append(method); - _method = method; - - _cache.Append(" "); - - // Append the HTTP request URL - _cache.Append(url); - _url = url; - - _cache.Append(" "); - - // Append the HTTP request protocol version - _cache.Append(protocol); - _protocol = protocol; - - _cache.Append("\r\n"); - return this; - } - - /// - /// Set the HTTP request header - /// - /// Header key - /// Header value - public HttpRequest SetHeader(string key, string value) - { - // Append the HTTP request header's key - _cache.Append(key); - - _cache.Append(": "); - - // Append the HTTP request header's value - _cache.Append(value); - - _cache.Append("\r\n"); - - // Add the header to the corresponding collection - _headers.Add((key, value)); - return this; - } - - /// - /// Set the HTTP request cookie - /// - /// Cookie name - /// Cookie value - public HttpRequest SetCookie(string name, string value) - { - string key = "Cookie"; - string cookie = name + "=" + value; - - // Append the HTTP request header's key - _cache.Append(key); - - _cache.Append(": "); - - // Append Cookie - _cache.Append(cookie); - - _cache.Append("\r\n"); - - // Add the header to the corresponding collection - _headers.Add((key, cookie)); - // Add the cookie to the corresponding collection - _cookies.Add((name, value)); - return this; - } - - /// - /// Add the HTTP request cookie - /// - /// Cookie name - /// Cookie value - public HttpRequest AddCookie(string name, string value) - { - // Append Cookie - _cache.Append("; "); - _cache.Append(name); - _cache.Append("="); - _cache.Append(value); - - // Add the cookie to the corresponding collection - _cookies.Add((name, value)); - return this; - } - - /// - /// Set the HTTP request body - /// - /// Body string content (default is "") - public HttpRequest SetBody(string body = "") - { - int length = string.IsNullOrEmpty(body) ? 0 : Encoding.UTF8.GetByteCount(body); - - // Append content length header - SetHeader("Content-Length", length.ToString()); - - _cache.Append("\r\n"); - - int index = (int)_cache.Size; - - // Append the HTTP request body - _cache.Append(body); - _bodyIndex = index; - _bodySize = length; - _bodyLength = length; - _bodyLengthProvided = true; - return this; - } - - /// - /// Set the HTTP request body - /// - /// Body binary content - public HttpRequest SetBody(byte[] body) - { - // Append content length header - SetHeader("Content-Length", body.Length.ToString()); - - _cache.Append("\r\n"); - - int index = (int)_cache.Size; - - // Append the HTTP request body - _cache.Append(body); - _bodyIndex = index; - _bodySize = body.Length; - _bodyLength = body.Length; - _bodyLengthProvided = true; - return this; - } - - /// - /// Set the HTTP request body - /// - /// Body buffer content - public HttpRequest SetBody(Buffer body) - { - // Append content length header - SetHeader("Content-Length", body.Size.ToString()); - - _cache.Append("\r\n"); - - int index = (int)_cache.Size; - - // Append the HTTP request body - _cache.Append(body.Data, body.Offset, body.Size); - _bodyIndex = index; - _bodySize = (int)body.Size; - _bodyLength = (int)body.Size; - _bodyLengthProvided = true; - return this; - } - - /// - /// Set the HTTP request body length - /// - /// Body length - public HttpRequest SetBodyLength(int length) - { - // Append content length header - SetHeader("Content-Length", length.ToString()); - - _cache.Append("\r\n"); - - int index = (int)_cache.Size; - - // Clear the HTTP request body - _bodyIndex = index; - _bodySize = 0; - _bodyLength = length; - _bodyLengthProvided = true; - return this; - } - - /// - /// Make HEAD request - /// - /// URL to request - public HttpRequest MakeHeadRequest(string url) - { - Clear(); - SetBegin("HEAD", url); - SetBody(); - return this; - } - - /// - /// Make GET request - /// - /// URL to request - public HttpRequest MakeGetRequest(string url) - { - Clear(); - SetBegin("GET", url); - SetBody(); - return this; - } - - /// - /// Make POST request - /// - /// URL to request - /// String content - /// Content type (default is "text/plain; charset=UTF-8") - public HttpRequest MakePostRequest(string url, string content, string contentType = "text/plain; charset=UTF-8") - { - Clear(); - SetBegin("POST", url); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make POST request - /// - /// URL to request - /// Binary content - /// Content type (default is "") - public HttpRequest MakePostRequest(string url, byte[] content, string contentType = "") - { - Clear(); - SetBegin("POST", url); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make POST request - /// - /// URL to request - /// Buffer content - /// Content type (default is "") - public HttpRequest MakePostRequest(string url, Buffer content, string contentType = "") - { - Clear(); - SetBegin("POST", url); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make PUT request - /// - /// URL to request - /// String content - /// Content type (default is "text/plain; charset=UTF-8") - public HttpRequest MakePutRequest(string url, string content, string contentType = "text/plain; charset=UTF-8") - { - Clear(); - SetBegin("PUT", url); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make PUT request - /// - /// URL to request - /// Binary content - /// Content type (default is "") - public HttpRequest MakePutRequest(string url, byte[] content, string contentType = "") - { - Clear(); - SetBegin("PUT", url); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make PUT request - /// - /// URL to request - /// Buffer content - /// Content type (default is "") - public HttpRequest MakePutRequest(string url, Buffer content, string contentType = "") - { - Clear(); - SetBegin("PUT", url); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make DELETE request - /// - /// URL to request - public HttpRequest MakeDeleteRequest(string url) - { - Clear(); - SetBegin("DELETE", url); - SetBody(); - return this; - } - - /// - /// Make OPTIONS request - /// - /// URL to request - public HttpRequest MakeOptionsRequest(string url) - { - Clear(); - SetBegin("OPTIONS", url); - SetBody(); - return this; - } - - /// - /// Make TRACE request - /// - /// URL to request - public HttpRequest MakeTraceRequest(string url) - { - Clear(); - SetBegin("TRACE", url); - SetBody(); - return this; - } - - // HTTP request method - private string _method; - // HTTP request URL - private string _url; - // HTTP request protocol - private string _protocol; - // HTTP request headers - private List<(string, string)> _headers = new List<(string, string)>(); - // HTTP request cookies - private List<(string, string)> _cookies = new List<(string, string)>(); - // HTTP request body - private int _bodyIndex; - private int _bodySize; - private int _bodyLength; - private bool _bodyLengthProvided; - - // HTTP request cache - private Buffer _cache = new Buffer(); - private int _cacheSize; - - // Is pending parts of HTTP request - internal bool IsPendingHeader() - { - return (!IsErrorSet && (_bodyIndex == 0)); - } - internal bool IsPendingBody() - { - return (!IsErrorSet && (_bodyIndex > 0) && (_bodySize > 0)); - } - - internal bool ReceiveHeader(byte[] buffer, int offset, int size) - { - // Update the request cache - _cache.Append(buffer, offset, size); - - // Try to seek for HTTP header separator - for (int i = _cacheSize; i < (int)_cache.Size; i++) - { - // Check for the request cache out of bounds - if ((i + 3) >= (int)_cache.Size) - break; - - // Check for the header separator - if ((_cache[i + 0] == '\r') && (_cache[i + 1] == '\n') && (_cache[i + 2] == '\r') && (_cache[i + 3] == '\n')) - { - int index = 0; - - // Set the error flag for a while... - IsErrorSet = true; - - // Parse method - int methodIndex = index; - int methodSize = 0; - while (_cache[index] != ' ') - { - methodSize++; - index++; - if (index >= (int)_cache.Size) - return false; - } - index++; - if (index >= (int)_cache.Size) - return false; - _method = _cache.ExtractString(methodIndex, methodSize); - - // Parse URL - int urlIndex = index; - int urlSize = 0; - while (_cache[index] != ' ') - { - urlSize++; - index++; - if (index >= (int)_cache.Size) - return false; - } - index++; - if (index >= (int)_cache.Size) - return false; - _url = _cache.ExtractString(urlIndex, urlSize); - - // Parse protocol version - int protocolIndex = index; - int protocolSize = 0; - while (_cache[index] != '\r') - { - protocolSize++; - index++; - if (index >= (int)_cache.Size) - return false; - } - index++; - if ((index >= (int)_cache.Size) || (_cache[index] != '\n')) - return false; - index++; - if (index >= (int)_cache.Size) - return false; - _protocol = _cache.ExtractString(protocolIndex, protocolSize); - - // Parse headers - while ((index < (int)_cache.Size) && (index < i)) - { - // Parse header name - int headerNameIndex = index; - int headerNameSize = 0; - while (_cache[index] != ':') - { - headerNameSize++; - index++; - if (index >= i) - break; - if (index >= (int)_cache.Size) - return false; - } - index++; - if (index >= i) - break; - if (index >= (int)_cache.Size) - return false; - - // Skip all prefix space characters - while (char.IsWhiteSpace((char)_cache[index])) - { - index++; - if (index >= i) - break; - if (index >= (int)_cache.Size) - return false; - } - - // Parse header value - int headerValueIndex = index; - int headerValueSize = 0; - while (_cache[index] != '\r') - { - headerValueSize++; - index++; - if (index >= i) - break; - if (index >= (int)_cache.Size) - return false; - } - index++; - if ((index >= (int)_cache.Size) || (_cache[index] != '\n')) - return false; - index++; - if (index >= (int)_cache.Size) - return false; - - // Validate header name and value (sometimes value can be empty) - if (headerNameSize == 0) - return false; - - // Add a new header - string headerName = _cache.ExtractString(headerNameIndex, headerNameSize); - string headerValue = _cache.ExtractString(headerValueIndex, headerValueSize); - _headers.Add((headerName, headerValue)); - - // Try to find the body content length - if (string.Compare(headerName, "Content-Length", StringComparison.OrdinalIgnoreCase) == 0) - { - _bodyLength = 0; - for (int j = headerValueIndex; j < (headerValueIndex + headerValueSize); j++) - { - if ((_cache[j] < '0') || (_cache[j] > '9')) - return false; - _bodyLength *= 10; - _bodyLength += _cache[j] - '0'; - _bodyLengthProvided = true; - } - } - - // Try to find Cookies - if (string.Compare(headerName, "Cookie", StringComparison.OrdinalIgnoreCase) == 0) - { - bool name = true; - bool token = false; - int current = headerValueIndex; - int nameIndex = index; - int nameSize = 0; - int cookieIndex = index; - int cookieSize = 0; - for (int j = headerValueIndex; j < (headerValueIndex + headerValueSize); j++) - { - if (_cache[j] == ' ') - { - if (token) - { - if (name) - { - nameIndex = current; - nameSize = j - current; - } - else - { - cookieIndex = current; - cookieSize = j - current; - } - } - token = false; - continue; - } - if (_cache[j] == '=') - { - if (token) - { - if (name) - { - nameIndex = current; - nameSize = j - current; - } - else - { - cookieIndex = current; - cookieSize = j - current; - } - } - token = false; - name = false; - continue; - } - if (_cache[j] == ';') - { - if (token) - { - if (name) - { - nameIndex = current; - nameSize = j - current; - } - else - { - cookieIndex = current; - cookieSize = j - current; - } - - // Validate the cookie - if ((nameSize > 0) && (cookieSize > 0)) - { - // Add the cookie to the corresponding collection - _cookies.Add((_cache.ExtractString(nameIndex, nameSize), _cache.ExtractString(cookieIndex, cookieSize))); - - // Resset the current cookie values - nameIndex = j; - nameSize = 0; - cookieIndex = j; - cookieSize = 0; - } - } - token = false; - name = true; - continue; - } - if (!token) - { - current = j; - token = true; - } - } - - // Process the last cookie - if (token) - { - if (name) - { - nameIndex = current; - nameSize = headerValueIndex + headerValueSize - current; - } - else - { - cookieIndex = current; - cookieSize = headerValueIndex + headerValueSize - current; - } - - // Validate the cookie - if ((nameSize > 0) && (cookieSize > 0)) - { - // Add the cookie to the corresponding collection - _cookies.Add((_cache.ExtractString(nameIndex, nameSize), _cache.ExtractString(cookieIndex, cookieSize))); - } - } - } - } - - // Reset the error flag - IsErrorSet = false; - - // Update the body index and size - _bodyIndex = i + 4; - _bodySize = (int)_cache.Size - i - 4; - - // Update the parsed cache size - _cacheSize = (int)_cache.Size; - - return true; - } - } - - // Update the parsed cache size - _cacheSize = ((int)_cache.Size >= 3) ? ((int)_cache.Size - 3) : 0; - - return false; - } - - internal bool ReceiveBody(byte[] buffer, int offset, int size) - { - // Update the request cache - _cache.Append(buffer, offset, size); - - // Update the parsed cache size - _cacheSize = (int)_cache.Size; - - // Update body size - _bodySize += size; - - // Check if the body length was provided - if (_bodyLengthProvided) - { - // Was the body fully received? - if (_bodySize >= _bodyLength) - { - _bodySize = _bodyLength; - return true; - } - } - else - { - // HEAD/GET/DELETE/OPTIONS/TRACE request might have no body - if ((Method == "HEAD") || (Method == "GET") || (Method == "DELETE") || (Method == "OPTIONS") || (Method == "TRACE")) - { - _bodyLength = 0; - _bodySize = 0; - return true; - } - - // Check the body content to find the request body end - if (_bodySize >= 4) - { - int index = _bodyIndex + _bodySize - 4; - - // Was the body fully received? - if ((_cache[index + 0] == '\r') && (_cache[index + 1] == '\n') && (_cache[index + 2] == '\r') && (_cache[index + 3] == '\n')) - { - _bodyLength = _bodySize; - return true; - } - } - } - - // Body was received partially... - return false; - } - } -} diff --git a/Plugins/NetCoreServer/HttpRequest.cs.meta b/Plugins/NetCoreServer/HttpRequest.cs.meta deleted file mode 100644 index 0c7dd786..00000000 --- a/Plugins/NetCoreServer/HttpRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9fba52dd0f76ae14db676148e0a34de9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/HttpResponse.cs b/Plugins/NetCoreServer/HttpResponse.cs deleted file mode 100644 index 0b5ece4b..00000000 --- a/Plugins/NetCoreServer/HttpResponse.cs +++ /dev/null @@ -1,945 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; - -namespace NetCoreServer -{ - /// - /// HTTP response is used to create or process parameters of HTTP protocol response(status, headers, etc). - /// - /// Not thread-safe. - public class HttpResponse - { - /// - /// Initialize an empty HTTP response - /// - public HttpResponse() - { - Clear(); - } - /// - /// Initialize a new HTTP response with a given status and protocol - /// - /// HTTP status - /// Protocol version (default is "HTTP/1.1") - public HttpResponse(int status, string protocol = "HTTP/1.1") - { - SetBegin(status, protocol); - } - /// - /// Initialize a new HTTP response with a given status, status phrase and protocol - /// - /// HTTP status - /// HTTP status phrase - /// Protocol version - public HttpResponse(int status, string statusPhrase, string protocol) - { - SetBegin(status, statusPhrase, protocol); - } - - /// - /// Is the HTTP response empty? - /// - public bool IsEmpty { get { return (_cache.Size > 0); } } - /// - /// Is the HTTP response error flag set? - /// - public bool IsErrorSet { get; private set; } - - /// - /// Get the HTTP response status - /// - public int Status { get; private set; } - - /// - /// Get the HTTP response status phrase - /// - public string StatusPhrase { get { return _statusPhrase; } } - /// - /// Get the HTTP response protocol version - /// - public string Protocol { get { return _protocol; } } - /// - /// Get the HTTP response headers count - /// - public long Headers { get { return _headers.Count; } } - /// - /// Get the HTTP response header by index - /// - public (string, string) Header(int i) - { - Debug.Assert((i < _headers.Count), "Index out of bounds!"); - if (i >= _headers.Count) - return ("", ""); - - return _headers[i]; - } - /// - /// Get the HTTP response body as string - /// - public string Body { get { return _cache.ExtractString(_bodyIndex, _bodySize); } } - /// - /// Get the HTTP request body as byte array - /// - public byte[] BodyBytes - { - get - { - byte[] bodyBytes = new byte[_bodySize]; - Array.Copy(_cache.Data, _bodyIndex, bodyBytes, 0, _bodySize); - return bodyBytes; - } - } - /// - /// Get the HTTP request body as read-only byte span - /// - public ReadOnlySpan BodySpan { get { return new ReadOnlySpan(_cache.Data, _bodyIndex, _bodySize); } } - /// - /// Get the HTTP response body length - /// - public long BodyLength { get { return _bodyLength; } } - - /// - /// Get the HTTP response cache content - /// - public Buffer Cache { get { return _cache; } } - - /// - /// Get string from the current HTTP response - /// - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine($"Status: {Status}"); - sb.AppendLine($"Status phrase: {StatusPhrase}"); - sb.AppendLine($"Protocol: {Protocol}"); - sb.AppendLine($"Headers: {Headers}"); - for (int i = 0; i < Headers; i++) - { - var header = Header(i); - sb.AppendLine($"{header.Item1} : {header.Item2}"); - } - sb.AppendLine($"Body: {BodyLength}"); - sb.AppendLine(Body); - return sb.ToString(); - } - - /// - /// Clear the HTTP response cache - /// - public HttpResponse Clear() - { - IsErrorSet = false; - Status = 0; - _statusPhrase = ""; - _protocol = ""; - _headers.Clear(); - _bodyIndex = 0; - _bodySize = 0; - _bodyLength = 0; - _bodyLengthProvided = false; - - _cache.Clear(); - _cacheSize = 0; - return this; - } - - /// - /// Set the HTTP response begin with a given status and protocol - /// - /// HTTP status - /// Protocol version (default is "HTTP/1.1") - public HttpResponse SetBegin(int status, string protocol = "HTTP/1.1") - { - string statusPhrase; - - switch (status) - { - case 100: statusPhrase = "Continue"; break; - case 101: statusPhrase = "Switching Protocols"; break; - case 102: statusPhrase = "Processing"; break; - case 103: statusPhrase = "Early Hints"; break; - - case 200: statusPhrase = "OK"; break; - case 201: statusPhrase = "Created"; break; - case 202: statusPhrase = "Accepted"; break; - case 203: statusPhrase = "Non-Authoritative Information"; break; - case 204: statusPhrase = "No Content"; break; - case 205: statusPhrase = "Reset Content"; break; - case 206: statusPhrase = "Partial Content"; break; - case 207: statusPhrase = "Multi-Status"; break; - case 208: statusPhrase = "Already Reported"; break; - - case 226: statusPhrase = "IM Used"; break; - - case 300: statusPhrase = "Multiple Choices"; break; - case 301: statusPhrase = "Moved Permanently"; break; - case 302: statusPhrase = "Found"; break; - case 303: statusPhrase = "See Other"; break; - case 304: statusPhrase = "Not Modified"; break; - case 305: statusPhrase = "Use Proxy"; break; - case 306: statusPhrase = "Switch Proxy"; break; - case 307: statusPhrase = "Temporary Redirect"; break; - case 308: statusPhrase = "Permanent Redirect"; break; - - case 400: statusPhrase = "Bad Request"; break; - case 401: statusPhrase = "Unauthorized"; break; - case 402: statusPhrase = "Payment Required"; break; - case 403: statusPhrase = "Forbidden"; break; - case 404: statusPhrase = "Not Found"; break; - case 405: statusPhrase = "Method Not Allowed"; break; - case 406: statusPhrase = "Not Acceptable"; break; - case 407: statusPhrase = "Proxy Authentication Required"; break; - case 408: statusPhrase = "Request Timeout"; break; - case 409: statusPhrase = "Conflict"; break; - case 410: statusPhrase = "Gone"; break; - case 411: statusPhrase = "Length Required"; break; - case 412: statusPhrase = "Precondition Failed"; break; - case 413: statusPhrase = "Payload Too Large"; break; - case 414: statusPhrase = "URI Too Long"; break; - case 415: statusPhrase = "Unsupported Media Type"; break; - case 416: statusPhrase = "Range Not Satisfiable"; break; - case 417: statusPhrase = "Expectation Failed"; break; - - case 421: statusPhrase = "Misdirected Request"; break; - case 422: statusPhrase = "Unprocessable Entity"; break; - case 423: statusPhrase = "Locked"; break; - case 424: statusPhrase = "Failed Dependency"; break; - case 425: statusPhrase = "Too Early"; break; - case 426: statusPhrase = "Upgrade Required"; break; - case 427: statusPhrase = "Unassigned"; break; - case 428: statusPhrase = "Precondition Required"; break; - case 429: statusPhrase = "Too Many Requests"; break; - case 431: statusPhrase = "Request Header Fields Too Large"; break; - - case 451: statusPhrase = "Unavailable For Legal Reasons"; break; - - case 500: statusPhrase = "Internal Server Error"; break; - case 501: statusPhrase = "Not Implemented"; break; - case 502: statusPhrase = "Bad Gateway"; break; - case 503: statusPhrase = "Service Unavailable"; break; - case 504: statusPhrase = "Gateway Timeout"; break; - case 505: statusPhrase = "HTTP Version Not Supported"; break; - case 506: statusPhrase = "Variant Also Negotiates"; break; - case 507: statusPhrase = "Insufficient Storage"; break; - case 508: statusPhrase = "Loop Detected"; break; - - case 510: statusPhrase = "Not Extended"; break; - case 511: statusPhrase = "Network Authentication Required"; break; - - default: statusPhrase = "Unknown"; break; - } - - SetBegin(status, statusPhrase, protocol); - return this; - } - - /// - /// Set the HTTP response begin with a given status, status phrase and protocol - /// - /// HTTP status - /// HTTP status phrase - /// Protocol version - public HttpResponse SetBegin(int status, string statusPhrase, string protocol) - { - // Clear the HTTP response cache - Clear(); - - // Append the HTTP response protocol version - _cache.Append(protocol); - _protocol = protocol; - - _cache.Append(" "); - - // Append the HTTP response status - _cache.Append(status.ToString()); - Status = status; - - _cache.Append(" "); - - // Append the HTTP response status phrase - _cache.Append(statusPhrase); - _statusPhrase = statusPhrase; - - _cache.Append("\r\n"); - return this; - } - - /// - /// Set the HTTP response content type - /// - /// Content extension - public HttpResponse SetContentType(string extension) - { - // Base content types - if (extension == ".html") - return SetHeader("Content-Type", "text/html"); - else if (extension == ".css") - return SetHeader("Content-Type", "text/css"); - else if (extension == ".js") - return SetHeader("Content-Type", "text/javascript"); - else if (extension == ".xml") - return SetHeader("Content-Type", "text/xml"); - - // Common content types - if (extension == ".gzip") - return SetHeader("Content-Type", "application/gzip"); - else if (extension == ".json") - return SetHeader("Content-Type", "application/json"); - else if (extension == ".map") - return SetHeader("Content-Type", "application/json"); - else if (extension == ".pdf") - return SetHeader("Content-Type", "application/pdf"); - else if (extension == ".zip") - return SetHeader("Content-Type", "application/zip"); - else if (extension == ".mp3") - return SetHeader("Content-Type", "audio/mpeg"); - else if (extension == ".jpg") - return SetHeader("Content-Type", "image/jpeg"); - else if (extension == ".gif") - return SetHeader("Content-Type", "image/gif"); - else if (extension == ".png") - return SetHeader("Content-Type", "image/png"); - else if (extension == ".svg") - return SetHeader("Content-Type", "image/svg+xml"); - else if (extension == ".mp4") - return SetHeader("Content-Type", "video/mp4"); - - // Application content types - if (extension == ".atom") - return SetHeader("Content-Type", "application/atom+xml"); - else if (extension == ".fastsoap") - return SetHeader("Content-Type", "application/fastsoap"); - else if (extension == ".ps") - return SetHeader("Content-Type", "application/postscript"); - else if (extension == ".soap") - return SetHeader("Content-Type", "application/soap+xml"); - else if (extension == ".sql") - return SetHeader("Content-Type", "application/sql"); - else if (extension == ".xslt") - return SetHeader("Content-Type", "application/xslt+xml"); - else if (extension == ".zlib") - return SetHeader("Content-Type", "application/zlib"); - - // Audio content types - if (extension == ".aac") - return SetHeader("Content-Type", "audio/aac"); - else if (extension == ".ac3") - return SetHeader("Content-Type", "audio/ac3"); - else if (extension == ".ogg") - return SetHeader("Content-Type", "audio/ogg"); - - // Font content types - if (extension == ".ttf") - return SetHeader("Content-Type", "font/ttf"); - - // Image content types - if (extension == ".bmp") - return SetHeader("Content-Type", "image/bmp"); - else if (extension == ".jpm") - return SetHeader("Content-Type", "image/jpm"); - else if (extension == ".jpx") - return SetHeader("Content-Type", "image/jpx"); - else if (extension == ".jrx") - return SetHeader("Content-Type", "image/jrx"); - else if (extension == ".tiff") - return SetHeader("Content-Type", "image/tiff"); - else if (extension == ".emf") - return SetHeader("Content-Type", "image/emf"); - else if (extension == ".wmf") - return SetHeader("Content-Type", "image/wmf"); - - // Message content types - if (extension == ".http") - return SetHeader("Content-Type", "message/http"); - else if (extension == ".s-http") - return SetHeader("Content-Type", "message/s-http"); - - // Model content types - if (extension == ".mesh") - return SetHeader("Content-Type", "model/mesh"); - else if (extension == ".vrml") - return SetHeader("Content-Type", "model/vrml"); - - // Text content types - if (extension == ".csv") - return SetHeader("Content-Type", "text/csv"); - else if (extension == ".plain") - return SetHeader("Content-Type", "text/plain"); - else if (extension == ".richtext") - return SetHeader("Content-Type", "text/richtext"); - else if (extension == ".rtf") - return SetHeader("Content-Type", "text/rtf"); - else if (extension == ".rtx") - return SetHeader("Content-Type", "text/rtx"); - else if (extension == ".sgml") - return SetHeader("Content-Type", "text/sgml"); - else if (extension == ".strings") - return SetHeader("Content-Type", "text/strings"); - else if (extension == ".url") - return SetHeader("Content-Type", "text/uri-list"); - - // Video content types - if (extension == ".H264") - return SetHeader("Content-Type", "video/H264"); - else if (extension == ".H265") - return SetHeader("Content-Type", "video/H265"); - else if (extension == ".mpeg") - return SetHeader("Content-Type", "video/mpeg"); - else if (extension == ".raw") - return SetHeader("Content-Type", "video/raw"); - - return this; - } - - /// - /// Set the HTTP response header - /// - /// Header key - /// Header value - public HttpResponse SetHeader(string key, string value) - { - // Append the HTTP response header's key - _cache.Append(key); - - _cache.Append(": "); - - // Append the HTTP response header's value - _cache.Append(value); - - _cache.Append("\r\n"); - - // Add the header to the corresponding collection - _headers.Add((key, value)); - return this; - } - - /// - /// Set the HTTP response cookie - /// - /// Cookie name - /// Cookie value - /// Cookie age in seconds until it expires (default is 86400) - /// Cookie path (default is "") - /// Cookie domain (default is "") - /// Cookie secure flag (default is true) - /// Cookie HTTP-only flag (default is false) - public HttpResponse SetCookie(string name, string value, int maxAge = 86400, string path = "", string domain = "", bool secure = true, bool httpOnly = false) - { - string key = "Set-Cookie"; - - // Append the HTTP response header's key - _cache.Append(key); - - _cache.Append(": "); - - // Append the HTTP response header's value - int valueIndex = (int)_cache.Size; - - // Append cookie - _cache.Append(name); - _cache.Append("="); - _cache.Append(value); - _cache.Append("; Max-Age="); - _cache.Append(maxAge.ToString()); - if (!string.IsNullOrEmpty(domain)) - { - _cache.Append("; Domain="); - _cache.Append(domain); - } - if (!string.IsNullOrEmpty(path)) - { - _cache.Append("; Path="); - _cache.Append(path); - } - if (secure) - _cache.Append("; Secure"); - if (httpOnly) - _cache.Append("; HttpOnly"); - - int valueSize = (int)_cache.Size - valueIndex; - - string cookie = _cache.ExtractString(valueIndex, valueSize); - - _cache.Append("\r\n"); - - // Add the header to the corresponding collection - _headers.Add((key, cookie)); - return this; - } - - /// - /// Set the HTTP response body - /// - /// Body string content (default is "") - public HttpResponse SetBody(string body = "") - { - int length = string.IsNullOrEmpty(body) ? 0 : Encoding.UTF8.GetByteCount(body); - - // Append content length header - SetHeader("Content-Length", length.ToString()); - - _cache.Append("\r\n"); - - int index = (int)_cache.Size; - - // Append the HTTP response body - _cache.Append(body); - _bodyIndex = index; - _bodySize = length; - _bodyLength = length; - _bodyLengthProvided = true; - return this; - } - - /// - /// Set the HTTP response body - /// - /// Body binary content - public HttpResponse SetBody(byte[] body) - { - // Append content length header - SetHeader("Content-Length", body.Length.ToString()); - - _cache.Append("\r\n"); - - int index = (int)_cache.Size; - - // Append the HTTP response body - _cache.Append(body); - _bodyIndex = index; - _bodySize = body.Length; - _bodyLength = body.Length; - _bodyLengthProvided = true; - return this; - } - - /// - /// Set the HTTP response body - /// - /// Body buffer content - public HttpResponse SetBody(Buffer body) - { - // Append content length header - SetHeader("Content-Length", body.Size.ToString()); - - _cache.Append("\r\n"); - - int index = (int)_cache.Size; - - // Append the HTTP response body - _cache.Append(body.Data, body.Offset, body.Size); - _bodyIndex = index; - _bodySize = (int)body.Size; - _bodyLength = (int)body.Size; - _bodyLengthProvided = true; - return this; - } - - /// - /// Set the HTTP response body length - /// - /// Body length - public HttpResponse SetBodyLength(int length) - { - // Append content length header - SetHeader("Content-Length", length.ToString()); - - _cache.Append("\r\n"); - - int index = (int)_cache.Size; - - // Clear the HTTP response body - _bodyIndex = index; - _bodySize = 0; - _bodyLength = length; - _bodyLengthProvided = true; - return this; - } - - /// - /// Make OK response - /// - /// OK status (default is 200 (OK)) - public HttpResponse MakeOkResponse(int status = 200) - { - Clear(); - SetBegin(status); - SetBody(); - return this; - } - - /// - /// Make ERROR response - /// - /// Error content (default is "") - /// Error content type (default is "text/plain; charset=UTF-8") - public HttpResponse MakeErrorResponse(string content = "", string contentType = "text/plain; charset=UTF-8") - { - return MakeErrorResponse(500, content, contentType); - } - - /// - /// Make ERROR response - /// - /// Error status - /// Error content (default is "") - /// Error content type (default is "text/plain; charset=UTF-8") - public HttpResponse MakeErrorResponse(int status, string content = "", string contentType = "text/plain; charset=UTF-8") - { - Clear(); - SetBegin(status); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make HEAD response - /// - public HttpResponse MakeHeadResponse() - { - Clear(); - SetBegin(200); - SetBody(); - return this; - } - - /// - /// Make GET response - /// - /// String content (default is "") - /// Content type (default is "text/plain; charset=UTF-8") - public HttpResponse MakeGetResponse(string content = "", string contentType = "text/plain; charset=UTF-8") - { - Clear(); - SetBegin(200); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make GET response - /// - /// String content - /// Content type (default is "") - public HttpResponse MakeGetResponse(byte[] content, string contentType = "") - { - Clear(); - SetBegin(200); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make GET response - /// - /// String content - /// Content type (default is "") - public HttpResponse MakeGetResponse(Buffer content, string contentType = "") - { - Clear(); - SetBegin(200); - if (!string.IsNullOrEmpty(contentType)) - SetHeader("Content-Type", contentType); - SetBody(content); - return this; - } - - /// - /// Make OPTIONS response - /// - /// Allow methods (default is "HEAD,GET,POST,PUT,DELETE,OPTIONS,TRACE") - public HttpResponse MakeOptionsResponse(string allow = "HEAD,GET,POST,PUT,DELETE,OPTIONS,TRACE") - { - Clear(); - SetBegin(200); - SetHeader("Allow", allow); - SetBody(); - return this; - } - - /// - /// Make TRACE response - /// - /// Request string content - public HttpResponse MakeTraceResponse(string request) - { - Clear(); - SetBegin(200); - SetHeader("Content-Type", "message/http"); - SetBody(request); - return this; - } - - /// - /// Make TRACE response - /// - /// Request binary content - public HttpResponse MakeTraceResponse(byte[] request) - { - Clear(); - SetBegin(200); - SetHeader("Content-Type", "message/http"); - SetBody(request); - return this; - } - - /// - /// Make TRACE response - /// - /// Request buffer content - public HttpResponse MakeTraceResponse(Buffer request) - { - Clear(); - SetBegin(200); - SetHeader("Content-Type", "message/http"); - SetBody(request); - return this; - } - - // HTTP response status phrase - private string _statusPhrase; - // HTTP response protocol - private string _protocol; - // HTTP response headers - private List<(string, string)> _headers = new List<(string, string)>(); - // HTTP response body - private int _bodyIndex; - private int _bodySize; - private int _bodyLength; - private bool _bodyLengthProvided; - - // HTTP response cache - private Buffer _cache = new Buffer(); - private int _cacheSize; - - // Is pending parts of HTTP response - internal bool IsPendingHeader() - { - return (!IsErrorSet && (_bodyIndex == 0)); - } - internal bool IsPendingBody() - { - return (!IsErrorSet && (_bodyIndex > 0) && (_bodySize > 0)); - } - - // Receive parts of HTTP response - internal bool ReceiveHeader(byte[] buffer, int offset, int size) - { - // Update the request cache - _cache.Append(buffer, offset, size); - - // Try to seek for HTTP header separator - for (int i = _cacheSize; i < (int)_cache.Size; i++) - { - // Check for the request cache out of bounds - if ((i + 3) >= (int)_cache.Size) - break; - - // Check for the header separator - if ((_cache[i + 0] == '\r') && (_cache[i + 1] == '\n') && (_cache[i + 2] == '\r') && (_cache[i + 3] == '\n')) - { - int index = 0; - - // Set the error flag for a while... - IsErrorSet = true; - - // Parse protocol version - int protocolIndex = index; - int protocolSize = 0; - while (_cache[index] != ' ') - { - protocolSize++; - index++; - if (index >= (int)_cache.Size) - return false; - } - index++; - if ((index >= (int)_cache.Size)) - return false; - _protocol = _cache.ExtractString(protocolIndex, protocolSize); - - // Parse status code - int statusIndex = index; - int statusSize = 0; - while (_cache[index] != ' ') - { - if ((_cache[index] < '0') || (_cache[index] > '9')) - return false; - statusSize++; - index++; - if (index >= (int)_cache.Size) - return false; - } - Status = 0; - for (int j = statusIndex; j < (statusIndex + statusSize); j++) - { - Status *= 10; - Status += _cache[j] - '0'; - } - index++; - if (index >= (int)_cache.Size) - return false; - - // Parse status phrase - int statusPhraseIndex = index; - int statusPhraseSize = 0; - while (_cache[index] != '\r') - { - statusPhraseSize++; - index++; - if (index >= (int)_cache.Size) - return false; - } - index++; - if ((index >= (int)_cache.Size) || (_cache[index] != '\n')) - return false; - index++; - if (index >= (int)_cache.Size) - return false; - _statusPhrase = _cache.ExtractString(statusPhraseIndex, statusPhraseSize); - - // Parse headers - while ((index < (int)_cache.Size) && (index < i)) - { - // Parse header name - int headerNameIndex = index; - int headerNameSize = 0; - while (_cache[index] != ':') - { - headerNameSize++; - index++; - if (index >= i) - break; - if (index >= (int)_cache.Size) - return false; - } - index++; - if (index >= i) - break; - if (index >= (int)_cache.Size) - return false; - - // Skip all prefix space characters - while (char.IsWhiteSpace((char)_cache[index])) - { - index++; - if (index >= i) - break; - if (index >= (int)_cache.Size) - return false; - } - - // Parse header value - int headerValueIndex = index; - int headerValueSize = 0; - while (_cache[index] != '\r') - { - headerValueSize++; - index++; - if (index >= i) - break; - if (index >= (int)_cache.Size) - return false; - } - index++; - if ((index >= (int)_cache.Size) || (_cache[index] != '\n')) - return false; - index++; - if (index >= (int)_cache.Size) - return false; - - // Validate header name and value (sometimes value can be empty) - if (headerNameSize == 0) - return false; - - // Add a new header - string headerName = _cache.ExtractString(headerNameIndex, headerNameSize); - string headerValue = _cache.ExtractString(headerValueIndex, headerValueSize); - _headers.Add((headerName, headerValue)); - - // Try to find the body content length - if (string.Compare(headerName, "Content-Length", StringComparison.OrdinalIgnoreCase) == 0) - { - _bodyLength = 0; - for (int j = headerValueIndex; j < (headerValueIndex + headerValueSize); j++) - { - if ((_cache[j] < '0') || (_cache[j] > '9')) - return false; - _bodyLength *= 10; - _bodyLength += _cache[j] - '0'; - _bodyLengthProvided = true; - } - } - } - - // Reset the error flag - IsErrorSet = false; - - // Update the body index and size - _bodyIndex = i + 4; - _bodySize = (int)_cache.Size - i - 4; - - // Update the parsed cache size - _cacheSize = (int)_cache.Size; - - return true; - } - } - - // Update the parsed cache size - _cacheSize = ((int)_cache.Size >= 3) ? ((int)_cache.Size - 3) : 0; - - return false; - } - - internal bool ReceiveBody(byte[] buffer, int offset, int size) - { - // Update the request cache - _cache.Append(buffer, offset, size); - - // Update the parsed cache size - _cacheSize = (int)_cache.Size; - - // Update body size - _bodySize += size; - - // Check if the body length was provided - if (_bodyLengthProvided) - { - // Was the body fully received? - if (_bodySize >= _bodyLength) - { - _bodySize = _bodyLength; - return true; - } - } - else - { - // Check the body content to find the response body end - if (_bodySize >= 4) - { - int index = _bodyIndex + _bodySize - 4; - - // Was the body fully received? - if ((_cache[index + 0] == '\r') && (_cache[index + 1] == '\n') && (_cache[index + 2] == '\r') && - (_cache[index + 3] == '\n')) - { - _bodyLength = _bodySize; - return true; - } - } - } - - // Body was received partially... - return false; - } - } -} diff --git a/Plugins/NetCoreServer/HttpResponse.cs.meta b/Plugins/NetCoreServer/HttpResponse.cs.meta deleted file mode 100644 index 334444bb..00000000 --- a/Plugins/NetCoreServer/HttpResponse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 96de6f914e3006e4b98c548ed8afc777 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/HttpServer.cs b/Plugins/NetCoreServer/HttpServer.cs deleted file mode 100644 index acc40835..00000000 --- a/Plugins/NetCoreServer/HttpServer.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.Net; -using System.IO; - -namespace NetCoreServer -{ - /// - /// HTTP server is used to create HTTP Web server and communicate with clients using HTTP protocol. It allows to receive GET, POST, PUT, DELETE requests and send HTTP responses. - /// - /// Thread-safe. - public class HttpServer : TcpServer - { - /// - /// Initialize HTTP server with a given IP address and port number - /// - /// IP address - /// Port number - public HttpServer(IPAddress address, int port) : base(address, port) { Cache = new FileCache(); } - /// - /// Initialize HTTP server with a given IP address and port number - /// - /// IP address - /// Port number - public HttpServer(string address, int port) : base(address, port) { Cache = new FileCache(); } - /// - /// Initialize HTTP server with a given IP endpoint - /// - /// IP endpoint - public HttpServer(IPEndPoint endpoint) : base(endpoint) { Cache = new FileCache(); } - - /// - /// Get the static content cache - /// - public FileCache Cache { get; } - - /// - /// Add static content cache - /// - /// Static content path - /// Cache prefix (default is "/") - /// Cache filter (default is "*.*") - /// Refresh cache timeout (default is 1 hour) - public void AddStaticContent(string path, string prefix = "/", string filter = "*.*", TimeSpan? timeout = null) - { - if (timeout == null) - timeout = TimeSpan.FromHours(1); - - bool Handler(FileCache cache, string key, byte[] value, TimeSpan timespan) - { - HttpResponse header = new HttpResponse(); - header.SetBegin(200); - header.SetContentType(Path.GetExtension(key)); - header.SetHeader("Cache-Control", $"max-age={timespan.Seconds}"); - header.SetBody(value); - return cache.Add(key, header.Cache.Data, timespan); - } - - Cache.InsertPath(path, prefix, filter, timeout.Value, Handler); - } - /// - /// Remove static content cache - /// - /// Static content path - public void RemoveStaticContent(string path) { Cache.RemovePath(path); } - /// - /// Clear static content cache - /// - public void ClearStaticContent() { Cache.Clear(); } - - protected override TcpSession CreateSession() { return new HttpSession(this); } - - #region IDisposable implementation - - // Disposed flag. - private bool _disposed; - - protected override void Dispose(bool disposingManagedResources) - { - if (!_disposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - Cache.Dispose(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - _disposed = true; - } - - // Call Dispose in the base class. - base.Dispose(disposingManagedResources); - } - - // The derived class does not have a Finalize method - // or a Dispose method without parameters because it inherits - // them from the base class. - - #endregion - } -} diff --git a/Plugins/NetCoreServer/HttpServer.cs.meta b/Plugins/NetCoreServer/HttpServer.cs.meta deleted file mode 100644 index 0f22b327..00000000 --- a/Plugins/NetCoreServer/HttpServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f3d24e18fb34517469c02c48c996ac13 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/HttpSession.cs b/Plugins/NetCoreServer/HttpSession.cs deleted file mode 100644 index 734ae2f1..00000000 --- a/Plugins/NetCoreServer/HttpSession.cs +++ /dev/null @@ -1,193 +0,0 @@ -namespace NetCoreServer -{ - /// - /// HTTP session is used to receive/send HTTP requests/responses from the connected HTTP client. - /// - /// Thread-safe. - public class HttpSession : TcpSession - { - public HttpSession(HttpServer server) : base(server) - { - Cache = server.Cache; - Request = new HttpRequest(); - Response = new HttpResponse(); - } - - /// - /// Get the static content cache - /// - public FileCache Cache { get; } - - /// - /// Get the HTTP request - /// - protected HttpRequest Request { get; } - - /// - /// Get the HTTP response - /// - public HttpResponse Response { get; } - - #region Send response / Send response body - - /// - /// Send the current HTTP response (synchronous) - /// - /// Size of sent data - public long SendResponse() { return SendResponse(Response); } - /// - /// Send the HTTP response (synchronous) - /// - /// HTTP response - /// Size of sent data - public long SendResponse(HttpResponse response) { return Send(response.Cache.Data, response.Cache.Offset, response.Cache.Size); } - - /// - /// Send the HTTP response body (synchronous) - /// - /// HTTP response body - /// Size of sent data - public long SendResponseBody(string body) { return Send(body); } - /// - /// Send the HTTP response body (synchronous) - /// - /// HTTP response body buffer - /// Size of sent data - public long SendResponseBody(byte[] buffer) { return Send(buffer); } - /// - /// Send the HTTP response body (synchronous) - /// - /// HTTP response body buffer - /// HTTP response body buffer offset - /// HTTP response body size - /// Size of sent data - public long SendResponseBody(byte[] buffer, long offset, long size) { return Send(buffer, offset, size); } - - /// - /// Send the current HTTP response (asynchronous) - /// - /// 'true' if the current HTTP response was successfully sent, 'false' if the session is not connected - public bool SendResponseAsync() { return SendResponseAsync(Response); } - /// - /// Send the HTTP response (asynchronous) - /// - /// HTTP response - /// 'true' if the current HTTP response was successfully sent, 'false' if the session is not connected - public bool SendResponseAsync(HttpResponse response) { return SendAsync(response.Cache.Data, response.Cache.Offset, response.Cache.Size); } - - /// - /// Send the HTTP response body (asynchronous) - /// - /// HTTP response body - /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected - public bool SendResponseBodyAsync(string body) { return SendAsync(body); } - /// - /// Send the HTTP response body (asynchronous) - /// - /// HTTP response body buffer - /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected - public bool SendResponseBodyAsync(byte[] buffer) { return SendAsync(buffer); } - /// - /// Send the HTTP response body (asynchronous) - /// - /// HTTP response body buffer - /// HTTP response body buffer offset - /// HTTP response body size - /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected - public bool SendResponseBodyAsync(byte[] buffer, long offset, long size) { return SendAsync(buffer, offset, size); } - - #endregion - - #region Session handlers - - protected override void OnReceived(byte[] buffer, long offset, long size) - { - // Receive HTTP request header - if (Request.IsPendingHeader()) - { - if (Request.ReceiveHeader(buffer, (int)offset, (int)size)) - OnReceivedRequestHeader(Request); - - size = 0; - } - - // Check for HTTP request error - if (Request.IsErrorSet) - { - OnReceivedRequestError(Request, "Invalid HTTP request!"); - Request.Clear(); - Disconnect(); - return; - } - - // Receive HTTP request body - if (Request.ReceiveBody(buffer, (int)offset, (int)size)) - { - OnReceivedRequestInternal(Request); - Request.Clear(); - return; - } - - // Check for HTTP request error - if (Request.IsErrorSet) - { - OnReceivedRequestError(Request, "Invalid HTTP request!"); - Request.Clear(); - Disconnect(); - return; - } - } - - protected override void OnDisconnected() - { - // Receive HTTP request body - if (Request.IsPendingBody()) - { - OnReceivedRequestInternal(Request); - Request.Clear(); - return; - } - } - - /// - /// Handle HTTP request header received notification - /// - /// Notification is called when HTTP request header was received from the client. - /// HTTP request - protected virtual void OnReceivedRequestHeader(HttpRequest request) {} - - /// - /// Handle HTTP request received notification - /// - /// Notification is called when HTTP request was received from the client. - /// HTTP request - protected virtual void OnReceivedRequest(HttpRequest request) {} - - /// - /// Handle HTTP request error notification - /// - /// Notification is called when HTTP request error was received from the client. - /// HTTP request - /// HTTP request error - protected virtual void OnReceivedRequestError(HttpRequest request, string error) {} - - #endregion - - private void OnReceivedRequestInternal(HttpRequest request) - { - // Try to get the cached response - if (request.Method == "GET") - { - var response = Cache.Find(request.Url); - if (response.Item1) - { - SendAsync(response.Item2); - return; - } - } - - // Process the request - OnReceivedRequest(request); - } - } -} diff --git a/Plugins/NetCoreServer/HttpSession.cs.meta b/Plugins/NetCoreServer/HttpSession.cs.meta deleted file mode 100644 index 7996f83e..00000000 --- a/Plugins/NetCoreServer/HttpSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c65e3d284dc4e7e429cc72cb2c81fa96 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/HttpsClient.cs b/Plugins/NetCoreServer/HttpsClient.cs deleted file mode 100644 index e4a4423f..00000000 --- a/Plugins/NetCoreServer/HttpsClient.cs +++ /dev/null @@ -1,423 +0,0 @@ -using System; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace NetCoreServer -{ - /// - /// HTTPS client is used to communicate with secured HTTPS Web server. It allows to send GET, POST, PUT, DELETE requests and receive HTTP result using secure transport. - /// - /// Thread-safe. - public class HttpsClient : SslClient - { - /// - /// Initialize HTTPS client with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public HttpsClient(SslContext context, IPAddress address, int port) : base(context, address, port) { Request = new HttpRequest(); Response = new HttpResponse(); } - /// - /// Initialize HTTPS client with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public HttpsClient(SslContext context, string address, int port) : base(context, address, port) { Request = new HttpRequest(); Response = new HttpResponse(); } - /// - /// Initialize HTTPS client with a given IP endpoint - /// - /// SSL context - /// IP endpoint - public HttpsClient(SslContext context, IPEndPoint endpoint) : base(context, endpoint) { Request = new HttpRequest(); Response = new HttpResponse(); } - - /// - /// Get the HTTP request - /// - public HttpRequest Request { get; protected set; } - - /// - /// Get the HTTP response - /// - protected HttpResponse Response { get; set; } - - #region Send request / Send request body - - /// - /// Send the current HTTP request (synchronous) - /// - /// Size of sent data - public long SendRequest() { return SendRequest(Request); } - /// - /// Send the HTTP request (synchronous) - /// - /// HTTP request - /// Size of sent data - public long SendRequest(HttpRequest request) { return Send(request.Cache.Data, request.Cache.Offset, request.Cache.Size); } - - /// - /// Send the HTTP request body (synchronous) - /// - /// HTTP request body - /// Size of sent data - public long SendRequestBody(string body) { return Send(body); } - /// - /// Send the HTTP request body (synchronous) - /// - /// HTTP request body buffer - /// Size of sent data - public long SendRequestBody(byte[] buffer) { return Send(buffer); } - /// - /// Send the HTTP request body (synchronous) - /// - /// HTTP request body buffer - /// HTTP request body buffer offset - /// HTTP request body size - /// Size of sent data - public long SendRequestBody(byte[] buffer, long offset, long size) { return Send(buffer, offset, size); } - - /// - /// Send the current HTTP request (asynchronous) - /// - /// 'true' if the current HTTP request was successfully sent, 'false' if the session is not connected - public bool SendRequestAsync() { return SendRequestAsync(Request); } - /// - /// Send the HTTP request (asynchronous) - /// - /// HTTP request - /// 'true' if the current HTTP request was successfully sent, 'false' if the session is not connected - public bool SendRequestAsync(HttpRequest request) { return SendAsync(request.Cache.Data, request.Cache.Offset, request.Cache.Size); } - - /// - /// Send the HTTP request body (asynchronous) - /// - /// HTTP request body - /// 'true' if the HTTP request body was successfully sent, 'false' if the session is not connected - public bool SendRequestBodyAsync(string body) { return SendAsync(body); } - /// - /// Send the HTTP request body (asynchronous) - /// - /// HTTP request body buffer - /// 'true' if the HTTP request body was successfully sent, 'false' if the session is not connected - public bool SendRequestBodyAsync(byte[] buffer) { return SendAsync(buffer); } - /// - /// Send the HTTP request body (asynchronous) - /// - /// HTTP request body buffer - /// HTTP request body buffer offset - /// HTTP request body size - /// 'true' if the HTTP request body was successfully sent, 'false' if the session is not connected - public bool SendRequestBodyAsync(byte[] buffer, long offset, long size) { return SendAsync(buffer, offset, size); } - - #endregion - - #region Session handlers - - protected override void OnReceived(byte[] buffer, long offset, long size) - { - // Receive HTTP response header - if (Response.IsPendingHeader()) - { - if (Response.ReceiveHeader(buffer, (int)offset, (int)size)) - OnReceivedResponseHeader(Response); - - size = 0; - } - - // Check for HTTP response error - if (Response.IsErrorSet) - { - OnReceivedResponseError(Response, "Invalid HTTP response!"); - Response.Clear(); - Disconnect(); - return; - } - - // Receive HTTP response body - if (Response.ReceiveBody(buffer, (int)offset, (int)size)) - { - OnReceivedResponse(Response); - Response.Clear(); - return; - } - - // Check for HTTP response error - if (Response.IsErrorSet) - { - OnReceivedResponseError(Response, "Invalid HTTP response!"); - Response.Clear(); - Disconnect(); - return; - } - } - - protected override void OnDisconnected() - { - // Receive HTTP response body - if (Response.IsPendingBody()) - { - OnReceivedResponse(Response); - Response.Clear(); - return; - } - } - - /// - /// Handle HTTP response header received notification - /// - /// Notification is called when HTTP response header was received from the server. - /// HTTP request - protected virtual void OnReceivedResponseHeader(HttpResponse response) { } - - /// - /// Handle HTTP response received notification - /// - /// Notification is called when HTTP response was received from the server. - /// HTTP response - protected virtual void OnReceivedResponse(HttpResponse response) { } - - /// - /// Handle HTTP response error notification - /// - /// Notification is called when HTTP response error was received from the server. - /// HTTP response - /// HTTP response error - protected virtual void OnReceivedResponseError(HttpResponse response, string error) { } - - #endregion - } - - /// - /// HTTPS extended client make requests to HTTPS Web server with returning Task as a synchronization primitive. - /// - /// Thread-safe. - public class HttpsClientEx : HttpsClient - { - /// - /// Initialize HTTPS client with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public HttpsClientEx(SslContext context, IPAddress address, int port) : base(context, address, port) { } - /// - /// Initialize HTTPS client with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public HttpsClientEx(SslContext context, string address, int port) : base(context, address, port) { } - /// - /// Initialize HTTPS client with a given IP endpoint - /// - /// SSL context - /// IP endpoint - public HttpsClientEx(SslContext context, IPEndPoint endpoint) : base(context, endpoint) { } - - #region Send request - - /// - /// Send current HTTP request - /// - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendRequest(TimeSpan? timeout = null) { return SendRequest(Request, timeout); } - /// - /// Send HTTP request - /// - /// HTTP request - /// HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendRequest(HttpRequest request, TimeSpan? timeout = null) - { - if (timeout == null) - timeout = TimeSpan.FromMinutes(1); - - _tcs = new TaskCompletionSource(); - Request = request; - - // Check if the HTTP request is valid - if (Request.IsEmpty || Request.IsErrorSet) - { - SetResultError("Invalid HTTP request!"); - return _tcs.Task; - } - - if (!IsHandshaked) - { - // Connect to the Web server - if (!ConnectAsync()) - { - SetResultError("Connection failed!"); - return _tcs.Task; - } - } - else - { - // Send prepared HTTP request - if (!SendRequestAsync()) - { - SetResultError("Failed to send HTTP request!"); - return _tcs.Task; - } - } - - void TimeoutHandler(object state) - { - // Disconnect on timeout - OnReceivedResponseError(Response, "Timeout!"); - Response.Clear(); - DisconnectAsync(); - } - - // Create a new timeout timer - if (_timer == null) - _timer = new Timer(TimeoutHandler, null, Timeout.Infinite, Timeout.Infinite); - - // Start the timeout timer - _timer.Change((int)timeout.Value.TotalMilliseconds, Timeout.Infinite); - - return _tcs.Task; - } - - /// - /// Send HEAD request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendHeadRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeHeadRequest(url), timeout); } - /// - /// Send GET request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendGetRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeGetRequest(url), timeout); } - /// - /// Send POST request - /// - /// URL to request - /// Content - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendPostRequest(string url, string content, TimeSpan? timeout = null) { return SendRequest(Request.MakePostRequest(url, content), timeout); } - /// - /// Send PUT request - /// - /// URL to request - /// Content - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendPutRequest(string url, string content, TimeSpan? timeout = null) { return SendRequest(Request.MakePutRequest(url, content), timeout); } - /// - /// Send DELETE request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendDeleteRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeDeleteRequest(url), timeout); } - /// - /// Send OPTIONS request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendOptionsRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeOptionsRequest(url), timeout); } - /// - /// Send TRACE request - /// - /// URL to request - /// Current HTTP request timeout (default is 1 minute) - /// HTTP request Task - public Task SendTraceRequest(string url, TimeSpan? timeout = null) { return SendRequest(Request.MakeTraceRequest(url), timeout); } - - #endregion - - #region Session handlers - - protected override void OnHandshaked() - { - // Send prepared HTTP request on connect - if (!Request.IsEmpty && !Request.IsErrorSet) - if (!SendRequestAsync()) - SetResultError("Failed to send HTTP request!"); - } - - protected override void OnDisconnected() - { - // Cancel timeout check timer - _timer?.Change(Timeout.Infinite, Timeout.Infinite); - - base.OnDisconnected(); - } - - protected override void OnReceivedResponse(HttpResponse response) - { - // Cancel timeout check timer - _timer?.Change(Timeout.Infinite, Timeout.Infinite); - - SetResultValue(response); - } - - protected override void OnReceivedResponseError(HttpResponse response, string error) - { - // Cancel timeout check timer - _timer?.Change(Timeout.Infinite, Timeout.Infinite); - - SetResultError(error); - } - - #endregion - - private TaskCompletionSource _tcs = new TaskCompletionSource(); - private Timer _timer; - - private void SetResultValue(HttpResponse response) - { - Response = new HttpResponse(); - _tcs.SetResult(response); - Request.Clear(); - } - - private void SetResultError(string error) - { - _tcs.SetException(new Exception(error)); - Request.Clear(); - } - - #region IDisposable implementation - - // Disposed flag. - private bool _disposed; - - protected override void Dispose(bool disposingManagedResources) - { - if (!_disposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - _timer?.Dispose(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - _disposed = true; - } - - // Call Dispose in the base class. - base.Dispose(disposingManagedResources); - } - - // The derived class does not have a Finalize method - // or a Dispose method without parameters because it inherits - // them from the base class. - - #endregion - } -} diff --git a/Plugins/NetCoreServer/HttpsClient.cs.meta b/Plugins/NetCoreServer/HttpsClient.cs.meta deleted file mode 100644 index c801d6d3..00000000 --- a/Plugins/NetCoreServer/HttpsClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 221568f8dd97b734f838d83fb3816d99 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/HttpsServer.cs b/Plugins/NetCoreServer/HttpsServer.cs deleted file mode 100644 index fa5b2cda..00000000 --- a/Plugins/NetCoreServer/HttpsServer.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.IO; -using System.Net; - -namespace NetCoreServer -{ - /// - /// HTTPS server is used to create secured HTTPS Web server and communicate with clients using secure HTTPS protocol. It allows to receive GET, POST, PUT, DELETE requests and send HTTP responses. - /// - /// Thread-safe. - public class HttpsServer : SslServer - { - /// - /// Initialize HTTPS server with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public HttpsServer(SslContext context, IPAddress address, int port) : base(context, address, port) { Cache = new FileCache(); } - /// - /// Initialize HTTPS server with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public HttpsServer(SslContext context, string address, int port) : base(context, address, port) { Cache = new FileCache(); } - /// - /// Initialize HTTPS server with a given IP endpoint - /// - /// SSL context - /// IP endpoint - public HttpsServer(SslContext context, IPEndPoint endpoint) : base(context, endpoint) { Cache = new FileCache(); } - - /// - /// Get the static content cache - /// - public FileCache Cache { get; } - - /// - /// Add static content cache - /// - /// Static content path - /// Cache prefix (default is "/") - /// Cache filter (default is "*.*") - /// Refresh cache timeout (default is 1 hour) - public void AddStaticContent(string path, string prefix = "/", string filter = "*.*", TimeSpan? timeout = null) - { - if (timeout == null) - timeout = TimeSpan.FromHours(1); - - bool Handler(FileCache cache, string key, byte[] value, TimeSpan timespan) - { - HttpResponse header = new HttpResponse(); - header.SetBegin(200); - header.SetContentType(Path.GetExtension(key)); - header.SetHeader("Cache-Control", $"max-age={timespan.Seconds}"); - header.SetBody(value); - return cache.Add(key, header.Cache.Data, timespan); - } - - Cache.InsertPath(path, prefix, filter, timeout.Value, Handler); - } - /// - /// Remove static content cache - /// - /// Static content path - public void RemoveStaticContent(string path) { Cache.RemovePath(path); } - /// - /// Clear static content cache - /// - public void ClearStaticContent() { Cache.Clear(); } - - protected override SslSession CreateSession() { return new HttpsSession(this); } - - #region IDisposable implementation - - // Disposed flag. - private bool _disposed; - - protected override void Dispose(bool disposingManagedResources) - { - if (!_disposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - Cache.Dispose(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - _disposed = true; - } - - // Call Dispose in the base class. - base.Dispose(disposingManagedResources); - } - - // The derived class does not have a Finalize method - // or a Dispose method without parameters because it inherits - // them from the base class. - - #endregion - } -} diff --git a/Plugins/NetCoreServer/HttpsServer.cs.meta b/Plugins/NetCoreServer/HttpsServer.cs.meta deleted file mode 100644 index 63ac97b6..00000000 --- a/Plugins/NetCoreServer/HttpsServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aa6229dca48470449852f1716dfb0ce8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/HttpsSession.cs b/Plugins/NetCoreServer/HttpsSession.cs deleted file mode 100644 index 74ab3542..00000000 --- a/Plugins/NetCoreServer/HttpsSession.cs +++ /dev/null @@ -1,193 +0,0 @@ -namespace NetCoreServer -{ - /// - /// HTTPS session is used to receive/send HTTP requests/responses from the connected HTTPS client. - /// - /// Thread-safe. - public class HttpsSession : SslSession - { - public HttpsSession(HttpsServer server) : base(server) - { - Cache = server.Cache; - Request = new HttpRequest(); - Response = new HttpResponse(); - } - - /// - /// Get the static content cache - /// - public FileCache Cache { get; } - - /// - /// Get the HTTP request - /// - protected HttpRequest Request { get; } - - /// - /// Get the HTTP response - /// - public HttpResponse Response { get; } - - #region Send response / Send response body - - /// - /// Send the current HTTP response (synchronous) - /// - /// Size of sent data - public long SendResponse() { return SendResponse(Response); } - /// - /// Send the HTTP response (synchronous) - /// - /// HTTP response - /// Size of sent data - public long SendResponse(HttpResponse response) { return Send(response.Cache.Data, response.Cache.Offset, response.Cache.Size); } - - /// - /// Send the HTTP response body (synchronous) - /// - /// HTTP response body - /// Size of sent data - public long SendResponseBody(string body) { return Send(body); } - /// - /// Send the HTTP response body (synchronous) - /// - /// HTTP response body buffer - /// Size of sent data - public long SendResponseBody(byte[] buffer) { return Send(buffer); } - /// - /// Send the HTTP response body (synchronous) - /// - /// HTTP response body buffer - /// HTTP response body buffer offset - /// HTTP response body size - /// Size of sent data - public long SendResponseBody(byte[] buffer, long offset, long size) { return Send(buffer, offset, size); } - - /// - /// Send the current HTTP response (asynchronous) - /// - /// 'true' if the current HTTP response was successfully sent, 'false' if the session is not connected - public bool SendResponseAsync() { return SendResponseAsync(Response); } - /// - /// Send the HTTP response (asynchronous) - /// - /// HTTP response - /// 'true' if the current HTTP response was successfully sent, 'false' if the session is not connected - public bool SendResponseAsync(HttpResponse response) { return SendAsync(response.Cache.Data, response.Cache.Offset, response.Cache.Size); } - - /// - /// Send the HTTP response body (asynchronous) - /// - /// HTTP response body - /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected - public bool SendResponseBodyAsync(string body) { return SendAsync(body); } - /// - /// Send the HTTP response body (asynchronous) - /// - /// HTTP response body buffer - /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected - public bool SendResponseBodyAsync(byte[] buffer) { return SendAsync(buffer); } - /// - /// Send the HTTP response body (asynchronous) - /// - /// HTTP response body buffer - /// HTTP response body buffer offset - /// HTTP response body size - /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected - public bool SendResponseBodyAsync(byte[] buffer, long offset, long size) { return SendAsync(buffer, offset, size); } - - #endregion - - #region Session handlers - - protected override void OnReceived(byte[] buffer, long offset, long size) - { - // Receive HTTP request header - if (Request.IsPendingHeader()) - { - if (Request.ReceiveHeader(buffer, (int)offset, (int)size)) - OnReceivedRequestHeader(Request); - - size = 0; - } - - // Check for HTTP request error - if (Request.IsErrorSet) - { - OnReceivedRequestError(Request, "Invalid HTTP request!"); - Request.Clear(); - Disconnect(); - return; - } - - // Receive HTTP request body - if (Request.ReceiveBody(buffer, (int)offset, (int)size)) - { - OnReceivedRequestInternal(Request); - Request.Clear(); - return; - } - - // Check for HTTP request error - if (Request.IsErrorSet) - { - OnReceivedRequestError(Request, "Invalid HTTP request!"); - Request.Clear(); - Disconnect(); - return; - } - } - - protected override void OnDisconnected() - { - // Receive HTTP request body - if (Request.IsPendingBody()) - { - OnReceivedRequestInternal(Request); - Request.Clear(); - return; - } - } - - /// - /// Handle HTTP request header received notification - /// - /// Notification is called when HTTP request header was received from the client. - /// HTTP request - protected virtual void OnReceivedRequestHeader(HttpRequest request) { } - - /// - /// Handle HTTP request received notification - /// - /// Notification is called when HTTP request was received from the client. - /// HTTP request - protected virtual void OnReceivedRequest(HttpRequest request) { } - - /// - /// Handle HTTP request error notification - /// - /// Notification is called when HTTP request error was received from the client. - /// HTTP request - /// HTTP request error - protected virtual void OnReceivedRequestError(HttpRequest request, string error) { } - - #endregion - - private void OnReceivedRequestInternal(HttpRequest request) - { - // Try to get the cached response - if (request.Method == "GET") - { - var response = Cache.Find(request.Url); - if (response.Item1) - { - SendAsync(response.Item2); - return; - } - } - - // Process the request - OnReceivedRequest(request); - } - } -} diff --git a/Plugins/NetCoreServer/HttpsSession.cs.meta b/Plugins/NetCoreServer/HttpsSession.cs.meta deleted file mode 100644 index b4782b0f..00000000 --- a/Plugins/NetCoreServer/HttpsSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9f4431bd58c7aa447beddb4b004d3ab3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/IWebSocket.cs b/Plugins/NetCoreServer/IWebSocket.cs deleted file mode 100644 index 4c05f0e2..00000000 --- a/Plugins/NetCoreServer/IWebSocket.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Net.Sockets; - -namespace NetCoreServer -{ - public interface IWebSocket - { - /// - /// Handle WebSocket client connecting notification - /// - /// Notification is called when WebSocket client is connecting to the server. You can handle the connection and change WebSocket upgrade HTTP request by providing your own headers. - /// WebSocket upgrade HTTP request - void OnWsConnecting(HttpRequest request); - /// - /// Handle WebSocket client connected notification - /// - /// WebSocket upgrade HTTP response - void OnWsConnected(HttpResponse response); - - /// - /// Handle WebSocket server session validating notification - /// - /// Notification is called when WebSocket client is connecting to the server. You can handle the connection and validate WebSocket upgrade HTTP request. - /// WebSocket upgrade HTTP request - /// WebSocket upgrade HTTP response - /// return 'true' if the WebSocket update request is valid, 'false' if the WebSocket update request is not valid - bool OnWsConnecting(HttpRequest request, HttpResponse response); - /// - /// Handle WebSocket server session connected notification - /// - /// WebSocket upgrade HTTP request - void OnWsConnected(HttpRequest request); - - /// - /// Handle WebSocket client disconnecting notification - /// - void OnWsDisconnecting(); - /// - /// Handle WebSocket client disconnected notification - /// - void OnWsDisconnected(); - - /// - /// Handle WebSocket received notification - /// - /// Received buffer - /// Received buffer offset - /// Received buffer size - void OnWsReceived(byte[] buffer, long offset, long size); - - /// - /// Handle WebSocket client close notification - /// - /// Received buffer - /// Received buffer offset - /// Received buffer size - void OnWsClose(byte[] buffer, long offset, long size); - - /// - /// Handle WebSocket ping notification - /// - /// Received buffer - /// Received buffer offset - /// Received buffer size - void OnWsPing(byte[] buffer, long offset, long size); - - /// - /// Handle WebSocket pong notification - /// - /// Received buffer - /// Received buffer offset - /// Received buffer size - void OnWsPong(byte[] buffer, long offset, long size); - - /// - /// Handle WebSocket error notification - /// - /// Error message - void OnWsError(string error); - - /// - /// Handle socket error notification - /// - /// Socket error - void OnWsError(SocketError error); - - /// - /// Send WebSocket server upgrade response - /// - /// WebSocket upgrade HTTP response - void SendUpgrade(HttpResponse response); - } -} diff --git a/Plugins/NetCoreServer/IWebSocket.cs.meta b/Plugins/NetCoreServer/IWebSocket.cs.meta deleted file mode 100644 index d2ad9c26..00000000 --- a/Plugins/NetCoreServer/IWebSocket.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3091eb088243b004888cb153590944e9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/NetCoreServer.asmdef b/Plugins/NetCoreServer/NetCoreServer.asmdef deleted file mode 100644 index 6839156e..00000000 --- a/Plugins/NetCoreServer/NetCoreServer.asmdef +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "NetCoreServer" -} diff --git a/Plugins/NetCoreServer/NetCoreServer.asmdef.meta b/Plugins/NetCoreServer/NetCoreServer.asmdef.meta deleted file mode 100644 index 229826e8..00000000 --- a/Plugins/NetCoreServer/NetCoreServer.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 302cce8bc3ee0014da34daebe3087f54 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/SslClient.cs b/Plugins/NetCoreServer/SslClient.cs deleted file mode 100644 index d4aa4584..00000000 --- a/Plugins/NetCoreServer/SslClient.cs +++ /dev/null @@ -1,1114 +0,0 @@ -using System; -using System.Net; -using System.Net.Security; -using System.Net.Sockets; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace NetCoreServer -{ - /// - /// SSL client is used to read/write data from/into the connected SSL server - /// - /// Thread-safe - public class SslClient : IDisposable - { - /// - /// Initialize SSL client with a given server IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public SslClient(SslContext context, IPAddress address, int port) : this(context, new IPEndPoint(address, port)) {} - /// - /// Initialize SSL client with a given server IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public SslClient(SslContext context, string address, int port) : this(context, new IPEndPoint(IPAddress.Parse(address), port)) { Address = address; } - /// - /// Initialize SSL client with a given IP endpoint - /// - /// SSL context - /// IP endpoint - public SslClient(SslContext context, IPEndPoint endpoint) - { - Id = Guid.NewGuid(); - Address = endpoint.Address.ToString(); - Context = context; - Endpoint = endpoint; - } - - /// - /// Client Id - /// - public Guid Id { get; } - - /// - /// SSL server DNS address - /// - public string Address { get; set; } - /// - /// SSL context - /// - public SslContext Context { get; private set; } - /// - /// IP endpoint - /// - public IPEndPoint Endpoint { get; private set; } - /// - /// Socket - /// - public Socket Socket { get; private set; } - - /// - /// Number of bytes pending sent by the client - /// - public long BytesPending { get; private set; } - /// - /// Number of bytes sending by the client - /// - public long BytesSending { get; private set; } - /// - /// Number of bytes sent by the client - /// - public long BytesSent { get; private set; } - /// - /// Number of bytes received by the client - /// - public long BytesReceived { get; private set; } - - /// - /// Option: dual mode socket - /// - /// - /// Specifies whether the Socket is a dual-mode socket used for both IPv4 and IPv6. - /// Will work only if socket is bound on IPv6 address. - /// - public bool OptionDualMode { get; set; } - /// - /// Option: keep alive - /// - /// - /// This option will setup SO_KEEPALIVE if the OS support this feature - /// - public bool OptionKeepAlive { get; set; } - /// - /// Option: no delay - /// - /// - /// This option will enable/disable Nagle's algorithm for SSL protocol - /// - public bool OptionNoDelay { get; set; } - /// - /// Option: receive buffer limit - /// - public int OptionReceiveBufferLimit { get; set; } = 0; - /// - /// Option: receive buffer size - /// - public int OptionReceiveBufferSize { get; set; } = 8192; - /// - /// Option: send buffer limit - /// - public int OptionSendBufferLimit { get; set; } = 0; - /// - /// Option: send buffer size - /// - public int OptionSendBufferSize { get; set; } = 8192; - - #region Connect/Disconnect client - - private bool _disconnecting; - private SocketAsyncEventArgs _connectEventArg; - private SslStream _sslStream; - private Guid? _sslStreamId; - - /// - /// Is the client connecting? - /// - public bool IsConnecting { get; private set; } - /// - /// Is the client connected? - /// - public bool IsConnected { get; private set; } - /// - /// Is the client handshaking? - /// - public bool IsHandshaking { get; private set; } - /// - /// Is the client handshaked? - /// - public bool IsHandshaked { get; private set; } - - /// - /// Create a new socket object - /// - /// - /// Method may be override if you need to prepare some specific socket object in your implementation. - /// - /// Socket object - protected virtual Socket CreateSocket() - { - return new Socket(Endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - } - - /// - /// Connect the client (synchronous) - /// - /// - /// Please note that synchronous connect will not receive data automatically! - /// You should use Receive() or ReceiveAsync() method manually after successful connection. - /// - /// 'true' if the client was successfully connected, 'false' if the client failed to connect - public virtual bool Connect() - { - if (IsConnected || IsHandshaked || IsConnecting || IsHandshaking) - return false; - - // Setup buffers - _receiveBuffer = new Buffer(); - _sendBufferMain = new Buffer(); - _sendBufferFlush = new Buffer(); - - // Setup event args - _connectEventArg = new SocketAsyncEventArgs(); - _connectEventArg.RemoteEndPoint = Endpoint; - _connectEventArg.Completed += OnAsyncCompleted; - - // Create a new client socket - Socket = CreateSocket(); - - // Update the client socket disposed flag - IsSocketDisposed = false; - - // Apply the option: dual mode (this option must be applied before connecting) - if (Socket.AddressFamily == AddressFamily.InterNetworkV6) - Socket.DualMode = OptionDualMode; - - // Call the client connecting handler - OnConnecting(); - - try - { - // Connect to the server - Socket.Connect(Endpoint); - } - catch (SocketException ex) - { - // Call the client error handler - SendError(ex.SocketErrorCode); - - // Reset event args - _connectEventArg.Completed -= OnAsyncCompleted; - - // Call the client disconnecting handler - OnDisconnecting(); - - // Close the client socket - Socket.Close(); - - // Dispose the client socket - Socket.Dispose(); - - // Dispose event arguments - _connectEventArg.Dispose(); - - // Call the client disconnected handler - OnDisconnected(); - - return false; - } - - // Apply the option: keep alive - if (OptionKeepAlive) - Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); - // Apply the option: no delay - if (OptionNoDelay) - Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - - // Prepare receive & send buffers - _receiveBuffer.Reserve(OptionReceiveBufferSize); - _sendBufferMain.Reserve(OptionSendBufferSize); - _sendBufferFlush.Reserve(OptionSendBufferSize); - - // Reset statistic - BytesPending = 0; - BytesSending = 0; - BytesSent = 0; - BytesReceived = 0; - - // Update the connected flag - IsConnected = true; - - // Call the client connected handler - OnConnected(); - - try - { - // Create SSL stream - _sslStreamId = Guid.NewGuid(); - _sslStream = (Context.CertificateValidationCallback != null) ? new SslStream(new NetworkStream(Socket, false), false, Context.CertificateValidationCallback) : new SslStream(new NetworkStream(Socket, false), false); - - // Call the session handshaking handler - OnHandshaking(); - - // SSL handshake - _sslStream.AuthenticateAsClient(Address, Context.Certificates ?? new X509CertificateCollection(new[] { Context.Certificate }), Context.Protocols, true); - } - catch (Exception) - { - SendError(SocketError.NotConnected); - DisconnectAsync(); - return false; - } - - // Update the handshaked flag - IsHandshaked = true; - - // Call the session handshaked handler - OnHandshaked(); - - // Call the empty send buffer handler - if (_sendBufferMain.IsEmpty) - OnEmpty(); - - return true; - } - - /// - /// Disconnect the client (synchronous) - /// - /// 'true' if the client was successfully disconnected, 'false' if the client is already disconnected - public virtual bool Disconnect() - { - if (!IsConnected && !IsConnecting) - return false; - - // Cancel connecting operation - if (IsConnecting) - Socket.CancelConnectAsync(_connectEventArg); - - if (_disconnecting) - return false; - - // Reset connecting & handshaking flags - IsConnecting = false; - IsHandshaking = false; - - // Update the disconnecting flag - _disconnecting = true; - - // Reset event args - _connectEventArg.Completed -= OnAsyncCompleted; - - // Call the client disconnecting handler - OnDisconnecting(); - - try - { - try - { - // Shutdown the SSL stream - _sslStream.ShutdownAsync().Wait(); - } - catch (Exception) {} - - // Dispose the SSL stream & buffer - _sslStream.Dispose(); - _sslStreamId = null; - - try - { - // Shutdown the socket associated with the client - Socket.Shutdown(SocketShutdown.Both); - } - catch (SocketException) {} - - // Close the client socket - Socket.Close(); - - // Dispose the client socket - Socket.Dispose(); - - // Dispose event arguments - _connectEventArg.Dispose(); - - // Update the client socket disposed flag - IsSocketDisposed = true; - } - catch (ObjectDisposedException) {} - - // Update the handshaked flag - IsHandshaked = false; - - // Update the connected flag - IsConnected = false; - - // Update sending/receiving flags - _receiving = false; - _sending = false; - - // Clear send/receive buffers - ClearBuffers(); - - // Call the client disconnected handler - OnDisconnected(); - - // Reset the disconnecting flag - _disconnecting = false; - - return true; - } - - /// - /// Reconnect the client (synchronous) - /// - /// 'true' if the client was successfully reconnected, 'false' if the client is already reconnected - public virtual bool Reconnect() - { - if (!Disconnect()) - return false; - - return Connect(); - } - - /// - /// Connect the client (asynchronous) - /// - /// 'true' if the client was successfully connected, 'false' if the client failed to connect - public virtual bool ConnectAsync() - { - if (IsConnected || IsHandshaked || IsConnecting || IsHandshaking) - return false; - - // Setup buffers - _receiveBuffer = new Buffer(); - _sendBufferMain = new Buffer(); - _sendBufferFlush = new Buffer(); - - // Setup event args - _connectEventArg = new SocketAsyncEventArgs(); - _connectEventArg.RemoteEndPoint = Endpoint; - _connectEventArg.Completed += OnAsyncCompleted; - - // Create a new client socket - Socket = CreateSocket(); - - // Update the client socket disposed flag - IsSocketDisposed = false; - - // Apply the option: dual mode (this option must be applied before connecting) - if (Socket.AddressFamily == AddressFamily.InterNetworkV6) - Socket.DualMode = OptionDualMode; - - // Update the connecting flag - IsConnecting = true; - - // Call the client connecting handler - OnConnecting(); - - // Async connect to the server - if (!Socket.ConnectAsync(_connectEventArg)) - ProcessConnect(_connectEventArg); - - return true; - } - - /// - /// Disconnect the client (asynchronous) - /// - /// 'true' if the client was successfully disconnected, 'false' if the client is already disconnected - public virtual bool DisconnectAsync() { return Disconnect(); } - - /// - /// Reconnect the client (asynchronous) - /// - /// 'true' if the client was successfully reconnected, 'false' if the client is already reconnected - public virtual bool ReconnectAsync() - { - if (!DisconnectAsync()) - return false; - - while (IsConnected) - Thread.Yield(); - - return ConnectAsync(); - } - - #endregion - - #region Send/Recieve data - - // Receive buffer - private bool _receiving; - private Buffer _receiveBuffer; - // Send buffer - private readonly object _sendLock = new object(); - private bool _sending; - private Buffer _sendBufferMain; - private Buffer _sendBufferFlush; - private long _sendBufferFlushOffset; - - /// - /// Send data to the server (synchronous) - /// - /// Buffer to send - /// Size of sent data - public virtual long Send(byte[] buffer) { return Send(buffer, 0, buffer.Length); } - - /// - /// Send data to the server (synchronous) - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - /// Size of sent data - public virtual long Send(byte[] buffer, long offset, long size) - { - if (!IsHandshaked) - return 0; - - if (size == 0) - return 0; - - try - { - // Sent data to the server - _sslStream.Write(buffer, (int)offset, (int)size); - - // Update statistic - BytesSent += size; - - // Call the buffer sent handler - OnSent(size, BytesPending + BytesSending); - - return size; - } - catch (Exception) - { - SendError(SocketError.OperationAborted); - Disconnect(); - return 0; - } - } - - /// - /// Send text to the server (synchronous) - /// - /// Text string to send - /// Size of sent text - public virtual long Send(string text) { return Send(Encoding.UTF8.GetBytes(text)); } - - /// - /// Send data to the server (asynchronous) - /// - /// Buffer to send - /// 'true' if the data was successfully sent, 'false' if the client is not connected - public virtual bool SendAsync(byte[] buffer) { return SendAsync(buffer, 0, buffer.Length); } - - /// - /// Send data to the server (asynchronous) - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - /// 'true' if the data was successfully sent, 'false' if the client is not connected - public virtual bool SendAsync(byte[] buffer, long offset, long size) - { - if (!IsHandshaked) - return false; - - if (size == 0) - return true; - - lock (_sendLock) - { - // Check the send buffer limit - if (((_sendBufferMain.Size + size) > OptionSendBufferLimit) && (OptionSendBufferLimit > 0)) - { - SendError(SocketError.NoBufferSpaceAvailable); - return false; - } - - // Fill the main send buffer - _sendBufferMain.Append(buffer, offset, size); - - // Update statistic - BytesPending = _sendBufferMain.Size; - - // Avoid multiple send handlers - if (_sending) - return true; - else - _sending = true; - - // Try to send the main buffer - TrySend(); - } - - return true; - } - - /// - /// Send text to the server (asynchronous) - /// - /// Text string to send - /// 'true' if the text was successfully sent, 'false' if the client is not connected - public virtual bool SendAsync(string text) { return SendAsync(Encoding.UTF8.GetBytes(text)); } - - /// - /// Receive data from the server (synchronous) - /// - /// Buffer to receive - /// Size of received data - public virtual long Receive(byte[] buffer) { return Receive(buffer, 0, buffer.Length); } - - /// - /// Receive data from the server (synchronous) - /// - /// Buffer to receive - /// Buffer offset - /// Buffer size - /// Size of received data - public virtual long Receive(byte[] buffer, long offset, long size) - { - if (!IsHandshaked) - return 0; - - if (size == 0) - return 0; - - try - { - // Receive data from the server - long received = _sslStream.Read(buffer, (int)offset, (int)size); - if (received > 0) - { - // Update statistic - BytesReceived += received; - - // Call the buffer received handler - OnReceived(buffer, 0, received); - } - - return received; - } - catch (Exception) - { - SendError(SocketError.OperationAborted); - Disconnect(); - return 0; - } - } - - /// - /// Receive text from the server (synchronous) - /// - /// Text size to receive - /// Received text - public virtual string Receive(long size) - { - var buffer = new byte[size]; - var length = Receive(buffer); - return Encoding.UTF8.GetString(buffer, 0, (int)length); - } - - /// - /// Receive data from the server (asynchronous) - /// - public virtual void ReceiveAsync() - { - // Try to receive data from the server - TryReceive(); - } - - /// - /// Try to receive new data - /// - private void TryReceive() - { - if (_receiving) - return; - - if (!IsHandshaked) - return; - - try - { - // Async receive with the receive handler - IAsyncResult result; - do - { - if (!IsHandshaked) - return; - - _receiving = true; - result = _sslStream.BeginRead(_receiveBuffer.Data, 0, (int)_receiveBuffer.Capacity, ProcessReceive, _sslStreamId); - } while (result.CompletedSynchronously); - - } - catch (ObjectDisposedException) {} - } - - /// - /// Try to send pending data - /// - private void TrySend() - { - if (!IsHandshaked) - return; - - bool empty = false; - - lock (_sendLock) - { - // Is previous socket send in progress? - if (_sendBufferFlush.IsEmpty) - { - // Swap flush and main buffers - _sendBufferFlush = Interlocked.Exchange(ref _sendBufferMain, _sendBufferFlush); - _sendBufferFlushOffset = 0; - - // Update statistic - BytesPending = 0; - BytesSending += _sendBufferFlush.Size; - - // Check if the flush buffer is empty - if (_sendBufferFlush.IsEmpty) - { - // Need to call empty send buffer handler - empty = true; - - // End sending process - _sending = false; - } - } - else - return; - } - - // Call the empty send buffer handler - if (empty) - { - OnEmpty(); - return; - } - - try - { - // Async write with the write handler - _sslStream.BeginWrite(_sendBufferFlush.Data, (int)_sendBufferFlushOffset, (int)(_sendBufferFlush.Size - _sendBufferFlushOffset), ProcessSend, _sslStreamId); - } - catch (ObjectDisposedException) {} - } - - /// - /// Clear send/receive buffers - /// - private void ClearBuffers() - { - lock (_sendLock) - { - // Clear send buffers - _sendBufferMain.Clear(); - _sendBufferFlush.Clear(); - _sendBufferFlushOffset= 0; - - // Update statistic - BytesPending = 0; - BytesSending = 0; - } - } - - #endregion - - #region IO processing - - /// - /// This method is called whenever a receive or send operation is completed on a socket - /// - private void OnAsyncCompleted(object sender, SocketAsyncEventArgs e) - { - if (IsSocketDisposed) - return; - - // Determine which type of operation just completed and call the associated handler - switch (e.LastOperation) - { - case SocketAsyncOperation.Connect: - ProcessConnect(e); - break; - default: - throw new ArgumentException("The last operation completed on the socket was not a receive or send"); - } - - } - - /// - /// This method is invoked when an asynchronous connect operation completes - /// - private void ProcessConnect(SocketAsyncEventArgs e) - { - IsConnecting = false; - - if (e.SocketError == SocketError.Success) - { - // Apply the option: keep alive - if (OptionKeepAlive) - Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); - // Apply the option: no delay - if (OptionNoDelay) - Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - - // Prepare receive & send buffers - _receiveBuffer.Reserve(OptionReceiveBufferSize); - _sendBufferMain.Reserve(OptionSendBufferSize); - _sendBufferFlush.Reserve(OptionSendBufferSize); - - // Reset statistic - BytesPending = 0; - BytesSending = 0; - BytesSent = 0; - BytesReceived = 0; - - // Update the connected flag - IsConnected = true; - - // Call the client connected handler - OnConnected(); - - try - { - // Create SSL stream - _sslStreamId = Guid.NewGuid(); - _sslStream = (Context.CertificateValidationCallback != null) ? new SslStream(new NetworkStream(Socket, false), false, Context.CertificateValidationCallback) : new SslStream(new NetworkStream(Socket, false), false); - - // Call the session handshaking handler - OnHandshaking(); - - // Begin the SSL handshake - IsHandshaking = true; - _sslStream.BeginAuthenticateAsClient(Address, Context.Certificates ?? new X509CertificateCollection(new[] { Context.Certificate }), Context.Protocols, true, ProcessHandshake, _sslStreamId); - } - catch (Exception) - { - SendError(SocketError.NotConnected); - DisconnectAsync(); - } - } - else - { - // Call the client disconnected handler - SendError(e.SocketError); - OnDisconnected(); - } - } - - /// - /// This method is invoked when an asynchronous handshake operation completes - /// - private void ProcessHandshake(IAsyncResult result) - { - try - { - IsHandshaking = false; - - if (IsHandshaked) - return; - - // Validate SSL stream Id - var sslStreamId = result.AsyncState as Guid?; - if (_sslStreamId != sslStreamId) - return; - - // End the SSL handshake - _sslStream.EndAuthenticateAsClient(result); - - // Update the handshaked flag - IsHandshaked = true; - - // Try to receive something from the server - TryReceive(); - - // Check the socket disposed state: in some rare cases it might be disconnected while receiving! - if (IsSocketDisposed) - return; - - // Call the session handshaked handler - OnHandshaked(); - - // Call the empty send buffer handler - if (_sendBufferMain.IsEmpty) - OnEmpty(); - } - catch (Exception) - { - SendError(SocketError.NotConnected); - DisconnectAsync(); - } - } - - /// - /// This method is invoked when an asynchronous receive operation completes - /// - private void ProcessReceive(IAsyncResult result) - { - try - { - if (!IsHandshaked) - return; - - // Validate SSL stream Id - var sslStreamId = result.AsyncState as Guid?; - if (_sslStreamId != sslStreamId) - return; - - // End the SSL read - long size = _sslStream.EndRead(result); - - // Received some data from the server - if (size > 0) - { - // Update statistic - BytesReceived += size; - - // Call the buffer received handler - OnReceived(_receiveBuffer.Data, 0, size); - - // If the receive buffer is full increase its size - if (_receiveBuffer.Capacity == size) - { - // Check the receive buffer limit - if (((2 * size) > OptionReceiveBufferLimit) && (OptionReceiveBufferLimit > 0)) - { - SendError(SocketError.NoBufferSpaceAvailable); - DisconnectAsync(); - return; - } - - _receiveBuffer.Reserve(2 * size); - } - } - - _receiving = false; - - // If zero is returned from a read operation, the remote end has closed the connection - if (size > 0) - { - if (!result.CompletedSynchronously) - TryReceive(); - } - else - DisconnectAsync(); - } - catch (Exception) - { - SendError(SocketError.OperationAborted); - DisconnectAsync(); - } - } - - /// - /// This method is invoked when an asynchronous send operation completes - /// - private void ProcessSend(IAsyncResult result) - { - try - { - if (!IsHandshaked) - return; - - // Validate SSL stream Id - var sslStreamId = result.AsyncState as Guid?; - if (_sslStreamId != sslStreamId) - return; - - // End the SSL write - _sslStream.EndWrite(result); - - long size = _sendBufferFlush.Size; - - // Send some data to the server - if (size > 0) - { - // Update statistic - BytesSending -= size; - BytesSent += size; - - // Increase the flush buffer offset - _sendBufferFlushOffset += size; - - // Successfully send the whole flush buffer - if (_sendBufferFlushOffset == _sendBufferFlush.Size) - { - // Clear the flush buffer - _sendBufferFlush.Clear(); - _sendBufferFlushOffset = 0; - } - - // Call the buffer sent handler - OnSent(size, BytesPending + BytesSending); - } - - // Try to send again if the client is valid - TrySend(); - } - catch (Exception) - { - SendError(SocketError.OperationAborted); - DisconnectAsync(); - } - } - - #endregion - - #region Session handlers - - /// - /// Handle client connecting notification - /// - protected virtual void OnConnecting() {} - /// - /// Handle client connected notification - /// - protected virtual void OnConnected() {} - /// - /// Handle client handshaking notification - /// - protected virtual void OnHandshaking() {} - /// - /// Handle client handshaked notification - /// - protected virtual void OnHandshaked() {} - /// - /// Handle client disconnecting notification - /// - protected virtual void OnDisconnecting() {} - /// - /// Handle client disconnected notification - /// - protected virtual void OnDisconnected() {} - - /// - /// Handle buffer received notification - /// - /// Received buffer - /// Received buffer offset - /// Received buffer size - /// - /// Notification is called when another chunk of buffer was received from the server - /// - protected virtual void OnReceived(byte[] buffer, long offset, long size) {} - /// - /// Handle buffer sent notification - /// - /// Size of sent buffer - /// Size of pending buffer - /// - /// Notification is called when another chunk of buffer was sent to the server. - /// This handler could be used to send another buffer to the server for instance when the pending size is zero. - /// - protected virtual void OnSent(long sent, long pending) {} - - /// - /// Handle empty send buffer notification - /// - /// - /// Notification is called when the send buffer is empty and ready for a new data to send. - /// This handler could be used to send another buffer to the server. - /// - protected virtual void OnEmpty() {} - - /// - /// Handle error notification - /// - /// Socket error code - protected virtual void OnError(SocketError error) {} - - #endregion - - #region Error handling - - /// - /// Send error notification - /// - /// Socket error code - private void SendError(SocketError error) - { - // Skip disconnect errors - if ((error == SocketError.ConnectionAborted) || - (error == SocketError.ConnectionRefused) || - (error == SocketError.ConnectionReset) || - (error == SocketError.OperationAborted) || - (error == SocketError.Shutdown)) - return; - - OnError(error); - } - - #endregion - - #region IDisposable implementation - - /// - /// Disposed flag - /// - public bool IsDisposed { get; private set; } - - /// - /// Client socket disposed flag - /// - public bool IsSocketDisposed { get; private set; } = true; - - // Implement IDisposable. - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposingManagedResources) - { - // The idea here is that Dispose(Boolean) knows whether it is - // being called to do explicit cleanup (the Boolean is true) - // versus being called due to a garbage collection (the Boolean - // is false). This distinction is useful because, when being - // disposed explicitly, the Dispose(Boolean) method can safely - // execute code using reference type fields that refer to other - // objects knowing for sure that these other objects have not been - // finalized or disposed of yet. When the Boolean is false, - // the Dispose(Boolean) method should not execute code that - // refer to reference type fields because those objects may - // have already been finalized." - - if (!IsDisposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - DisconnectAsync(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - IsDisposed = true; - } - } - - // Use C# destructor syntax for finalization code. - ~SslClient() - { - // Simply call Dispose(false). - Dispose(false); - } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/SslClient.cs.meta b/Plugins/NetCoreServer/SslClient.cs.meta deleted file mode 100644 index e91e9881..00000000 --- a/Plugins/NetCoreServer/SslClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5a0de8e760f9efe42bb784d59abd5353 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/SslContext.cs b/Plugins/NetCoreServer/SslContext.cs deleted file mode 100644 index 0c529e8e..00000000 --- a/Plugins/NetCoreServer/SslContext.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Net.Security; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; - -namespace NetCoreServer -{ - /// - /// SSL context - /// - public class SslContext - { - /// - /// Initialize SSL context with default protocols - /// - public SslContext() : this(SslProtocols.Tls12) {} - /// - /// Initialize SSL context with given protocols - /// - /// SSL protocols - public SslContext(SslProtocols protocols) { Protocols = protocols; } - /// - /// Initialize SSL context with given protocols and certificate - /// - /// SSL protocols - /// SSL certificate - public SslContext(SslProtocols protocols, X509Certificate certificate) : this(protocols, certificate, null) {} - /// - /// Initialize SSL context with given protocols, certificate and validation callback - /// - /// SSL protocols - /// SSL certificate - /// SSL certificate - public SslContext(SslProtocols protocols, X509Certificate certificate, RemoteCertificateValidationCallback certificateValidationCallback) - { - Protocols = protocols; - Certificate = certificate; - CertificateValidationCallback = certificateValidationCallback; - } - /// - /// Initialize SSL context with given protocols and certificates collection - /// - /// SSL protocols - /// SSL certificates collection - public SslContext(SslProtocols protocols, X509Certificate2Collection certificates) : this(protocols, certificates, null) {} - /// - /// Initialize SSL context with given protocols, certificates collection and validation callback - /// - /// SSL protocols - /// SSL certificates collection - /// SSL certificate - public SslContext(SslProtocols protocols, X509Certificate2Collection certificates, RemoteCertificateValidationCallback certificateValidationCallback) - { - Protocols = protocols; - Certificates = certificates; - CertificateValidationCallback = certificateValidationCallback; - } - - /// - /// SSL protocols - /// - public SslProtocols Protocols { get; set; } - /// - /// SSL certificate - /// - public X509Certificate Certificate { get; set; } - /// - /// SSL certificates collection - /// - public X509Certificate2Collection Certificates { get; set; } - /// - /// SSL certificate validation callback - /// - public RemoteCertificateValidationCallback CertificateValidationCallback { get; set; } - - /// - /// Is the client is asked for a certificate for authentication. - /// Note that this is only a request - if no certificate is provided, the server still accepts the connection request. - /// - public bool ClientCertificateRequired { get; set; } - } -} diff --git a/Plugins/NetCoreServer/SslContext.cs.meta b/Plugins/NetCoreServer/SslContext.cs.meta deleted file mode 100644 index 7001e270..00000000 --- a/Plugins/NetCoreServer/SslContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bbb7e07dfc758bb4391bfa300eff4784 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/SslServer.cs b/Plugins/NetCoreServer/SslServer.cs deleted file mode 100644 index 96635783..00000000 --- a/Plugins/NetCoreServer/SslServer.cs +++ /dev/null @@ -1,582 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; - -namespace NetCoreServer -{ - /// - /// SSL server is used to connect, disconnect and manage SSL sessions - /// - /// Thread-safe - public class SslServer : IDisposable - { - /// - /// Initialize SSL server with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public SslServer(SslContext context, IPAddress address, int port) : this(context, new IPEndPoint(address, port)) {} - /// - /// Initialize SSL server with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public SslServer(SslContext context, string address, int port) : this(context, new IPEndPoint(IPAddress.Parse(address), port)) {} - - /// - /// Initialize SSL server with a given IP endpoint - /// - /// SSL context - /// IP endpoint - public SslServer(SslContext context, IPEndPoint endpoint) - { - Id = Guid.NewGuid(); - Context = context; - Endpoint = endpoint; - } - - /// - /// Server Id - /// - public Guid Id { get; } - - /// - /// SSL context - /// - public SslContext Context { get; private set; } - /// - /// IP endpoint - /// - public IPEndPoint Endpoint { get; private set; } - - /// - /// Number of sessions connected to the server - /// - public long ConnectedSessions { get { return Sessions.Count; } } - /// - /// Number of bytes pending sent by the server - /// - public long BytesPending { get { return _bytesPending; } } - /// - /// Number of bytes sent by the server - /// - public long BytesSent { get { return _bytesSent; } } - /// - /// Number of bytes received by the server - /// - public long BytesReceived { get { return _bytesReceived; } } - - /// - /// Option: acceptor backlog size - /// - /// - /// This option will set the listening socket's backlog size - /// - public int OptionAcceptorBacklog { get; set; } = 1024; - /// - /// Option: dual mode socket - /// - /// - /// Specifies whether the Socket is a dual-mode socket used for both IPv4 and IPv6. - /// Will work only if socket is bound on IPv6 address. - /// - public bool OptionDualMode { get; set; } - /// - /// Option: keep alive - /// - /// - /// This option will setup SO_KEEPALIVE if the OS support this feature - /// - public bool OptionKeepAlive { get; set; } - /// - /// Option: no delay - /// - /// - /// This option will enable/disable Nagle's algorithm for SSL protocol - /// - public bool OptionNoDelay { get; set; } - /// - /// Option: reuse address - /// - /// - /// This option will enable/disable SO_REUSEADDR if the OS support this feature - /// - public bool OptionReuseAddress { get; set; } - /// - /// Option: enables a socket to be bound for exclusive access - /// - /// - /// This option will enable/disable SO_EXCLUSIVEADDRUSE if the OS support this feature - /// - public bool OptionExclusiveAddressUse { get; set; } - /// - /// Option: receive buffer size - /// - public int OptionReceiveBufferSize { get; set; } = 8192; - /// - /// Option: send buffer size - /// - public int OptionSendBufferSize { get; set; } = 8192; - - #region Start/Stop server - - // Server acceptor - private Socket _acceptorSocket; - private SocketAsyncEventArgs _acceptorEventArg; - - // Server statistic - internal long _bytesPending; - internal long _bytesSent; - internal long _bytesReceived; - - /// - /// Is the server started? - /// - public bool IsStarted { get; private set; } - /// - /// Is the server accepting new clients? - /// - public bool IsAccepting { get; private set; } - - /// - /// Create a new socket object - /// - /// - /// Method may be override if you need to prepare some specific socket object in your implementation. - /// - /// Socket object - protected virtual Socket CreateSocket() - { - return new Socket(Endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - } - - /// - /// Start the server - /// - /// 'true' if the server was successfully started, 'false' if the server failed to start - public virtual bool Start() - { - Debug.Assert(!IsStarted, "SSL server is already started!"); - if (IsStarted) - return false; - - // Setup acceptor event arg - _acceptorEventArg = new SocketAsyncEventArgs(); - _acceptorEventArg.Completed += OnAsyncCompleted; - - // Create a new acceptor socket - _acceptorSocket = CreateSocket(); - - // Update the acceptor socket disposed flag - IsSocketDisposed = false; - - // Apply the option: reuse address - _acceptorSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, OptionReuseAddress); - // Apply the option: exclusive address use - _acceptorSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, OptionExclusiveAddressUse); - // Apply the option: dual mode (this option must be applied before listening) - if (_acceptorSocket.AddressFamily == AddressFamily.InterNetworkV6) - _acceptorSocket.DualMode = OptionDualMode; - - // Bind the acceptor socket to the IP endpoint - _acceptorSocket.Bind(Endpoint); - // Refresh the endpoint property based on the actual endpoint created - Endpoint = (IPEndPoint)_acceptorSocket.LocalEndPoint; - - // Call the server starting handler - OnStarting(); - - // Start listen to the acceptor socket with the given accepting backlog size - _acceptorSocket.Listen(OptionAcceptorBacklog); - - // Reset statistic - _bytesPending = 0; - _bytesSent = 0; - _bytesReceived = 0; - - // Update the started flag - IsStarted = true; - - // Call the server started handler - OnStarted(); - - // Perform the first server accept - IsAccepting = true; - StartAccept(_acceptorEventArg); - - return true; - } - - /// - /// Stop the server - /// - /// 'true' if the server was successfully stopped, 'false' if the server is already stopped - public virtual bool Stop() - { - Debug.Assert(IsStarted, "SSL server is not started!"); - if (!IsStarted) - return false; - - // Stop accepting new clients - IsAccepting = false; - - // Reset acceptor event arg - _acceptorEventArg.Completed -= OnAsyncCompleted; - - // Call the server stopping handler - OnStopping(); - - try - { - // Close the acceptor socket - _acceptorSocket.Close(); - - // Dispose the acceptor socket - _acceptorSocket.Dispose(); - - // Dispose event arguments - _acceptorEventArg.Dispose(); - - // Update the acceptor socket disposed flag - IsSocketDisposed = true; - } - catch (ObjectDisposedException) {} - - // Disconnect all sessions - DisconnectAll(); - - // Update the started flag - IsStarted = false; - - // Call the server stopped handler - OnStopped(); - - return true; - } - - /// - /// Restart the server - /// - /// 'true' if the server was successfully restarted, 'false' if the server failed to restart - public virtual bool Restart() - { - if (!Stop()) - return false; - - while (IsStarted) - Thread.Yield(); - - return Start(); - } - - #endregion - - #region Accepting clients - - /// - /// Start accept a new client connection - /// - private void StartAccept(SocketAsyncEventArgs e) - { - // Socket must be cleared since the context object is being reused - e.AcceptSocket = null; - - // Async accept a new client connection - if (!_acceptorSocket.AcceptAsync(e)) - ProcessAccept(e); - } - - /// - /// Process accepted client connection - /// - private void ProcessAccept(SocketAsyncEventArgs e) - { - if (e.SocketError == SocketError.Success) - { - // Create a new session to register - var session = CreateSession(); - - // Register the session - RegisterSession(session); - - // Connect new session - session.Connect(e.AcceptSocket); - } - else - SendError(e.SocketError); - - // Accept the next client connection - if (IsAccepting) - StartAccept(e); - } - - /// - /// This method is the callback method associated with Socket.AcceptAsync() - /// operations and is invoked when an accept operation is complete - /// - private void OnAsyncCompleted(object sender, SocketAsyncEventArgs e) - { - if (IsSocketDisposed) - return; - - ProcessAccept(e); - } - - #endregion - - #region Session factory - - /// - /// Create SSL session factory method - /// - /// SSL session - protected virtual SslSession CreateSession() { return new SslSession(this); } - - #endregion - - #region Session management - - // Server sessions - protected readonly ConcurrentDictionary Sessions = new ConcurrentDictionary(); - - /// - /// Disconnect all connected sessions - /// - /// 'true' if all sessions were successfully disconnected, 'false' if the server is not started - public virtual bool DisconnectAll() - { - if (!IsStarted) - return false; - - // Disconnect all sessions - foreach (var session in Sessions.Values) - session.Disconnect(); - - return true; - } - - /// - /// Find a session with a given Id - /// - /// Session Id - /// Session with a given Id or null if the session it not connected - public SslSession FindSession(Guid id) - { - // Try to find the required session - return Sessions.TryGetValue(id, out SslSession result) ? result : null; - } - - /// - /// Register a new session - /// - /// Session to register - internal void RegisterSession(SslSession session) - { - // Register a new session - Sessions.TryAdd(session.Id, session); - } - - /// - /// Unregister session by Id - /// - /// Session Id - internal void UnregisterSession(Guid id) - { - // Unregister session by Id - Sessions.TryRemove(id, out SslSession temp); - } - - #endregion - - #region Multicasting - - /// - /// Multicast data to all connected sessions - /// - /// Buffer to multicast - /// 'true' if the data was successfully multicasted, 'false' if the data was not multicasted - public virtual bool Multicast(byte[] buffer) { return Multicast(buffer, 0, buffer.Length); } - - /// - /// Multicast data to all connected clients - /// - /// Buffer to multicast - /// Buffer offset - /// Buffer size - /// 'true' if the data was successfully multicasted, 'false' if the data was not multicasted - public virtual bool Multicast(byte[] buffer, long offset, long size) - { - if (!IsStarted) - return false; - - if (size == 0) - return true; - - // Multicast data to all sessions - foreach (var session in Sessions.Values) - session.SendAsync(buffer, offset, size); - - return true; - } - - /// - /// Multicast text to all connected clients - /// - /// Text string to multicast - /// 'true' if the text was successfully multicasted, 'false' if the text was not multicasted - public virtual bool Multicast(string text) { return Multicast(Encoding.UTF8.GetBytes(text)); } - - #endregion - - #region Server handlers - - /// - /// Handle server starting notification - /// - protected virtual void OnStarting() {} - /// - /// Handle server started notification - /// - protected virtual void OnStarted() {} - /// - /// Handle server stopping notification - /// - protected virtual void OnStopping() {} - /// - /// Handle server stopped notification - /// - protected virtual void OnStopped() {} - - /// - /// Handle session connecting notification - /// - /// Connecting session - protected virtual void OnConnecting(SslSession session) {} - /// - /// Handle session connected notification - /// - /// Connected session - protected virtual void OnConnected(SslSession session) {} - /// - /// Handle session handshaking notification - /// - /// Handshaking session - protected virtual void OnHandshaking(SslSession session) {} - /// - /// Handle session handshaked notification - /// - /// Handshaked session - protected virtual void OnHandshaked(SslSession session) {} - /// - /// Handle session disconnecting notification - /// - /// Disconnecting session - protected virtual void OnDisconnecting(SslSession session) {} - /// - /// Handle session disconnected notification - /// - /// Disconnected session - protected virtual void OnDisconnected(SslSession session) {} - - /// - /// Handle error notification - /// - /// Socket error code - protected virtual void OnError(SocketError error) {} - - internal void OnConnectingInternal(SslSession session) { OnConnecting(session); } - internal void OnConnectedInternal(SslSession session) { OnConnected(session); } - internal void OnHandshakingInternal(SslSession session) { OnHandshaking(session); } - internal void OnHandshakedInternal(SslSession session) { OnHandshaked(session); } - internal void OnDisconnectingInternal(SslSession session) { OnDisconnecting(session); } - internal void OnDisconnectedInternal(SslSession session) { OnDisconnected(session); } - - #endregion - - #region Error handling - - /// - /// Send error notification - /// - /// Socket error code - private void SendError(SocketError error) - { - // Skip disconnect errors - if ((error == SocketError.ConnectionAborted) || - (error == SocketError.ConnectionRefused) || - (error == SocketError.ConnectionReset) || - (error == SocketError.OperationAborted) || - (error == SocketError.Shutdown)) - return; - - OnError(error); - } - - #endregion - - #region IDisposable implementation - - /// - /// Disposed flag - /// - public bool IsDisposed { get; private set; } - - /// - /// Acceptor socket disposed flag - /// - public bool IsSocketDisposed { get; private set; } = true; - - // Implement IDisposable. - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposingManagedResources) - { - // The idea here is that Dispose(Boolean) knows whether it is - // being called to do explicit cleanup (the Boolean is true) - // versus being called due to a garbage collection (the Boolean - // is false). This distinction is useful because, when being - // disposed explicitly, the Dispose(Boolean) method can safely - // execute code using reference type fields that refer to other - // objects knowing for sure that these other objects have not been - // finalized or disposed of yet. When the Boolean is false, - // the Dispose(Boolean) method should not execute code that - // refer to reference type fields because those objects may - // have already been finalized." - - if (!IsDisposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - Stop(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - IsDisposed = true; - } - } - - // Use C# destructor syntax for finalization code. - ~SslServer() - { - // Simply call Dispose(false). - Dispose(false); - } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/SslServer.cs.meta b/Plugins/NetCoreServer/SslServer.cs.meta deleted file mode 100644 index 81efc785..00000000 --- a/Plugins/NetCoreServer/SslServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1c1438d721010e8479d359be3e062961 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/SslSession.cs b/Plugins/NetCoreServer/SslSession.cs deleted file mode 100644 index 98a8e962..00000000 --- a/Plugins/NetCoreServer/SslSession.cs +++ /dev/null @@ -1,838 +0,0 @@ -using System; -using System.Net.Security; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace NetCoreServer -{ - /// - /// SSL session is used to read and write data from the connected SSL client - /// - /// Thread-safe - public class SslSession : IDisposable - { - /// - /// Initialize the session with a given server - /// - /// SSL server - public SslSession(SslServer server) - { - Id = Guid.NewGuid(); - Server = server; - OptionReceiveBufferSize = server.OptionReceiveBufferSize; - OptionSendBufferSize = server.OptionSendBufferSize; - } - - /// - /// Session Id - /// - public Guid Id { get; } - - /// - /// Server - /// - public SslServer Server { get; } - /// - /// Socket - /// - public Socket Socket { get; private set; } - - /// - /// Number of bytes pending sent by the session - /// - public long BytesPending { get; private set; } - /// - /// Number of bytes sending by the session - /// - public long BytesSending { get; private set; } - /// - /// Number of bytes sent by the session - /// - public long BytesSent { get; private set; } - /// - /// Number of bytes received by the session - /// - public long BytesReceived { get; private set; } - - /// - /// Option: receive buffer limit - /// - public int OptionReceiveBufferLimit { get; set; } = 0; - /// - /// Option: receive buffer size - /// - public int OptionReceiveBufferSize { get; set; } = 8192; - /// - /// Option: send buffer limit - /// - public int OptionSendBufferLimit { get; set; } = 0; - /// - /// Option: send buffer size - /// - public int OptionSendBufferSize { get; set; } = 8192; - - #region Connect/Disconnect session - - private bool _disconnecting; - private SslStream _sslStream; - private Guid? _sslStreamId; - - /// - /// Is the session connected? - /// - public bool IsConnected { get; private set; } - /// - /// Is the session handshaked? - /// - public bool IsHandshaked { get; private set; } - - /// - /// Connect the session - /// - /// Session socket - internal void Connect(Socket socket) - { - Socket = socket; - - // Update the session socket disposed flag - IsSocketDisposed = false; - - // Setup buffers - _receiveBuffer = new Buffer(); - _sendBufferMain = new Buffer(); - _sendBufferFlush = new Buffer(); - - // Apply the option: keep alive - if (Server.OptionKeepAlive) - Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); - // Apply the option: no delay - if (Server.OptionNoDelay) - Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - - // Prepare receive & send buffers - _receiveBuffer.Reserve(OptionReceiveBufferSize); - _sendBufferMain.Reserve(OptionSendBufferSize); - _sendBufferFlush.Reserve(OptionSendBufferSize); - - // Reset statistic - BytesPending = 0; - BytesSending = 0; - BytesSent = 0; - BytesReceived = 0; - - // Call the session connecting handler - OnConnecting(); - - // Call the session connecting handler in the server - Server.OnConnectingInternal(this); - - // Update the connected flag - IsConnected = true; - - // Call the session connected handler - OnConnected(); - - // Call the session connected handler in the server - Server.OnConnectedInternal(this); - - try - { - // Create SSL stream - _sslStreamId = Guid.NewGuid(); - _sslStream = (Server.Context.CertificateValidationCallback != null) ? new SslStream(new NetworkStream(Socket, false), false, Server.Context.CertificateValidationCallback) : new SslStream(new NetworkStream(Socket, false), false); - - // Call the session handshaking handler - OnHandshaking(); - - // Call the session handshaking handler in the server - Server.OnHandshakingInternal(this); - - // Begin the SSL handshake - _sslStream.BeginAuthenticateAsServer(Server.Context.Certificate, Server.Context.ClientCertificateRequired, Server.Context.Protocols, false, ProcessHandshake, _sslStreamId); - } - catch (Exception) - { - SendError(SocketError.NotConnected); - Disconnect(); - } - } - - /// - /// Disconnect the session - /// - /// 'true' if the section was successfully disconnected, 'false' if the section is already disconnected - public virtual bool Disconnect() - { - if (!IsConnected) - return false; - - if (_disconnecting) - return false; - - // Update the disconnecting flag - _disconnecting = true; - - // Call the session disconnecting handler - OnDisconnecting(); - - // Call the session disconnecting handler in the server - Server.OnDisconnectingInternal(this); - - try - { - try - { - // Shutdown the SSL stream - _sslStream.ShutdownAsync().Wait(); - } - catch (Exception) {} - - // Dispose the SSL stream & buffer - _sslStream.Dispose(); - _sslStreamId = null; - - try - { - // Shutdown the socket associated with the client - Socket.Shutdown(SocketShutdown.Both); - } - catch (SocketException) {} - - // Close the session socket - Socket.Close(); - - // Dispose the session socket - Socket.Dispose(); - - // Update the session socket disposed flag - IsSocketDisposed = true; - } - catch (ObjectDisposedException) {} - - // Update the handshaked flag - IsHandshaked = false; - - // Update the connected flag - IsConnected = false; - - // Update sending/receiving flags - _receiving = false; - _sending = false; - - // Clear send/receive buffers - ClearBuffers(); - - // Call the session disconnected handler - OnDisconnected(); - - // Call the session disconnected handler in the server - Server.OnDisconnectedInternal(this); - - // Unregister session - Server.UnregisterSession(Id); - - // Reset the disconnecting flag - _disconnecting = false; - - return true; - } - - #endregion - - #region Send/Recieve data - - // Receive buffer - private bool _receiving; - private Buffer _receiveBuffer; - // Send buffer - private readonly object _sendLock = new object(); - private bool _sending; - private Buffer _sendBufferMain; - private Buffer _sendBufferFlush; - private long _sendBufferFlushOffset; - - /// - /// Send data to the client (synchronous) - /// - /// Buffer to send - /// Size of sent data - public virtual long Send(byte[] buffer) { return Send(buffer, 0, buffer.Length); } - - /// - /// Send data to the client (synchronous) - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - /// Size of sent data - public virtual long Send(byte[] buffer, long offset, long size) - { - if (!IsHandshaked) - return 0; - - if (size == 0) - return 0; - - try - { - // Sent data to the server - _sslStream.Write(buffer, (int)offset, (int)size); - - // Update statistic - BytesSent += size; - Interlocked.Add(ref Server._bytesSent, size); - - // Call the buffer sent handler - OnSent(size, BytesPending + BytesSending); - - return size; - } - catch (Exception) - { - SendError(SocketError.OperationAborted); - Disconnect(); - return 0; - } - } - - /// - /// Send text to the client (synchronous) - /// - /// Text string to send - /// Size of sent text - public virtual long Send(string text) { return Send(Encoding.UTF8.GetBytes(text)); } - - /// - /// Send data to the client (asynchronous) - /// - /// Buffer to send - /// 'true' if the data was successfully sent, 'false' if the session is not connected - public virtual bool SendAsync(byte[] buffer) { return SendAsync(buffer, 0, buffer.Length); } - - /// - /// Send data to the client (asynchronous) - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - /// 'true' if the data was successfully sent, 'false' if the session is not connected - public virtual bool SendAsync(byte[] buffer, long offset, long size) - { - if (!IsHandshaked) - return false; - - if (size == 0) - return true; - - lock (_sendLock) - { - // Check the send buffer limit - if (((_sendBufferMain.Size + size) > OptionSendBufferLimit) && (OptionSendBufferLimit > 0)) - { - SendError(SocketError.NoBufferSpaceAvailable); - return false; - } - - // Fill the main send buffer - _sendBufferMain.Append(buffer, offset, size); - - // Update statistic - BytesPending = _sendBufferMain.Size; - - // Avoid multiple send handlers - if (_sending) - return true; - else - _sending = true; - - // Try to send the main buffer - TrySend(); - } - - return true; - } - - /// - /// Send text to the client (asynchronous) - /// - /// Text string to send - /// 'true' if the text was successfully sent, 'false' if the session is not connected - public virtual bool SendAsync(string text) { return SendAsync(Encoding.UTF8.GetBytes(text)); } - - /// - /// Receive data from the client (synchronous) - /// - /// Buffer to receive - /// Size of received data - public virtual long Receive(byte[] buffer) { return Receive(buffer, 0, buffer.Length); } - - /// - /// Receive data from the client (synchronous) - /// - /// Buffer to receive - /// Buffer offset - /// Buffer size - /// Size of received data - public virtual long Receive(byte[] buffer, long offset, long size) - { - if (!IsHandshaked) - return 0; - - if (size == 0) - return 0; - - try - { - // Receive data from the client - long received = _sslStream.Read(buffer, (int)offset, (int)size); - if (received > 0) - { - // Update statistic - BytesReceived += received; - Interlocked.Add(ref Server._bytesReceived, received); - - // Call the buffer received handler - OnReceived(buffer, 0, received); - } - - return received; - } - catch (Exception) - { - SendError(SocketError.OperationAborted); - Disconnect(); - return 0; - } - } - - /// - /// Receive text from the client (synchronous) - /// - /// Text size to receive - /// Received text - public virtual string Receive(long size) - { - var buffer = new byte[size]; - var length = Receive(buffer); - return Encoding.UTF8.GetString(buffer, 0, (int)length); - } - - /// - /// Receive data from the client (asynchronous) - /// - public virtual void ReceiveAsync() - { - // Try to receive data from the client - TryReceive(); - } - - /// - /// Try to receive new data - /// - private void TryReceive() - { - if (_receiving) - return; - - if (!IsHandshaked) - return; - - try - { - // Async receive with the receive handler - IAsyncResult result; - do - { - if (!IsHandshaked) - return; - - _receiving = true; - result = _sslStream.BeginRead(_receiveBuffer.Data, 0, (int)_receiveBuffer.Capacity, ProcessReceive, _sslStreamId); - } while (result.CompletedSynchronously); - } - catch (ObjectDisposedException) {} - } - - /// - /// Try to send pending data - /// - private void TrySend() - { - if (!IsHandshaked) - return; - - bool empty = false; - - lock (_sendLock) - { - // Is previous socket send in progress? - if (_sendBufferFlush.IsEmpty) - { - // Swap flush and main buffers - _sendBufferFlush = Interlocked.Exchange(ref _sendBufferMain, _sendBufferFlush); - _sendBufferFlushOffset = 0; - - // Update statistic - BytesPending = 0; - BytesSending += _sendBufferFlush.Size; - - // Check if the flush buffer is empty - if (_sendBufferFlush.IsEmpty) - { - // Need to call empty send buffer handler - empty = true; - - // End sending process - _sending = false; - } - } - else - return; - } - - // Call the empty send buffer handler - if (empty) - { - OnEmpty(); - return; - } - - try - { - // Async write with the write handler - _sslStream.BeginWrite(_sendBufferFlush.Data, (int)_sendBufferFlushOffset, (int)(_sendBufferFlush.Size - _sendBufferFlushOffset), ProcessSend, _sslStreamId); - } - catch (ObjectDisposedException) {} - } - - /// - /// Clear send/receive buffers - /// - private void ClearBuffers() - { - lock (_sendLock) - { - // Clear send buffers - _sendBufferMain.Clear(); - _sendBufferFlush.Clear(); - _sendBufferFlushOffset= 0; - - // Update statistic - BytesPending = 0; - BytesSending = 0; - } - } - - #endregion - - #region IO processing - - /// - /// This method is invoked when an asynchronous handshake operation completes - /// - private void ProcessHandshake(IAsyncResult result) - { - try - { - if (IsHandshaked) - return; - - // Validate SSL stream Id - var sslStreamId = result.AsyncState as Guid?; - if (_sslStreamId != sslStreamId) - return; - - // End the SSL handshake - _sslStream.EndAuthenticateAsServer(result); - - // Update the handshaked flag - IsHandshaked = true; - - // Try to receive something from the client - TryReceive(); - - // Check the socket disposed state: in some rare cases it might be disconnected while receiving! - if (IsSocketDisposed) - return; - - // Call the session handshaked handler - OnHandshaked(); - - // Call the session handshaked handler in the server - Server.OnHandshakedInternal(this); - - // Call the empty send buffer handler - if (_sendBufferMain.IsEmpty) - OnEmpty(); - } - catch (Exception) - { - SendError(SocketError.NotConnected); - Disconnect(); - } - } - - /// - /// This method is invoked when an asynchronous receive operation completes - /// - private void ProcessReceive(IAsyncResult result) - { - try - { - if (!IsHandshaked) - return; - - // Validate SSL stream Id - var sslStreamId = result.AsyncState as Guid?; - if (_sslStreamId != sslStreamId) - return; - - // End the SSL read - long size = _sslStream.EndRead(result); - - // Received some data from the client - if (size > 0) - { - // Update statistic - BytesReceived += size; - Interlocked.Add(ref Server._bytesReceived, size); - - // Call the buffer received handler - OnReceived(_receiveBuffer.Data, 0, size); - - // If the receive buffer is full increase its size - if (_receiveBuffer.Capacity == size) - { - // Check the receive buffer limit - if (((2 * size) > OptionReceiveBufferLimit) && (OptionReceiveBufferLimit > 0)) - { - SendError(SocketError.NoBufferSpaceAvailable); - Disconnect(); - return; - } - - _receiveBuffer.Reserve(2 * size); - } - } - - _receiving = false; - - // If zero is returned from a read operation, the remote end has closed the connection - if (size > 0) - { - if (!result.CompletedSynchronously) - TryReceive(); - } - else - Disconnect(); - } - catch (Exception) - { - SendError(SocketError.OperationAborted); - Disconnect(); - } - } - - /// - /// This method is invoked when an asynchronous send operation completes - /// - private void ProcessSend(IAsyncResult result) - { - try - { - // Validate SSL stream Id - var sslStreamId = result.AsyncState as Guid?; - if (_sslStreamId != sslStreamId) - return; - - if (!IsHandshaked) - return; - - // End the SSL write - _sslStream.EndWrite(result); - - long size = _sendBufferFlush.Size; - - // Send some data to the client - if (size > 0) - { - // Update statistic - BytesSending -= size; - BytesSent += size; - Interlocked.Add(ref Server._bytesSent, size); - - // Increase the flush buffer offset - _sendBufferFlushOffset += size; - - // Successfully send the whole flush buffer - if (_sendBufferFlushOffset == _sendBufferFlush.Size) - { - // Clear the flush buffer - _sendBufferFlush.Clear(); - _sendBufferFlushOffset = 0; - } - - // Call the buffer sent handler - OnSent(size, BytesPending + BytesSending); - } - - // Try to send again if the session is valid - TrySend(); - } - catch (Exception) - { - SendError(SocketError.OperationAborted); - Disconnect(); - } - } - - #endregion - - #region Session handlers - - /// - /// Handle client connecting notification - /// - protected virtual void OnConnecting() {} - /// - /// Handle client connected notification - /// - protected virtual void OnConnected() {} - /// - /// Handle client handshaking notification - /// - protected virtual void OnHandshaking() {} - /// - /// Handle client handshaked notification - /// - protected virtual void OnHandshaked() {} - /// - /// Handle client disconnecting notification - /// - protected virtual void OnDisconnecting() {} - /// - /// Handle client disconnected notification - /// - protected virtual void OnDisconnected() {} - - /// - /// Handle buffer received notification - /// - /// Received buffer - /// Received buffer offset - /// Received buffer size - /// - /// Notification is called when another chunk of buffer was received from the client - /// - protected virtual void OnReceived(byte[] buffer, long offset, long size) {} - /// - /// Handle buffer sent notification - /// - /// Size of sent buffer - /// Size of pending buffer - /// - /// Notification is called when another chunk of buffer was sent to the client. - /// This handler could be used to send another buffer to the client for instance when the pending size is zero. - /// - protected virtual void OnSent(long sent, long pending) {} - - /// - /// Handle empty send buffer notification - /// - /// - /// Notification is called when the send buffer is empty and ready for a new data to send. - /// This handler could be used to send another buffer to the client. - /// - protected virtual void OnEmpty() {} - - /// - /// Handle error notification - /// - /// Socket error code - protected virtual void OnError(SocketError error) {} - - #endregion - - #region Error handling - - /// - /// Send error notification - /// - /// Socket error code - private void SendError(SocketError error) - { - // Skip disconnect errors - if ((error == SocketError.ConnectionAborted) || - (error == SocketError.ConnectionRefused) || - (error == SocketError.ConnectionReset) || - (error == SocketError.OperationAborted) || - (error == SocketError.Shutdown)) - return; - - OnError(error); - } - - #endregion - - #region IDisposable implementation - - /// - /// Disposed flag - /// - public bool IsDisposed { get; private set; } - - /// - /// Session socket disposed flag - /// - public bool IsSocketDisposed { get; private set; } = true; - - // Implement IDisposable. - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposingManagedResources) - { - // The idea here is that Dispose(Boolean) knows whether it is - // being called to do explicit cleanup (the Boolean is true) - // versus being called due to a garbage collection (the Boolean - // is false). This distinction is useful because, when being - // disposed explicitly, the Dispose(Boolean) method can safely - // execute code using reference type fields that refer to other - // objects knowing for sure that these other objects have not been - // finalized or disposed of yet. When the Boolean is false, - // the Dispose(Boolean) method should not execute code that - // refer to reference type fields because those objects may - // have already been finalized." - - if (!IsDisposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - Disconnect(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - IsDisposed = true; - } - } - - // Use C# destructor syntax for finalization code. - ~SslSession() - { - // Simply call Dispose(false). - Dispose(false); - } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/SslSession.cs.meta b/Plugins/NetCoreServer/SslSession.cs.meta deleted file mode 100644 index f7e1b80a..00000000 --- a/Plugins/NetCoreServer/SslSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 63263b81fa53b864ab998c0b41a0a3ac -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/TcpClient.cs b/Plugins/NetCoreServer/TcpClient.cs deleted file mode 100644 index 4255fa3d..00000000 --- a/Plugins/NetCoreServer/TcpClient.cs +++ /dev/null @@ -1,994 +0,0 @@ -using System; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace NetCoreServer -{ - /// - /// TCP client is used to read/write data from/into the connected TCP server - /// - /// Thread-safe - public class TcpClient : IDisposable - { - /// - /// Initialize TCP client with a given server IP address and port number - /// - /// IP address - /// Port number - public TcpClient(IPAddress address, int port) : this(new IPEndPoint(address, port)) {} - /// - /// Initialize TCP client with a given server IP address and port number - /// - /// IP address - /// Port number - public TcpClient(string address, int port) : this(new IPEndPoint(IPAddress.Parse(address), port)) {} - /// - /// Initialize TCP client with a given IP endpoint - /// - /// IP endpoint - public TcpClient(IPEndPoint endpoint) - { - Id = Guid.NewGuid(); - Endpoint = endpoint; - } - - /// - /// Client Id - /// - public Guid Id { get; } - - /// - /// IP endpoint - /// - public IPEndPoint Endpoint { get; private set; } - /// - /// Socket - /// - public Socket Socket { get; private set; } - - /// - /// Number of bytes pending sent by the client - /// - public long BytesPending { get; private set; } - /// - /// Number of bytes sending by the client - /// - public long BytesSending { get; private set; } - /// - /// Number of bytes sent by the client - /// - public long BytesSent { get; private set; } - /// - /// Number of bytes received by the client - /// - public long BytesReceived { get; private set; } - - /// - /// Option: dual mode socket - /// - /// - /// Specifies whether the Socket is a dual-mode socket used for both IPv4 and IPv6. - /// Will work only if socket is bound on IPv6 address. - /// - public bool OptionDualMode { get; set; } - /// - /// Option: keep alive - /// - /// - /// This option will setup SO_KEEPALIVE if the OS support this feature - /// - public bool OptionKeepAlive { get; set; } - /// - /// Option: no delay - /// - /// - /// This option will enable/disable Nagle's algorithm for TCP protocol - /// - public bool OptionNoDelay { get; set; } - /// - /// Option: receive buffer limit - /// - public int OptionReceiveBufferLimit { get; set; } = 0; - /// - /// Option: receive buffer size - /// - public int OptionReceiveBufferSize { get; set; } = 8192; - /// - /// Option: send buffer limit - /// - public int OptionSendBufferLimit { get; set; } = 0; - /// - /// Option: send buffer size - /// - public int OptionSendBufferSize { get; set; } = 8192; - - #region Connect/Disconnect client - - private SocketAsyncEventArgs _connectEventArg; - - /// - /// Is the client connecting? - /// - public bool IsConnecting { get; private set; } - /// - /// Is the client connected? - /// - public bool IsConnected { get; private set; } - - /// - /// Create a new socket object - /// - /// - /// Method may be override if you need to prepare some specific socket object in your implementation. - /// - /// Socket object - protected virtual Socket CreateSocket() - { - return new Socket(Endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - } - - /// - /// Connect the client (synchronous) - /// - /// - /// Please note that synchronous connect will not receive data automatically! - /// You should use Receive() or ReceiveAsync() method manually after successful connection. - /// - /// 'true' if the client was successfully connected, 'false' if the client failed to connect - public virtual bool Connect() - { - if (IsConnected || IsConnecting) - return false; - - // Setup buffers - _receiveBuffer = new Buffer(); - _sendBufferMain = new Buffer(); - _sendBufferFlush = new Buffer(); - - // Setup event args - _connectEventArg = new SocketAsyncEventArgs(); - _connectEventArg.RemoteEndPoint = Endpoint; - _connectEventArg.Completed += OnAsyncCompleted; - _receiveEventArg = new SocketAsyncEventArgs(); - _receiveEventArg.Completed += OnAsyncCompleted; - _sendEventArg = new SocketAsyncEventArgs(); - _sendEventArg.Completed += OnAsyncCompleted; - - // Create a new client socket - Socket = CreateSocket(); - - // Update the client socket disposed flag - IsSocketDisposed = false; - - // Apply the option: dual mode (this option must be applied before connecting) - if (Socket.AddressFamily == AddressFamily.InterNetworkV6) - Socket.DualMode = OptionDualMode; - - // Call the client connecting handler - OnConnecting(); - - try - { - // Connect to the server - Socket.Connect(Endpoint); - } - catch (SocketException ex) - { - // Call the client error handler - SendError(ex.SocketErrorCode); - - // Reset event args - _connectEventArg.Completed -= OnAsyncCompleted; - _receiveEventArg.Completed -= OnAsyncCompleted; - _sendEventArg.Completed -= OnAsyncCompleted; - - // Call the client disconnecting handler - OnDisconnecting(); - - // Close the client socket - Socket.Close(); - - // Dispose the client socket - Socket.Dispose(); - - // Dispose event arguments - _connectEventArg.Dispose(); - _receiveEventArg.Dispose(); - _sendEventArg.Dispose(); - - // Call the client disconnected handler - OnDisconnected(); - - return false; - } - - // Apply the option: keep alive - if (OptionKeepAlive) - Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); - // Apply the option: no delay - if (OptionNoDelay) - Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - - // Prepare receive & send buffers - _receiveBuffer.Reserve(OptionReceiveBufferSize); - _sendBufferMain.Reserve(OptionSendBufferSize); - _sendBufferFlush.Reserve(OptionSendBufferSize); - - // Reset statistic - BytesPending = 0; - BytesSending = 0; - BytesSent = 0; - BytesReceived = 0; - - // Update the connected flag - IsConnected = true; - - // Call the client connected handler - OnConnected(); - - // Call the empty send buffer handler - if (_sendBufferMain.IsEmpty) - OnEmpty(); - - return true; - } - - /// - /// Disconnect the client (synchronous) - /// - /// 'true' if the client was successfully disconnected, 'false' if the client is already disconnected - public virtual bool Disconnect() - { - if (!IsConnected && !IsConnecting) - return false; - - // Cancel connecting operation - if (IsConnecting) - Socket.CancelConnectAsync(_connectEventArg); - - // Reset event args - _connectEventArg.Completed -= OnAsyncCompleted; - _receiveEventArg.Completed -= OnAsyncCompleted; - _sendEventArg.Completed -= OnAsyncCompleted; - - // Call the client disconnecting handler - OnDisconnecting(); - - try - { - try - { - // Shutdown the socket associated with the client - Socket.Shutdown(SocketShutdown.Both); - } - catch (SocketException) {} - - // Close the client socket - Socket.Close(); - - // Dispose the client socket - Socket.Dispose(); - - // Dispose event arguments - _connectEventArg.Dispose(); - _receiveEventArg.Dispose(); - _sendEventArg.Dispose(); - - // Update the client socket disposed flag - IsSocketDisposed = true; - } - catch (ObjectDisposedException) {} - - // Update the connected flag - IsConnected = false; - - // Update sending/receiving flags - _receiving = false; - _sending = false; - - // Clear send/receive buffers - ClearBuffers(); - - // Call the client disconnected handler - OnDisconnected(); - - return true; - } - - /// - /// Reconnect the client (synchronous) - /// - /// 'true' if the client was successfully reconnected, 'false' if the client is already reconnected - public virtual bool Reconnect() - { - if (!Disconnect()) - return false; - - return Connect(); - } - - /// - /// Connect the client (asynchronous) - /// - /// 'true' if the client was successfully connected, 'false' if the client failed to connect - public virtual bool ConnectAsync() - { - if (IsConnected || IsConnecting) - return false; - - // Setup buffers - _receiveBuffer = new Buffer(); - _sendBufferMain = new Buffer(); - _sendBufferFlush = new Buffer(); - - // Setup event args - _connectEventArg = new SocketAsyncEventArgs(); - _connectEventArg.RemoteEndPoint = Endpoint; - _connectEventArg.Completed += OnAsyncCompleted; - _receiveEventArg = new SocketAsyncEventArgs(); - _receiveEventArg.Completed += OnAsyncCompleted; - _sendEventArg = new SocketAsyncEventArgs(); - _sendEventArg.Completed += OnAsyncCompleted; - - // Create a new client socket - Socket = CreateSocket(); - - // Update the client socket disposed flag - IsSocketDisposed = false; - - // Apply the option: dual mode (this option must be applied before connecting) - if (Socket.AddressFamily == AddressFamily.InterNetworkV6) - Socket.DualMode = OptionDualMode; - - // Update the connecting flag - IsConnecting = true; - - // Call the client connecting handler - OnConnecting(); - - // Async connect to the server - if (!Socket.ConnectAsync(_connectEventArg)) - ProcessConnect(_connectEventArg); - - return true; - } - - /// - /// Disconnect the client (asynchronous) - /// - /// 'true' if the client was successfully disconnected, 'false' if the client is already disconnected - public virtual bool DisconnectAsync() { return Disconnect(); } - - /// - /// Reconnect the client (asynchronous) - /// - /// 'true' if the client was successfully reconnected, 'false' if the client is already reconnected - public virtual bool ReconnectAsync() - { - if (!DisconnectAsync()) - return false; - - while (IsConnected) - Thread.Yield(); - - return ConnectAsync(); - } - - #endregion - - #region Send/Recieve data - - // Receive buffer - private bool _receiving; - private Buffer _receiveBuffer; - private SocketAsyncEventArgs _receiveEventArg; - // Send buffer - private readonly object _sendLock = new object(); - private bool _sending; - private Buffer _sendBufferMain; - private Buffer _sendBufferFlush; - private SocketAsyncEventArgs _sendEventArg; - private long _sendBufferFlushOffset; - - /// - /// Send data to the server (synchronous) - /// - /// Buffer to send - /// Size of sent data - public virtual long Send(byte[] buffer) { return Send(buffer, 0, buffer.Length); } - - /// - /// Send data to the server (synchronous) - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - /// Size of sent data - public virtual long Send(byte[] buffer, long offset, long size) - { - if (!IsConnected) - return 0; - - if (size == 0) - return 0; - - // Sent data to the server - long sent = Socket.Send(buffer, (int)offset, (int)size, SocketFlags.None, out SocketError ec); - if (sent > 0) - { - // Update statistic - BytesSent += sent; - - // Call the buffer sent handler - OnSent(sent, BytesPending + BytesSending); - } - - // Check for socket error - if (ec != SocketError.Success) - { - SendError(ec); - Disconnect(); - } - - return sent; - } - - /// - /// Send text to the server (synchronous) - /// - /// Text string to send - /// Size of sent text - public virtual long Send(string text) { return Send(Encoding.UTF8.GetBytes(text)); } - - /// - /// Send data to the server (asynchronous) - /// - /// Buffer to send - /// 'true' if the data was successfully sent, 'false' if the client is not connected - public virtual bool SendAsync(byte[] buffer) { return SendAsync(buffer, 0, buffer.Length); } - - /// - /// Send data to the server (asynchronous) - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - /// 'true' if the data was successfully sent, 'false' if the client is not connected - public virtual bool SendAsync(byte[] buffer, long offset, long size) - { - if (!IsConnected) - return false; - - if (size == 0) - return true; - - lock (_sendLock) - { - // Check the send buffer limit - if (((_sendBufferMain.Size + size) > OptionSendBufferLimit) && (OptionSendBufferLimit > 0)) - { - SendError(SocketError.NoBufferSpaceAvailable); - return false; - } - - // Fill the main send buffer - _sendBufferMain.Append(buffer, offset, size); - - // Update statistic - BytesPending = _sendBufferMain.Size; - - // Avoid multiple send handlers - if (_sending) - return true; - else - _sending = true; - - // Try to send the main buffer - TrySend(); - } - - return true; - } - - /// - /// Send text to the server (asynchronous) - /// - /// Text string to send - /// 'true' if the text was successfully sent, 'false' if the client is not connected - public virtual bool SendAsync(string text) { return SendAsync(Encoding.UTF8.GetBytes(text)); } - - /// - /// Receive data from the server (synchronous) - /// - /// Buffer to receive - /// Size of received data - public virtual long Receive(byte[] buffer) { return Receive(buffer, 0, buffer.Length); } - - /// - /// Receive data from the server (synchronous) - /// - /// Buffer to receive - /// Buffer offset - /// Buffer size - /// Size of received data - public virtual long Receive(byte[] buffer, long offset, long size) - { - if (!IsConnected) - return 0; - - if (size == 0) - return 0; - - // Receive data from the server - long received = Socket.Receive(buffer, (int)offset, (int)size, SocketFlags.None, out SocketError ec); - if (received > 0) - { - // Update statistic - BytesReceived += received; - - // Call the buffer received handler - OnReceived(buffer, 0, received); - } - - // Check for socket error - if (ec != SocketError.Success) - { - SendError(ec); - Disconnect(); - } - - return received; - } - - /// - /// Receive text from the server (synchronous) - /// - /// Text size to receive - /// Received text - public virtual string Receive(long size) - { - var buffer = new byte[size]; - var length = Receive(buffer); - return Encoding.UTF8.GetString(buffer, 0, (int)length); - } - - /// - /// Receive data from the server (asynchronous) - /// - public virtual void ReceiveAsync() - { - // Try to receive data from the server - TryReceive(); - } - - /// - /// Try to receive new data - /// - private void TryReceive() - { - if (_receiving) - return; - - if (!IsConnected) - return; - - bool process = true; - - while (process) - { - process = false; - - try - { - // Async receive with the receive handler - _receiving = true; - _receiveEventArg.SetBuffer(_receiveBuffer.Data, 0, (int)_receiveBuffer.Capacity); - if (!Socket.ReceiveAsync(_receiveEventArg)) - process = ProcessReceive(_receiveEventArg); - } - catch (ObjectDisposedException) {} - } - } - - /// - /// Try to send pending data - /// - private void TrySend() - { - if (!IsConnected) - return; - - bool empty = false; - bool process = true; - - while (process) - { - process = false; - - lock (_sendLock) - { - // Is previous socket send in progress? - if (_sendBufferFlush.IsEmpty) - { - // Swap flush and main buffers - _sendBufferFlush = Interlocked.Exchange(ref _sendBufferMain, _sendBufferFlush); - _sendBufferFlushOffset = 0; - - // Update statistic - BytesPending = 0; - BytesSending += _sendBufferFlush.Size; - - // Check if the flush buffer is empty - if (_sendBufferFlush.IsEmpty) - { - // Need to call empty send buffer handler - empty = true; - - // End sending process - _sending = false; - } - } - else - return; - } - - // Call the empty send buffer handler - if (empty) - { - OnEmpty(); - return; - } - - try - { - // Async write with the write handler - _sendEventArg.SetBuffer(_sendBufferFlush.Data, (int)_sendBufferFlushOffset, (int)(_sendBufferFlush.Size - _sendBufferFlushOffset)); - if (!Socket.SendAsync(_sendEventArg)) - process = ProcessSend(_sendEventArg); - } - catch (ObjectDisposedException) {} - } - } - - /// - /// Clear send/receive buffers - /// - private void ClearBuffers() - { - lock (_sendLock) - { - // Clear send buffers - _sendBufferMain.Clear(); - _sendBufferFlush.Clear(); - _sendBufferFlushOffset= 0; - - // Update statistic - BytesPending = 0; - BytesSending = 0; - } - } - - #endregion - - #region IO processing - - /// - /// This method is called whenever a receive or send operation is completed on a socket - /// - private void OnAsyncCompleted(object sender, SocketAsyncEventArgs e) - { - if (IsSocketDisposed) - return; - - // Determine which type of operation just completed and call the associated handler - switch (e.LastOperation) - { - case SocketAsyncOperation.Connect: - ProcessConnect(e); - break; - case SocketAsyncOperation.Receive: - if (ProcessReceive(e)) - TryReceive(); - break; - case SocketAsyncOperation.Send: - if (ProcessSend(e)) - TrySend(); - break; - default: - throw new ArgumentException("The last operation completed on the socket was not a receive or send"); - } - - } - - /// - /// This method is invoked when an asynchronous connect operation completes - /// - private void ProcessConnect(SocketAsyncEventArgs e) - { - IsConnecting = false; - - if (e.SocketError == SocketError.Success) - { - // Apply the option: keep alive - if (OptionKeepAlive) - Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); - // Apply the option: no delay - if (OptionNoDelay) - Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - - // Prepare receive & send buffers - _receiveBuffer.Reserve(OptionReceiveBufferSize); - _sendBufferMain.Reserve(OptionSendBufferSize); - _sendBufferFlush.Reserve(OptionSendBufferSize); - - // Reset statistic - BytesPending = 0; - BytesSending = 0; - BytesSent = 0; - BytesReceived = 0; - - // Update the connected flag - IsConnected = true; - - // Try to receive something from the server - TryReceive(); - - // Check the socket disposed state: in some rare cases it might be disconnected while receiving! - if (IsSocketDisposed) - return; - - // Call the client connected handler - OnConnected(); - - // Call the empty send buffer handler - if (_sendBufferMain.IsEmpty) - OnEmpty(); - } - else - { - // Call the client disconnected handler - SendError(e.SocketError); - OnDisconnected(); - } - } - - /// - /// This method is invoked when an asynchronous receive operation completes - /// - private bool ProcessReceive(SocketAsyncEventArgs e) - { - if (!IsConnected) - return false; - - long size = e.BytesTransferred; - - // Received some data from the server - if (size > 0) - { - // Update statistic - BytesReceived += size; - - // Call the buffer received handler - OnReceived(_receiveBuffer.Data, 0, size); - - // If the receive buffer is full increase its size - if (_receiveBuffer.Capacity == size) - { - // Check the receive buffer limit - if (((2 * size) > OptionReceiveBufferLimit) && (OptionReceiveBufferLimit > 0)) - { - SendError(SocketError.NoBufferSpaceAvailable); - DisconnectAsync(); - return false; - } - - _receiveBuffer.Reserve(2 * size); - } - } - - _receiving = false; - - // Try to receive again if the client is valid - if (e.SocketError == SocketError.Success) - { - // If zero is returned from a read operation, the remote end has closed the connection - if (size > 0) - return true; - else - DisconnectAsync(); - } - else - { - SendError(e.SocketError); - DisconnectAsync(); - } - - return false; - } - - /// - /// This method is invoked when an asynchronous send operation completes - /// - private bool ProcessSend(SocketAsyncEventArgs e) - { - if (!IsConnected) - return false; - - long size = e.BytesTransferred; - - // Send some data to the server - if (size > 0) - { - // Update statistic - BytesSending -= size; - BytesSent += size; - - // Increase the flush buffer offset - _sendBufferFlushOffset += size; - - // Successfully send the whole flush buffer - if (_sendBufferFlushOffset == _sendBufferFlush.Size) - { - // Clear the flush buffer - _sendBufferFlush.Clear(); - _sendBufferFlushOffset = 0; - } - - // Call the buffer sent handler - OnSent(size, BytesPending + BytesSending); - } - - // Try to send again if the client is valid - if (e.SocketError == SocketError.Success) - return true; - else - { - SendError(e.SocketError); - DisconnectAsync(); - return false; - } - } - - #endregion - - #region Session handlers - - /// - /// Handle client connecting notification - /// - protected virtual void OnConnecting() {} - /// - /// Handle client connected notification - /// - protected virtual void OnConnected() {} - /// - /// Handle client disconnecting notification - /// - protected virtual void OnDisconnecting() {} - /// - /// Handle client disconnected notification - /// - protected virtual void OnDisconnected() {} - - /// - /// Handle buffer received notification - /// - /// Received buffer - /// Received buffer offset - /// Received buffer size - /// - /// Notification is called when another chunk of buffer was received from the server - /// - protected virtual void OnReceived(byte[] buffer, long offset, long size) {} - /// - /// Handle buffer sent notification - /// - /// Size of sent buffer - /// Size of pending buffer - /// - /// Notification is called when another chunk of buffer was sent to the server. - /// This handler could be used to send another buffer to the server for instance when the pending size is zero. - /// - protected virtual void OnSent(long sent, long pending) {} - - /// - /// Handle empty send buffer notification - /// - /// - /// Notification is called when the send buffer is empty and ready for a new data to send. - /// This handler could be used to send another buffer to the server. - /// - protected virtual void OnEmpty() {} - - /// - /// Handle error notification - /// - /// Socket error code - protected virtual void OnError(SocketError error) {} - - #endregion - - #region Error handling - - /// - /// Send error notification - /// - /// Socket error code - private void SendError(SocketError error) - { - // Skip disconnect errors - if ((error == SocketError.ConnectionAborted) || - (error == SocketError.ConnectionRefused) || - (error == SocketError.ConnectionReset) || - (error == SocketError.OperationAborted) || - (error == SocketError.Shutdown)) - return; - - OnError(error); - } - - #endregion - - #region IDisposable implementation - - /// - /// Disposed flag - /// - public bool IsDisposed { get; private set; } - - /// - /// Client socket disposed flag - /// - public bool IsSocketDisposed { get; private set; } = true; - - // Implement IDisposable. - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposingManagedResources) - { - // The idea here is that Dispose(Boolean) knows whether it is - // being called to do explicit cleanup (the Boolean is true) - // versus being called due to a garbage collection (the Boolean - // is false). This distinction is useful because, when being - // disposed explicitly, the Dispose(Boolean) method can safely - // execute code using reference type fields that refer to other - // objects knowing for sure that these other objects have not been - // finalized or disposed of yet. When the Boolean is false, - // the Dispose(Boolean) method should not execute code that - // refer to reference type fields because those objects may - // have already been finalized." - - if (!IsDisposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - DisconnectAsync(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - IsDisposed = true; - } - } - - // Use C# destructor syntax for finalization code. - ~TcpClient() - { - // Simply call Dispose(false). - Dispose(false); - } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/TcpClient.cs.meta b/Plugins/NetCoreServer/TcpClient.cs.meta deleted file mode 100644 index 697aa21a..00000000 --- a/Plugins/NetCoreServer/TcpClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7a9708a921c3a3540b17c8e8b7dc8deb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/TcpServer.cs b/Plugins/NetCoreServer/TcpServer.cs deleted file mode 100644 index 8cdd311b..00000000 --- a/Plugins/NetCoreServer/TcpServer.cs +++ /dev/null @@ -1,561 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; - -namespace NetCoreServer -{ - /// - /// TCP server is used to connect, disconnect and manage TCP sessions - /// - /// Thread-safe - public class TcpServer : IDisposable - { - /// - /// Initialize TCP server with a given IP address and port number - /// - /// IP address - /// Port number - public TcpServer(IPAddress address, int port) : this(new IPEndPoint(address, port)) {} - /// - /// Initialize TCP server with a given IP address and port number - /// - /// IP address - /// Port number - public TcpServer(string address, int port) : this(new IPEndPoint(IPAddress.Parse(address), port)) {} - /// - /// Initialize TCP server with a given IP endpoint - /// - /// IP endpoint - public TcpServer(IPEndPoint endpoint) - { - Id = Guid.NewGuid(); - Endpoint = endpoint; - } - - /// - /// Server Id - /// - public Guid Id { get; } - - /// - /// IP endpoint - /// - public IPEndPoint Endpoint { get; private set; } - - /// - /// Number of sessions connected to the server - /// - public long ConnectedSessions { get { return Sessions.Count; } } - /// - /// Number of bytes pending sent by the server - /// - public long BytesPending { get { return _bytesPending; } } - /// - /// Number of bytes sent by the server - /// - public long BytesSent { get { return _bytesSent; } } - /// - /// Number of bytes received by the server - /// - public long BytesReceived { get { return _bytesReceived; } } - - /// - /// Option: acceptor backlog size - /// - /// - /// This option will set the listening socket's backlog size - /// - public int OptionAcceptorBacklog { get; set; } = 1024; - /// - /// Option: dual mode socket - /// - /// - /// Specifies whether the Socket is a dual-mode socket used for both IPv4 and IPv6. - /// Will work only if socket is bound on IPv6 address. - /// - public bool OptionDualMode { get; set; } - /// - /// Option: keep alive - /// - /// - /// This option will setup SO_KEEPALIVE if the OS support this feature - /// - public bool OptionKeepAlive { get; set; } - /// - /// Option: no delay - /// - /// - /// This option will enable/disable Nagle's algorithm for TCP protocol - /// - public bool OptionNoDelay { get; set; } - /// - /// Option: reuse address - /// - /// - /// This option will enable/disable SO_REUSEADDR if the OS support this feature - /// - public bool OptionReuseAddress { get; set; } - /// - /// Option: enables a socket to be bound for exclusive access - /// - /// - /// This option will enable/disable SO_EXCLUSIVEADDRUSE if the OS support this feature - /// - public bool OptionExclusiveAddressUse { get; set; } - /// - /// Option: receive buffer size - /// - public int OptionReceiveBufferSize { get; set; } = 8192; - /// - /// Option: send buffer size - /// - public int OptionSendBufferSize { get; set; } = 8192; - - #region Start/Stop server - - // Server acceptor - private Socket _acceptorSocket; - private SocketAsyncEventArgs _acceptorEventArg; - - // Server statistic - internal long _bytesPending; - internal long _bytesSent; - internal long _bytesReceived; - - /// - /// Is the server started? - /// - public bool IsStarted { get; private set; } - /// - /// Is the server accepting new clients? - /// - public bool IsAccepting { get; private set; } - - /// - /// Create a new socket object - /// - /// - /// Method may be override if you need to prepare some specific socket object in your implementation. - /// - /// Socket object - protected virtual Socket CreateSocket() - { - return new Socket(Endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - } - - /// - /// Start the server - /// - /// 'true' if the server was successfully started, 'false' if the server failed to start - public virtual bool Start() - { - Debug.Assert(!IsStarted, "TCP server is already started!"); - if (IsStarted) - return false; - - // Setup acceptor event arg - _acceptorEventArg = new SocketAsyncEventArgs(); - _acceptorEventArg.Completed += OnAsyncCompleted; - - // Create a new acceptor socket - _acceptorSocket = CreateSocket(); - - // Update the acceptor socket disposed flag - IsSocketDisposed = false; - - // Apply the option: reuse address - _acceptorSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, OptionReuseAddress); - // Apply the option: exclusive address use - _acceptorSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, OptionExclusiveAddressUse); - // Apply the option: dual mode (this option must be applied before listening) - if (_acceptorSocket.AddressFamily == AddressFamily.InterNetworkV6) - _acceptorSocket.DualMode = OptionDualMode; - - // Bind the acceptor socket to the IP endpoint - _acceptorSocket.Bind(Endpoint); - // Refresh the endpoint property based on the actual endpoint created - Endpoint = (IPEndPoint)_acceptorSocket.LocalEndPoint; - - // Call the server starting handler - OnStarting(); - - // Start listen to the acceptor socket with the given accepting backlog size - _acceptorSocket.Listen(OptionAcceptorBacklog); - - // Reset statistic - _bytesPending = 0; - _bytesSent = 0; - _bytesReceived = 0; - - // Update the started flag - IsStarted = true; - - // Call the server started handler - OnStarted(); - - // Perform the first server accept - IsAccepting = true; - StartAccept(_acceptorEventArg); - - return true; - } - - /// - /// Stop the server - /// - /// 'true' if the server was successfully stopped, 'false' if the server is already stopped - public virtual bool Stop() - { - Debug.Assert(IsStarted, "TCP server is not started!"); - if (!IsStarted) - return false; - - // Stop accepting new clients - IsAccepting = false; - - // Reset acceptor event arg - _acceptorEventArg.Completed -= OnAsyncCompleted; - - // Call the server stopping handler - OnStopping(); - - try - { - // Close the acceptor socket - _acceptorSocket.Close(); - - // Dispose the acceptor socket - _acceptorSocket.Dispose(); - - // Dispose event arguments - _acceptorEventArg.Dispose(); - - // Update the acceptor socket disposed flag - IsSocketDisposed = true; - } - catch (ObjectDisposedException) {} - - // Disconnect all sessions - DisconnectAll(); - - // Update the started flag - IsStarted = false; - - // Call the server stopped handler - OnStopped(); - - return true; - } - - /// - /// Restart the server - /// - /// 'true' if the server was successfully restarted, 'false' if the server failed to restart - public virtual bool Restart() - { - if (!Stop()) - return false; - - while (IsStarted) - Thread.Yield(); - - return Start(); - } - - #endregion - - #region Accepting clients - - /// - /// Start accept a new client connection - /// - private void StartAccept(SocketAsyncEventArgs e) - { - // Socket must be cleared since the context object is being reused - e.AcceptSocket = null; - - // Async accept a new client connection - if (!_acceptorSocket.AcceptAsync(e)) - ProcessAccept(e); - } - - /// - /// Process accepted client connection - /// - private void ProcessAccept(SocketAsyncEventArgs e) - { - if (e.SocketError == SocketError.Success) - { - // Create a new session to register - var session = CreateSession(); - - // Register the session - RegisterSession(session); - - // Connect new session - session.Connect(e.AcceptSocket); - } - else - SendError(e.SocketError); - - // Accept the next client connection - if (IsAccepting) - StartAccept(e); - } - - /// - /// This method is the callback method associated with Socket.AcceptAsync() - /// operations and is invoked when an accept operation is complete - /// - private void OnAsyncCompleted(object sender, SocketAsyncEventArgs e) - { - if (IsSocketDisposed) - return; - - ProcessAccept(e); - } - - #endregion - - #region Session factory - - /// - /// Create TCP session factory method - /// - /// TCP session - protected virtual TcpSession CreateSession() { return new TcpSession(this); } - - #endregion - - #region Session management - - // Server sessions - protected readonly ConcurrentDictionary Sessions = new ConcurrentDictionary(); - - /// - /// Disconnect all connected sessions - /// - /// 'true' if all sessions were successfully disconnected, 'false' if the server is not started - public virtual bool DisconnectAll() - { - if (!IsStarted) - return false; - - // Disconnect all sessions - foreach (var session in Sessions.Values) - session.Disconnect(); - - return true; - } - - /// - /// Find a session with a given Id - /// - /// Session Id - /// Session with a given Id or null if the session it not connected - public TcpSession FindSession(Guid id) - { - // Try to find the required session - return Sessions.TryGetValue(id, out TcpSession result) ? result : null; - } - - /// - /// Register a new session - /// - /// Session to register - internal void RegisterSession(TcpSession session) - { - // Register a new session - Sessions.TryAdd(session.Id, session); - } - - /// - /// Unregister session by Id - /// - /// Session Id - internal void UnregisterSession(Guid id) - { - // Unregister session by Id - Sessions.TryRemove(id, out TcpSession temp); - } - - #endregion - - #region Multicasting - - /// - /// Multicast data to all connected sessions - /// - /// Buffer to multicast - /// 'true' if the data was successfully multicasted, 'false' if the data was not multicasted - public virtual bool Multicast(byte[] buffer) { return Multicast(buffer, 0, buffer.Length); } - - /// - /// Multicast data to all connected clients - /// - /// Buffer to multicast - /// Buffer offset - /// Buffer size - /// 'true' if the data was successfully multicasted, 'false' if the data was not multicasted - public virtual bool Multicast(byte[] buffer, long offset, long size) - { - if (!IsStarted) - return false; - - if (size == 0) - return true; - - // Multicast data to all sessions - foreach (var session in Sessions.Values) - session.SendAsync(buffer, offset, size); - - return true; - } - - /// - /// Multicast text to all connected clients - /// - /// Text string to multicast - /// 'true' if the text was successfully multicasted, 'false' if the text was not multicasted - public virtual bool Multicast(string text) { return Multicast(Encoding.UTF8.GetBytes(text)); } - - #endregion - - #region Server handlers - - /// - /// Handle server starting notification - /// - protected virtual void OnStarting() {} - /// - /// Handle server started notification - /// - protected virtual void OnStarted() {} - /// - /// Handle server stopping notification - /// - protected virtual void OnStopping() {} - /// - /// Handle server stopped notification - /// - protected virtual void OnStopped() {} - - /// - /// Handle session connecting notification - /// - /// Connecting session - protected virtual void OnConnecting(TcpSession session) {} - /// - /// Handle session connected notification - /// - /// Connected session - protected virtual void OnConnected(TcpSession session) {} - /// - /// Handle session disconnecting notification - /// - /// Disconnecting session - protected virtual void OnDisconnecting(TcpSession session) {} - /// - /// Handle session disconnected notification - /// - /// Disconnected session - protected virtual void OnDisconnected(TcpSession session) {} - - /// - /// Handle error notification - /// - /// Socket error code - protected virtual void OnError(SocketError error) {} - - internal void OnConnectingInternal(TcpSession session) { OnConnecting(session); } - internal void OnConnectedInternal(TcpSession session) { OnConnected(session); } - internal void OnDisconnectingInternal(TcpSession session) { OnDisconnecting(session); } - internal void OnDisconnectedInternal(TcpSession session) { OnDisconnected(session); } - - #endregion - - #region Error handling - - /// - /// Send error notification - /// - /// Socket error code - private void SendError(SocketError error) - { - // Skip disconnect errors - if ((error == SocketError.ConnectionAborted) || - (error == SocketError.ConnectionRefused) || - (error == SocketError.ConnectionReset) || - (error == SocketError.OperationAborted) || - (error == SocketError.Shutdown)) - return; - - OnError(error); - } - - #endregion - - #region IDisposable implementation - - /// - /// Disposed flag - /// - public bool IsDisposed { get; private set; } - - /// - /// Acceptor socket disposed flag - /// - public bool IsSocketDisposed { get; private set; } = true; - - // Implement IDisposable. - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposingManagedResources) - { - // The idea here is that Dispose(Boolean) knows whether it is - // being called to do explicit cleanup (the Boolean is true) - // versus being called due to a garbage collection (the Boolean - // is false). This distinction is useful because, when being - // disposed explicitly, the Dispose(Boolean) method can safely - // execute code using reference type fields that refer to other - // objects knowing for sure that these other objects have not been - // finalized or disposed of yet. When the Boolean is false, - // the Dispose(Boolean) method should not execute code that - // refer to reference type fields because those objects may - // have already been finalized." - - if (!IsDisposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - Stop(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - IsDisposed = true; - } - } - - // Use C# destructor syntax for finalization code. - ~TcpServer() - { - // Simply call Dispose(false). - Dispose(false); - } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/TcpServer.cs.meta b/Plugins/NetCoreServer/TcpServer.cs.meta deleted file mode 100644 index 62195fab..00000000 --- a/Plugins/NetCoreServer/TcpServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 101abb21a85972840b901983f616cf74 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/TcpSession.cs b/Plugins/NetCoreServer/TcpSession.cs deleted file mode 100644 index 76625e0c..00000000 --- a/Plugins/NetCoreServer/TcpSession.cs +++ /dev/null @@ -1,777 +0,0 @@ -using System; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace NetCoreServer -{ - /// - /// TCP session is used to read and write data from the connected TCP client - /// - /// Thread-safe - public class TcpSession : IDisposable - { - /// - /// Initialize the session with a given server - /// - /// TCP server - public TcpSession(TcpServer server) - { - Id = Guid.NewGuid(); - Server = server; - OptionReceiveBufferSize = server.OptionReceiveBufferSize; - OptionSendBufferSize = server.OptionSendBufferSize; - } - - /// - /// Session Id - /// - public Guid Id { get; } - - /// - /// Server - /// - public TcpServer Server { get; } - /// - /// Socket - /// - public Socket Socket { get; private set; } - - /// - /// Number of bytes pending sent by the session - /// - public long BytesPending { get; private set; } - /// - /// Number of bytes sending by the session - /// - public long BytesSending { get; private set; } - /// - /// Number of bytes sent by the session - /// - public long BytesSent { get; private set; } - /// - /// Number of bytes received by the session - /// - public long BytesReceived { get; private set; } - - /// - /// Option: receive buffer limit - /// - public int OptionReceiveBufferLimit { get; set; } = 0; - /// - /// Option: receive buffer size - /// - public int OptionReceiveBufferSize { get; set; } = 8192; - /// - /// Option: send buffer limit - /// - public int OptionSendBufferLimit { get; set; } = 0; - /// - /// Option: send buffer size - /// - public int OptionSendBufferSize { get; set; } = 8192; - - #region Connect/Disconnect session - - /// - /// Is the session connected? - /// - public bool IsConnected { get; private set; } - - /// - /// Connect the session - /// - /// Session socket - internal void Connect(Socket socket) - { - Socket = socket; - - // Update the session socket disposed flag - IsSocketDisposed = false; - - // Setup buffers - _receiveBuffer = new Buffer(); - _sendBufferMain = new Buffer(); - _sendBufferFlush = new Buffer(); - - // Setup event args - _receiveEventArg = new SocketAsyncEventArgs(); - _receiveEventArg.Completed += OnAsyncCompleted; - _sendEventArg = new SocketAsyncEventArgs(); - _sendEventArg.Completed += OnAsyncCompleted; - - // Apply the option: keep alive - if (Server.OptionKeepAlive) - Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); - // Apply the option: no delay - if (Server.OptionNoDelay) - Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - - // Prepare receive & send buffers - _receiveBuffer.Reserve(OptionReceiveBufferSize); - _sendBufferMain.Reserve(OptionSendBufferSize); - _sendBufferFlush.Reserve(OptionSendBufferSize); - - // Reset statistic - BytesPending = 0; - BytesSending = 0; - BytesSent = 0; - BytesReceived = 0; - - // Call the session connecting handler - OnConnecting(); - - // Call the session connecting handler in the server - Server.OnConnectingInternal(this); - - // Update the connected flag - IsConnected = true; - - // Try to receive something from the client - TryReceive(); - - // Check the socket disposed state: in some rare cases it might be disconnected while receiving! - if (IsSocketDisposed) - return; - - // Call the session connected handler - OnConnected(); - - // Call the session connected handler in the server - Server.OnConnectedInternal(this); - - // Call the empty send buffer handler - if (_sendBufferMain.IsEmpty) - OnEmpty(); - } - - /// - /// Disconnect the session - /// - /// 'true' if the section was successfully disconnected, 'false' if the section is already disconnected - public virtual bool Disconnect() - { - if (!IsConnected) - return false; - - // Reset event args - _receiveEventArg.Completed -= OnAsyncCompleted; - _sendEventArg.Completed -= OnAsyncCompleted; - - // Call the session disconnecting handler - OnDisconnecting(); - - // Call the session disconnecting handler in the server - Server.OnDisconnectingInternal(this); - - try - { - try - { - // Shutdown the socket associated with the client - Socket.Shutdown(SocketShutdown.Both); - } - catch (SocketException) {} - - // Close the session socket - Socket.Close(); - - // Dispose the session socket - Socket.Dispose(); - - // Dispose event arguments - _receiveEventArg.Dispose(); - _sendEventArg.Dispose(); - - // Update the session socket disposed flag - IsSocketDisposed = true; - } - catch (ObjectDisposedException) {} - - // Update the connected flag - IsConnected = false; - - // Update sending/receiving flags - _receiving = false; - _sending = false; - - // Clear send/receive buffers - ClearBuffers(); - - // Call the session disconnected handler - OnDisconnected(); - - // Call the session disconnected handler in the server - Server.OnDisconnectedInternal(this); - - // Unregister session - Server.UnregisterSession(Id); - - return true; - } - - #endregion - - #region Send/Recieve data - - // Receive buffer - private bool _receiving; - private Buffer _receiveBuffer; - private SocketAsyncEventArgs _receiveEventArg; - // Send buffer - private readonly object _sendLock = new object(); - private bool _sending; - private Buffer _sendBufferMain; - private Buffer _sendBufferFlush; - private SocketAsyncEventArgs _sendEventArg; - private long _sendBufferFlushOffset; - - /// - /// Send data to the client (synchronous) - /// - /// Buffer to send - /// Size of sent data - public virtual long Send(byte[] buffer) { return Send(buffer, 0, buffer.Length); } - - /// - /// Send data to the client (synchronous) - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - /// Size of sent data - public virtual long Send(byte[] buffer, long offset, long size) - { - if (!IsConnected) - return 0; - - if (size == 0) - return 0; - - // Sent data to the client - long sent = Socket.Send(buffer, (int)offset, (int)size, SocketFlags.None, out SocketError ec); - if (sent > 0) - { - // Update statistic - BytesSent += sent; - Interlocked.Add(ref Server._bytesSent, size); - - // Call the buffer sent handler - OnSent(sent, BytesPending + BytesSending); - } - - // Check for socket error - if (ec != SocketError.Success) - { - SendError(ec); - Disconnect(); - } - - return sent; - } - - /// - /// Send text to the client (synchronous) - /// - /// Text string to send - /// Size of sent data - public virtual long Send(string text) { return Send(Encoding.UTF8.GetBytes(text)); } - - /// - /// Send data to the client (asynchronous) - /// - /// Buffer to send - /// 'true' if the data was successfully sent, 'false' if the session is not connected - public virtual bool SendAsync(byte[] buffer) { return SendAsync(buffer, 0, buffer.Length); } - - /// - /// Send data to the client (asynchronous) - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - /// 'true' if the data was successfully sent, 'false' if the session is not connected - public virtual bool SendAsync(byte[] buffer, long offset, long size) - { - if (!IsConnected) - return false; - - if (size == 0) - return true; - - lock (_sendLock) - { - // Check the send buffer limit - if (((_sendBufferMain.Size + size) > OptionSendBufferLimit) && (OptionSendBufferLimit > 0)) - { - SendError(SocketError.NoBufferSpaceAvailable); - return false; - } - - // Fill the main send buffer - _sendBufferMain.Append(buffer, offset, size); - - // Update statistic - BytesPending = _sendBufferMain.Size; - - // Avoid multiple send handlers - if (_sending) - return true; - else - _sending = true; - - // Try to send the main buffer - TrySend(); - } - - return true; - } - - /// - /// Send text to the client (asynchronous) - /// - /// Text string to send - /// 'true' if the text was successfully sent, 'false' if the session is not connected - public virtual bool SendAsync(string text) { return SendAsync(Encoding.UTF8.GetBytes(text)); } - - /// - /// Receive data from the client (synchronous) - /// - /// Buffer to receive - /// Size of received data - public virtual long Receive(byte[] buffer) { return Receive(buffer, 0, buffer.Length); } - - /// - /// Receive data from the client (synchronous) - /// - /// Buffer to receive - /// Buffer offset - /// Buffer size - /// Size of received data - public virtual long Receive(byte[] buffer, long offset, long size) - { - if (!IsConnected) - return 0; - - if (size == 0) - return 0; - - // Receive data from the client - long received = Socket.Receive(buffer, (int)offset, (int)size, SocketFlags.None, out SocketError ec); - if (received > 0) - { - // Update statistic - BytesReceived += received; - Interlocked.Add(ref Server._bytesReceived, received); - - // Call the buffer received handler - OnReceived(buffer, 0, received); - } - - // Check for socket error - if (ec != SocketError.Success) - { - SendError(ec); - Disconnect(); - } - - return received; - } - - /// - /// Receive text from the client (synchronous) - /// - /// Text size to receive - /// Received text - public virtual string Receive(long size) - { - var buffer = new byte[size]; - var length = Receive(buffer); - return Encoding.UTF8.GetString(buffer, 0, (int)length); - } - - /// - /// Receive data from the client (asynchronous) - /// - public virtual void ReceiveAsync() - { - // Try to receive data from the client - TryReceive(); - } - - /// - /// Try to receive new data - /// - private void TryReceive() - { - if (_receiving) - return; - - if (!IsConnected) - return; - - bool process = true; - - while (process) - { - process = false; - - try - { - // Async receive with the receive handler - _receiving = true; - _receiveEventArg.SetBuffer(_receiveBuffer.Data, 0, (int)_receiveBuffer.Capacity); - if (!Socket.ReceiveAsync(_receiveEventArg)) - process = ProcessReceive(_receiveEventArg); - } - catch (ObjectDisposedException) {} - } - } - - /// - /// Try to send pending data - /// - private void TrySend() - { - if (!IsConnected) - return; - - bool empty = false; - bool process = true; - - while (process) - { - process = false; - - lock (_sendLock) - { - // Is previous socket send in progress? - if (_sendBufferFlush.IsEmpty) - { - // Swap flush and main buffers - _sendBufferFlush = Interlocked.Exchange(ref _sendBufferMain, _sendBufferFlush); - _sendBufferFlushOffset = 0; - - // Update statistic - BytesPending = 0; - BytesSending += _sendBufferFlush.Size; - - // Check if the flush buffer is empty - if (_sendBufferFlush.IsEmpty) - { - // Need to call empty send buffer handler - empty = true; - - // End sending process - _sending = false; - } - } - else - return; - } - - // Call the empty send buffer handler - if (empty) - { - OnEmpty(); - return; - } - - try - { - // Async write with the write handler - _sendEventArg.SetBuffer(_sendBufferFlush.Data, (int)_sendBufferFlushOffset, (int)(_sendBufferFlush.Size - _sendBufferFlushOffset)); - if (!Socket.SendAsync(_sendEventArg)) - process = ProcessSend(_sendEventArg); - } - catch (ObjectDisposedException) {} - } - } - - /// - /// Clear send/receive buffers - /// - private void ClearBuffers() - { - lock (_sendLock) - { - // Clear send buffers - _sendBufferMain.Clear(); - _sendBufferFlush.Clear(); - _sendBufferFlushOffset= 0; - - // Update statistic - BytesPending = 0; - BytesSending = 0; - } - } - - #endregion - - #region IO processing - - /// - /// This method is called whenever a receive or send operation is completed on a socket - /// - private void OnAsyncCompleted(object sender, SocketAsyncEventArgs e) - { - if (IsSocketDisposed) - return; - - // Determine which type of operation just completed and call the associated handler - switch (e.LastOperation) - { - case SocketAsyncOperation.Receive: - if (ProcessReceive(e)) - TryReceive(); - break; - case SocketAsyncOperation.Send: - if (ProcessSend(e)) - TrySend(); - break; - default: - throw new ArgumentException("The last operation completed on the socket was not a receive or send"); - } - - } - - /// - /// This method is invoked when an asynchronous receive operation completes - /// - private bool ProcessReceive(SocketAsyncEventArgs e) - { - if (!IsConnected) - return false; - - long size = e.BytesTransferred; - - // Received some data from the client - if (size > 0) - { - // Update statistic - BytesReceived += size; - Interlocked.Add(ref Server._bytesReceived, size); - - // Call the buffer received handler - OnReceived(_receiveBuffer.Data, 0, size); - - // If the receive buffer is full increase its size - if (_receiveBuffer.Capacity == size) - { - // Check the receive buffer limit - if (((2 * size) > OptionReceiveBufferLimit) && (OptionReceiveBufferLimit > 0)) - { - SendError(SocketError.NoBufferSpaceAvailable); - Disconnect(); - return false; - } - - _receiveBuffer.Reserve(2 * size); - } - } - - _receiving = false; - - // Try to receive again if the session is valid - if (e.SocketError == SocketError.Success) - { - // If zero is returned from a read operation, the remote end has closed the connection - if (size > 0) - return true; - else - Disconnect(); - } - else - { - SendError(e.SocketError); - Disconnect(); - } - - return false; - } - - /// - /// This method is invoked when an asynchronous send operation completes - /// - private bool ProcessSend(SocketAsyncEventArgs e) - { - if (!IsConnected) - return false; - - long size = e.BytesTransferred; - - // Send some data to the client - if (size > 0) - { - // Update statistic - BytesSending -= size; - BytesSent += size; - Interlocked.Add(ref Server._bytesSent, size); - - // Increase the flush buffer offset - _sendBufferFlushOffset += size; - - // Successfully send the whole flush buffer - if (_sendBufferFlushOffset == _sendBufferFlush.Size) - { - // Clear the flush buffer - _sendBufferFlush.Clear(); - _sendBufferFlushOffset = 0; - } - - // Call the buffer sent handler - OnSent(size, BytesPending + BytesSending); - } - - // Try to send again if the session is valid - if (e.SocketError == SocketError.Success) - return true; - else - { - SendError(e.SocketError); - Disconnect(); - return false; - } - } - - #endregion - - #region Session handlers - - /// - /// Handle client connecting notification - /// - protected virtual void OnConnecting() {} - /// - /// Handle client connected notification - /// - protected virtual void OnConnected() {} - /// - /// Handle client disconnecting notification - /// - protected virtual void OnDisconnecting() {} - /// - /// Handle client disconnected notification - /// - protected virtual void OnDisconnected() {} - - /// - /// Handle buffer received notification - /// - /// Received buffer - /// Received buffer offset - /// Received buffer size - /// - /// Notification is called when another chunk of buffer was received from the client - /// - protected virtual void OnReceived(byte[] buffer, long offset, long size) {} - /// - /// Handle buffer sent notification - /// - /// Size of sent buffer - /// Size of pending buffer - /// - /// Notification is called when another chunk of buffer was sent to the client. - /// This handler could be used to send another buffer to the client for instance when the pending size is zero. - /// - protected virtual void OnSent(long sent, long pending) {} - - /// - /// Handle empty send buffer notification - /// - /// - /// Notification is called when the send buffer is empty and ready for a new data to send. - /// This handler could be used to send another buffer to the client. - /// - protected virtual void OnEmpty() {} - - /// - /// Handle error notification - /// - /// Socket error code - protected virtual void OnError(SocketError error) {} - - #endregion - - #region Error handling - - /// - /// Send error notification - /// - /// Socket error code - private void SendError(SocketError error) - { - // Skip disconnect errors - if ((error == SocketError.ConnectionAborted) || - (error == SocketError.ConnectionRefused) || - (error == SocketError.ConnectionReset) || - (error == SocketError.OperationAborted) || - (error == SocketError.Shutdown)) - return; - - OnError(error); - } - - #endregion - - #region IDisposable implementation - - /// - /// Disposed flag - /// - public bool IsDisposed { get; private set; } - - /// - /// Session socket disposed flag - /// - public bool IsSocketDisposed { get; private set; } = true; - - // Implement IDisposable. - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposingManagedResources) - { - // The idea here is that Dispose(Boolean) knows whether it is - // being called to do explicit cleanup (the Boolean is true) - // versus being called due to a garbage collection (the Boolean - // is false). This distinction is useful because, when being - // disposed explicitly, the Dispose(Boolean) method can safely - // execute code using reference type fields that refer to other - // objects knowing for sure that these other objects have not been - // finalized or disposed of yet. When the Boolean is false, - // the Dispose(Boolean) method should not execute code that - // refer to reference type fields because those objects may - // have already been finalized." - - if (!IsDisposed) - { - if (disposingManagedResources) - { - // Dispose managed resources here... - Disconnect(); - } - - // Dispose unmanaged resources here... - - // Set large fields to null here... - - // Mark as disposed. - IsDisposed = true; - } - } - - // Use C# destructor syntax for finalization code. - ~TcpSession() - { - // Simply call Dispose(false). - Dispose(false); - } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/TcpSession.cs.meta b/Plugins/NetCoreServer/TcpSession.cs.meta deleted file mode 100644 index 55a94392..00000000 --- a/Plugins/NetCoreServer/TcpSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fa84f3de0cf867145a3025a04d99c933 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/Utilities.cs b/Plugins/NetCoreServer/Utilities.cs deleted file mode 100644 index 0776c676..00000000 --- a/Plugins/NetCoreServer/Utilities.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Text; - -namespace NetCoreServer -{ - /// - /// Conversion metrics utilities - /// - public class Utilities - { - /// - /// Generate data size string. Will return a pretty string of bytes, KiB, MiB, GiB, TiB based on the given bytes. - /// - /// Data size in bytes - /// String with data size representation - public static string GenerateDataSize(double b) - { - var sb = new StringBuilder(); - - long bytes = (long)b; - long absBytes = Math.Abs(bytes); - - if (absBytes >= (1024L * 1024L * 1024L * 1024L)) - { - long tb = bytes / (1024L * 1024L * 1024L * 1024L); - long gb = (bytes % (1024L * 1024L * 1024L * 1024L)) / (1024 * 1024 * 1024); - sb.Append(tb); - sb.Append('.'); - sb.Append((gb < 100) ? "0" : ""); - sb.Append((gb < 10) ? "0" : ""); - sb.Append(gb); - sb.Append(" TiB"); - } - else if (absBytes >= (1024 * 1024 * 1024)) - { - long gb = bytes / (1024 * 1024 * 1024); - long mb = (bytes % (1024 * 1024 * 1024)) / (1024 * 1024); - sb.Append(gb); - sb.Append('.'); - sb.Append((mb < 100) ? "0" : ""); - sb.Append((mb < 10) ? "0" : ""); - sb.Append(mb); - sb.Append(" GiB"); - } - else if (absBytes >= (1024 * 1024)) - { - long mb = bytes / (1024 * 1024); - long kb = (bytes % (1024 * 1024)) / 1024; - sb.Append(mb); - sb.Append('.'); - sb.Append((kb < 100) ? "0" : ""); - sb.Append((kb < 10) ? "0" : ""); - sb.Append(kb); - sb.Append(" MiB"); - } - else if (absBytes >= 1024) - { - long kb = bytes / 1024; - bytes = bytes % 1024; - sb.Append(kb); - sb.Append('.'); - sb.Append((bytes < 100) ? "0" : ""); - sb.Append((bytes < 10) ? "0" : ""); - sb.Append(bytes); - sb.Append(" KiB"); - } - else - { - sb.Append(bytes); - sb.Append(" bytes"); - } - - return sb.ToString(); - } - - /// - /// Generate time period string. Will return a pretty string of ns, mcs, ms, s, m, h based on the given nanoseconds. - /// - /// Milliseconds - /// String with time period representation - public static string GenerateTimePeriod(double ms) - { - var sb = new StringBuilder(); - - long nanoseconds = (long) (ms * 1000.0 * 1000.0); - long absNanoseconds = Math.Abs(nanoseconds); - - if (absNanoseconds >= (60 * 60 * 1000000000L)) - { - long hours = nanoseconds / (60 * 60 * 1000000000L); - long minutes = ((nanoseconds % (60 * 60 * 1000000000L)) / 1000000000) / 60; - long seconds = ((nanoseconds % (60 * 60 * 1000000000L)) / 1000000000) % 60; - long milliseconds = ((nanoseconds % (60 * 60 * 1000000000L)) % 1000000000) / 1000000; - sb.Append(hours); - sb.Append(':'); - sb.Append((minutes < 10) ? "0" : ""); - sb.Append(minutes); - sb.Append(':'); - sb.Append((seconds < 10) ? "0" : ""); - sb.Append(seconds); - sb.Append('.'); - sb.Append((milliseconds < 100) ? "0" : ""); - sb.Append((milliseconds < 10) ? "0" : ""); - sb.Append(milliseconds); - sb.Append(" h"); - } - else if (absNanoseconds >= (60 * 1000000000L)) - { - long minutes = nanoseconds / (60 * 1000000000L); - long seconds = (nanoseconds % (60 * 1000000000L)) / 1000000000; - long milliseconds = ((nanoseconds % (60 * 1000000000L)) % 1000000000) / 1000000; - sb.Append(minutes); - sb.Append(':'); - sb.Append((seconds < 10) ? "0" : ""); - sb.Append(seconds); - sb.Append('.'); - sb.Append((milliseconds < 100) ? "0" : ""); - sb.Append((milliseconds < 10) ? "0" : ""); - sb.Append(milliseconds); - sb.Append(" m"); - } - else if (absNanoseconds >= 1000000000) - { - long seconds = nanoseconds / 1000000000; - long milliseconds = (nanoseconds % 1000000000) / 1000000; - sb.Append(seconds); - sb.Append('.'); - sb.Append((milliseconds < 100) ? "0" : ""); - sb.Append((milliseconds < 10) ? "0" : ""); - sb.Append(milliseconds); - sb.Append(" s"); - } - else if (absNanoseconds >= 1000000) - { - long milliseconds = nanoseconds / 1000000; - long microseconds = (nanoseconds % 1000000) / 1000; - sb.Append(milliseconds); - sb.Append('.'); - sb.Append((microseconds < 100) ? "0" : ""); - sb.Append((microseconds < 10) ? "0" : ""); - sb.Append(microseconds); - sb.Append(" ms"); - } - else if (absNanoseconds >= 1000) - { - long microseconds = nanoseconds / 1000; - nanoseconds = nanoseconds % 1000; - sb.Append(microseconds); - sb.Append('.'); - sb.Append((nanoseconds < 100) ? "0" : ""); - sb.Append((nanoseconds < 10) ? "0" : ""); - sb.Append(nanoseconds); - sb.Append(" mcs"); - } - else - { - sb.Append(nanoseconds); - sb.Append(" ns"); - } - - return sb.ToString(); - } - } -} diff --git a/Plugins/NetCoreServer/Utilities.cs.meta b/Plugins/NetCoreServer/Utilities.cs.meta deleted file mode 100644 index 1627ec8b..00000000 --- a/Plugins/NetCoreServer/Utilities.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fe5df566e27b42a4f841c628bf991a86 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/WebSocket.cs b/Plugins/NetCoreServer/WebSocket.cs deleted file mode 100644 index 97688863..00000000 --- a/Plugins/NetCoreServer/WebSocket.cs +++ /dev/null @@ -1,620 +0,0 @@ -using System; -using System.Text; -using System.Security.Cryptography; -using System.Collections.Generic; -using System.Net.Sockets; - -namespace NetCoreServer -{ - /// - /// WebSocket utility class - /// - public class WebSocket : IWebSocket - { - private readonly IWebSocket _wsHandler; - - public WebSocket(IWebSocket wsHandler) { _wsHandler = wsHandler; ClearWsBuffers(); InitWsNonce(); } - - /// - /// Final frame - /// - public const byte WS_FIN = 0x80; - /// - /// Text frame - /// - public const byte WS_TEXT = 0x01; - /// - /// Binary frame - /// - public const byte WS_BINARY = 0x02; - /// - /// Close frame - /// - public const byte WS_CLOSE = 0x08; - /// - /// Ping frame - /// - public const byte WS_PING = 0x09; - /// - /// Pong frame - /// - public const byte WS_PONG = 0x0A; - - /// - /// Perform WebSocket client upgrade - /// - /// WebSocket upgrade HTTP response - /// WebSocket client Id - /// 'true' if the WebSocket was successfully upgrade, 'false' if the WebSocket was not upgrade - public bool PerformClientUpgrade(HttpResponse response, Guid id) - { - if (response.Status != 101) - return false; - - bool error = false; - bool accept = false; - bool connection = false; - bool upgrade = false; - - // Validate WebSocket handshake headers - for (int i = 0; i < response.Headers; i++) - { - var header = response.Header(i); - var key = header.Item1; - var value = header.Item2; - - if (string.Compare(key, "Connection", StringComparison.OrdinalIgnoreCase) == 0) - { - if (string.Compare(value, "Upgrade", StringComparison.OrdinalIgnoreCase) != 0) - { - error = true; - _wsHandler.OnWsError("Invalid WebSocket handshaked response: 'Connection' header value must be 'Upgrade'"); - break; - } - - connection = true; - } - else if (string.Compare(key, "Upgrade", StringComparison.OrdinalIgnoreCase) == 0) - { - if (string.Compare(value, "websocket", StringComparison.OrdinalIgnoreCase) != 0) - { - error = true; - _wsHandler.OnWsError("Invalid WebSocket handshaked response: 'Upgrade' header value must be 'websocket'"); - break; - } - - upgrade = true; - } - else if (string.Compare(key, "Sec-WebSocket-Accept", StringComparison.OrdinalIgnoreCase) == 0) - { - // Calculate the original WebSocket hash - string wskey = Convert.ToBase64String(WsNonce) + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - string wshash; - using (SHA1Managed sha1 = new SHA1Managed()) - { - wshash = Encoding.UTF8.GetString(sha1.ComputeHash(Encoding.UTF8.GetBytes(wskey))); - } - - // Get the received WebSocket hash - wskey = Encoding.UTF8.GetString(Convert.FromBase64String(value)); - - // Compare original and received hashes - if (string.Compare(wskey, wshash, StringComparison.InvariantCulture) != 0) - { - error = true; - _wsHandler.OnWsError("Invalid WebSocket handshaked response: 'Sec-WebSocket-Accept' value validation failed"); - break; - } - - accept = true; - } - } - - // Failed to perform WebSocket handshake - if (!accept || !connection || !upgrade) - { - if (!error) - _wsHandler.OnWsError("Invalid WebSocket response"); - return false; - } - - // WebSocket successfully handshaked! - WsHandshaked = true; - WsRandom.NextBytes(WsSendMask); - _wsHandler.OnWsConnected(response); - - return true; - } - - /// - /// Perform WebSocket server upgrade - /// - /// WebSocket upgrade HTTP request - /// WebSocket upgrade HTTP response - /// 'true' if the WebSocket was successfully upgrade, 'false' if the WebSocket was not upgrade - public bool PerformServerUpgrade(HttpRequest request, HttpResponse response) - { - if (request.Method != "GET") - return false; - - bool error = false; - bool connection = false; - bool upgrade = false; - bool wsKey = false; - bool wsVersion = false; - - string accept = ""; - - // Validate WebSocket handshake headers - for (int i = 0; i < request.Headers; i++) - { - var header = request.Header(i); - var key = header.Item1; - var value = header.Item2; - - if (string.Compare(key, "Connection", StringComparison.OrdinalIgnoreCase) == 0) - { - if ((string.Compare(value, "Upgrade", StringComparison.OrdinalIgnoreCase) != 0) && (string.Compare(value, "keep-alive, Upgrade", StringComparison.OrdinalIgnoreCase) != 0)) - { - error = true; - response.MakeErrorResponse(400, "Invalid WebSocket handshaked request: 'Connection' header value must be 'Upgrade' or 'keep-alive, Upgrade'"); - break; - } - - connection = true; - } - else if (string.Compare(key, "Upgrade", StringComparison.OrdinalIgnoreCase) == 0) - { - if (string.Compare(value, "websocket", StringComparison.OrdinalIgnoreCase) != 0) - { - error = true; - response.MakeErrorResponse(400, "Invalid WebSocket handshaked request: 'Upgrade' header value must be 'websocket'"); - break; - } - - upgrade = true; - } - else if (string.Compare(key, "Sec-WebSocket-Key", StringComparison.OrdinalIgnoreCase) == 0) - { - if (string.IsNullOrEmpty(value)) - { - error = true; - response.MakeErrorResponse(400, "Invalid WebSocket handshaked request: 'Sec-WebSocket-Key' header value must be non empty"); - break; - } - - // Calculate the original WebSocket hash - string wskey = value + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - byte[] wshash; - using (SHA1Managed sha1 = new SHA1Managed()) - { - wshash = sha1.ComputeHash(Encoding.UTF8.GetBytes(wskey)); - } - - accept = Convert.ToBase64String(wshash); - - wsKey = true; - } - else if (string.Compare(key, "Sec-WebSocket-Version", StringComparison.OrdinalIgnoreCase) == 0) - { - if (string.Compare(value, "13", StringComparison.OrdinalIgnoreCase) != 0) - { - error = true; - response.MakeErrorResponse(400, "Invalid WebSocket handshaked request: 'Sec-WebSocket-Version' header value must be '13'"); - break; - } - - wsVersion = true; - } - } - - // Filter out non WebSocket handshake requests - if (!connection && !upgrade && !wsKey && !wsVersion) - return false; - - // Failed to perform WebSocket handshake - if (!connection || !upgrade || !wsKey || !wsVersion) - { - if (!error) - response.MakeErrorResponse(400, "Invalid WebSocket response"); - _wsHandler.SendUpgrade(response); - return false; - } - - // Prepare WebSocket upgrade success response - response.Clear(); - response.SetBegin(101); - response.SetHeader("Connection", "Upgrade"); - response.SetHeader("Upgrade", "websocket"); - response.SetHeader("Sec-WebSocket-Accept", accept); - response.SetBody(); - - // Validate WebSocket upgrade request and response - if (!_wsHandler.OnWsConnecting(request, response)) - return false; - - // Send WebSocket upgrade response - _wsHandler.SendUpgrade(response); - - // WebSocket successfully handshaked! - WsHandshaked = true; - for (int i = 0; i < WsSendMask.Length; ++i) - { - WsSendMask[i] = 0; - } - _wsHandler.OnWsConnected(request); - - return true; - } - - /// - /// Prepare WebSocket send frame - /// - /// WebSocket opcode - /// WebSocket mask - /// Buffer to send - /// Buffer offset - /// Buffer size - /// WebSocket status (default is 0) - public void PrepareSendFrame(byte opcode, bool mask, byte[] buffer, long offset, long size, int status = 0) - { - // Clear the previous WebSocket send buffer - WsSendBuffer.Clear(); - - // Append WebSocket frame opcode - WsSendBuffer.Add(opcode); - - // Append WebSocket frame size - if (size <= 125) - WsSendBuffer.Add((byte)(((int)size & 0xFF) | (mask ? 0x80 : 0))); - else if (size <= 65535) - { - WsSendBuffer.Add((byte)(126 | (mask ? 0x80 : 0))); - WsSendBuffer.Add((byte)((size >> 8) & 0xFF)); - WsSendBuffer.Add((byte)(size & 0xFF)); - } - else - { - WsSendBuffer.Add((byte)(127 | (mask ? 0x80 : 0))); - for (int i = 7; i >= 0; i--) - WsSendBuffer.Add((byte)((size >> (8 * i)) & 0xFF)); - } - - if (mask) - { - // Append WebSocket frame mask - WsSendBuffer.Add(WsSendMask[0]); - WsSendBuffer.Add(WsSendMask[1]); - WsSendBuffer.Add(WsSendMask[2]); - WsSendBuffer.Add(WsSendMask[3]); - } - - // Resize WebSocket frame buffer - int bufferOffset = WsSendBuffer.Count; - WsSendBuffer.AddRange(new byte[size]); - - // Mask WebSocket frame content - for (int i = 0; i < size; i++) - WsSendBuffer[bufferOffset + i] = (byte)(buffer[offset + i] ^ WsSendMask[i % 4]); - } - - /// - /// Prepare WebSocket send frame - /// - /// Buffer to send - /// Buffer offset - /// Buffer size - public void PrepareReceiveFrame(byte[] buffer, long offset, long size) - { - lock (WsReceiveLock) - { - var index = 0; - - // Clear received data after WebSocket frame was processed - if (WsFrameReceived) - { - WsFrameReceived = false; - WsHeaderSize = 0; - WsPayloadSize = 0; - WsReceiveFrameBuffer.Clear(); - Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length); - } - if (WsFinalReceived) - { - WsFinalReceived = false; - WsReceiveFinalBuffer.Clear(); - } - - while (size > 0) - { - // Clear received data after WebSocket frame was processed - if (WsFrameReceived) - { - WsFrameReceived = false; - WsHeaderSize = 0; - WsPayloadSize = 0; - WsReceiveFrameBuffer.Clear(); - Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length); - } - if (WsFinalReceived) - { - WsFinalReceived = false; - WsReceiveFinalBuffer.Clear(); - } - - // Prepare WebSocket frame opcode and mask flag - if (WsReceiveFrameBuffer.Count < 2) - { - for (int i = 0; i < 2; i++, index++, size--) - { - if (size == 0) - return; - WsReceiveFrameBuffer.Add(buffer[offset + index]); - } - } - - byte opcode = (byte)(WsReceiveFrameBuffer[0] & 0x0F); - bool fin = ((WsReceiveFrameBuffer[0] >> 7) & 0x01) != 0; - bool mask = ((WsReceiveFrameBuffer[1] >> 7) & 0x01) != 0; - int payload = WsReceiveFrameBuffer[1] & (~0x80); - - // Prepare WebSocket opcode - WsOpcode = (opcode != 0) ? opcode : WsOpcode; - - // Prepare WebSocket frame size - if (payload <= 125) - { - WsHeaderSize = 2 + (mask ? 4 : 0); - WsPayloadSize = payload; - } - else if (payload == 126) - { - if (WsReceiveFrameBuffer.Count < 4) - { - for (int i = 0; i < 2; i++, index++, size--) - { - if (size == 0) - return; - WsReceiveFrameBuffer.Add(buffer[offset + index]); - } - } - - payload = ((WsReceiveFrameBuffer[2] << 8) | (WsReceiveFrameBuffer[3] << 0)); - WsHeaderSize = 4 + (mask ? 4 : 0); - WsPayloadSize = payload; - } - else if (payload == 127) - { - if (WsReceiveFrameBuffer.Count < 10) - { - for (int i = 0; i < 8; i++, index++, size--) - { - if (size == 0) - return; - WsReceiveFrameBuffer.Add(buffer[offset + index]); - } - } - - payload = ((WsReceiveFrameBuffer[2] << 56) | (WsReceiveFrameBuffer[3] << 48) | (WsReceiveFrameBuffer[4] << 40) | (WsReceiveFrameBuffer[5] << 32) | (WsReceiveFrameBuffer[6] << 24) | (WsReceiveFrameBuffer[7] << 16) | (WsReceiveFrameBuffer[8] << 8) | (WsReceiveFrameBuffer[9] << 0)); - WsHeaderSize = 10 + (mask ? 4 : 0); - WsPayloadSize = payload; - } - - // Prepare WebSocket frame mask - if (mask) - { - if (WsReceiveFrameBuffer.Count < WsHeaderSize) - { - for (int i = 0; i < 4; i++, index++, size--) - { - if (size == 0) - return; - WsReceiveFrameBuffer.Add(buffer[offset + index]); - WsReceiveMask[i] = buffer[offset + index]; - } - } - } - - int total = WsHeaderSize + WsPayloadSize; - int length = Math.Min(total - WsReceiveFrameBuffer.Count, (int)size); - - // Prepare WebSocket frame payload - for (int i = (int)offset + index; i < (int)offset + index + length; ++i) - { - WsReceiveFrameBuffer.Add(buffer[i]); - } - index += length; - size -= length; - - // Process WebSocket frame - if (WsReceiveFrameBuffer.Count == total) - { - // Unmask WebSocket frame content - if (mask) - { - for (int i = 0; i < WsPayloadSize; i++) - WsReceiveFinalBuffer.Add((byte)(WsReceiveFrameBuffer[WsHeaderSize + i] ^ WsReceiveMask[i % 4])); - } - else - WsReceiveFinalBuffer.AddRange(WsReceiveFrameBuffer.GetRange(WsHeaderSize, WsPayloadSize)); - - WsFrameReceived = true; - - // Finalize WebSocket frame - if (fin) - { - WsFinalReceived = true; - - switch (WsOpcode) - { - case WS_PING: - { - // Call the WebSocket ping handler - _wsHandler.OnWsPing(WsReceiveFinalBuffer.ToArray(), 0, WsReceiveFinalBuffer.Count); - break; - } - case WS_PONG: - { - // Call the WebSocket pong handler - _wsHandler.OnWsPong(WsReceiveFinalBuffer.ToArray(), 0, WsReceiveFinalBuffer.Count); - break; - } - case WS_CLOSE: - { - // Call the WebSocket close handler - _wsHandler.OnWsClose(WsReceiveFinalBuffer.ToArray(), 0, WsReceiveFinalBuffer.Count); - break; - } - case WS_BINARY: - case WS_TEXT: - { - // Call the WebSocket received handler - _wsHandler.OnWsReceived(WsReceiveFinalBuffer.ToArray(), 0, WsReceiveFinalBuffer.Count); - break; - } - } - } - } - } - } - } - - /// - /// Required WebSocket receive frame size - /// - public int RequiredReceiveFrameSize() - { - lock (WsReceiveLock) - { - if (WsFrameReceived) - return 0; - - // Required WebSocket frame opcode and mask flag - if (WsReceiveFrameBuffer.Count < 2) - return 2 - WsReceiveFrameBuffer.Count; - - bool mask = ((WsReceiveFrameBuffer[1] >> 7) & 0x01) != 0; - int payload = WsReceiveFrameBuffer[1] & (~0x80); - - // Required WebSocket frame size - if ((payload == 126) && (WsReceiveFrameBuffer.Count < 4)) - return 4 - WsReceiveFrameBuffer.Count; - if ((payload == 127) && (WsReceiveFrameBuffer.Count < 10)) - return 10 - WsReceiveFrameBuffer.Count; - - // Required WebSocket frame mask - if ((mask) && (WsReceiveFrameBuffer.Count < WsHeaderSize)) - return WsHeaderSize - WsReceiveFrameBuffer.Count; - - // Required WebSocket frame payload - return WsHeaderSize + WsPayloadSize - WsReceiveFrameBuffer.Count; - } - } - - /// - /// Clear WebSocket send/receive buffers - /// - public void ClearWsBuffers() - { - lock (WsReceiveLock) - { - WsFrameReceived = false; - WsFinalReceived = false; - WsHeaderSize = 0; - WsPayloadSize = 0; - WsReceiveFrameBuffer.Clear(); - WsReceiveFinalBuffer.Clear(); - Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length); - } - - lock (WsSendLock) - { - WsSendBuffer.Clear(); - Array.Clear(WsSendMask, 0, WsSendMask.Length); - } - } - - /// - /// Initialize WebSocket random nonce - /// - public void InitWsNonce() => WsRandom.NextBytes(WsNonce); - - public void OnWsConnecting(HttpRequest request) {} - public void OnWsConnected(HttpResponse response) {} - public bool OnWsConnecting(HttpRequest request, HttpResponse response) { return true; } - public void OnWsConnected(HttpRequest request) {} - public void OnWsDisconnecting() {} - public void OnWsDisconnected() {} - public void OnWsReceived(byte[] buffer, long offset, long size) {} - public void OnWsClose(byte[] buffer, long offset, long size) {} - public void OnWsPing(byte[] buffer, long offset, long size) {} - public void OnWsPong(byte[] buffer, long offset, long size) {} - public void OnWsError(string error) {} - public void OnWsError(SocketError error) {} - public void SendUpgrade(HttpResponse response) {} - - /// - /// Handshaked flag - /// - internal bool WsHandshaked; - /// - /// Received frame flag - /// - internal bool WsFrameReceived; - /// - /// Received final flag - /// - internal bool WsFinalReceived; - /// - /// Received frame opcode - /// - internal int WsOpcode; - /// - /// Received frame header size - /// - internal int WsHeaderSize; - /// - /// Received frame payload size - /// - internal int WsPayloadSize; - - /// - /// Receive buffer lock - /// - internal readonly object WsReceiveLock = new object(); - /// - /// Receive frame buffer - /// - internal readonly List WsReceiveFrameBuffer = new List(); - /// - /// Receive final buffer - /// - internal readonly List WsReceiveFinalBuffer = new List(); - /// - /// Receive mask - /// - internal readonly byte[] WsReceiveMask = new byte[4]; - - /// - /// Send buffer lock - /// - internal readonly object WsSendLock = new object(); - /// - /// Send buffer - /// - internal readonly List WsSendBuffer = new List(); - /// - /// Send mask - /// - internal readonly byte[] WsSendMask = new byte[4]; - - /// - /// WebSocket random generator - /// - internal readonly Random WsRandom = new Random(); - /// - /// WebSocket random nonce of 16 bytes - /// - internal readonly byte[] WsNonce = new byte[16]; - } -} diff --git a/Plugins/NetCoreServer/WebSocket.cs.meta b/Plugins/NetCoreServer/WebSocket.cs.meta deleted file mode 100644 index 78ca3814..00000000 --- a/Plugins/NetCoreServer/WebSocket.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d3b99cb73dd994842ac6c5b13bbde4df -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/WsClient.cs b/Plugins/NetCoreServer/WsClient.cs deleted file mode 100644 index 8f67a229..00000000 --- a/Plugins/NetCoreServer/WsClient.cs +++ /dev/null @@ -1,443 +0,0 @@ -using System.Net; -using System.Net.Sockets; -using System.Text; - -namespace NetCoreServer -{ - /// - /// WebSocket client - /// - /// WebSocket client is used to communicate with WebSocket server. Thread-safe. - public class WsClient : HttpClient, IWebSocket - { - internal readonly WebSocket WebSocket; - - /// - /// Initialize WebSocket client with a given IP address and port number - /// - /// IP address - /// Port number - public WsClient(IPAddress address, int port) : base(address, port) { WebSocket = new WebSocket(this); } - /// - /// Initialize WebSocket client with a given IP address and port number - /// - /// IP address - /// Port number - public WsClient(string address, int port) : base(address, port) { WebSocket = new WebSocket(this); } - /// - /// Initialize WebSocket client with a given IP endpoint - /// - /// IP endpoint - public WsClient(IPEndPoint endpoint) : base(endpoint) { WebSocket = new WebSocket(this); } - - /// - /// WebSocket random nonce - /// - public byte[] WsNonce => WebSocket.WsNonce; - - #region WebSocket connection methods - - public override bool Connect() { _syncConnect = true; return base.Connect(); } - public override bool ConnectAsync() { _syncConnect = false; return base.ConnectAsync(); } - public virtual bool Close(int status) { SendClose(status, null, 0, 0); base.Disconnect(); return true; } - public virtual bool CloseAsync(int status) { SendCloseAsync(status, null, 0, 0); base.DisconnectAsync(); return true; } - - #endregion - - #region WebSocket send text methods - - public long SendText(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, true, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendText(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, true, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendTextAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, true, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendTextAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send binary methods - - public long SendBinary(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, true, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendBinary(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, true, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendBinaryAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, true, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendBinaryAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send close methods - - public long SendClose(int status, byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, true, buffer, offset, size, status); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendClose(int status, string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, true, data, 0, data.Length, status); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendCloseAsync(int status, byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, true, buffer, offset, size, status); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendCloseAsync(int status, string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, true, data, 0, data.Length, status); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send ping methods - - public long SendPing(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendPing(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPingAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPingAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send pong methods - - public long SendPong(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, true, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendPong(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, true, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPongAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, true, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPongAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket receive methods - - public string ReceiveText() - { - Buffer result = new Buffer(); - - if (!WebSocket.WsHandshaked) - return result.ExtractString(0, result.Data.Length); - - Buffer cache = new Buffer(); - - // Receive WebSocket frame data - while (!WebSocket.WsFinalReceived) - { - while (!WebSocket.WsFrameReceived) - { - int required = WebSocket.RequiredReceiveFrameSize(); - cache.Resize(required); - int received = (int)base.Receive(cache.Data, 0, required); - if (received != required) - return result.ExtractString(0, result.Data.Length); - WebSocket.PrepareReceiveFrame(cache.Data, 0, received); - } - if (!WebSocket.WsFinalReceived) - WebSocket.PrepareReceiveFrame(null, 0, 0); - } - - // Copy WebSocket frame data - result.Append(WebSocket.WsReceiveFinalBuffer.ToArray(), 0, WebSocket.WsReceiveFinalBuffer.Count); - WebSocket.PrepareReceiveFrame(null, 0, 0); - return result.ExtractString(0, result.Data.Length); - } - - public Buffer ReceiveBinary() - { - Buffer result = new Buffer(); - - if (!WebSocket.WsHandshaked) - return result; - - Buffer cache = new Buffer(); - - // Receive WebSocket frame data - while (!WebSocket.WsFinalReceived) - { - while (!WebSocket.WsFrameReceived) - { - int required = WebSocket.RequiredReceiveFrameSize(); - cache.Resize(required); - int received = (int)base.Receive(cache.Data, 0, required); - if (received != required) - return result; - WebSocket.PrepareReceiveFrame(cache.Data, 0, received); - } - if (!WebSocket.WsFinalReceived) - WebSocket.PrepareReceiveFrame(null, 0, 0); - } - - // Copy WebSocket frame data - result.Append(WebSocket.WsReceiveFinalBuffer.ToArray(), 0, WebSocket.WsReceiveFinalBuffer.Count); - WebSocket.PrepareReceiveFrame(null, 0, 0); - return result; - } - - #endregion - - #region Session handlers - - protected override void OnConnected() - { - // Clear WebSocket send/receive buffers - WebSocket.ClearWsBuffers(); - - // Fill the WebSocket upgrade HTTP request - OnWsConnecting(Request); - - // Send the WebSocket upgrade HTTP request - if (_syncConnect) - SendRequest(Request); - else - SendRequestAsync(Request); - } - - protected override void OnDisconnecting() - { - if (WebSocket.WsHandshaked) - OnWsDisconnecting(); - } - - protected override void OnDisconnected() - { - // Disconnect WebSocket - if (WebSocket.WsHandshaked) - { - WebSocket.WsHandshaked = false; - OnWsDisconnected(); - } - - // Reset WebSocket upgrade HTTP request and response - Request.Clear(); - Response.Clear(); - - // Clear WebSocket send/receive buffers - WebSocket.ClearWsBuffers(); - - // Initialize new WebSocket random nonce - WebSocket.InitWsNonce(); - } - - protected override void OnReceived(byte[] buffer, long offset, long size) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - // Prepare receive frame - WebSocket.PrepareReceiveFrame(buffer, offset, size); - return; - } - - base.OnReceived(buffer, offset, size); - } - - protected override void OnReceivedResponseHeader(HttpResponse response) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - return; - - // Try to perform WebSocket upgrade - if (!WebSocket.PerformClientUpgrade(response, Id)) - { - base.OnReceivedResponseHeader(response); - return; - } - } - - protected override void OnReceivedResponse(HttpResponse response) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - // Prepare receive frame from the remaining response body - var body = Response.Body; - var data = Encoding.UTF8.GetBytes(body); - WebSocket.PrepareReceiveFrame(data, 0, data.Length); - return; - } - - base.OnReceivedResponse(response); - } - - protected override void OnReceivedResponseError(HttpResponse response, string error) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - OnError(new SocketError()); - return; - } - - base.OnReceivedResponseError(response, error); - } - - #endregion - - #region Web socket handlers - - public virtual void OnWsConnecting(HttpRequest request) {} - public virtual void OnWsConnected(HttpResponse response) {} - public virtual bool OnWsConnecting(HttpRequest request, HttpResponse response) { return true; } - public virtual void OnWsConnected(HttpRequest request) {} - public virtual void OnWsDisconnecting() {} - public virtual void OnWsDisconnected() {} - public virtual void OnWsReceived(byte[] buffer, long offset, long size) {} - public virtual void OnWsClose(byte[] buffer, long offset, long size) { CloseAsync(1000); } - public virtual void OnWsPing(byte[] buffer, long offset, long size) { SendPongAsync(buffer, offset, size); } - public virtual void OnWsPong(byte[] buffer, long offset, long size) {} - public virtual void OnWsError(string error) { OnError(SocketError.SocketError); } - public virtual void OnWsError(SocketError error) { OnError(error); } - public virtual void SendUpgrade(HttpResponse response) {} - - #endregion - - // Sync connect flag - private bool _syncConnect; - } -} diff --git a/Plugins/NetCoreServer/WsClient.cs.meta b/Plugins/NetCoreServer/WsClient.cs.meta deleted file mode 100644 index 7d67ddcf..00000000 --- a/Plugins/NetCoreServer/WsClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9d6801ac66149d943b5fe370066d1d98 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/WsServer.cs b/Plugins/NetCoreServer/WsServer.cs deleted file mode 100644 index a20d8afd..00000000 --- a/Plugins/NetCoreServer/WsServer.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System.Net; -using System.Net.Sockets; -using System.Text; - -namespace NetCoreServer -{ - /// - /// WebSocket server - /// - /// WebSocket server is used to communicate with clients using WebSocket protocol. Thread-safe. - public class WsServer : HttpServer, IWebSocket - { - internal readonly WebSocket WebSocket; - - /// - /// Initialize WebSocket server with a given IP address and port number - /// - /// IP address - /// Port number - public WsServer(IPAddress address, int port) : base(address, port) { WebSocket = new WebSocket(this); } - /// - /// Initialize WebSocket server with a given IP address and port number - /// - /// IP address - /// Port number - public WsServer(string address, int port) : base(address, port) { WebSocket = new WebSocket(this); } - /// - /// Initialize WebSocket server with a given IP endpoint - /// - /// IP endpoint - public WsServer(IPEndPoint endpoint) : base(endpoint) { WebSocket = new WebSocket(this); } - - public virtual bool CloseAll(int status) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, null, 0, 0, status); - if (!Multicast(WebSocket.WsSendBuffer.ToArray())) - return false; - - return base.DisconnectAll(); - } - } - - public override bool Multicast(byte[] buffer, long offset, long size) - { - if (!IsStarted) - return false; - - if (size == 0) - return true; - - // Multicast data to all WebSocket sessions - foreach (var session in Sessions.Values) - { - if (session is WsSession wsSession) - { - if (wsSession.WebSocket.WsHandshaked) - wsSession.SendAsync(buffer, offset, size); - } - } - - return true; - } - - #region WebSocket multicast text methods - - public bool MulticastText(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, buffer, offset, size); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool MulticastText(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, data, 0, data.Length); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket multicast binary methods - - public bool MulticastBinary(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, buffer, offset, size); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool MulticastBinary(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, data, 0, data.Length); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket multicast ping methods - - public bool SendPing(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, buffer, offset, size); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPing(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, data, 0, data.Length); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket multicast pong methods - - public bool SendPong(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, buffer, offset, size); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPong(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, data, 0, data.Length); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - protected override TcpSession CreateSession() { return new WsSession(this); } - - public void OnWsConnecting(HttpRequest request) { } - public void OnWsConnected(HttpResponse response) { } - public bool OnWsConnecting(HttpRequest request, HttpResponse response) { return true; } - public void OnWsConnected(HttpRequest request) { } - public void OnWsDisconnecting() { } - public void OnWsDisconnected() { } - public void OnWsReceived(byte[] buffer, long offset, long size) { } - public void OnWsClose(byte[] buffer, long offset, long size) { } - public void OnWsPing(byte[] buffer, long offset, long size) { } - public void OnWsPong(byte[] buffer, long offset, long size) { } - public void OnWsError(string error) { } - public void OnWsError(SocketError error) { } - public void SendUpgrade(HttpResponse response) { } - } -} diff --git a/Plugins/NetCoreServer/WsServer.cs.meta b/Plugins/NetCoreServer/WsServer.cs.meta deleted file mode 100644 index 2c335264..00000000 --- a/Plugins/NetCoreServer/WsServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7250c01c753e03d43a61428fd961f48a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/WsSession.cs b/Plugins/NetCoreServer/WsSession.cs deleted file mode 100644 index 77a107ef..00000000 --- a/Plugins/NetCoreServer/WsSession.cs +++ /dev/null @@ -1,398 +0,0 @@ -using System.Net.Sockets; -using System.Text; - -namespace NetCoreServer -{ - /// - /// WebSocket session - /// - /// WebSocket session is used to read and write data from the connected WebSocket client. Thread-safe. - public class WsSession : HttpSession, IWebSocket - { - internal readonly WebSocket WebSocket; - - public WsSession(WsServer server) : base(server) { WebSocket = new WebSocket(this); } - - // WebSocket connection methods - public virtual bool Close(int status) { SendCloseAsync(status, null, 0, 0); base.Disconnect(); return true; } - - #region WebSocket send text methods - - public long SendText(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendText(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendTextAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendTextAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send binary methods - - public long SendBinary(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendBinary(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendBinaryAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendBinaryAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send close methods - - public long SendClose(int status, byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, buffer, offset, size, status); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendClose(int status, string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, data, 0, data.Length, status); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendCloseAsync(int status, byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, buffer, offset, size, status); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendCloseAsync(int status, string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, data, 0, data.Length, status); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send ping methods - - public long SendPing(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendPing(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPingAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPingAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send pong methods - - public long SendPong(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendPong(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPongAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPongAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket receive methods - - public string ReceiveText() - { - Buffer result = new Buffer(); - - if (!WebSocket.WsHandshaked) - return result.ExtractString(0, result.Data.Length); - - Buffer cache = new Buffer(); - - // Receive WebSocket frame data - while (!WebSocket.WsFinalReceived) - { - while (!WebSocket.WsFrameReceived) - { - int required = WebSocket.RequiredReceiveFrameSize(); - cache.Resize(required); - int received = (int)base.Receive(cache.Data, 0, required); - if (received != required) - return result.ExtractString(0, result.Data.Length); - WebSocket.PrepareReceiveFrame(cache.Data, 0, received); - } - if (!WebSocket.WsFinalReceived) - WebSocket.PrepareReceiveFrame(null, 0, 0); - } - - // Copy WebSocket frame data - result.Append(WebSocket.WsReceiveFinalBuffer.ToArray(), 0, WebSocket.WsReceiveFinalBuffer.Count); - WebSocket.PrepareReceiveFrame(null, 0, 0); - return result.ExtractString(0, result.Data.Length); - } - - public Buffer ReceiveBinary() - { - Buffer result = new Buffer(); - - if (!WebSocket.WsHandshaked) - return result; - - Buffer cache = new Buffer(); - - // Receive WebSocket frame data - while (!WebSocket.WsFinalReceived) - { - while (!WebSocket.WsFrameReceived) - { - int required = WebSocket.RequiredReceiveFrameSize(); - cache.Resize(required); - int received = (int)base.Receive(cache.Data, 0, required); - if (received != required) - return result; - WebSocket.PrepareReceiveFrame(cache.Data, 0, received); - } - if (!WebSocket.WsFinalReceived) - WebSocket.PrepareReceiveFrame(null, 0, 0); - } - - // Copy WebSocket frame data - result.Append(WebSocket.WsReceiveFinalBuffer.ToArray(), 0, WebSocket.WsReceiveFinalBuffer.Count); - WebSocket.PrepareReceiveFrame(null, 0, 0); - return result; - } - - #endregion - - #region Session handlers - - protected override void OnDisconnecting() - { - if (WebSocket.WsHandshaked) - OnWsDisconnecting(); - } - - protected override void OnDisconnected() - { - // Disconnect WebSocket - if (WebSocket.WsHandshaked) - { - WebSocket.WsHandshaked = false; - OnWsDisconnected(); - } - - // Reset WebSocket upgrade HTTP request and response - Request.Clear(); - Response.Clear(); - - // Clear WebSocket send/receive buffers - WebSocket.ClearWsBuffers(); - - // Initialize new WebSocket random nonce - WebSocket.InitWsNonce(); - } - - protected override void OnReceived(byte[] buffer, long offset, long size) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - // Prepare receive frame - WebSocket.PrepareReceiveFrame(buffer, offset, size); - return; - } - - base.OnReceived(buffer, offset, size); - } - - protected override void OnReceivedRequestHeader(HttpRequest request) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - return; - - // Try to perform WebSocket upgrade - if (!WebSocket.PerformServerUpgrade(request, Response)) - { - base.OnReceivedRequestHeader(request); - return; - } - } - - protected override void OnReceivedRequest(HttpRequest request) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - // Prepare receive frame from the remaining request body - var body = Request.Body; - var data = Encoding.UTF8.GetBytes(body); - WebSocket.PrepareReceiveFrame(data, 0, data.Length); - return; - } - - base.OnReceivedRequest(request); - } - - protected override void OnReceivedRequestError(HttpRequest request, string error) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - OnError(new SocketError()); - return; - } - - base.OnReceivedRequestError(request, error); - } - - #endregion - - #region Web socket handlers - - public virtual void OnWsConnecting(HttpRequest request) { } - public virtual void OnWsConnected(HttpResponse response) { } - public virtual bool OnWsConnecting(HttpRequest request, HttpResponse response) { return true; } - public virtual void OnWsConnected(HttpRequest request) { } - public virtual void OnWsDisconnecting() { } - public virtual void OnWsDisconnected() { } - public virtual void OnWsReceived(byte[] buffer, long offset, long size) { } - public virtual void OnWsClose(byte[] buffer, long offset, long size) { Close(1000); } - public virtual void OnWsPing(byte[] buffer, long offset, long size) { SendPongAsync(buffer, offset, size); } - public virtual void OnWsPong(byte[] buffer, long offset, long size) { } - public virtual void OnWsError(string error) { OnError(SocketError.SocketError); } - public virtual void OnWsError(SocketError error) { OnError(error); } - - public void SendUpgrade(HttpResponse response) { SendResponseAsync(response); } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/WsSession.cs.meta b/Plugins/NetCoreServer/WsSession.cs.meta deleted file mode 100644 index 3dd044e9..00000000 --- a/Plugins/NetCoreServer/WsSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d849693d6fbd99f43ba085856cc3b5de -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/WssClient.cs b/Plugins/NetCoreServer/WssClient.cs deleted file mode 100644 index 028eb823..00000000 --- a/Plugins/NetCoreServer/WssClient.cs +++ /dev/null @@ -1,446 +0,0 @@ -using System.Net; -using System.Net.Sockets; -using System.Text; - -namespace NetCoreServer -{ - /// - /// WebSocket secure client - /// - /// WebSocket secure client is used to communicate with secure WebSocket server. Thread-safe. - public class WssClient : HttpsClient, IWebSocket - { - internal readonly WebSocket WebSocket; - - /// - /// Initialize WebSocket client with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public WssClient(SslContext context, IPAddress address, int port) : base(context, address, port) { WebSocket = new WebSocket(this); } - /// - /// Initialize WebSocket client with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public WssClient(SslContext context, string address, int port) : base(context, address, port) { WebSocket = new WebSocket(this); } - /// - /// Initialize WebSocket client with a given IP endpoint - /// - /// SSL context - /// IP endpoint - public WssClient(SslContext context, IPEndPoint endpoint) : base(context, endpoint) { WebSocket = new WebSocket(this); } - - /// - /// WebSocket random nonce - /// - public byte[] WsNonce => WebSocket.WsNonce; - - #region WebSocket connection methods - - public override bool Connect() { _syncConnect = true; return base.Connect(); } - public override bool ConnectAsync() { _syncConnect = false; return base.ConnectAsync(); } - public virtual bool Close(int status) { SendClose(status, null, 0, 0); base.Disconnect(); return true; } - public virtual bool CloseAsync(int status) { SendCloseAsync(status, null, 0, 0); base.DisconnectAsync(); return true; } - - #endregion - - #region WebSocket send text methods - - public long SendText(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, true, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendText(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, true, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendTextAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, true, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendTextAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send binary methods - - public long SendBinary(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, true, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendBinary(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, true, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendBinaryAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, true, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendBinaryAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send close methods - - public long SendClose(int status, byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, true, buffer, offset, size, status); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendClose(int status, string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, true, data, 0, data.Length, status); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendCloseAsync(int status, byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, true, buffer, offset, size, status); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendCloseAsync(int status, string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, true, data, 0, data.Length, status); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send ping methods - - public long SendPing(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendPing(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPingAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPingAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send pong methods - - public long SendPong(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, true, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendPong(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, true, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPongAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, true, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPongAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, true, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket receive methods - - public string ReceiveText() - { - Buffer result = new Buffer(); - - if (!WebSocket.WsHandshaked) - return result.ExtractString(0, result.Data.Length); - - Buffer cache = new Buffer(); - - // Receive WebSocket frame data - while (!WebSocket.WsFinalReceived) - { - while (!WebSocket.WsFrameReceived) - { - int required = WebSocket.RequiredReceiveFrameSize(); - cache.Resize(required); - int received = (int)base.Receive(cache.Data, 0, required); - if (received != required) - return result.ExtractString(0, result.Data.Length); - WebSocket.PrepareReceiveFrame(cache.Data, 0, received); - } - if (!WebSocket.WsFinalReceived) - WebSocket.PrepareReceiveFrame(null, 0, 0); - } - - // Copy WebSocket frame data - result.Append(WebSocket.WsReceiveFinalBuffer.ToArray(), 0, WebSocket.WsReceiveFinalBuffer.Count); - WebSocket.PrepareReceiveFrame(null, 0, 0); - return result.ExtractString(0, result.Data.Length); - } - - public Buffer ReceiveBinary() - { - Buffer result = new Buffer(); - - if (!WebSocket.WsHandshaked) - return result; - - Buffer cache = new Buffer(); - - // Receive WebSocket frame data - while (!WebSocket.WsFinalReceived) - { - while (!WebSocket.WsFrameReceived) - { - int required = WebSocket.RequiredReceiveFrameSize(); - cache.Resize(required); - int received = (int)base.Receive(cache.Data, 0, required); - if (received != required) - return result; - WebSocket.PrepareReceiveFrame(cache.Data, 0, received); - } - if (!WebSocket.WsFinalReceived) - WebSocket.PrepareReceiveFrame(null, 0, 0); - } - - // Copy WebSocket frame data - result.Append(WebSocket.WsReceiveFinalBuffer.ToArray(), 0, WebSocket.WsReceiveFinalBuffer.Count); - WebSocket.PrepareReceiveFrame(null, 0, 0); - return result; - } - - #endregion - - #region Session handlers - - protected override void OnHandshaked() - { - // Clear WebSocket send/receive buffers - WebSocket.ClearWsBuffers(); - - // Fill the WebSocket upgrade HTTP request - OnWsConnecting(Request); - - // Send the WebSocket upgrade HTTP request - if (_syncConnect) - SendRequest(Request); - else - SendRequestAsync(Request); - } - - protected override void OnDisconnecting() - { - if (WebSocket.WsHandshaked) - OnWsDisconnecting(); - } - - protected override void OnDisconnected() - { - // Disconnect WebSocket - if (WebSocket.WsHandshaked) - { - WebSocket.WsHandshaked = false; - OnWsDisconnected(); - } - - // Reset WebSocket upgrade HTTP request and response - Request.Clear(); - Response.Clear(); - - // Clear WebSocket send/receive buffers - WebSocket.ClearWsBuffers(); - - // Initialize new WebSocket random nonce - WebSocket.InitWsNonce(); - } - - protected override void OnReceived(byte[] buffer, long offset, long size) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - // Prepare receive frame - WebSocket.PrepareReceiveFrame(buffer, offset, size); - return; - } - - base.OnReceived(buffer, offset, size); - } - - protected override void OnReceivedResponseHeader(HttpResponse response) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - return; - - // Try to perform WebSocket upgrade - if (!WebSocket.PerformClientUpgrade(response, Id)) - { - base.OnReceivedResponseHeader(response); - return; - } - } - - protected override void OnReceivedResponse(HttpResponse response) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - // Prepare receive frame from the remaining response body - var body = Response.Body; - var data = Encoding.UTF8.GetBytes(body); - WebSocket.PrepareReceiveFrame(data, 0, data.Length); - return; - } - - base.OnReceivedResponse(response); - } - - protected override void OnReceivedResponseError(HttpResponse response, string error) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - OnError(new SocketError()); - return; - } - - base.OnReceivedResponseError(response, error); - } - - #endregion - - #region Web socket handlers - - public virtual void OnWsConnecting(HttpRequest request) {} - public virtual void OnWsConnected(HttpResponse response) {} - public virtual bool OnWsConnecting(HttpRequest request, HttpResponse response) { return true; } - public virtual void OnWsConnected(HttpRequest request) {} - public virtual void OnWsDisconnecting() {} - public virtual void OnWsDisconnected() {} - public virtual void OnWsReceived(byte[] buffer, long offset, long size) {} - public virtual void OnWsClose(byte[] buffer, long offset, long size) { CloseAsync(1000); } - public virtual void OnWsPing(byte[] buffer, long offset, long size) { SendPongAsync(buffer, offset, size); } - public virtual void OnWsPong(byte[] buffer, long offset, long size) {} - public virtual void OnWsError(string error) { OnError(SocketError.SocketError); } - public virtual void OnWsError(SocketError error) { OnError(error); } - public virtual void SendUpgrade(HttpResponse response) {} - - #endregion - - // Sync connect flag - private bool _syncConnect; - } -} diff --git a/Plugins/NetCoreServer/WssClient.cs.meta b/Plugins/NetCoreServer/WssClient.cs.meta deleted file mode 100644 index da9b2e17..00000000 --- a/Plugins/NetCoreServer/WssClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e347ea067c1fc3e40b361742cf0d5add -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/WssServer.cs b/Plugins/NetCoreServer/WssServer.cs deleted file mode 100644 index 63db684b..00000000 --- a/Plugins/NetCoreServer/WssServer.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System.Net; -using System.Net.Sockets; -using System.Text; - -namespace NetCoreServer -{ - /// - /// WebSocket secure server - /// - /// WebSocket secure server is used to communicate with clients using WebSocket protocol. Thread-safe. - public class WssServer : HttpsServer, IWebSocket - { - internal readonly WebSocket WebSocket; - - /// - /// Initialize WebSocket server with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public WssServer(SslContext context, IPAddress address, int port) : base(context, address, port) { WebSocket = new WebSocket(this); } - /// - /// Initialize WebSocket server with a given IP address and port number - /// - /// SSL context - /// IP address - /// Port number - public WssServer(SslContext context, string address, int port) : base(context, address, port) { WebSocket = new WebSocket(this); } - /// - /// Initialize WebSocket server with a given IP endpoint - /// - /// SSL context - /// IP endpoint - public WssServer(SslContext context, IPEndPoint endpoint) : base(context, endpoint) { WebSocket = new WebSocket(this); } - - public virtual bool CloseAll(int status) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, null, 0, 0, status); - if (!Multicast(WebSocket.WsSendBuffer.ToArray())) - return false; - - return base.DisconnectAll(); - } - } - - public override bool Multicast(byte[] buffer, long offset, long size) - { - if (!IsStarted) - return false; - - if (size == 0) - return true; - - // Multicast data to all WebSocket sessions - foreach (var session in Sessions.Values) - { - if (session is WssSession wssSession) - { - if (wssSession.WebSocket.WsHandshaked) - wssSession.SendAsync(buffer, offset, size); - } - } - - return true; - } - - #region WebSocket multicast text methods - - public bool MulticastText(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, buffer, offset, size); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool MulticastText(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, data, 0, data.Length); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket multicast binary methods - - public bool MulticastBinary(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, buffer, offset, size); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool MulticastBinary(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, data, 0, data.Length); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket multicast ping methods - - public bool SendPing(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, buffer, offset, size); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPing(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, data, 0, data.Length); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket multicast pong methods - - public bool SendPong(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, buffer, offset, size); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPong(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, data, 0, data.Length); - return Multicast(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - protected override SslSession CreateSession() { return new WssSession(this); } - - public void OnWsConnecting(HttpRequest request) { } - public void OnWsConnected(HttpResponse response) { } - public bool OnWsConnecting(HttpRequest request, HttpResponse response) { return true; } - public void OnWsConnected(HttpRequest request) { } - public void OnWsDisconnecting() { } - public void OnWsDisconnected() { } - public void OnWsReceived(byte[] buffer, long offset, long size) { } - public void OnWsClose(byte[] buffer, long offset, long size) { } - public void OnWsPing(byte[] buffer, long offset, long size) { } - public void OnWsPong(byte[] buffer, long offset, long size) { } - public void OnWsError(string error) { } - public void OnWsError(SocketError error) { } - public void SendUpgrade(HttpResponse response) { } - } -} diff --git a/Plugins/NetCoreServer/WssServer.cs.meta b/Plugins/NetCoreServer/WssServer.cs.meta deleted file mode 100644 index e9c1f229..00000000 --- a/Plugins/NetCoreServer/WssServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5a2d14121419bf24aaf5ddeb4f8f9c65 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/NetCoreServer/WssSession.cs b/Plugins/NetCoreServer/WssSession.cs deleted file mode 100644 index 0a7b55c4..00000000 --- a/Plugins/NetCoreServer/WssSession.cs +++ /dev/null @@ -1,398 +0,0 @@ -using System.Net.Sockets; -using System.Text; - -namespace NetCoreServer -{ - /// - /// WebSocket secure session - /// - /// WebSocket secure session is used to read and write data from the connected WebSocket client. Thread-safe. - public class WssSession : HttpsSession, IWebSocket - { - internal readonly WebSocket WebSocket; - - public WssSession(WssServer server) : base(server) { WebSocket = new WebSocket(this); } - - // WebSocket connection methods - public virtual bool Close(int status) { SendCloseAsync(status, null, 0, 0); base.Disconnect(); return true; } - - #region WebSocket send text methods - - public long SendText(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendText(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendTextAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendTextAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_TEXT, false, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send binary methods - - public long SendBinary(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendBinary(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendBinaryAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendBinaryAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_BINARY, false, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send close methods - - public long SendClose(int status, byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, buffer, offset, size, status); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendClose(int status, string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, data, 0, data.Length, status); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendCloseAsync(int status, byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, buffer, offset, size, status); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendCloseAsync(int status, string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_CLOSE, false, data, 0, data.Length, status); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send ping methods - - public long SendPing(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendPing(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPingAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPingAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PING, false, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket send pong methods - - public long SendPong(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, buffer, offset, size); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public long SendPong(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, data, 0, data.Length); - return base.Send(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPongAsync(byte[] buffer, long offset, long size) - { - lock (WebSocket.WsSendLock) - { - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, buffer, offset, size); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - public bool SendPongAsync(string text) - { - lock (WebSocket.WsSendLock) - { - var data = Encoding.UTF8.GetBytes(text); - WebSocket.PrepareSendFrame(WebSocket.WS_FIN | WebSocket.WS_PONG, false, data, 0, data.Length); - return base.SendAsync(WebSocket.WsSendBuffer.ToArray()); - } - } - - #endregion - - #region WebSocket receive methods - - public string ReceiveText() - { - Buffer result = new Buffer(); - - if (!WebSocket.WsHandshaked) - return result.ExtractString(0, result.Data.Length); - - Buffer cache = new Buffer(); - - // Receive WebSocket frame data - while (!WebSocket.WsFinalReceived) - { - while (!WebSocket.WsFrameReceived) - { - int required = WebSocket.RequiredReceiveFrameSize(); - cache.Resize(required); - int received = (int)base.Receive(cache.Data, 0, required); - if (received != required) - return result.ExtractString(0, result.Data.Length); - WebSocket.PrepareReceiveFrame(cache.Data, 0, received); - } - if (!WebSocket.WsFinalReceived) - WebSocket.PrepareReceiveFrame(null, 0, 0); - } - - // Copy WebSocket frame data - result.Append(WebSocket.WsReceiveFinalBuffer.ToArray(), 0, WebSocket.WsReceiveFinalBuffer.Count); - WebSocket.PrepareReceiveFrame(null, 0, 0); - return result.ExtractString(0, result.Data.Length); - } - - public Buffer ReceiveBinary() - { - Buffer result = new Buffer(); - - if (!WebSocket.WsHandshaked) - return result; - - Buffer cache = new Buffer(); - - // Receive WebSocket frame data - while (!WebSocket.WsFinalReceived) - { - while (!WebSocket.WsFrameReceived) - { - int required = WebSocket.RequiredReceiveFrameSize(); - cache.Resize(required); - int received = (int)base.Receive(cache.Data, 0, required); - if (received != required) - return result; - WebSocket.PrepareReceiveFrame(cache.Data, 0, received); - } - if (!WebSocket.WsFinalReceived) - WebSocket.PrepareReceiveFrame(null, 0, 0); - } - - // Copy WebSocket frame data - result.Append(WebSocket.WsReceiveFinalBuffer.ToArray(), 0, WebSocket.WsReceiveFinalBuffer.Count); - WebSocket.PrepareReceiveFrame(null, 0, 0); - return result; - } - - #endregion - - #region Session handlers - - protected override void OnDisconnecting() - { - if (WebSocket.WsHandshaked) - OnWsDisconnecting(); - } - - protected override void OnDisconnected() - { - // Disconnect WebSocket - if (WebSocket.WsHandshaked) - { - WebSocket.WsHandshaked = false; - OnWsDisconnected(); - } - - // Reset WebSocket upgrade HTTP request and response - Request.Clear(); - Response.Clear(); - - // Clear WebSocket send/receive buffers - WebSocket.ClearWsBuffers(); - - // Initialize new WebSocket random nonce - WebSocket.InitWsNonce(); - } - - protected override void OnReceived(byte[] buffer, long offset, long size) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - // Prepare receive frame - WebSocket.PrepareReceiveFrame(buffer, offset, size); - return; - } - - base.OnReceived(buffer, offset, size); - } - - protected override void OnReceivedRequestHeader(HttpRequest request) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - return; - - // Try to perform WebSocket upgrade - if (!WebSocket.PerformServerUpgrade(request, Response)) - { - base.OnReceivedRequestHeader(request); - return; - } - } - - protected override void OnReceivedRequest(HttpRequest request) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - // Prepare receive frame from the remaining request body - var body = Request.Body; - var data = Encoding.UTF8.GetBytes(body); - WebSocket.PrepareReceiveFrame(data, 0, data.Length); - return; - } - - base.OnReceivedRequest(request); - } - - protected override void OnReceivedRequestError(HttpRequest request, string error) - { - // Check for WebSocket handshaked status - if (WebSocket.WsHandshaked) - { - OnError(new SocketError()); - return; - } - - base.OnReceivedRequestError(request, error); - } - - #endregion - - #region Web socket handlers - - public virtual void OnWsConnecting(HttpRequest request) { } - public virtual void OnWsConnected(HttpResponse response) { } - public virtual bool OnWsConnecting(HttpRequest request, HttpResponse response) { return true; } - public virtual void OnWsConnected(HttpRequest request) { } - public virtual void OnWsDisconnecting() { } - public virtual void OnWsDisconnected() { } - public virtual void OnWsReceived(byte[] buffer, long offset, long size) { } - public virtual void OnWsClose(byte[] buffer, long offset, long size) { Close(1000); } - public virtual void OnWsPing(byte[] buffer, long offset, long size) { SendPongAsync(buffer, offset, size); } - public virtual void OnWsPong(byte[] buffer, long offset, long size) { } - public virtual void OnWsError(string error) { OnError(SocketError.SocketError); } - public virtual void OnWsError(SocketError error) { OnError(error); } - - public void SendUpgrade(HttpResponse response) { SendResponseAsync(response); } - - #endregion - } -} diff --git a/Plugins/NetCoreServer/WssSession.cs.meta b/Plugins/NetCoreServer/WssSession.cs.meta deleted file mode 100644 index 43679c76..00000000 --- a/Plugins/NetCoreServer/WssSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: caa06db51c6c9d441a982787abf52736 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/System.Buffers.dll b/Plugins/System.Buffers.dll deleted file mode 100644 index fb2911dd6e5a1163748e1a8419cda0a8705513c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27840 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 diff --git a/Plugins/System.Buffers.dll.meta b/Plugins/System.Buffers.dll.meta deleted file mode 100644 index db649ce9..00000000 --- a/Plugins/System.Buffers.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 8e7af8fe9839770458b3b543b27f9b68 -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/Plugins/System.Memory.dll b/Plugins/System.Memory.dll deleted file mode 100644 index c3c7bf321800994594315bde75e99feff9c1ec16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144016 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 V)(=vOdiTlg@L|6ZQ<^#M{{V27;<^9; diff --git a/Plugins/System.Memory.dll.meta b/Plugins/System.Memory.dll.meta deleted file mode 100644 index eae7a542..00000000 --- a/Plugins/System.Memory.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 093c0580b60756443bc1d9c561452e36 -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/Plugins/System.Runtime.CompilerServices.Unsafe.dll b/Plugins/System.Runtime.CompilerServices.Unsafe.dll deleted file mode 100644 index 51974c748d20014eeb3c93d4be85bf3e3f9cc437..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16776 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 hHisRZbV`?Ae|o^oW`YG)Y_G{|u$l{{Xs_QC0u| diff --git a/Plugins/System.Runtime.CompilerServices.Unsafe.dll.meta b/Plugins/System.Runtime.CompilerServices.Unsafe.dll.meta deleted file mode 100644 index c0101e84..00000000 --- a/Plugins/System.Runtime.CompilerServices.Unsafe.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: faa5df203ffb85e4e81c6230b4bf1025 -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/Plugins/System.Threading.Channels.dll b/Plugins/System.Threading.Channels.dll deleted file mode 100644 index 0cd63c3353ff22fecfa873b15b552172f47533d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45944 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 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/Plugins/UniTask/Editor/SplitterGUILayout.cs.meta b/Plugins/UniTask/Editor/SplitterGUILayout.cs.meta deleted file mode 100644 index 4d718f4e..00000000 --- a/Plugins/UniTask/Editor/SplitterGUILayout.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 40ef2e46f900131419e869398a8d3c9d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Editor/UniTask.Editor.asmdef b/Plugins/UniTask/Editor/UniTask.Editor.asmdef deleted file mode 100644 index c618c6ac..00000000 --- a/Plugins/UniTask/Editor/UniTask.Editor.asmdef +++ /dev/null @@ -1,17 +0,0 @@ -{ - "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/Plugins/UniTask/Editor/UniTask.Editor.asmdef.meta b/Plugins/UniTask/Editor/UniTask.Editor.asmdef.meta deleted file mode 100644 index 821b87b7..00000000 --- a/Plugins/UniTask/Editor/UniTask.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 4129704b5a1a13841ba16f230bf24a57 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Editor/UniTaskTrackerTreeView.cs b/Plugins/UniTask/Editor/UniTaskTrackerTreeView.cs deleted file mode 100644 index e7b62692..00000000 --- a/Plugins/UniTask/Editor/UniTaskTrackerTreeView.cs +++ /dev/null @@ -1,182 +0,0 @@ -#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/Plugins/UniTask/Editor/UniTaskTrackerTreeView.cs.meta b/Plugins/UniTask/Editor/UniTaskTrackerTreeView.cs.meta deleted file mode 100644 index 9b34d7b9..00000000 --- a/Plugins/UniTask/Editor/UniTaskTrackerTreeView.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 52e2d973a2156674e8c1c9433ed031f7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Editor/UniTaskTrackerWindow.cs b/Plugins/UniTask/Editor/UniTaskTrackerWindow.cs deleted file mode 100644 index 242ac6db..00000000 --- a/Plugins/UniTask/Editor/UniTaskTrackerWindow.cs +++ /dev/null @@ -1,209 +0,0 @@ -#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/Plugins/UniTask/Editor/UniTaskTrackerWindow.cs.meta b/Plugins/UniTask/Editor/UniTaskTrackerWindow.cs.meta deleted file mode 100644 index ba1b7045..00000000 --- a/Plugins/UniTask/Editor/UniTaskTrackerWindow.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5bee3e3860e37484aa3b861bf76d129f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime.meta b/Plugins/UniTask/Runtime.meta deleted file mode 100644 index 43d6dadd..00000000 --- a/Plugins/UniTask/Runtime.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b15491a798abf4a4490137b6c6aa4faa -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/AsyncLazy.cs b/Plugins/UniTask/Runtime/AsyncLazy.cs deleted file mode 100644 index 51bfadc7..00000000 --- a/Plugins/UniTask/Runtime/AsyncLazy.cs +++ /dev/null @@ -1,245 +0,0 @@ -#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/Plugins/UniTask/Runtime/AsyncLazy.cs.meta b/Plugins/UniTask/Runtime/AsyncLazy.cs.meta deleted file mode 100644 index 554d1628..00000000 --- a/Plugins/UniTask/Runtime/AsyncLazy.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 01d1404ca421466419a7db7340ff5e77 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/AsyncReactiveProperty.cs b/Plugins/UniTask/Runtime/AsyncReactiveProperty.cs deleted file mode 100644 index a08844df..00000000 --- a/Plugins/UniTask/Runtime/AsyncReactiveProperty.cs +++ /dev/null @@ -1,644 +0,0 @@ -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/Plugins/UniTask/Runtime/AsyncReactiveProperty.cs.meta b/Plugins/UniTask/Runtime/AsyncReactiveProperty.cs.meta deleted file mode 100644 index d64e3cff..00000000 --- a/Plugins/UniTask/Runtime/AsyncReactiveProperty.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8ef320b87f537ee4fb2282e765dc6166 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/AsyncUnit.cs b/Plugins/UniTask/Runtime/AsyncUnit.cs deleted file mode 100644 index 1d4bc742..00000000 --- a/Plugins/UniTask/Runtime/AsyncUnit.cs +++ /dev/null @@ -1,26 +0,0 @@ -#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/Plugins/UniTask/Runtime/AsyncUnit.cs.meta b/Plugins/UniTask/Runtime/AsyncUnit.cs.meta deleted file mode 100644 index e0ee1329..00000000 --- a/Plugins/UniTask/Runtime/AsyncUnit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4f95ac245430d304bb5128d13b6becc8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/CancellationTokenEqualityComparer.cs b/Plugins/UniTask/Runtime/CancellationTokenEqualityComparer.cs deleted file mode 100644 index 42e94451..00000000 --- a/Plugins/UniTask/Runtime/CancellationTokenEqualityComparer.cs +++ /dev/null @@ -1,23 +0,0 @@ -#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/Plugins/UniTask/Runtime/CancellationTokenEqualityComparer.cs.meta b/Plugins/UniTask/Runtime/CancellationTokenEqualityComparer.cs.meta deleted file mode 100644 index a4fe3fd9..00000000 --- a/Plugins/UniTask/Runtime/CancellationTokenEqualityComparer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7d739f510b125b74fa7290ac4335e46e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/CancellationTokenExtensions.cs b/Plugins/UniTask/Runtime/CancellationTokenExtensions.cs deleted file mode 100644 index 3f3a532a..00000000 --- a/Plugins/UniTask/Runtime/CancellationTokenExtensions.cs +++ /dev/null @@ -1,182 +0,0 @@ -#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/Plugins/UniTask/Runtime/CancellationTokenExtensions.cs.meta b/Plugins/UniTask/Runtime/CancellationTokenExtensions.cs.meta deleted file mode 100644 index 28a69586..00000000 --- a/Plugins/UniTask/Runtime/CancellationTokenExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4be7209f04146bd45ac5ee775a5f7c26 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/CancellationTokenSourceExtensions.cs b/Plugins/UniTask/Runtime/CancellationTokenSourceExtensions.cs deleted file mode 100644 index c5199444..00000000 --- a/Plugins/UniTask/Runtime/CancellationTokenSourceExtensions.cs +++ /dev/null @@ -1,44 +0,0 @@ -#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/Plugins/UniTask/Runtime/CancellationTokenSourceExtensions.cs.meta b/Plugins/UniTask/Runtime/CancellationTokenSourceExtensions.cs.meta deleted file mode 100644 index fd09fe4b..00000000 --- a/Plugins/UniTask/Runtime/CancellationTokenSourceExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 22d85d07f1e70ab42a7a4c25bd65e661 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Channel.cs b/Plugins/UniTask/Runtime/Channel.cs deleted file mode 100644 index 5a484fdc..00000000 --- a/Plugins/UniTask/Runtime/Channel.cs +++ /dev/null @@ -1,450 +0,0 @@ -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/Plugins/UniTask/Runtime/Channel.cs.meta b/Plugins/UniTask/Runtime/Channel.cs.meta deleted file mode 100644 index 32edb9c0..00000000 --- a/Plugins/UniTask/Runtime/Channel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5ceb3107bbdd1f14eb39091273798360 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/CompilerServices.meta b/Plugins/UniTask/Runtime/CompilerServices.meta deleted file mode 100644 index dd98fb2d..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 21b4f7b92c7b3fb4488477ff2dbb46ce -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs b/Plugins/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs deleted file mode 100644 index 700fc339..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ - -#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/Plugins/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs.meta b/Plugins/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs.meta deleted file mode 100644 index 19961dfb..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices/AsyncMethodBuilderAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 02ce354d37b10454e8376062f7cbe57a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs b/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs deleted file mode 100644 index 1aa990d9..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs +++ /dev/null @@ -1,269 +0,0 @@ - -#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/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs.meta b/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs.meta deleted file mode 100644 index ad43cfcf..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskMethodBuilder.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 68d72a45afdec574ebc26e7de2c38330 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs b/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs deleted file mode 100644 index 82e91f38..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs +++ /dev/null @@ -1,137 +0,0 @@ - -#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/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs.meta b/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs.meta deleted file mode 100644 index 9bcc50e0..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e891aaac17b933a47a9d7fa3b8e1226f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs b/Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs deleted file mode 100644 index 1cffeced..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs +++ /dev/null @@ -1,380 +0,0 @@ -#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/Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs.meta b/Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs.meta deleted file mode 100644 index 2cb82e08..00000000 --- a/Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 98649642833cabf44a9dc060ce4c84a1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/EnumerableAsyncExtensions.cs b/Plugins/UniTask/Runtime/EnumerableAsyncExtensions.cs deleted file mode 100644 index 004e7631..00000000 --- a/Plugins/UniTask/Runtime/EnumerableAsyncExtensions.cs +++ /dev/null @@ -1,34 +0,0 @@ -#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/Plugins/UniTask/Runtime/EnumerableAsyncExtensions.cs.meta b/Plugins/UniTask/Runtime/EnumerableAsyncExtensions.cs.meta deleted file mode 100644 index d2e49304..00000000 --- a/Plugins/UniTask/Runtime/EnumerableAsyncExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ff50260d74bd54c4b92cf99895549445 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs b/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs deleted file mode 100644 index 785bbc28..00000000 --- a/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs +++ /dev/null @@ -1,287 +0,0 @@ -#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/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs.meta b/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs.meta deleted file mode 100644 index a07b336d..00000000 --- a/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bc661232f11e4a741af54ba1c175d5ee -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/ExceptionExtensions.cs b/Plugins/UniTask/Runtime/ExceptionExtensions.cs deleted file mode 100644 index e4118980..00000000 --- a/Plugins/UniTask/Runtime/ExceptionExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ - -using System; - -namespace Cysharp.Threading.Tasks -{ - public static class ExceptionExtensions - { - public static bool IsOperationCanceledException(this Exception exception) - { - return exception is OperationCanceledException; - } - } -} - diff --git a/Plugins/UniTask/Runtime/ExceptionExtensions.cs.meta b/Plugins/UniTask/Runtime/ExceptionExtensions.cs.meta deleted file mode 100644 index 98330016..00000000 --- a/Plugins/UniTask/Runtime/ExceptionExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 930800098504c0d46958ce23a0495202 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External.meta b/Plugins/UniTask/Runtime/External.meta deleted file mode 100644 index ed41fba7..00000000 --- a/Plugins/UniTask/Runtime/External.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3ca5324a9c36ca243b4a65f0c26d9d89 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/Addressables.meta b/Plugins/UniTask/Runtime/External/Addressables.meta deleted file mode 100644 index d4236d5d..00000000 --- a/Plugins/UniTask/Runtime/External/Addressables.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: cea691b2e4a6c9d4f83c28d727c8be6f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs b/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs deleted file mode 100644 index f321bdba..00000000 --- a/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs +++ /dev/null @@ -1,401 +0,0 @@ -// 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/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta b/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta deleted file mode 100644 index 6927930d..00000000 --- a/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3dc6441f9094f354b931dc3c79fb99e5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef b/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef deleted file mode 100644 index 7b9e296e..00000000 --- a/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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" - } - ], - "noEngineReferences": false -} \ No newline at end of file diff --git a/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta b/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta deleted file mode 100644 index b0178c4a..00000000 --- a/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 593a5b492d29ac6448b1ebf7f035ef33 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/DOTween.meta b/Plugins/UniTask/Runtime/External/DOTween.meta deleted file mode 100644 index 46803ad0..00000000 --- a/Plugins/UniTask/Runtime/External/DOTween.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 1c3e7f43fe06e7646ab8353eeda8c979 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs b/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs deleted file mode 100644 index 80ae27c0..00000000 --- a/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs +++ /dev/null @@ -1,470 +0,0 @@ -// 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/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta b/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta deleted file mode 100644 index 63131b04..00000000 --- a/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1f448d5bc5b232e4f98d89d5d1832e8e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef b/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef deleted file mode 100644 index 7bdb2b61..00000000 --- a/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta b/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta deleted file mode 100644 index 427fe290..00000000 --- a/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 029c1c1b674aaae47a6841a0b89ad80e -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/TextMeshPro.meta b/Plugins/UniTask/Runtime/External/TextMeshPro.meta deleted file mode 100644 index 0e4abee2..00000000 --- a/Plugins/UniTask/Runtime/External/TextMeshPro.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: aca11e82ff083e740bb47c31ce3aa945 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs b/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs deleted file mode 100644 index 22f081c2..00000000 --- a/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs +++ /dev/null @@ -1,224 +0,0 @@ -#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/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs.meta b/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs.meta deleted file mode 100644 index 2e39d2e8..00000000 --- a/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.InputField.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 79f4f2475e0b2c44e97ed1dee760627b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs b/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs deleted file mode 100644 index 362aa830..00000000 --- a/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs +++ /dev/null @@ -1,130 +0,0 @@ -#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/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs.meta b/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs.meta deleted file mode 100644 index 752d125c..00000000 --- a/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b6ba480edafb67d4e91bb10feb64fae5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef b/Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef deleted file mode 100644 index 6bb01d7f..00000000 --- a/Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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/Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef.meta b/Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef.meta deleted file mode 100644 index 4b59831d..00000000 --- a/Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: dc47925d1a5fa2946bdd37746b2b5d48 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/IUniTaskAsyncEnumerable.cs b/Plugins/UniTask/Runtime/IUniTaskAsyncEnumerable.cs deleted file mode 100644 index 847d4305..00000000 --- a/Plugins/UniTask/Runtime/IUniTaskAsyncEnumerable.cs +++ /dev/null @@ -1,91 +0,0 @@ -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/Plugins/UniTask/Runtime/IUniTaskAsyncEnumerable.cs.meta b/Plugins/UniTask/Runtime/IUniTaskAsyncEnumerable.cs.meta deleted file mode 100644 index 12f0fe52..00000000 --- a/Plugins/UniTask/Runtime/IUniTaskAsyncEnumerable.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b20cf9f02ac585948a4372fa4ee06504 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/IUniTaskSource.cs b/Plugins/UniTask/Runtime/IUniTaskSource.cs deleted file mode 100644 index 88147811..00000000 --- a/Plugins/UniTask/Runtime/IUniTaskSource.cs +++ /dev/null @@ -1,124 +0,0 @@ -#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/Plugins/UniTask/Runtime/IUniTaskSource.cs.meta b/Plugins/UniTask/Runtime/IUniTaskSource.cs.meta deleted file mode 100644 index b225d1c7..00000000 --- a/Plugins/UniTask/Runtime/IUniTaskSource.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3e4d023d8404ab742b5e808c98097c3c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal.meta b/Plugins/UniTask/Runtime/Internal.meta deleted file mode 100644 index 58b76fb5..00000000 --- a/Plugins/UniTask/Runtime/Internal.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c0a7527158c388f4c881a15a078a18e1 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/ArrayPool.cs b/Plugins/UniTask/Runtime/Internal/ArrayPool.cs deleted file mode 100644 index e1d9d3b6..00000000 --- a/Plugins/UniTask/Runtime/Internal/ArrayPool.cs +++ /dev/null @@ -1,150 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/ArrayPool.cs.meta b/Plugins/UniTask/Runtime/Internal/ArrayPool.cs.meta deleted file mode 100644 index 693816cc..00000000 --- a/Plugins/UniTask/Runtime/Internal/ArrayPool.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f83ebad81fb89fb4882331616ca6d248 -timeCreated: 1532361008 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/ArrayPoolUtil.cs b/Plugins/UniTask/Runtime/Internal/ArrayPoolUtil.cs deleted file mode 100644 index 016901db..00000000 --- a/Plugins/UniTask/Runtime/Internal/ArrayPoolUtil.cs +++ /dev/null @@ -1,115 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/ArrayPoolUtil.cs.meta b/Plugins/UniTask/Runtime/Internal/ArrayPoolUtil.cs.meta deleted file mode 100644 index e06ec652..00000000 --- a/Plugins/UniTask/Runtime/Internal/ArrayPoolUtil.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 424cc208fb61d4e448b08fcfa0eee25e -timeCreated: 1532361007 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/ArrayUtil.cs b/Plugins/UniTask/Runtime/Internal/ArrayUtil.cs deleted file mode 100644 index fc7a808c..00000000 --- a/Plugins/UniTask/Runtime/Internal/ArrayUtil.cs +++ /dev/null @@ -1,73 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/ArrayUtil.cs.meta b/Plugins/UniTask/Runtime/Internal/ArrayUtil.cs.meta deleted file mode 100644 index 645fc4ed..00000000 --- a/Plugins/UniTask/Runtime/Internal/ArrayUtil.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 23146a82ec99f2542a87971c8d3d7988 -timeCreated: 1532361007 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs b/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs deleted file mode 100644 index a3111268..00000000 --- a/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs +++ /dev/null @@ -1,225 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs.meta b/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs.meta deleted file mode 100644 index b04e5418..00000000 --- a/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f66c32454e50f2546b17deadc80a4c77 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/DiagnosticsExtensions.cs b/Plugins/UniTask/Runtime/Internal/DiagnosticsExtensions.cs deleted file mode 100644 index 77d998fb..00000000 --- a/Plugins/UniTask/Runtime/Internal/DiagnosticsExtensions.cs +++ /dev/null @@ -1,249 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/DiagnosticsExtensions.cs.meta b/Plugins/UniTask/Runtime/Internal/DiagnosticsExtensions.cs.meta deleted file mode 100644 index 6c1f06c2..00000000 --- a/Plugins/UniTask/Runtime/Internal/DiagnosticsExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f80fb1c9ed4c99447be1b0a47a8d980b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/Error.cs b/Plugins/UniTask/Runtime/Internal/Error.cs deleted file mode 100644 index 5c7bc93b..00000000 --- a/Plugins/UniTask/Runtime/Internal/Error.cs +++ /dev/null @@ -1,79 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/Error.cs.meta b/Plugins/UniTask/Runtime/Internal/Error.cs.meta deleted file mode 100644 index 2e5d219a..00000000 --- a/Plugins/UniTask/Runtime/Internal/Error.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5f39f495294d4604b8082202faf98554 -timeCreated: 1532361007 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/MinimumQueue.cs b/Plugins/UniTask/Runtime/Internal/MinimumQueue.cs deleted file mode 100644 index a6b567ad..00000000 --- a/Plugins/UniTask/Runtime/Internal/MinimumQueue.cs +++ /dev/null @@ -1,112 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/MinimumQueue.cs.meta b/Plugins/UniTask/Runtime/Internal/MinimumQueue.cs.meta deleted file mode 100644 index dc067367..00000000 --- a/Plugins/UniTask/Runtime/Internal/MinimumQueue.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7d63add489ccc99498114d79702b904d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs b/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs deleted file mode 100644 index 43625ab5..00000000 --- a/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs +++ /dev/null @@ -1,260 +0,0 @@ - -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/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs.meta b/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs.meta deleted file mode 100644 index 603dbc93..00000000 --- a/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 340c6d420bb4f484aa8683415ea92571 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/PooledDelegate.cs b/Plugins/UniTask/Runtime/Internal/PooledDelegate.cs deleted file mode 100644 index 518244fe..00000000 --- a/Plugins/UniTask/Runtime/Internal/PooledDelegate.cs +++ /dev/null @@ -1,50 +0,0 @@ -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/Plugins/UniTask/Runtime/Internal/PooledDelegate.cs.meta b/Plugins/UniTask/Runtime/Internal/PooledDelegate.cs.meta deleted file mode 100644 index 7f92aff4..00000000 --- a/Plugins/UniTask/Runtime/Internal/PooledDelegate.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8932579438742fa40b010edd412dbfba -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs b/Plugins/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs deleted file mode 100644 index cbabdab1..00000000 --- a/Plugins/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs +++ /dev/null @@ -1,64 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs.meta b/Plugins/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs.meta deleted file mode 100644 index 42543911..00000000 --- a/Plugins/UniTask/Runtime/Internal/RuntimeHelpersAbstraction.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 94975e4d4e0c0ea4ba787d3872ce9bb4 -timeCreated: 1532361007 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/StatePool.cs b/Plugins/UniTask/Runtime/Internal/StatePool.cs deleted file mode 100644 index e1d40bd7..00000000 --- a/Plugins/UniTask/Runtime/Internal/StatePool.cs +++ /dev/null @@ -1,153 +0,0 @@ -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/Plugins/UniTask/Runtime/Internal/StatePool.cs.meta b/Plugins/UniTask/Runtime/Internal/StatePool.cs.meta deleted file mode 100644 index 6779aa1e..00000000 --- a/Plugins/UniTask/Runtime/Internal/StatePool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 60cdf0bcaea36b444a7ae7263ae7598f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/TaskTracker.cs b/Plugins/UniTask/Runtime/Internal/TaskTracker.cs deleted file mode 100644 index c163e22d..00000000 --- a/Plugins/UniTask/Runtime/Internal/TaskTracker.cs +++ /dev/null @@ -1,178 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/TaskTracker.cs.meta b/Plugins/UniTask/Runtime/Internal/TaskTracker.cs.meta deleted file mode 100644 index 5563bf78..00000000 --- a/Plugins/UniTask/Runtime/Internal/TaskTracker.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a203c73eb4ccdbb44bddfd82d38fdda9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/UnityEqualityComparer.cs b/Plugins/UniTask/Runtime/Internal/UnityEqualityComparer.cs deleted file mode 100644 index 906f3b6a..00000000 --- a/Plugins/UniTask/Runtime/Internal/UnityEqualityComparer.cs +++ /dev/null @@ -1,267 +0,0 @@ -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/Plugins/UniTask/Runtime/Internal/UnityEqualityComparer.cs.meta b/Plugins/UniTask/Runtime/Internal/UnityEqualityComparer.cs.meta deleted file mode 100644 index 79eb04f6..00000000 --- a/Plugins/UniTask/Runtime/Internal/UnityEqualityComparer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ebaaf14253c9cfb47b23283218ff9b67 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs b/Plugins/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs deleted file mode 100644 index 0da9f5a7..00000000 --- a/Plugins/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -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/Plugins/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs.meta b/Plugins/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs.meta deleted file mode 100644 index 54bd2eb5..00000000 --- a/Plugins/UniTask/Runtime/Internal/UnityWebRequestExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 111ba0e639de1d7428af6c823ead4918 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/ValueStopwatch.cs b/Plugins/UniTask/Runtime/Internal/ValueStopwatch.cs deleted file mode 100644 index d55d1f6c..00000000 --- a/Plugins/UniTask/Runtime/Internal/ValueStopwatch.cs +++ /dev/null @@ -1,37 +0,0 @@ -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/Plugins/UniTask/Runtime/Internal/ValueStopwatch.cs.meta b/Plugins/UniTask/Runtime/Internal/ValueStopwatch.cs.meta deleted file mode 100644 index b7c6b09c..00000000 --- a/Plugins/UniTask/Runtime/Internal/ValueStopwatch.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f16fb466974ad034c8732c79c7fd67ea -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Internal/WeakDictionary.cs b/Plugins/UniTask/Runtime/Internal/WeakDictionary.cs deleted file mode 100644 index 3feaad88..00000000 --- a/Plugins/UniTask/Runtime/Internal/WeakDictionary.cs +++ /dev/null @@ -1,334 +0,0 @@ -#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/Plugins/UniTask/Runtime/Internal/WeakDictionary.cs.meta b/Plugins/UniTask/Runtime/Internal/WeakDictionary.cs.meta deleted file mode 100644 index 9dc1672a..00000000 --- a/Plugins/UniTask/Runtime/Internal/WeakDictionary.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6c78563864409714593226af59bcb6f3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq.meta b/Plugins/UniTask/Runtime/Linq.meta deleted file mode 100644 index 44b8435d..00000000 --- a/Plugins/UniTask/Runtime/Linq.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 81dae03e99a778b478111177315cd866 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Aggregate.cs b/Plugins/UniTask/Runtime/Linq/Aggregate.cs deleted file mode 100644 index 78647ff3..00000000 --- a/Plugins/UniTask/Runtime/Linq/Aggregate.cs +++ /dev/null @@ -1,318 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Aggregate.cs.meta b/Plugins/UniTask/Runtime/Linq/Aggregate.cs.meta deleted file mode 100644 index 837df4a9..00000000 --- a/Plugins/UniTask/Runtime/Linq/Aggregate.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5dc68c05a4228c643937f6ebd185bcca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/All.cs b/Plugins/UniTask/Runtime/Linq/All.cs deleted file mode 100644 index 5d6d5f0e..00000000 --- a/Plugins/UniTask/Runtime/Linq/All.cs +++ /dev/null @@ -1,108 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/All.cs.meta b/Plugins/UniTask/Runtime/Linq/All.cs.meta deleted file mode 100644 index d378ff0e..00000000 --- a/Plugins/UniTask/Runtime/Linq/All.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7271437e0033af2448b600ee248924dd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Any.cs b/Plugins/UniTask/Runtime/Linq/Any.cs deleted file mode 100644 index 2d43167c..00000000 --- a/Plugins/UniTask/Runtime/Linq/Any.cs +++ /dev/null @@ -1,136 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Any.cs.meta b/Plugins/UniTask/Runtime/Linq/Any.cs.meta deleted file mode 100644 index 1070bcc8..00000000 --- a/Plugins/UniTask/Runtime/Linq/Any.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e2b2e65745263994fbe34f3e0ec8eb12 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/AppendPrepend.cs b/Plugins/UniTask/Runtime/Linq/AppendPrepend.cs deleted file mode 100644 index 3935afd8..00000000 --- a/Plugins/UniTask/Runtime/Linq/AppendPrepend.cs +++ /dev/null @@ -1,151 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/AppendPrepend.cs.meta b/Plugins/UniTask/Runtime/Linq/AppendPrepend.cs.meta deleted file mode 100644 index 6d2ee046..00000000 --- a/Plugins/UniTask/Runtime/Linq/AppendPrepend.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3268ec424b8055f45aa2a26d17c80468 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs b/Plugins/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs deleted file mode 100644 index c00452e1..00000000 --- a/Plugins/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Cysharp.Threading.Tasks.Linq -{ - public static partial class UniTaskAsyncEnumerable - { - public static IUniTaskAsyncEnumerable AsUniTaskAsyncEnumerable(this IUniTaskAsyncEnumerable source) - { - return source; - } - } -} diff --git a/Plugins/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs.meta b/Plugins/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs.meta deleted file mode 100644 index 90f6207c..00000000 --- a/Plugins/UniTask/Runtime/Linq/AsUniTaskAsyncEnumerable.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 69866e262589ea643bbc62a1d696077a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs b/Plugins/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs deleted file mode 100644 index e7f99685..00000000 --- a/Plugins/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs +++ /dev/null @@ -1,356 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs.meta b/Plugins/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs.meta deleted file mode 100644 index a4e96dc0..00000000 --- a/Plugins/UniTask/Runtime/Linq/AsyncEnumeratorBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 01ba1d3b17e13fb4c95740131c7e6e19 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Average.cs b/Plugins/UniTask/Runtime/Linq/Average.cs deleted file mode 100644 index b2ce42c1..00000000 --- a/Plugins/UniTask/Runtime/Linq/Average.cs +++ /dev/null @@ -1,1524 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Average.cs.meta b/Plugins/UniTask/Runtime/Linq/Average.cs.meta deleted file mode 100644 index 8f60dfc5..00000000 --- a/Plugins/UniTask/Runtime/Linq/Average.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 58499f95012fb3c47bb7bcbc5862e562 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Buffer.cs b/Plugins/UniTask/Runtime/Linq/Buffer.cs deleted file mode 100644 index be395b68..00000000 --- a/Plugins/UniTask/Runtime/Linq/Buffer.cs +++ /dev/null @@ -1,345 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Buffer.cs.meta b/Plugins/UniTask/Runtime/Linq/Buffer.cs.meta deleted file mode 100644 index e7154e4d..00000000 --- a/Plugins/UniTask/Runtime/Linq/Buffer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 951310243334a3148a7872977cb31c5c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Cast.cs b/Plugins/UniTask/Runtime/Linq/Cast.cs deleted file mode 100644 index 0a0c0f8f..00000000 --- a/Plugins/UniTask/Runtime/Linq/Cast.cs +++ /dev/null @@ -1,53 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Cast.cs.meta b/Plugins/UniTask/Runtime/Linq/Cast.cs.meta deleted file mode 100644 index 913b043c..00000000 --- a/Plugins/UniTask/Runtime/Linq/Cast.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: edebeae8b61352b428abe9ce8f3fc71a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/CombineLatest.cs b/Plugins/UniTask/Runtime/Linq/CombineLatest.cs deleted file mode 100644 index 92fb1daa..00000000 --- a/Plugins/UniTask/Runtime/Linq/CombineLatest.cs +++ /dev/null @@ -1,11372 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/CombineLatest.cs.meta b/Plugins/UniTask/Runtime/Linq/CombineLatest.cs.meta deleted file mode 100644 index 4e8b1c34..00000000 --- a/Plugins/UniTask/Runtime/Linq/CombineLatest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6cb07f6e88287e34d9b9301a572284a5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Concat.cs b/Plugins/UniTask/Runtime/Linq/Concat.cs deleted file mode 100644 index 715795e8..00000000 --- a/Plugins/UniTask/Runtime/Linq/Concat.cs +++ /dev/null @@ -1,164 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Concat.cs.meta b/Plugins/UniTask/Runtime/Linq/Concat.cs.meta deleted file mode 100644 index 6bfcf318..00000000 --- a/Plugins/UniTask/Runtime/Linq/Concat.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7cb9e19c449127a459851a135ce7d527 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Contains.cs b/Plugins/UniTask/Runtime/Linq/Contains.cs deleted file mode 100644 index a93f566c..00000000 --- a/Plugins/UniTask/Runtime/Linq/Contains.cs +++ /dev/null @@ -1,50 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Contains.cs.meta b/Plugins/UniTask/Runtime/Linq/Contains.cs.meta deleted file mode 100644 index 9bd414b3..00000000 --- a/Plugins/UniTask/Runtime/Linq/Contains.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 36ab06d30f3223048b4f676e05431a7f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Count.cs b/Plugins/UniTask/Runtime/Linq/Count.cs deleted file mode 100644 index 807b529b..00000000 --- a/Plugins/UniTask/Runtime/Linq/Count.cs +++ /dev/null @@ -1,144 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Count.cs.meta b/Plugins/UniTask/Runtime/Linq/Count.cs.meta deleted file mode 100644 index 35db3324..00000000 --- a/Plugins/UniTask/Runtime/Linq/Count.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e606d38eed688574bb2ba89d983cc9bb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Create.cs b/Plugins/UniTask/Runtime/Linq/Create.cs deleted file mode 100644 index 61b7afd3..00000000 --- a/Plugins/UniTask/Runtime/Linq/Create.cs +++ /dev/null @@ -1,174 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Create.cs.meta b/Plugins/UniTask/Runtime/Linq/Create.cs.meta deleted file mode 100644 index 5aba456f..00000000 --- a/Plugins/UniTask/Runtime/Linq/Create.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0202f723469f93945afa063bfb440d15 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/DefaultIfEmpty.cs b/Plugins/UniTask/Runtime/Linq/DefaultIfEmpty.cs deleted file mode 100644 index 3d21bd7c..00000000 --- a/Plugins/UniTask/Runtime/Linq/DefaultIfEmpty.cs +++ /dev/null @@ -1,142 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/DefaultIfEmpty.cs.meta b/Plugins/UniTask/Runtime/Linq/DefaultIfEmpty.cs.meta deleted file mode 100644 index 5aa59939..00000000 --- a/Plugins/UniTask/Runtime/Linq/DefaultIfEmpty.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 19e437c039ad7e1478dbce1779ef8660 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Distinct.cs b/Plugins/UniTask/Runtime/Linq/Distinct.cs deleted file mode 100644 index 85bf795b..00000000 --- a/Plugins/UniTask/Runtime/Linq/Distinct.cs +++ /dev/null @@ -1,277 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Distinct.cs.meta b/Plugins/UniTask/Runtime/Linq/Distinct.cs.meta deleted file mode 100644 index 61804b7f..00000000 --- a/Plugins/UniTask/Runtime/Linq/Distinct.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8f09903be66e5d943b243d7c19cb3811 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/DistinctUntilChanged.cs b/Plugins/UniTask/Runtime/Linq/DistinctUntilChanged.cs deleted file mode 100644 index d91bef9f..00000000 --- a/Plugins/UniTask/Runtime/Linq/DistinctUntilChanged.cs +++ /dev/null @@ -1,662 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/DistinctUntilChanged.cs.meta b/Plugins/UniTask/Runtime/Linq/DistinctUntilChanged.cs.meta deleted file mode 100644 index 84cddf8d..00000000 --- a/Plugins/UniTask/Runtime/Linq/DistinctUntilChanged.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0351f6767df7e644b935d4d599968162 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Do.cs b/Plugins/UniTask/Runtime/Linq/Do.cs deleted file mode 100644 index f6df368d..00000000 --- a/Plugins/UniTask/Runtime/Linq/Do.cs +++ /dev/null @@ -1,258 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Do.cs.meta b/Plugins/UniTask/Runtime/Linq/Do.cs.meta deleted file mode 100644 index 766bbb5f..00000000 --- a/Plugins/UniTask/Runtime/Linq/Do.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dd83c8e12dedf75409b829b93146d130 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ElementAt.cs b/Plugins/UniTask/Runtime/Linq/ElementAt.cs deleted file mode 100644 index 930675e5..00000000 --- a/Plugins/UniTask/Runtime/Linq/ElementAt.cs +++ /dev/null @@ -1,58 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ElementAt.cs.meta b/Plugins/UniTask/Runtime/Linq/ElementAt.cs.meta deleted file mode 100644 index fb0850b6..00000000 --- a/Plugins/UniTask/Runtime/Linq/ElementAt.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c835bd2dd8555234c8919c7b8ef3b69a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Empty.cs b/Plugins/UniTask/Runtime/Linq/Empty.cs deleted file mode 100644 index 2f5b3a49..00000000 --- a/Plugins/UniTask/Runtime/Linq/Empty.cs +++ /dev/null @@ -1,47 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Empty.cs.meta b/Plugins/UniTask/Runtime/Linq/Empty.cs.meta deleted file mode 100644 index bfa577ac..00000000 --- a/Plugins/UniTask/Runtime/Linq/Empty.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4fa123ad6258abb4184721b719a13810 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Except.cs b/Plugins/UniTask/Runtime/Linq/Except.cs deleted file mode 100644 index c4054823..00000000 --- a/Plugins/UniTask/Runtime/Linq/Except.cs +++ /dev/null @@ -1,116 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Except.cs.meta b/Plugins/UniTask/Runtime/Linq/Except.cs.meta deleted file mode 100644 index f61a1aab..00000000 --- a/Plugins/UniTask/Runtime/Linq/Except.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 38c1c4129f59dcb49a5b864eaf4ec63c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/First.cs b/Plugins/UniTask/Runtime/Linq/First.cs deleted file mode 100644 index da5688b4..00000000 --- a/Plugins/UniTask/Runtime/Linq/First.cs +++ /dev/null @@ -1,200 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/First.cs.meta b/Plugins/UniTask/Runtime/Linq/First.cs.meta deleted file mode 100644 index 6924307a..00000000 --- a/Plugins/UniTask/Runtime/Linq/First.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 417946e97e9eed84db6f840f57037ca6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ForEach.cs b/Plugins/UniTask/Runtime/Linq/ForEach.cs deleted file mode 100644 index 60f246dd..00000000 --- a/Plugins/UniTask/Runtime/Linq/ForEach.cs +++ /dev/null @@ -1,193 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ForEach.cs.meta b/Plugins/UniTask/Runtime/Linq/ForEach.cs.meta deleted file mode 100644 index 53177562..00000000 --- a/Plugins/UniTask/Runtime/Linq/ForEach.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ca8d7f8177ba16140920af405aea3fd4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/GroupBy.cs b/Plugins/UniTask/Runtime/Linq/GroupBy.cs deleted file mode 100644 index b9460ae4..00000000 --- a/Plugins/UniTask/Runtime/Linq/GroupBy.cs +++ /dev/null @@ -1,923 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/GroupBy.cs.meta b/Plugins/UniTask/Runtime/Linq/GroupBy.cs.meta deleted file mode 100644 index 14897018..00000000 --- a/Plugins/UniTask/Runtime/Linq/GroupBy.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a2de80df1cc8a1240ab0ee7badd334d0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/GroupJoin.cs b/Plugins/UniTask/Runtime/Linq/GroupJoin.cs deleted file mode 100644 index 607b2217..00000000 --- a/Plugins/UniTask/Runtime/Linq/GroupJoin.cs +++ /dev/null @@ -1,612 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/GroupJoin.cs.meta b/Plugins/UniTask/Runtime/Linq/GroupJoin.cs.meta deleted file mode 100644 index f171ed19..00000000 --- a/Plugins/UniTask/Runtime/Linq/GroupJoin.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7bf7759d03bf3f64190d3ae83b182c2c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Intersect.cs b/Plugins/UniTask/Runtime/Linq/Intersect.cs deleted file mode 100644 index 3faf645f..00000000 --- a/Plugins/UniTask/Runtime/Linq/Intersect.cs +++ /dev/null @@ -1,117 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Intersect.cs.meta b/Plugins/UniTask/Runtime/Linq/Intersect.cs.meta deleted file mode 100644 index 28cf8e30..00000000 --- a/Plugins/UniTask/Runtime/Linq/Intersect.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 93999a70f5d57134bbe971f3e988c4f2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Join.cs b/Plugins/UniTask/Runtime/Linq/Join.cs deleted file mode 100644 index 2d80889e..00000000 --- a/Plugins/UniTask/Runtime/Linq/Join.cs +++ /dev/null @@ -1,728 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Join.cs.meta b/Plugins/UniTask/Runtime/Linq/Join.cs.meta deleted file mode 100644 index 3ab1015a..00000000 --- a/Plugins/UniTask/Runtime/Linq/Join.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dc4ff8cb6d7c9a64896f2f082124d6b3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Last.cs b/Plugins/UniTask/Runtime/Linq/Last.cs deleted file mode 100644 index 664bb27d..00000000 --- a/Plugins/UniTask/Runtime/Linq/Last.cs +++ /dev/null @@ -1,240 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Last.cs.meta b/Plugins/UniTask/Runtime/Linq/Last.cs.meta deleted file mode 100644 index edfa124a..00000000 --- a/Plugins/UniTask/Runtime/Linq/Last.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a0ccc93be1387fa4a975f06310127c11 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/LongCount.cs b/Plugins/UniTask/Runtime/Linq/LongCount.cs deleted file mode 100644 index 78ae805f..00000000 --- a/Plugins/UniTask/Runtime/Linq/LongCount.cs +++ /dev/null @@ -1,144 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/LongCount.cs.meta b/Plugins/UniTask/Runtime/Linq/LongCount.cs.meta deleted file mode 100644 index 862c2bcf..00000000 --- a/Plugins/UniTask/Runtime/Linq/LongCount.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 198b39e58ced3ab4f97ccbe0916787d5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Max.cs b/Plugins/UniTask/Runtime/Linq/Max.cs deleted file mode 100644 index d244a15d..00000000 --- a/Plugins/UniTask/Runtime/Linq/Max.cs +++ /dev/null @@ -1,200 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Max.cs.meta b/Plugins/UniTask/Runtime/Linq/Max.cs.meta deleted file mode 100644 index 2125edf6..00000000 --- a/Plugins/UniTask/Runtime/Linq/Max.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5c8a118a6b664c441820b8a87d7f6e28 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Min.cs b/Plugins/UniTask/Runtime/Linq/Min.cs deleted file mode 100644 index 8768a86e..00000000 --- a/Plugins/UniTask/Runtime/Linq/Min.cs +++ /dev/null @@ -1,200 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Min.cs.meta b/Plugins/UniTask/Runtime/Linq/Min.cs.meta deleted file mode 100644 index 91378dc9..00000000 --- a/Plugins/UniTask/Runtime/Linq/Min.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 57ac9da21d3457849a8e45548290a508 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/MinMax.cs b/Plugins/UniTask/Runtime/Linq/MinMax.cs deleted file mode 100644 index aae3541b..00000000 --- a/Plugins/UniTask/Runtime/Linq/MinMax.cs +++ /dev/null @@ -1,3763 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/MinMax.cs.meta b/Plugins/UniTask/Runtime/Linq/MinMax.cs.meta deleted file mode 100644 index 3856b65f..00000000 --- a/Plugins/UniTask/Runtime/Linq/MinMax.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2d6da02d9ab970e4999daf7147d98e36 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Never.cs b/Plugins/UniTask/Runtime/Linq/Never.cs deleted file mode 100644 index 2dbce711..00000000 --- a/Plugins/UniTask/Runtime/Linq/Never.cs +++ /dev/null @@ -1,56 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Never.cs.meta b/Plugins/UniTask/Runtime/Linq/Never.cs.meta deleted file mode 100644 index ba9d358c..00000000 --- a/Plugins/UniTask/Runtime/Linq/Never.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8b307c3d3be71a94da251564bcdefa3d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/OfType.cs b/Plugins/UniTask/Runtime/Linq/OfType.cs deleted file mode 100644 index fea8069f..00000000 --- a/Plugins/UniTask/Runtime/Linq/OfType.cs +++ /dev/null @@ -1,61 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/OfType.cs.meta b/Plugins/UniTask/Runtime/Linq/OfType.cs.meta deleted file mode 100644 index 6ace53fd..00000000 --- a/Plugins/UniTask/Runtime/Linq/OfType.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 111ffe87a7d700442a9ef5af554b252c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/OrderBy.cs b/Plugins/UniTask/Runtime/Linq/OrderBy.cs deleted file mode 100644 index d0c379fe..00000000 --- a/Plugins/UniTask/Runtime/Linq/OrderBy.cs +++ /dev/null @@ -1,558 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/OrderBy.cs.meta b/Plugins/UniTask/Runtime/Linq/OrderBy.cs.meta deleted file mode 100644 index 5c6b3e4a..00000000 --- a/Plugins/UniTask/Runtime/Linq/OrderBy.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 413883ceff8546143bdf200aafa4b8f7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Pairwise.cs b/Plugins/UniTask/Runtime/Linq/Pairwise.cs deleted file mode 100644 index 5d44a9e8..00000000 --- a/Plugins/UniTask/Runtime/Linq/Pairwise.cs +++ /dev/null @@ -1,128 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Pairwise.cs.meta b/Plugins/UniTask/Runtime/Linq/Pairwise.cs.meta deleted file mode 100644 index 727b8cf4..00000000 --- a/Plugins/UniTask/Runtime/Linq/Pairwise.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cddbf051d2a88f549986c468b23214af -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Publish.cs b/Plugins/UniTask/Runtime/Linq/Publish.cs deleted file mode 100644 index d218c0f2..00000000 --- a/Plugins/UniTask/Runtime/Linq/Publish.cs +++ /dev/null @@ -1,173 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Publish.cs.meta b/Plugins/UniTask/Runtime/Linq/Publish.cs.meta deleted file mode 100644 index f3a81ba3..00000000 --- a/Plugins/UniTask/Runtime/Linq/Publish.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 93c684d1e88c09d4e89b79437d97b810 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Queue.cs b/Plugins/UniTask/Runtime/Linq/Queue.cs deleted file mode 100644 index b5c221fb..00000000 --- a/Plugins/UniTask/Runtime/Linq/Queue.cs +++ /dev/null @@ -1,103 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Queue.cs.meta b/Plugins/UniTask/Runtime/Linq/Queue.cs.meta deleted file mode 100644 index 35f3fab2..00000000 --- a/Plugins/UniTask/Runtime/Linq/Queue.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b7ea1bcf9dbebb042bc99c7816249e02 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Range.cs b/Plugins/UniTask/Runtime/Linq/Range.cs deleted file mode 100644 index 24a795d1..00000000 --- a/Plugins/UniTask/Runtime/Linq/Range.cs +++ /dev/null @@ -1,75 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Range.cs.meta b/Plugins/UniTask/Runtime/Linq/Range.cs.meta deleted file mode 100644 index 36272fcf..00000000 --- a/Plugins/UniTask/Runtime/Linq/Range.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d826418a813498648b10542d0a5fb173 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Repeat.cs b/Plugins/UniTask/Runtime/Linq/Repeat.cs deleted file mode 100644 index db90a1ae..00000000 --- a/Plugins/UniTask/Runtime/Linq/Repeat.cs +++ /dev/null @@ -1,68 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Repeat.cs.meta b/Plugins/UniTask/Runtime/Linq/Repeat.cs.meta deleted file mode 100644 index 693d5790..00000000 --- a/Plugins/UniTask/Runtime/Linq/Repeat.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3819a3925165a674d80ee848c8600379 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Return.cs b/Plugins/UniTask/Runtime/Linq/Return.cs deleted file mode 100644 index ba8fa8df..00000000 --- a/Plugins/UniTask/Runtime/Linq/Return.cs +++ /dev/null @@ -1,63 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Return.cs.meta b/Plugins/UniTask/Runtime/Linq/Return.cs.meta deleted file mode 100644 index ad264d0d..00000000 --- a/Plugins/UniTask/Runtime/Linq/Return.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4313cd8ecf705e44f9064ce46e293c2c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Reverse.cs b/Plugins/UniTask/Runtime/Linq/Reverse.cs deleted file mode 100644 index 48d43181..00000000 --- a/Plugins/UniTask/Runtime/Linq/Reverse.cs +++ /dev/null @@ -1,78 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Reverse.cs.meta b/Plugins/UniTask/Runtime/Linq/Reverse.cs.meta deleted file mode 100644 index 4a28306a..00000000 --- a/Plugins/UniTask/Runtime/Linq/Reverse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b2769e65c729b4f4ca6af9826d9c7b90 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Select.cs b/Plugins/UniTask/Runtime/Linq/Select.cs deleted file mode 100644 index 50e9cec9..00000000 --- a/Plugins/UniTask/Runtime/Linq/Select.cs +++ /dev/null @@ -1,760 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Select.cs.meta b/Plugins/UniTask/Runtime/Linq/Select.cs.meta deleted file mode 100644 index 476e9723..00000000 --- a/Plugins/UniTask/Runtime/Linq/Select.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dc68e598ca44a134b988dfaf5e53bfba -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/SelectMany.cs b/Plugins/UniTask/Runtime/Linq/SelectMany.cs deleted file mode 100644 index 6cad2a50..00000000 --- a/Plugins/UniTask/Runtime/Linq/SelectMany.cs +++ /dev/null @@ -1,892 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/SelectMany.cs.meta b/Plugins/UniTask/Runtime/Linq/SelectMany.cs.meta deleted file mode 100644 index a8dbbaf6..00000000 --- a/Plugins/UniTask/Runtime/Linq/SelectMany.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d81862f0eb12680479ccaaf2ac319d24 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/SequenceEqual.cs b/Plugins/UniTask/Runtime/Linq/SequenceEqual.cs deleted file mode 100644 index 9512ea7d..00000000 --- a/Plugins/UniTask/Runtime/Linq/SequenceEqual.cs +++ /dev/null @@ -1,87 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/SequenceEqual.cs.meta b/Plugins/UniTask/Runtime/Linq/SequenceEqual.cs.meta deleted file mode 100644 index ee2b75c2..00000000 --- a/Plugins/UniTask/Runtime/Linq/SequenceEqual.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b382772aba6128842928cdb6b2e034b0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Single.cs b/Plugins/UniTask/Runtime/Linq/Single.cs deleted file mode 100644 index 30df1b3d..00000000 --- a/Plugins/UniTask/Runtime/Linq/Single.cs +++ /dev/null @@ -1,230 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Single.cs.meta b/Plugins/UniTask/Runtime/Linq/Single.cs.meta deleted file mode 100644 index c053dfd7..00000000 --- a/Plugins/UniTask/Runtime/Linq/Single.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1bcd3928b90472e43a3a92c3ba708967 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Skip.cs b/Plugins/UniTask/Runtime/Linq/Skip.cs deleted file mode 100644 index 6f4831d1..00000000 --- a/Plugins/UniTask/Runtime/Linq/Skip.cs +++ /dev/null @@ -1,69 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Skip.cs.meta b/Plugins/UniTask/Runtime/Linq/Skip.cs.meta deleted file mode 100644 index 25ad847b..00000000 --- a/Plugins/UniTask/Runtime/Linq/Skip.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9c46b6c7dce0cb049a73c81084c75154 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/SkipLast.cs b/Plugins/UniTask/Runtime/Linq/SkipLast.cs deleted file mode 100644 index 9d127b87..00000000 --- a/Plugins/UniTask/Runtime/Linq/SkipLast.cs +++ /dev/null @@ -1,159 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/SkipLast.cs.meta b/Plugins/UniTask/Runtime/Linq/SkipLast.cs.meta deleted file mode 100644 index 06b1ede4..00000000 --- a/Plugins/UniTask/Runtime/Linq/SkipLast.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: df1d7f44d4fe7754f972c9e0b6fa72d5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/SkipUntil.cs b/Plugins/UniTask/Runtime/Linq/SkipUntil.cs deleted file mode 100644 index 5a707bb3..00000000 --- a/Plugins/UniTask/Runtime/Linq/SkipUntil.cs +++ /dev/null @@ -1,187 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/SkipUntil.cs.meta b/Plugins/UniTask/Runtime/Linq/SkipUntil.cs.meta deleted file mode 100644 index 0772ed01..00000000 --- a/Plugins/UniTask/Runtime/Linq/SkipUntil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: de932d79c8d9f3841a066d05ff29edc9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/SkipUntilCanceled.cs b/Plugins/UniTask/Runtime/Linq/SkipUntilCanceled.cs deleted file mode 100644 index f4c96798..00000000 --- a/Plugins/UniTask/Runtime/Linq/SkipUntilCanceled.cs +++ /dev/null @@ -1,173 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/SkipUntilCanceled.cs.meta b/Plugins/UniTask/Runtime/Linq/SkipUntilCanceled.cs.meta deleted file mode 100644 index 9f67181d..00000000 --- a/Plugins/UniTask/Runtime/Linq/SkipUntilCanceled.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4b1a778aef7150d47b93a49aa1bc34ae -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/SkipWhile.cs b/Plugins/UniTask/Runtime/Linq/SkipWhile.cs deleted file mode 100644 index 771a2e25..00000000 --- a/Plugins/UniTask/Runtime/Linq/SkipWhile.cs +++ /dev/null @@ -1,379 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/SkipWhile.cs.meta b/Plugins/UniTask/Runtime/Linq/SkipWhile.cs.meta deleted file mode 100644 index f2b210a9..00000000 --- a/Plugins/UniTask/Runtime/Linq/SkipWhile.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0b74b9fe361bf7148b51a29c8b2561e8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Subscribe.cs b/Plugins/UniTask/Runtime/Linq/Subscribe.cs deleted file mode 100644 index 0785bc28..00000000 --- a/Plugins/UniTask/Runtime/Linq/Subscribe.cs +++ /dev/null @@ -1,536 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Subscribe.cs.meta b/Plugins/UniTask/Runtime/Linq/Subscribe.cs.meta deleted file mode 100644 index ea835671..00000000 --- a/Plugins/UniTask/Runtime/Linq/Subscribe.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 263479eb04c189741931fc0e2f615c2d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Sum.cs b/Plugins/UniTask/Runtime/Linq/Sum.cs deleted file mode 100644 index 1101cd7f..00000000 --- a/Plugins/UniTask/Runtime/Linq/Sum.cs +++ /dev/null @@ -1,1244 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Sum.cs.meta b/Plugins/UniTask/Runtime/Linq/Sum.cs.meta deleted file mode 100644 index 5331e349..00000000 --- a/Plugins/UniTask/Runtime/Linq/Sum.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4149754066a21a341be58c04357061f6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Take.cs b/Plugins/UniTask/Runtime/Linq/Take.cs deleted file mode 100644 index 6cd4eda6..00000000 --- a/Plugins/UniTask/Runtime/Linq/Take.cs +++ /dev/null @@ -1,124 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Take.cs.meta b/Plugins/UniTask/Runtime/Linq/Take.cs.meta deleted file mode 100644 index 1cc91ab0..00000000 --- a/Plugins/UniTask/Runtime/Linq/Take.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 42f02cb84e5875b488304755d0e1383d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/TakeLast.cs b/Plugins/UniTask/Runtime/Linq/TakeLast.cs deleted file mode 100644 index ca0084e9..00000000 --- a/Plugins/UniTask/Runtime/Linq/TakeLast.cs +++ /dev/null @@ -1,175 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/TakeLast.cs.meta b/Plugins/UniTask/Runtime/Linq/TakeLast.cs.meta deleted file mode 100644 index d80037f4..00000000 --- a/Plugins/UniTask/Runtime/Linq/TakeLast.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 510aa9fd35b45fc40bcdb7e59f01fd1b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/TakeUntil.cs b/Plugins/UniTask/Runtime/Linq/TakeUntil.cs deleted file mode 100644 index 25371ad9..00000000 --- a/Plugins/UniTask/Runtime/Linq/TakeUntil.cs +++ /dev/null @@ -1,190 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/TakeUntil.cs.meta b/Plugins/UniTask/Runtime/Linq/TakeUntil.cs.meta deleted file mode 100644 index 44cf63e1..00000000 --- a/Plugins/UniTask/Runtime/Linq/TakeUntil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 12bda324162f15349afefc2c152ac07f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/TakeUntilCanceled.cs b/Plugins/UniTask/Runtime/Linq/TakeUntilCanceled.cs deleted file mode 100644 index 67ee3c8c..00000000 --- a/Plugins/UniTask/Runtime/Linq/TakeUntilCanceled.cs +++ /dev/null @@ -1,164 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/TakeUntilCanceled.cs.meta b/Plugins/UniTask/Runtime/Linq/TakeUntilCanceled.cs.meta deleted file mode 100644 index 4a89be54..00000000 --- a/Plugins/UniTask/Runtime/Linq/TakeUntilCanceled.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e82f498cf3a1df04cbf646773fc11319 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/TakeWhile.cs b/Plugins/UniTask/Runtime/Linq/TakeWhile.cs deleted file mode 100644 index 6239c776..00000000 --- a/Plugins/UniTask/Runtime/Linq/TakeWhile.cs +++ /dev/null @@ -1,342 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/TakeWhile.cs.meta b/Plugins/UniTask/Runtime/Linq/TakeWhile.cs.meta deleted file mode 100644 index f2173d59..00000000 --- a/Plugins/UniTask/Runtime/Linq/TakeWhile.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bca55adabcc4b3141b50b8b09634f764 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Throw.cs b/Plugins/UniTask/Runtime/Linq/Throw.cs deleted file mode 100644 index b6994c46..00000000 --- a/Plugins/UniTask/Runtime/Linq/Throw.cs +++ /dev/null @@ -1,54 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Throw.cs.meta b/Plugins/UniTask/Runtime/Linq/Throw.cs.meta deleted file mode 100644 index c768ef1e..00000000 --- a/Plugins/UniTask/Runtime/Linq/Throw.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9d05a7d4f4161e549b4789e1022baae8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ToArray.cs b/Plugins/UniTask/Runtime/Linq/ToArray.cs deleted file mode 100644 index 35549681..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToArray.cs +++ /dev/null @@ -1,60 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ToArray.cs.meta b/Plugins/UniTask/Runtime/Linq/ToArray.cs.meta deleted file mode 100644 index 679d61c9..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToArray.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: debb010bbb1622e43b94fe70ec0133dd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ToDictionary.cs b/Plugins/UniTask/Runtime/Linq/ToDictionary.cs deleted file mode 100644 index 083ace0c..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToDictionary.cs +++ /dev/null @@ -1,278 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ToDictionary.cs.meta b/Plugins/UniTask/Runtime/Linq/ToDictionary.cs.meta deleted file mode 100644 index 4deed194..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToDictionary.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 03b109b1fe1f2df46aa56ffb26747654 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ToHashSet.cs b/Plugins/UniTask/Runtime/Linq/ToHashSet.cs deleted file mode 100644 index d058cb1d..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToHashSet.cs +++ /dev/null @@ -1,50 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ToHashSet.cs.meta b/Plugins/UniTask/Runtime/Linq/ToHashSet.cs.meta deleted file mode 100644 index 8d3c4af2..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToHashSet.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7a3e552113af96e4986805ec3c4fc80a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ToList.cs b/Plugins/UniTask/Runtime/Linq/ToList.cs deleted file mode 100644 index e6fa35e1..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToList.cs +++ /dev/null @@ -1,42 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ToList.cs.meta b/Plugins/UniTask/Runtime/Linq/ToList.cs.meta deleted file mode 100644 index 4f093738..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToList.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3859c1b31e81d9b44b282e7d97e11635 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ToLookup.cs b/Plugins/UniTask/Runtime/Linq/ToLookup.cs deleted file mode 100644 index 015c1c07..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToLookup.cs +++ /dev/null @@ -1,554 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ToLookup.cs.meta b/Plugins/UniTask/Runtime/Linq/ToLookup.cs.meta deleted file mode 100644 index 7dd8ecd6..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToLookup.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 57da22563bcd6ca4aaf256d941de5cb0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ToObservable.cs b/Plugins/UniTask/Runtime/Linq/ToObservable.cs deleted file mode 100644 index 4f483887..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToObservable.cs +++ /dev/null @@ -1,97 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ToObservable.cs.meta b/Plugins/UniTask/Runtime/Linq/ToObservable.cs.meta deleted file mode 100644 index 44d917e3..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToObservable.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b4f6f48a532188e4c80b7ebe69aea3a8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs b/Plugins/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs deleted file mode 100644 index 02523c6f..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs +++ /dev/null @@ -1,1115 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs.meta b/Plugins/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs.meta deleted file mode 100644 index 45fd3b08..00000000 --- a/Plugins/UniTask/Runtime/Linq/ToUniTaskAsyncEnumerable.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d7192de2a0581ec4db62962cc1404af5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/UniTask.Linq.asmdef b/Plugins/UniTask/Runtime/Linq/UniTask.Linq.asmdef deleted file mode 100644 index db84553b..00000000 --- a/Plugins/UniTask/Runtime/Linq/UniTask.Linq.asmdef +++ /dev/null @@ -1,15 +0,0 @@ -{ - "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/Plugins/UniTask/Runtime/Linq/UniTask.Linq.asmdef.meta b/Plugins/UniTask/Runtime/Linq/UniTask.Linq.asmdef.meta deleted file mode 100644 index 1c85d19e..00000000 --- a/Plugins/UniTask/Runtime/Linq/UniTask.Linq.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 5c01796d064528144a599661eaab93a6 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Union.cs b/Plugins/UniTask/Runtime/Linq/Union.cs deleted file mode 100644 index 2ceefab1..00000000 --- a/Plugins/UniTask/Runtime/Linq/Union.cs +++ /dev/null @@ -1,26 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Union.cs.meta b/Plugins/UniTask/Runtime/Linq/Union.cs.meta deleted file mode 100644 index 1d9c7adb..00000000 --- a/Plugins/UniTask/Runtime/Linq/Union.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ae57a55bdeba98b4f8ff234d98d7dd76 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/UnityExtensions.meta b/Plugins/UniTask/Runtime/Linq/UnityExtensions.meta deleted file mode 100644 index fcace85b..00000000 --- a/Plugins/UniTask/Runtime/Linq/UnityExtensions.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5a87f19d29d934f469c06e9639b468ae -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs b/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs deleted file mode 100644 index 585fff96..00000000 --- a/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs +++ /dev/null @@ -1,77 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs.meta b/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs.meta deleted file mode 100644 index 6336e0e3..00000000 --- a/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryUpdate.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 00520eb52e49b5b4e8d9870d6ff1aced -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs b/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs deleted file mode 100644 index f678e7aa..00000000 --- a/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs +++ /dev/null @@ -1,240 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs.meta b/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs.meta deleted file mode 100644 index 9d2be702..00000000 --- a/Plugins/UniTask/Runtime/Linq/UnityExtensions/EveryValueChanged.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1ec39f1c41c305344854782c935ad354 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs b/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs deleted file mode 100644 index 53ecfcd7..00000000 --- a/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs +++ /dev/null @@ -1,312 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs.meta b/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs.meta deleted file mode 100644 index aa790c52..00000000 --- a/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 382caacde439855418709c641e4d7b04 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Where.cs b/Plugins/UniTask/Runtime/Linq/Where.cs deleted file mode 100644 index 1b5ac47f..00000000 --- a/Plugins/UniTask/Runtime/Linq/Where.cs +++ /dev/null @@ -1,818 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Where.cs.meta b/Plugins/UniTask/Runtime/Linq/Where.cs.meta deleted file mode 100644 index 7e503375..00000000 --- a/Plugins/UniTask/Runtime/Linq/Where.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d882a3238d9535e4e8ce1ad3291eb7fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Linq/Zip.cs b/Plugins/UniTask/Runtime/Linq/Zip.cs deleted file mode 100644 index af6d5f17..00000000 --- a/Plugins/UniTask/Runtime/Linq/Zip.cs +++ /dev/null @@ -1,541 +0,0 @@ -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/Plugins/UniTask/Runtime/Linq/Zip.cs.meta b/Plugins/UniTask/Runtime/Linq/Zip.cs.meta deleted file mode 100644 index bf121637..00000000 --- a/Plugins/UniTask/Runtime/Linq/Zip.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: acc1acff153e347418f0f30b1c535994 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/MoveNextSource.cs b/Plugins/UniTask/Runtime/MoveNextSource.cs deleted file mode 100644 index 3e9ca236..00000000 --- a/Plugins/UniTask/Runtime/MoveNextSource.cs +++ /dev/null @@ -1,63 +0,0 @@ -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/Plugins/UniTask/Runtime/MoveNextSource.cs.meta b/Plugins/UniTask/Runtime/MoveNextSource.cs.meta deleted file mode 100644 index 60a0908c..00000000 --- a/Plugins/UniTask/Runtime/MoveNextSource.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dc4c5dc2a5f246e4f8df44cab735826c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/PlayerLoopHelper.cs b/Plugins/UniTask/Runtime/PlayerLoopHelper.cs deleted file mode 100644 index 3c605a42..00000000 --- a/Plugins/UniTask/Runtime/PlayerLoopHelper.cs +++ /dev/null @@ -1,564 +0,0 @@ -#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(); - 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) - { - foreach (var subSystem in header.subSystemList) - { - if (subSystem.type == typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization)) - { - return true; - } - } - } - - return false; - } - -#endif - - } -} - diff --git a/Plugins/UniTask/Runtime/PlayerLoopHelper.cs.meta b/Plugins/UniTask/Runtime/PlayerLoopHelper.cs.meta deleted file mode 100644 index 2487ef77..00000000 --- a/Plugins/UniTask/Runtime/PlayerLoopHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 15fb5b85042f19640b973ce651795aca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/PlayerLoopTimer.cs b/Plugins/UniTask/Runtime/PlayerLoopTimer.cs deleted file mode 100644 index f8a877a4..00000000 --- a/Plugins/UniTask/Runtime/PlayerLoopTimer.cs +++ /dev/null @@ -1,262 +0,0 @@ -#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/Plugins/UniTask/Runtime/PlayerLoopTimer.cs.meta b/Plugins/UniTask/Runtime/PlayerLoopTimer.cs.meta deleted file mode 100644 index eb2b50a0..00000000 --- a/Plugins/UniTask/Runtime/PlayerLoopTimer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 57095a17fdca7ee4380450910afc7f26 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Progress.cs b/Plugins/UniTask/Runtime/Progress.cs deleted file mode 100644 index ed112902..00000000 --- a/Plugins/UniTask/Runtime/Progress.cs +++ /dev/null @@ -1,87 +0,0 @@ -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/Plugins/UniTask/Runtime/Progress.cs.meta b/Plugins/UniTask/Runtime/Progress.cs.meta deleted file mode 100644 index f0e1f197..00000000 --- a/Plugins/UniTask/Runtime/Progress.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e3377e2ae934ed54fb8fd5388e2d9eb9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/TaskPool.cs b/Plugins/UniTask/Runtime/TaskPool.cs deleted file mode 100644 index 8e619322..00000000 --- a/Plugins/UniTask/Runtime/TaskPool.cs +++ /dev/null @@ -1,123 +0,0 @@ -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 -{ - // internaly 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/Plugins/UniTask/Runtime/TaskPool.cs.meta b/Plugins/UniTask/Runtime/TaskPool.cs.meta deleted file mode 100644 index 94c78058..00000000 --- a/Plugins/UniTask/Runtime/TaskPool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 19f4e6575150765449cc99f25f06f25f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/TimeoutController.cs b/Plugins/UniTask/Runtime/TimeoutController.cs deleted file mode 100644 index ad95cb5a..00000000 --- a/Plugins/UniTask/Runtime/TimeoutController.cs +++ /dev/null @@ -1,129 +0,0 @@ -#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/Plugins/UniTask/Runtime/TimeoutController.cs.meta b/Plugins/UniTask/Runtime/TimeoutController.cs.meta deleted file mode 100644 index 4f3d16d9..00000000 --- a/Plugins/UniTask/Runtime/TimeoutController.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6347ab34d2db6d744a654e8d62d96b96 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/TriggerEvent.cs b/Plugins/UniTask/Runtime/TriggerEvent.cs deleted file mode 100644 index 503e9db9..00000000 --- a/Plugins/UniTask/Runtime/TriggerEvent.cs +++ /dev/null @@ -1,311 +0,0 @@ -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/Plugins/UniTask/Runtime/TriggerEvent.cs.meta b/Plugins/UniTask/Runtime/TriggerEvent.cs.meta deleted file mode 100644 index bbd47af7..00000000 --- a/Plugins/UniTask/Runtime/TriggerEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f68b22bb8f66f5c4885f9bd3c4fc43ed -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Triggers.meta b/Plugins/UniTask/Runtime/Triggers.meta deleted file mode 100644 index d0956e08..00000000 --- a/Plugins/UniTask/Runtime/Triggers.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 32f076424319db74c974014cb60a08de -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs b/Plugins/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs deleted file mode 100644 index a734f29d..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs +++ /dev/null @@ -1,32 +0,0 @@ -#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/Plugins/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs.meta b/Plugins/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs.meta deleted file mode 100644 index 097fdb61..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncAwakeTrigger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ef2840a2586894741a0ae211b8fd669b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs b/Plugins/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs deleted file mode 100644 index 811f9770..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs +++ /dev/null @@ -1,97 +0,0 @@ -#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/Plugins/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs.meta b/Plugins/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs.meta deleted file mode 100644 index 64500494..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncDestroyTrigger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f4afdcb1cbadf954ba8b1cf465429e17 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Triggers/AsyncStartTrigger.cs b/Plugins/UniTask/Runtime/Triggers/AsyncStartTrigger.cs deleted file mode 100644 index 63da82aa..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncStartTrigger.cs +++ /dev/null @@ -1,38 +0,0 @@ -#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/Plugins/UniTask/Runtime/Triggers/AsyncStartTrigger.cs.meta b/Plugins/UniTask/Runtime/Triggers/AsyncStartTrigger.cs.meta deleted file mode 100644 index 9ef06e8e..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncStartTrigger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b4fd0f75e54ec3d4fbcb7fc65b11646b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Triggers/AsyncTriggerBase.cs b/Plugins/UniTask/Runtime/Triggers/AsyncTriggerBase.cs deleted file mode 100644 index fb6ca6ef..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncTriggerBase.cs +++ /dev/null @@ -1,310 +0,0 @@ -#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/Plugins/UniTask/Runtime/Triggers/AsyncTriggerBase.cs.meta b/Plugins/UniTask/Runtime/Triggers/AsyncTriggerBase.cs.meta deleted file mode 100644 index e101ea2d..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncTriggerBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2c0c2bcee832c6641b25949c412f020f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs b/Plugins/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs deleted file mode 100644 index 49e7f0b8..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs +++ /dev/null @@ -1,85 +0,0 @@ -#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 - { - /// 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) - { - 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/Plugins/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs.meta b/Plugins/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs.meta deleted file mode 100644 index 348783dd..00000000 --- a/Plugins/UniTask/Runtime/Triggers/AsyncTriggerExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 59b61dbea1562a84fb7a38ae0a0a0f88 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs b/Plugins/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs deleted file mode 100644 index 6ef50146..00000000 --- a/Plugins/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs +++ /dev/null @@ -1,4457 +0,0 @@ -#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/Plugins/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs.meta b/Plugins/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs.meta deleted file mode 100644 index 82aa6792..00000000 --- a/Plugins/UniTask/Runtime/Triggers/MonoBehaviourMessagesTriggers.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c30655636c35c3d4da44064af3d2d9a7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.Bridge.cs b/Plugins/UniTask/Runtime/UniTask.Bridge.cs deleted file mode 100644 index c9042999..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Bridge.cs +++ /dev/null @@ -1,18 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.Bridge.cs.meta b/Plugins/UniTask/Runtime/UniTask.Bridge.cs.meta deleted file mode 100644 index 6f8da804..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Bridge.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bd6beac8e0ebd264e9ba246c39429c72 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.Delay.cs b/Plugins/UniTask/Runtime/UniTask.Delay.cs deleted file mode 100644 index 7e922f44..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Delay.cs +++ /dev/null @@ -1,963 +0,0 @@ -#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.FixedUpdate). - /// - public static YieldAwaitable WaitForFixedUpdate() - { - return UniTask.Yield(PlayerLoopTiming.FixedUpdate); - } - - /// - /// Same as UniTask.Yield(PlayerLoopTiming.FixedUpdate, cancellationToken). - /// - public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken) - { - return UniTask.Yield(PlayerLoopTiming.FixedUpdate, 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/Plugins/UniTask/Runtime/UniTask.Delay.cs.meta b/Plugins/UniTask/Runtime/UniTask.Delay.cs.meta deleted file mode 100644 index 08ce5793..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Delay.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ecff7972251de0848b2c0fa89bbd3489 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.Factory.cs b/Plugins/UniTask/Runtime/UniTask.Factory.cs deleted file mode 100644 index 2f6a6a9e..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Factory.cs +++ /dev/null @@ -1,499 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.Factory.cs.meta b/Plugins/UniTask/Runtime/UniTask.Factory.cs.meta deleted file mode 100644 index 31bc0c95..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Factory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4e12b66d6b9bd7845b04a594cbe386b4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.Run.cs b/Plugins/UniTask/Runtime/UniTask.Run.cs deleted file mode 100644 index ac3e7958..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Run.cs +++ /dev/null @@ -1,289 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.Run.cs.meta b/Plugins/UniTask/Runtime/UniTask.Run.cs.meta deleted file mode 100644 index 9a780aea..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Run.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8473162fc285a5f44bcca90f7da073e7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.Threading.cs b/Plugins/UniTask/Runtime/UniTask.Threading.cs deleted file mode 100644 index 71d6aec2..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Threading.cs +++ /dev/null @@ -1,412 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.Threading.cs.meta b/Plugins/UniTask/Runtime/UniTask.Threading.cs.meta deleted file mode 100644 index fa512b8c..00000000 --- a/Plugins/UniTask/Runtime/UniTask.Threading.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4132ea600454134439fa2c7eb931b5e6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs b/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs deleted file mode 100644 index 0a09fe09..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs +++ /dev/null @@ -1,582 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs.meta b/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs.meta deleted file mode 100644 index 6e64dc7e..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 87c9c533491903a4288536b5ac173db8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.WhenAll.Generated.cs b/Plugins/UniTask/Runtime/UniTask.WhenAll.Generated.cs deleted file mode 100644 index 9ef07d62..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WhenAll.Generated.cs +++ /dev/null @@ -1,5011 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.WhenAll.Generated.cs.meta b/Plugins/UniTask/Runtime/UniTask.WhenAll.Generated.cs.meta deleted file mode 100644 index 40ed46cd..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WhenAll.Generated.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5110117231c8a6d4095fd0cbd3f4c142 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.WhenAll.cs b/Plugins/UniTask/Runtime/UniTask.WhenAll.cs deleted file mode 100644 index 39f6a9ad..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WhenAll.cs +++ /dev/null @@ -1,237 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.WhenAll.cs.meta b/Plugins/UniTask/Runtime/UniTask.WhenAll.cs.meta deleted file mode 100644 index 0366aa87..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WhenAll.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 355997a305ba64248822eec34998a1a0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.WhenAny.Generated.cs b/Plugins/UniTask/Runtime/UniTask.WhenAny.Generated.cs deleted file mode 100644 index 09b98e62..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WhenAny.Generated.cs +++ /dev/null @@ -1,5060 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.WhenAny.Generated.cs.meta b/Plugins/UniTask/Runtime/UniTask.WhenAny.Generated.cs.meta deleted file mode 100644 index 49a2c3fd..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WhenAny.Generated.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 13d604ac281570c4eac9962429f19ca9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.WhenAny.cs b/Plugins/UniTask/Runtime/UniTask.WhenAny.cs deleted file mode 100644 index 09eb32d7..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WhenAny.cs +++ /dev/null @@ -1,359 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.WhenAny.cs.meta b/Plugins/UniTask/Runtime/UniTask.WhenAny.cs.meta deleted file mode 100644 index c10f7621..00000000 --- a/Plugins/UniTask/Runtime/UniTask.WhenAny.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c32578978c37eaf41bdd90e1b034637d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.asmdef b/Plugins/UniTask/Runtime/UniTask.asmdef deleted file mode 100644 index a5c594d7..00000000 --- a/Plugins/UniTask/Runtime/UniTask.asmdef +++ /dev/null @@ -1,45 +0,0 @@ -{ - "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/Plugins/UniTask/Runtime/UniTask.asmdef.meta b/Plugins/UniTask/Runtime/UniTask.asmdef.meta deleted file mode 100644 index e497045e..00000000 --- a/Plugins/UniTask/Runtime/UniTask.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: f51ebe6a0ceec4240a699833d6309b23 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTask.cs b/Plugins/UniTask/Runtime/UniTask.cs deleted file mode 100644 index 8eb2087a..00000000 --- a/Plugins/UniTask/Runtime/UniTask.cs +++ /dev/null @@ -1,707 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTask.cs.meta b/Plugins/UniTask/Runtime/UniTask.cs.meta deleted file mode 100644 index 04eb6b64..00000000 --- a/Plugins/UniTask/Runtime/UniTask.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8947adf23181ff04db73829df217ca94 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs b/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs deleted file mode 100644 index 67b882ee..00000000 --- a/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs +++ /dev/null @@ -1,941 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs.meta b/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs.meta deleted file mode 100644 index 2ae5ee31..00000000 --- a/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ed03524d09e7eb24a9fb9137198feb84 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTaskExtensions.Shorthand.cs b/Plugins/UniTask/Runtime/UniTaskExtensions.Shorthand.cs deleted file mode 100644 index 0e51a459..00000000 --- a/Plugins/UniTask/Runtime/UniTaskExtensions.Shorthand.cs +++ /dev/null @@ -1,187 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTaskExtensions.Shorthand.cs.meta b/Plugins/UniTask/Runtime/UniTaskExtensions.Shorthand.cs.meta deleted file mode 100644 index e2dcc142..00000000 --- a/Plugins/UniTask/Runtime/UniTaskExtensions.Shorthand.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4b4ff020f73dc6d4b8ebd4760d61fb43 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTaskExtensions.cs b/Plugins/UniTask/Runtime/UniTaskExtensions.cs deleted file mode 100644 index d3301090..00000000 --- a/Plugins/UniTask/Runtime/UniTaskExtensions.cs +++ /dev/null @@ -1,921 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTaskExtensions.cs.meta b/Plugins/UniTask/Runtime/UniTaskExtensions.cs.meta deleted file mode 100644 index 0d229460..00000000 --- a/Plugins/UniTask/Runtime/UniTaskExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 05460c617dae1e440861a7438535389f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTaskObservableExtensions.cs b/Plugins/UniTask/Runtime/UniTaskObservableExtensions.cs deleted file mode 100644 index d54a5fdb..00000000 --- a/Plugins/UniTask/Runtime/UniTaskObservableExtensions.cs +++ /dev/null @@ -1,750 +0,0 @@ -#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(); - } - - 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(); - } - - 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/Plugins/UniTask/Runtime/UniTaskObservableExtensions.cs.meta b/Plugins/UniTask/Runtime/UniTaskObservableExtensions.cs.meta deleted file mode 100644 index 527a49fc..00000000 --- a/Plugins/UniTask/Runtime/UniTaskObservableExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eaea262a5ad393d419c15b3b2901d664 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTaskScheduler.cs b/Plugins/UniTask/Runtime/UniTaskScheduler.cs deleted file mode 100644 index 2f91f2ad..00000000 --- a/Plugins/UniTask/Runtime/UniTaskScheduler.cs +++ /dev/null @@ -1,103 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTaskScheduler.cs.meta b/Plugins/UniTask/Runtime/UniTaskScheduler.cs.meta deleted file mode 100644 index 5e29191f..00000000 --- a/Plugins/UniTask/Runtime/UniTaskScheduler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d6cad69921702d5488d96b5ef30df1b0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTaskSynchronizationContext.cs b/Plugins/UniTask/Runtime/UniTaskSynchronizationContext.cs deleted file mode 100644 index 450e019f..00000000 --- a/Plugins/UniTask/Runtime/UniTaskSynchronizationContext.cs +++ /dev/null @@ -1,158 +0,0 @@ -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/Plugins/UniTask/Runtime/UniTaskSynchronizationContext.cs.meta b/Plugins/UniTask/Runtime/UniTaskSynchronizationContext.cs.meta deleted file mode 100644 index 9828c893..00000000 --- a/Plugins/UniTask/Runtime/UniTaskSynchronizationContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: abf3aae9813db2849bce518f8596e920 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UniTaskVoid.cs b/Plugins/UniTask/Runtime/UniTaskVoid.cs deleted file mode 100644 index c7e9ed98..00000000 --- a/Plugins/UniTask/Runtime/UniTaskVoid.cs +++ /dev/null @@ -1,19 +0,0 @@ -#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/Plugins/UniTask/Runtime/UniTaskVoid.cs.meta b/Plugins/UniTask/Runtime/UniTaskVoid.cs.meta deleted file mode 100644 index 01f7156c..00000000 --- a/Plugins/UniTask/Runtime/UniTaskVoid.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e9f28cd922179634d863011548f89ae7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs b/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs deleted file mode 100644 index 90889f3d..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs +++ /dev/null @@ -1,198 +0,0 @@ -#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, 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/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs.meta b/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs.meta deleted file mode 100644 index 79be9231..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e9147caba40da434da95b39709c13784 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs b/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs deleted file mode 100644 index 5805dbb1..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs +++ /dev/null @@ -1,140 +0,0 @@ - #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/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs.meta b/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs.meta deleted file mode 100644 index 510c49e3..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 98f5fedb44749ab4688674d79126b46a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs b/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs deleted file mode 100644 index db0a8922..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs +++ /dev/null @@ -1,102 +0,0 @@ -#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/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs.meta b/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs.meta deleted file mode 100644 index c07df0b8..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 30979a768fbd4b94f8694eee8a305c99 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs b/Plugins/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs deleted file mode 100644 index fdfe55ca..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs +++ /dev/null @@ -1,14 +0,0 @@ -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/Plugins/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs.meta b/Plugins/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs.meta deleted file mode 100644 index 6e45863f..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.MonoBehaviour.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2edd588bb09eb0a4695d039d6a1f02b2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs b/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs deleted file mode 100644 index 8f8e3a17..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs +++ /dev/null @@ -1,928 +0,0 @@ -#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 - - public static AsyncOperationAwaiter GetAwaiter(this AsyncOperation asyncOperation) - { - Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - return new AsyncOperationAwaiter(asyncOperation); - } - - 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/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs.meta b/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs.meta deleted file mode 100644 index 6dfab815..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8cc7fd65dd1433e419be4764aeb51391 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs b/Plugins/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs deleted file mode 100644 index 11ebd63a..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs +++ /dev/null @@ -1,826 +0,0 @@ -#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 = cancellationToken1.RegisterWithoutCaptureExecutionContext(cancel2, this); - } - } - - return new UniTask(this, completionSource.Version); - } - - void Invoke() - { - completionSource.TrySetResult(true); - } - - static void OnCanceled1(object state) - { - var self = (UnityEventHandlerAsyncEnumerator)state; - self.DisposeAsync().Forget(); - } - - static void OnCanceled2(object state) - { - var self = (UnityEventHandlerAsyncEnumerator)state; - self.DisposeAsync().Forget(); - } - - public UniTask DisposeAsync() - { - if (!isDisposed) - { - isDisposed = true; - TaskTracker.RemoveTracking(this); - registration1.Dispose(); - registration2.Dispose(); - unityEvent.RemoveListener(unityAction); - } - - 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 = cancellationToken1.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; - self.DisposeAsync().Forget(); - } - - static void OnCanceled2(object state) - { - var self = (UnityEventHandlerAsyncEnumerator)state; - 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); - } - - return default; - } - } - } -} - -#endif \ No newline at end of file diff --git a/Plugins/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs.meta b/Plugins/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs.meta deleted file mode 100644 index 90c5d515..00000000 --- a/Plugins/UniTask/Runtime/UnityAsyncExtensions.uGUI.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6804799fba2376d4099561d176101aff -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UnityBindingExtensions.cs b/Plugins/UniTask/Runtime/UnityBindingExtensions.cs deleted file mode 100644 index 749f02a8..00000000 --- a/Plugins/UniTask/Runtime/UnityBindingExtensions.cs +++ /dev/null @@ -1,245 +0,0 @@ -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, Text text, bool rebindOnError = true) - { - BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); - } - - public static void BindTo(this IUniTaskAsyncEnumerable source, Text text, CancellationToken cancellationToken, bool rebindOnError = true) - { - BindToCore(source, text, cancellationToken, rebindOnError).Forget(); - } - - static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, 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, Text text, bool rebindOnError = true) - { - BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); - } - - public static void BindTo(this IUniTaskAsyncEnumerable source, Text text, CancellationToken cancellationToken, bool rebindOnError = true) - { - BindToCore(source, text, cancellationToken, rebindOnError).Forget(); - } - - public static void BindTo(this AsyncReactiveProperty source, Text text, bool rebindOnError = true) - { - BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget(); - } - - static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable source, 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/Plugins/UniTask/Runtime/UnityBindingExtensions.cs.meta b/Plugins/UniTask/Runtime/UnityBindingExtensions.cs.meta deleted file mode 100644 index 3fae798e..00000000 --- a/Plugins/UniTask/Runtime/UnityBindingExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 090b20e3528552b4a8d751f7df525c2b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/UnityWebRequestException.cs b/Plugins/UniTask/Runtime/UnityWebRequestException.cs deleted file mode 100644 index d2a37ce5..00000000 --- a/Plugins/UniTask/Runtime/UnityWebRequestException.cs +++ /dev/null @@ -1,67 +0,0 @@ -#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 (Text != null) - { - msg = Error + Environment.NewLine + Text; - } - else - { - msg = Error; - } - } - return msg; - } - } - } -} - -#endif \ No newline at end of file diff --git a/Plugins/UniTask/Runtime/UnityWebRequestException.cs.meta b/Plugins/UniTask/Runtime/UnityWebRequestException.cs.meta deleted file mode 100644 index 50c475e8..00000000 --- a/Plugins/UniTask/Runtime/UnityWebRequestException.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 013a499e522703a42962a779b4d9850c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/Runtime/_InternalVisibleTo.cs b/Plugins/UniTask/Runtime/_InternalVisibleTo.cs deleted file mode 100644 index ab7c10c9..00000000 --- a/Plugins/UniTask/Runtime/_InternalVisibleTo.cs +++ /dev/null @@ -1,6 +0,0 @@ -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/Plugins/UniTask/Runtime/_InternalVisibleTo.cs.meta b/Plugins/UniTask/Runtime/_InternalVisibleTo.cs.meta deleted file mode 100644 index 2ec6cd36..00000000 --- a/Plugins/UniTask/Runtime/_InternalVisibleTo.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8507e97eb606fad4b99c6edf92e19cb8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/UniTask/package.json b/Plugins/UniTask/package.json deleted file mode 100644 index f2e0b59b..00000000 --- a/Plugins/UniTask/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "com.cysharp.unitask", - "displayName": "UniTask", - "author": { "name": "Cysharp, Inc.", "url": "https://cysharp.co.jp/en/" }, - "version": "2.3.1", - "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/Plugins/UniTask/package.json.meta b/Plugins/UniTask/package.json.meta deleted file mode 100644 index 65439e6e..00000000 --- a/Plugins/UniTask/package.json.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: d1a9a71f68bb0d04db91ddaa3329abf9 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/WebSocket.meta b/Plugins/WebSocket.meta deleted file mode 100644 index e9beae76..00000000 --- a/Plugins/WebSocket.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e500f39d3a0936c44809c52a96697ade -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/WebSocket/WebSocket_LnlM.asmdef b/Plugins/WebSocket/WebSocket_LnlM.asmdef deleted file mode 100644 index 162d95ad..00000000 --- a/Plugins/WebSocket/WebSocket_LnlM.asmdef +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "WebSocket" -} diff --git a/Plugins/WebSocket/WebSocket_LnlM.asmdef.meta b/Plugins/WebSocket/WebSocket_LnlM.asmdef.meta deleted file mode 100644 index e6d36a40..00000000 --- a/Plugins/WebSocket/WebSocket_LnlM.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: d969dd435f4843f4a9b7e2a7c04f4839 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/WebSocket/WebSocket_LnlM.jslib b/Plugins/WebSocket/WebSocket_LnlM.jslib deleted file mode 100644 index 50c300f0..00000000 --- a/Plugins/WebSocket/WebSocket_LnlM.jslib +++ /dev/null @@ -1,143 +0,0 @@ -var LibraryWebSockets_LnlM = { - $webSocketInstances_LnlM: [], - - // Create instance and connect to server - // Events: DataEvent = 0, ConnectEvent = 1, DisconnectEvent = 2, ErrorEvent = 3 - SocketCreate_LnlM: function(url) - { - var str = UTF8ToString(url); - var socket = { - socket: new WebSocket(str), - buffer: new Uint8Array(0), - events: [] - } - - socket.socket.binaryType = 'arraybuffer'; - - socket.socket.onopen = function(e) { - socket.events.push({ - type: 1, - }); - }; - - socket.socket.onmessage = function(e) { - // TODO: handle other data types? - if (e.data instanceof Blob) - { - var reader = new FileReader(); - reader.addEventListener("loadend", function() { - socket.events.push({ - type: 0, - data: new Uint8Array(reader.result) - }); - }); - reader.readAsArrayBuffer(e.data); - } - else if (e.data instanceof ArrayBuffer) - { - socket.events.push({ - type: 0, - data: new Uint8Array(e.data) - }); - } - }; - - socket.socket.onerror = function(e) { - // Ref: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code - socket.events.push({ - type: 3, - code: e.code, - reason: e.reason, - }); - }; - - socket.socket.onclose = function(e) { - // Ref: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code - socket.events.push({ - type: 2, - code: e.code, - reason: e.reason, - }); - }; - - // Return instance pointer - var instance = webSocketInstances_LnlM.push(socket) - 1; - return instance; - }, - - // Get connection state - GetSocketState_LnlM: function (socketInstance) - { - var socket = webSocketInstances_LnlM[socketInstance]; - // Ref: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState - if (!socket) - return 3; - return socket.socket.readyState; - }, - - // Get latest event type - GetSocketEventType_LnlM: function(socketInstance) - { - var socket = webSocketInstances_LnlM[socketInstance]; - if (!socket || socket.events.length == 0) - return -1; - return socket.events[0].type; - }, - - // Get latest error code - GetSocketErrorCode_LnlM: function(socketInstance) - { - var socket = webSocketInstances_LnlM[socketInstance]; - if (!socket || socket.events.length == 0 || (socket.events[0].type != 3 && socket.events[0].type != 2)) - return 0; - return socket.events[0].code; - }, - - // Get latest data length - GetSocketDataLength_LnlM: function(socketInstance) - { - var socket = webSocketInstances_LnlM[socketInstance]; - if (!socket || socket.events.length == 0 || socket.events[0].type != 0 || socket.events[0].data.length == 0) - return 0; - return socket.events[0].data.length; - }, - - // Get latest data byte array - GetSocketData_LnlM: function(socketInstance, ptr, length) - { - var socket = webSocketInstances_LnlM[socketInstance]; - if (!socket || socket.events.length == 0 || socket.events[0].type != 0 || socket.events[0].data.length == 0 || socket.events[0].data.length > length) - return; - HEAPU8.set(socket.events[0].data, ptr); - }, - - // Dequeue network event - SocketEventDequeue_LnlM: function(socketInstance) - { - var socket = webSocketInstances_LnlM[socketInstance]; - if (!socket || socket.events.length == 0) - return; - socket.events = socket.events.slice(1); - }, - - // Send message - SocketSend_LnlM: function (socketInstance, ptr, length) - { - var socket = webSocketInstances_LnlM[socketInstance]; - if (!socket) - return; - socket.socket.send(HEAPU8.buffer.slice(ptr, ptr + length)); - }, - - // Close connection - SocketClose_LnlM: function (socketInstance) - { - var socket = webSocketInstances_LnlM[socketInstance]; - if (!socket) - return; - socket.socket.close(); - } -}; - -autoAddDeps(LibraryWebSockets_LnlM, '$webSocketInstances_LnlM'); -mergeInto(LibraryManager.library, LibraryWebSockets_LnlM); diff --git a/Plugins/WebSocket/WebSocket_LnlM.jslib.meta b/Plugins/WebSocket/WebSocket_LnlM.jslib.meta deleted file mode 100644 index a4f0052d..00000000 --- a/Plugins/WebSocket/WebSocket_LnlM.jslib.meta +++ /dev/null @@ -1,32 +0,0 @@ -fileFormatVersion: 2 -guid: 3b767cc116f846f4b813fe00142b8736 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 0 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 0 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - - first: - WebGL: WebGL - second: - enabled: 1 - settings: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger.meta b/Plugins/ZLogger.meta deleted file mode 100644 index d50bec2f..00000000 --- a/Plugins/ZLogger.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: db44732e1837b834bb95baf6afc1f8ed -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/AsyncProcessZLogger.cs b/Plugins/ZLogger/AsyncProcessZLogger.cs deleted file mode 100644 index f85be34b..00000000 --- a/Plugins/ZLogger/AsyncProcessZLogger.cs +++ /dev/null @@ -1,133 +0,0 @@ -using Microsoft.Extensions.Logging; -using System; -using System.Linq.Expressions; -using ZLogger.Entries; - -namespace ZLogger -{ - public class AsyncProcessZLogger : ILogger - { - readonly Func ReturnStringStateFormatter = (state, _) => state; - - readonly string categoryName; - readonly IAsyncLogProcessor logProcessor; - - public AsyncProcessZLogger(string categoryName, IAsyncLogProcessor logProcessor) - { - this.categoryName = categoryName; - this.logProcessor = logProcessor; - } - - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { - var factory = CreateLogEntry.factory; - if (factory != null) - { - var info = new LogInfo(categoryName, DateTimeOffset.UtcNow, logLevel, eventId, exception); - var entry = factory.Invoke(state, info); - logProcessor.Post(entry); - } - else - { - var info = new LogInfo(categoryName, DateTimeOffset.UtcNow, logLevel, eventId, exception); - if (StateTypeDetector.IsInternalFormattedLogValues || state == null) - { - // null state automatically converted to FormattedLogValues struct. - logProcessor.Post(StringFormatterEntry.Create(info, state, exception, formatter)); - } - else - { - // sometimes state has context(like HttpContext), it require to format in scope. - var message = formatter(state, exception); - logProcessor.Post(StringFormatterEntry.Create(info, message, exception, ReturnStringStateFormatter)); - } - } - } - - - static class StateTypeDetector - { - public static readonly bool IsInternalFormattedLogValues; - - static StateTypeDetector() - { - IsInternalFormattedLogValues = typeof(TState).FullName == "Microsoft.Extensions.Logging.FormattedLogValues"; - } - } - - public IDisposable BeginScope(TState state) - { - // currently scope is not supported... - return NullDisposable.Instance; - } - - public bool IsEnabled(LogLevel logLevel) - { - return logLevel != LogLevel.None; - } - - class NullDisposable : IDisposable - { - public static IDisposable Instance = new NullDisposable(); - - NullDisposable() - { - - } - - public void Dispose() - { - } - } - - - // call CreateLogEntry without cast(boxing) - static class CreateLogEntry - // where T:IZLoggerState - { - public static readonly Func factory; - - static CreateLogEntry() - { - if (typeof(IZLoggerState).IsAssignableFrom(typeof(T))) - { - try - { - var factoryField = typeof(T).GetField("Factory", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); - LogForUnity(factoryField); - - if (factoryField != null) - { - factory = factoryField.GetValue(null) as Func; - } - } - catch (Exception ex) - { - LogForUnity(ex); - } - } - else - { - factory = null; - } - } - - static void LogForUnity(System.Reflection.FieldInfo fieldInfo) - { -#if UNITY_2018_3_OR_NEWER - if(fieldInfo == null) - { - UnityEngine.Debug.Log("State.Factory FieldInfo is null."); - } -#endif - } - - static void LogForUnity(Exception ex) - { -#if UNITY_2018_3_OR_NEWER - UnityEngine.Debug.Log(ex); -#endif - } - } - } -} \ No newline at end of file diff --git a/Plugins/ZLogger/AsyncProcessZLogger.cs.meta b/Plugins/ZLogger/AsyncProcessZLogger.cs.meta deleted file mode 100644 index 0e44cce6..00000000 --- a/Plugins/ZLogger/AsyncProcessZLogger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9d2f862d257f1404f96b6bc25fe3711f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/AsyncStreamLineMessageWriter.cs b/Plugins/ZLogger/AsyncStreamLineMessageWriter.cs deleted file mode 100644 index f1ae67af..00000000 --- a/Plugins/ZLogger/AsyncStreamLineMessageWriter.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; -using System.Threading.Channels; -using System.Threading.Tasks; - -namespace ZLogger -{ - public class AsyncStreamLineMessageWriter : IAsyncLogProcessor, IAsyncDisposable - { - readonly byte[] newLine; - readonly bool crlf; - readonly byte newLine1; - readonly byte newLine2; - - readonly Stream stream; - readonly Channel channel; - readonly Task writeLoop; - readonly ZLoggerOptions options; - readonly CancellationTokenSource cancellationTokenSource; - - public AsyncStreamLineMessageWriter(Stream stream, ZLoggerOptions options) - { - this.newLine = Encoding.UTF8.GetBytes(Environment.NewLine); - this.cancellationTokenSource = new CancellationTokenSource(); - if (newLine.Length == 1) - { - // cr or lf - this.newLine1 = newLine[0]; - this.newLine2 = default; - this.crlf = false; - } - else - { - // crlf(windows) - this.newLine1 = newLine[0]; - this.newLine2 = newLine[1]; - this.crlf = true; - } - - this.options = options; - this.stream = stream; - this.channel = Channel.CreateUnbounded(new UnboundedChannelOptions - { - AllowSynchronousContinuations = false, // always should be in async loop. - SingleWriter = false, - SingleReader = true, - }); - this.writeLoop = Task.Run(WriteLoop); - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Post(IZLoggerEntry log) - { - channel.Writer.TryWrite(log); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void AppendLine(StreamBufferWriter writer) - { - if (writer.TryGetForNewLine(out var buffer, out var index)) - { - if (crlf) - { - buffer[index] = newLine1; - buffer[index + 1] = newLine2; - writer.Advance(2); - } - else - { - buffer[index] = newLine1; - writer.Advance(1); - } - } - else - { - var span = writer.GetSpan(newLine.Length); - newLine.CopyTo(span); - } - } - - async Task WriteLoop() - { - var writer = new StreamBufferWriter(stream); - var reader = channel.Reader; - var sw = Stopwatch.StartNew(); - try - { - while (await reader.WaitToReadAsync().ConfigureAwait(false)) - { - LogInfo info = default; - try - { - while (reader.TryRead(out var value)) - { - info = value.LogInfo; - - if (options.EnableStructuredLogging) - { - var jsonWriter = options.GetThreadStaticUtf8JsonWriter(writer); - try - { - jsonWriter.WriteStartObject(); - - value.FormatUtf8(writer, options, jsonWriter); - value.Return(); - - jsonWriter.WriteEndObject(); - jsonWriter.Flush(); - } - finally - { - jsonWriter.Reset(); - } - } - else - { - value.FormatUtf8(writer, options, null); - value.Return(); - } - - AppendLine(writer); - } - info = default; - - if (options.FlushRate != null && !cancellationTokenSource.IsCancellationRequested) - { - sw.Stop(); - var sleepTime = options.FlushRate.Value - sw.Elapsed; - if (sleepTime > TimeSpan.Zero) - { - try - { - await Task.Delay(sleepTime, cancellationTokenSource.Token).ConfigureAwait(false); - } - catch (OperationCanceledException) - { - } - } - } - writer.Flush(); // flush before wait. - - sw.Reset(); - sw.Start(); - } - catch (Exception ex) - { - try - { - if (options.InternalErrorLogger != null) - { - options.InternalErrorLogger(info, ex); - } - else - { - Console.WriteLine(ex); - } - } - catch { } - } - } - } - catch (OperationCanceledException) - { - } - finally - { - try - { - writer.Flush(); - } - catch { } - } - } - - public async ValueTask DisposeAsync() - { - try - { - channel.Writer.Complete(); - cancellationTokenSource.Cancel(); - await writeLoop.ConfigureAwait(false); - } - finally - { - this.stream.Dispose(); - } - } - } -} diff --git a/Plugins/ZLogger/AsyncStreamLineMessageWriter.cs.meta b/Plugins/ZLogger/AsyncStreamLineMessageWriter.cs.meta deleted file mode 100644 index 7ac106eb..00000000 --- a/Plugins/ZLogger/AsyncStreamLineMessageWriter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 18379c4127f5cf14b97cdab9b8dff7d3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Entries.meta b/Plugins/ZLogger/Entries.meta deleted file mode 100644 index 2c637b5d..00000000 --- a/Plugins/ZLogger/Entries.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d294f837d86c6b946989edda84042442 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Entries/FormatLogEntry.cs b/Plugins/ZLogger/Entries/FormatLogEntry.cs deleted file mode 100644 index ea79ba42..00000000 --- a/Plugins/ZLogger/Entries/FormatLogEntry.cs +++ /dev/null @@ -1,3710 +0,0 @@ -#pragma warning disable CS8601 -#pragma warning disable CS8618 - -using Cysharp.Text; -using System; -using System.Buffers; -using System.Collections.Concurrent; -using System.Diagnostics.CodeAnalysis; -using System.Text.Json; -using System.Runtime.CompilerServices; - -namespace ZLogger.Entries -{ - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1) - { - Payload = payload; - Format = format; - Arg1 = arg1; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1) - { - Payload = payload; - Format = format; - Arg1 = arg1; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - public readonly T13 Arg13; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - Arg13 = arg13; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - public readonly T13 Arg13; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - Arg13 = arg13; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - public readonly T13 Arg13; - public readonly T14 Arg14; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - Arg13 = arg13; - Arg14 = arg14; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - public readonly T13 Arg13; - public readonly T14 Arg14; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - Arg13 = arg13; - Arg14 = arg14; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - public readonly T13 Arg13; - public readonly T14 Arg14; - public readonly T15 Arg15; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - Arg13 = arg13; - Arg14 = arg14; - Arg15 = arg15; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - public readonly T13 Arg13; - public readonly T14 Arg14; - public readonly T15 Arg15; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - Arg13 = arg13; - Arg14 = arg14; - Arg15 = arg15; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public struct FormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - public readonly T13 Arg13; - public readonly T14 Arg14; - public readonly T15 Arg15; - public readonly T16 Arg16; - - public FormatLogState([AllowNull]TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - Arg13 = arg13; - Arg14 = arg14; - Arg15 = arg15; - Arg16 = arg16; - } - - static IZLoggerEntry factory(FormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return FormatLogEntry.Create(logInfo, this); - } - } - - public struct PreparedFormatLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly Utf8PreparedFormat Format; - public readonly T1 Arg1; - public readonly T2 Arg2; - public readonly T3 Arg3; - public readonly T4 Arg4; - public readonly T5 Arg5; - public readonly T6 Arg6; - public readonly T7 Arg7; - public readonly T8 Arg8; - public readonly T9 Arg9; - public readonly T10 Arg10; - public readonly T11 Arg11; - public readonly T12 Arg12; - public readonly T13 Arg13; - public readonly T14 Arg14; - public readonly T15 Arg15; - public readonly T16 Arg16; - - public PreparedFormatLogState([AllowNull]TPayload payload, Utf8PreparedFormat format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - Payload = payload; - Format = format; - Arg1 = arg1; - Arg2 = arg2; - Arg3 = arg3; - Arg4 = arg4; - Arg5 = arg5; - Arg6 = arg6; - Arg7 = arg7; - Arg8 = arg8; - Arg9 = arg9; - Arg10 = arg10; - Arg11 = arg11; - Arg12 = arg12; - Arg13 = arg13; - Arg14 = arg14; - Arg15 = arg15; - Arg16 = arg16; - } - - static IZLoggerEntry factory(PreparedFormatLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return PreparedFormatLogEntry.Create(logInfo, this); - } - } - - public class FormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - FormatLogState state; - - public LogInfo LogInfo { get; private set; } - - FormatLogEntry() - { - } - - public static FormatLogEntry Create(in LogInfo logInfo, in FormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new FormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.AppendFormat(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15, state.Arg16); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - ZString.Utf8Format(writer, state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15, state.Arg16); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - - public class PreparedFormatLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - PreparedFormatLogState state; - - public LogInfo LogInfo { get; private set; } - - PreparedFormatLogEntry() - { - } - - public static PreparedFormatLogEntry Create(in LogInfo logInfo, in PreparedFormatLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new PreparedFormatLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - var sb = ZString.CreateUtf8StringBuilder(true); - try - { - state.Format.FormatTo(ref sb, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15, state.Arg16); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - finally - { - sb.Dispose(); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - state.Format.FormatTo(ref writer, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15, state.Arg16); - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } - -} diff --git a/Plugins/ZLogger/Entries/FormatLogEntry.cs.meta b/Plugins/ZLogger/Entries/FormatLogEntry.cs.meta deleted file mode 100644 index d31f7970..00000000 --- a/Plugins/ZLogger/Entries/FormatLogEntry.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 53be67810265d874ebd7365af08b791f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Entries/MessageLogEntry.cs b/Plugins/ZLogger/Entries/MessageLogEntry.cs deleted file mode 100644 index db4f11ce..00000000 --- a/Plugins/ZLogger/Entries/MessageLogEntry.cs +++ /dev/null @@ -1,122 +0,0 @@ -#pragma warning disable CS8601 -#pragma warning disable CS8618 - -using Cysharp.Text; -using System; -using System.Buffers; -using System.Collections.Concurrent; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; -using System.Text.Json; - -namespace ZLogger.Entries -{ - public struct MessageLogState : IZLoggerState - { - public static readonly Func, LogInfo, IZLoggerEntry> Factory = factory; - - public readonly TPayload Payload; - public readonly string Message; - - public MessageLogState([AllowNull]TPayload payload, string message) - { - Payload = payload; - Message = message; - } - - static IZLoggerEntry factory(MessageLogState self, LogInfo logInfo) - { - return self.CreateLogEntry(logInfo); - } - - public IZLoggerEntry CreateLogEntry(LogInfo logInfo) - { - return MessageLogEntry.Create(logInfo, this); - } - } - - public class MessageLogEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - - MessageLogState state; - - public LogInfo LogInfo { get; private set; } - - MessageLogEntry() - { - } - - public static MessageLogEntry Create(in LogInfo logInfo, in MessageLogState state) - { - if (!cache.TryDequeue(out var result)) - { - result = new MessageLogEntry(); - } - - result.LogInfo = logInfo; - result.state = state; - return result; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - - using (var sb = ZString.CreateUtf8StringBuilder(true)) - { - sb.Append(state.Message); - jsonWriter.WriteString(options.MessagePropertyName, sb.AsSpan()); - } - - jsonWriter.WritePropertyName(options.PayloadPropertyName); - JsonSerializer.Serialize(jsonWriter, state.Payload, options.JsonSerializerOptions); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - - var str = state.Message; - if (str != null) - { - var memory = writer.GetMemory(Encoding.UTF8.GetMaxByteCount(str.Length)); - if (MemoryMarshal.TryGetArray(memory, out var segment) && segment.Array != null) - { - var written1 = Encoding.UTF8.GetBytes(str, 0, str.Length, segment.Array, segment.Offset); - writer.Advance(written1); - } - } - - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public void Return() - { - state = default; - LogInfo = default; - cache.Enqueue(this); - } - - public void SwitchCasePayload(System.Action payloadCallback, object state) - { - if (typeof(TPayload1) == typeof(TPayload)) - { - payloadCallback(this, Unsafe.As(ref Unsafe.AsRef(this.state.Payload)), state); - } - } - - public object GetPayload() - { - return state.Payload; - } - } -} diff --git a/Plugins/ZLogger/Entries/MessageLogEntry.cs.meta b/Plugins/ZLogger/Entries/MessageLogEntry.cs.meta deleted file mode 100644 index 51905c18..00000000 --- a/Plugins/ZLogger/Entries/MessageLogEntry.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1a92f1538222b574f85c25e54c547b05 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Entries/StringFormatterEntry.cs b/Plugins/ZLogger/Entries/StringFormatterEntry.cs deleted file mode 100644 index 63137079..00000000 --- a/Plugins/ZLogger/Entries/StringFormatterEntry.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Buffers; -using System.Collections.Concurrent; -using System.Runtime.InteropServices; -using System.Text; -using System.Text.Json; - -namespace ZLogger.Entries -{ - public class StringFormatterEntry : IZLoggerEntry - { - static readonly ConcurrentQueue> cache = new ConcurrentQueue>(); - static readonly byte[] newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine); - -#pragma warning disable CS8618 - TState state; - Exception exception; - Func formatter; - - public LogInfo LogInfo { get; private set; } - -#pragma warning restore CS8618 - - public static StringFormatterEntry Create(LogInfo info, TState state, Exception exception, Func formatter) - { - if (!cache.TryDequeue(out var entry)) - { - entry = new StringFormatterEntry(); - } - - entry.LogInfo = info; - entry.state = state; - entry.exception = exception; - entry.formatter = formatter; - - return entry; - } - - public void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - var str = formatter(state, exception); - - if (options.EnableStructuredLogging && jsonWriter != null) - { - options.StructuredLoggingFormatter.Invoke(jsonWriter, this.LogInfo); - jsonWriter.WriteString(options.MessagePropertyName, str); - jsonWriter.WriteNull(options.PayloadPropertyName); - } - else - { - options.PrefixFormatter?.Invoke(writer, this.LogInfo); - - if (str != null) - { - var memory = writer.GetMemory(Encoding.UTF8.GetMaxByteCount(str.Length)); - if (MemoryMarshal.TryGetArray(memory, out var segment) && segment.Array != null) - { - var written1 = Encoding.UTF8.GetBytes(str, 0, str.Length, segment.Array, segment.Offset); - writer.Advance(written1); - } - } - - options.SuffixFormatter?.Invoke(writer, this.LogInfo); - if (this.LogInfo.Exception != null) - { - options.ExceptionFormatter(writer, this.LogInfo.Exception); - } - } - } - - public object GetPayload() - { - return null; - } - - public void SwitchCasePayload(Action payloadCallback, object state) - { - } - - public void Return() - { - this.state = default; - this.LogInfo = default; - this.exception = default; - this.formatter = default; - } - } -} diff --git a/Plugins/ZLogger/Entries/StringFormatterEntry.cs.meta b/Plugins/ZLogger/Entries/StringFormatterEntry.cs.meta deleted file mode 100644 index ea03b473..00000000 --- a/Plugins/ZLogger/Entries/StringFormatterEntry.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 827156fd432a2974ea62950cef297ace -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/IAsyncLogProcessor.cs b/Plugins/ZLogger/IAsyncLogProcessor.cs deleted file mode 100644 index 6860f7dc..00000000 --- a/Plugins/ZLogger/IAsyncLogProcessor.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ZLogger -{ - public interface IAsyncLogProcessor : IAsyncDisposable - { - void Post(IZLoggerEntry log); - } -} diff --git a/Plugins/ZLogger/IAsyncLogProcessor.cs.meta b/Plugins/ZLogger/IAsyncLogProcessor.cs.meta deleted file mode 100644 index f0d37385..00000000 --- a/Plugins/ZLogger/IAsyncLogProcessor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2c7c8b9f18dd59443a2cb62643a5a890 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/IZLoggerEntry.cs b/Plugins/ZLogger/IZLoggerEntry.cs deleted file mode 100644 index 82dddb51..00000000 --- a/Plugins/ZLogger/IZLoggerEntry.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Cysharp.Text; -using System; -using System.Buffers; -using System.Text.Json; - -namespace ZLogger -{ - public interface IZLoggerEntry - { - LogInfo LogInfo { get; } - void FormatUtf8(IBufferWriter writer, ZLoggerOptions options, Utf8JsonWriter jsonWriter); - void SwitchCasePayload(Action payloadCallback, object state); - object GetPayload(); - void Return(); - } - - public static class ZLoggerEntryExtensions - { - public static string FormatToString(this IZLoggerEntry entry, ZLoggerOptions options, Utf8JsonWriter jsonWriter) - { - var boxedBuilder = (IBufferWriter)ZString.CreateUtf8StringBuilder(); - try - { - entry.FormatUtf8(boxedBuilder, options, jsonWriter); - return boxedBuilder.ToString(); - } - finally - { - ((Utf8ValueStringBuilder)boxedBuilder).Dispose(); - } - } - } -} \ No newline at end of file diff --git a/Plugins/ZLogger/IZLoggerEntry.cs.meta b/Plugins/ZLogger/IZLoggerEntry.cs.meta deleted file mode 100644 index 8eebc9c8..00000000 --- a/Plugins/ZLogger/IZLoggerEntry.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d3d97e074aaba5248b5a506c41d7af07 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/IZLoggerState.cs b/Plugins/ZLogger/IZLoggerState.cs deleted file mode 100644 index 1549354f..00000000 --- a/Plugins/ZLogger/IZLoggerState.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZLogger -{ - public interface IZLoggerState - { - IZLoggerEntry CreateLogEntry(LogInfo logInfo); - } -} diff --git a/Plugins/ZLogger/IZLoggerState.cs.meta b/Plugins/ZLogger/IZLoggerState.cs.meta deleted file mode 100644 index bb8e385a..00000000 --- a/Plugins/ZLogger/IZLoggerState.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 90b9c67f12e999641a7c6bc202f07992 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/LogInfo.cs b/Plugins/ZLogger/LogInfo.cs deleted file mode 100644 index f975ed98..00000000 --- a/Plugins/ZLogger/LogInfo.cs +++ /dev/null @@ -1,100 +0,0 @@ -using Microsoft.Extensions.Logging; -using System; -using System.Text.Json; - -namespace ZLogger -{ - public readonly struct LogInfo - { - public readonly string CategoryName; - public readonly DateTimeOffset Timestamp; - public readonly LogLevel LogLevel; - public readonly EventId EventId; - public readonly Exception Exception; - - public LogInfo(string categoryName, DateTimeOffset timestamp, LogLevel logLevel, EventId eventId, Exception exception) - { - EventId = eventId; - CategoryName = categoryName; - Timestamp = timestamp; - LogLevel = logLevel; - Exception = exception; - } - - static readonly JsonEncodedText CategoryNameText = JsonEncodedText.Encode(nameof(CategoryName)); - static readonly JsonEncodedText TimestampText = JsonEncodedText.Encode(nameof(Timestamp)); - static readonly JsonEncodedText LogLevelText = JsonEncodedText.Encode(nameof(LogLevel)); - static readonly JsonEncodedText EventIdText = JsonEncodedText.Encode(nameof(EventId)); - static readonly JsonEncodedText EventIdNameText = JsonEncodedText.Encode("EventIdName"); - static readonly JsonEncodedText ExceptionText = JsonEncodedText.Encode(nameof(Exception)); - - static readonly JsonEncodedText NameText = JsonEncodedText.Encode("Name"); - static readonly JsonEncodedText MessageText = JsonEncodedText.Encode("Message"); - static readonly JsonEncodedText StackTraceText = JsonEncodedText.Encode("StackTrace"); - static readonly JsonEncodedText InnerExceptionText = JsonEncodedText.Encode("InnerException"); - - static readonly JsonEncodedText Trace = JsonEncodedText.Encode(nameof(LogLevel.Trace)); - static readonly JsonEncodedText Debug = JsonEncodedText.Encode(nameof(LogLevel.Debug)); - static readonly JsonEncodedText Information = JsonEncodedText.Encode(nameof(LogLevel.Information)); - static readonly JsonEncodedText Warning = JsonEncodedText.Encode(nameof(LogLevel.Warning)); - static readonly JsonEncodedText Error = JsonEncodedText.Encode(nameof(LogLevel.Error)); - static readonly JsonEncodedText Critical = JsonEncodedText.Encode(nameof(LogLevel.Critical)); - static readonly JsonEncodedText None = JsonEncodedText.Encode(nameof(LogLevel.None)); - - public void WriteToJsonWriter(Utf8JsonWriter writer) - { - writer.WriteString(CategoryNameText, CategoryName); - writer.WriteString(LogLevelText, LogLevelToEncodedText(LogLevel)); - writer.WriteNumber(EventIdText, EventId.Id); - writer.WriteString(EventIdNameText, EventId.Name); - writer.WriteString(TimestampText, Timestamp); - writer.WritePropertyName(ExceptionText); - WriteException(writer, Exception); - } - - static void WriteException(Utf8JsonWriter writer, Exception ex) - { - if (ex == null) - { - writer.WriteNullValue(); - } - else - { - writer.WriteStartObject(); - { - writer.WriteString(NameText, ex.GetType().FullName); - writer.WriteString(MessageText, ex.Message); - writer.WriteString(StackTraceText, ex.StackTrace); - writer.WritePropertyName(InnerExceptionText); - { - WriteException(writer, ex.InnerException); - } - } - writer.WriteEndObject(); - } - } - - static JsonEncodedText LogLevelToEncodedText(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return Trace; - case LogLevel.Debug: - return Debug; - case LogLevel.Information: - return Information; - case LogLevel.Warning: - return Warning; - case LogLevel.Error: - return Error; - case LogLevel.Critical: - return Critical; - case LogLevel.None: - return None; - default: - return JsonEncodedText.Encode(((int)logLevel).ToString()); - } - } - } -} \ No newline at end of file diff --git a/Plugins/ZLogger/LogInfo.cs.meta b/Plugins/ZLogger/LogInfo.cs.meta deleted file mode 100644 index 6479c23e..00000000 --- a/Plugins/ZLogger/LogInfo.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c5ecb024d9eef7d4dafcd632a245ee1c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Providers.meta b/Plugins/ZLogger/Providers.meta deleted file mode 100644 index 52a4fe2f..00000000 --- a/Plugins/ZLogger/Providers.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: aa66b97aa0dc2194aa35101f5d4c7376 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Providers/RollingFilestream.cs b/Plugins/ZLogger/Providers/RollingFilestream.cs deleted file mode 100644 index ed55d133..00000000 --- a/Plugins/ZLogger/Providers/RollingFilestream.cs +++ /dev/null @@ -1,228 +0,0 @@ -using System; -using System.IO; -using System.Text.RegularExpressions; - -namespace ZLogger.Providers -{ - internal class RollingFileStream : Stream - { - static readonly Regex NumberRegex = new Regex("(\\d)+$", RegexOptions.Compiled); - - readonly object streamLock = new object(); - readonly Func timestampPattern; - readonly Func fileNameSelector; - readonly long rollSizeInBytes; - readonly ZLoggerOptions options; - -#pragma warning disable CS8618 - - bool disposed = false; - int writtenLength; - string fileName; - Stream innerStream; - DateTimeOffset currentTimestampPattern; - - public RollingFileStream(Func fileNameSelector, Func timestampPattern, int rollSizeKB, ZLoggerOptions options) - { - this.timestampPattern = timestampPattern; - this.fileNameSelector = fileNameSelector; - this.rollSizeInBytes = rollSizeKB * 1024; - this.options = options; - - ValidateFileNameSelector(); - TryChangeNewRollingFile(); - } - -#pragma warning restore CS8618 - - void ValidateFileNameSelector() - { - var now = DateTimeOffset.UtcNow; - var fileName1 = Path.GetFileNameWithoutExtension(fileNameSelector(now, 0)); - var fileName2 = Path.GetFileNameWithoutExtension(fileNameSelector(now, 1)); - - if (!NumberRegex.IsMatch(fileName1) || !NumberRegex.IsMatch(fileName2)) - { - throw new ArgumentException("fileNameSelector is invalid format, must be int(sequence no) is last."); - } - - var seqStr1 = NumberRegex.Match(fileName1).Groups[0].Value; - var seqStr2 = NumberRegex.Match(fileName2).Groups[0].Value; - - int seq1; - int seq2; - if (!int.TryParse(seqStr1, out seq1) || !int.TryParse(seqStr2, out seq2)) - { - throw new ArgumentException("fileNameSelector is invalid format, must be int(sequence no) is last."); - } - - if (seq1 == seq2) - { - throw new ArgumentException("fileNameSelector is invalid format, must be int(sequence no) is incremental."); - } - } - - void TryChangeNewRollingFile() - { - var now = DateTimeOffset.UtcNow; - DateTimeOffset ts; - try - { - ts = timestampPattern(now); - } - catch (Exception ex) - { - throw new InvalidOperationException("timestampPattern convert failed.", ex); - } - - // needs to create next file - if (innerStream == null || ts != currentTimestampPattern || writtenLength >= rollSizeInBytes) - { - int sequenceNo = 0; - if (innerStream != null && ts == currentTimestampPattern) - { - sequenceNo = ExtractCurrentSequence(fileName) + 1; - } - - string fn = null; - while (true) - { - try - { - var newFn = fileNameSelector(now, sequenceNo); - if (fn == newFn) - { - throw new InvalidOperationException("fileNameSelector indicate same filname"); - } - fn = newFn; - } - catch (Exception ex) - { - throw new InvalidOperationException("fileNameSelector convert failed", ex); - } - - var fi = new FileInfo(fn); - if (fi.Exists) - { - if (fi.Length >= rollSizeInBytes) - { - sequenceNo++; - continue; - } - } - break; - } - - lock (streamLock) - { - if (disposed) return; - try - { - if (innerStream != null) - { - innerStream.Flush(); - innerStream.Dispose(); - } - } - catch (Exception ex) - { - throw new InvalidOperationException("Can't dispose fileStream", ex); - } - - try - { - fileName = fn; - currentTimestampPattern = ts; - if (File.Exists(fileName)) - { - writtenLength = (int)new FileInfo(fileName).Length; - } - else - { - writtenLength = 0; - } - - var di = new FileInfo(fileName).Directory; - if (!di.Exists) - { - di.Create(); - } - // useAsync:false, use sync(in thread) processor, don't use FileStream buffer(use buffer size = 1). - innerStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite, 1, false); - } - catch (Exception ex) - { - throw new InvalidOperationException("Can't create FileStream", ex); - } - } - } - } - - static int ExtractCurrentSequence(string fileName) - { - int extensionDotIndex = fileName.LastIndexOf('.'); - - fileName = Path.GetFileNameWithoutExtension(fileName); - - var sequenceString = NumberRegex.Match(fileName).Groups[0].Value; - int seq; - if (int.TryParse(sequenceString, out seq)) - { - return seq; - } - else - { - return 0; - } - } - - #region override - - public override bool CanRead => innerStream.CanRead; - - public override bool CanSeek => innerStream.CanSeek; - - public override bool CanWrite => innerStream.CanWrite; - - public override long Length => innerStream.Length; - - public override long Position { get => innerStream.Position; set => innerStream.Position = value; } - - public override void Flush() - { - innerStream.Flush(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return innerStream.Read(buffer, offset, count); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return innerStream.Seek(offset, origin); - } - public override void SetLength(long value) - { - innerStream.SetLength(value); - } - - public override void Write(byte[] buffer, int offset, int count) - { - TryChangeNewRollingFile(); - innerStream.Write(buffer, offset, count); - writtenLength += count; - } - - protected override void Dispose(bool disposing) - { - lock (streamLock) - { - innerStream.Dispose(); - disposed = true; - } - } - - #endregion - } -} diff --git a/Plugins/ZLogger/Providers/RollingFilestream.cs.meta b/Plugins/ZLogger/Providers/RollingFilestream.cs.meta deleted file mode 100644 index 28d69f4c..00000000 --- a/Plugins/ZLogger/Providers/RollingFilestream.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e842d3e2a60ebe0418a9fe73ccccd29f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Providers/ZLoggerConsoleLoggerProvider.cs b/Plugins/ZLogger/Providers/ZLoggerConsoleLoggerProvider.cs deleted file mode 100644 index 7b3f1ea8..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerConsoleLoggerProvider.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.Text; - -namespace ZLogger.Providers -{ - [ProviderAlias("ZLoggerConsole")] - public class ZLoggerConsoleLoggerProvider : ILoggerProvider - { - internal const string DefaultOptionName = "ZLoggerConsole.Default"; - - AsyncStreamLineMessageWriter streamWriter; - - public ZLoggerConsoleLoggerProvider(IOptionsMonitor options) - : this(true, null, options) - { - } - - public ZLoggerConsoleLoggerProvider(bool consoleOutputEncodingToUtf8, string optionName, IOptionsMonitor options) - { - if (consoleOutputEncodingToUtf8) - { - Console.OutputEncoding = new UTF8Encoding(false); - } - - var opt = options.Get(optionName ?? DefaultOptionName); - this.streamWriter = new AsyncStreamLineMessageWriter(Console.OpenStandardOutput(), opt); - } - - public ILogger CreateLogger(string categoryName) - { - return new AsyncProcessZLogger(categoryName, streamWriter); - } - - public void Dispose() - { - streamWriter.DisposeAsync().AsTask().Wait(); - } - } -} diff --git a/Plugins/ZLogger/Providers/ZLoggerConsoleLoggerProvider.cs.meta b/Plugins/ZLogger/Providers/ZLoggerConsoleLoggerProvider.cs.meta deleted file mode 100644 index 79fbb14a..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerConsoleLoggerProvider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cea5f46a7d055704fb864f79ac329cfa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Providers/ZLoggerFileLoggerProvider.cs b/Plugins/ZLogger/Providers/ZLoggerFileLoggerProvider.cs deleted file mode 100644 index b1708241..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerFileLoggerProvider.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading; - -namespace ZLogger.Providers -{ - [ProviderAlias("ZLoggerFile")] - public class ZLoggerFileLoggerProvider : ILoggerProvider - { - internal const string DefaultOptionName = "ZLoggerFile.Default"; - - AsyncStreamLineMessageWriter streamWriter; - - public ZLoggerFileLoggerProvider(string filePath, IOptionsMonitor options) - : this(filePath, DefaultOptionName, options) - { - } - - public ZLoggerFileLoggerProvider(string filePath, string optionName, IOptionsMonitor options) - { - var di = new FileInfo(filePath).Directory; - if (!di.Exists) - { - di.Create(); - } - - var opt = options.Get(optionName ?? DefaultOptionName); - - // useAsync:false, use sync(in thread) processor, don't use FileStream buffer(use buffer size = 1). - var stream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite, 1, false); - this.streamWriter = new AsyncStreamLineMessageWriter(stream, opt); - } - - public ILogger CreateLogger(string categoryName) - { - return new AsyncProcessZLogger(categoryName, streamWriter); - } - - public void Dispose() - { - streamWriter.DisposeAsync().AsTask().Wait(); - } - } -} diff --git a/Plugins/ZLogger/Providers/ZLoggerFileLoggerProvider.cs.meta b/Plugins/ZLogger/Providers/ZLoggerFileLoggerProvider.cs.meta deleted file mode 100644 index ec2536ab..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerFileLoggerProvider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 68ce0d89eccdc9448a3b1f366bf0ed5f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Providers/ZLoggerLogProcessorLoggerProvider.cs b/Plugins/ZLogger/Providers/ZLoggerLogProcessorLoggerProvider.cs deleted file mode 100644 index a651da9b..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerLogProcessorLoggerProvider.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace ZLogger.Providers -{ - [ProviderAlias("ZLoggerLogProcessor")] - public class ZLoggerLogProcessorLoggerProvider : ILoggerProvider - { - IAsyncLogProcessor processor; - - public ZLoggerLogProcessorLoggerProvider(IAsyncLogProcessor processor) - { - this.processor = processor; - } - - public ILogger CreateLogger(string categoryName) - { - return new AsyncProcessZLogger(categoryName, processor); - } - - public void Dispose() - { - processor.DisposeAsync().AsTask().Wait(); - } - } -} diff --git a/Plugins/ZLogger/Providers/ZLoggerLogProcessorLoggerProvider.cs.meta b/Plugins/ZLogger/Providers/ZLoggerLogProcessorLoggerProvider.cs.meta deleted file mode 100644 index a616cb16..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerLogProcessorLoggerProvider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 913d185740df0c24388489d16db917c4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Providers/ZLoggerRollingFileLoggerProvider.cs b/Plugins/ZLogger/Providers/ZLoggerRollingFileLoggerProvider.cs deleted file mode 100644 index 259fe2c1..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerRollingFileLoggerProvider.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading; - -namespace ZLogger.Providers -{ - [ProviderAlias("ZLoggerRollingFile")] - public class ZLoggerRollingFileLoggerProvider : ILoggerProvider - { - internal const string DefaultOptionName = "ZLoggerRollingFile.Default"; - - AsyncStreamLineMessageWriter streamWriter; - - public ZLoggerRollingFileLoggerProvider(Func fileNameSelector, Func timestampPattern, int rollSizeKB, IOptionsMonitor options) - : this(fileNameSelector, timestampPattern, rollSizeKB, DefaultOptionName, options) - { - } - - public ZLoggerRollingFileLoggerProvider(Func fileNameSelector, Func timestampPattern, int rollSizeKB, string optionName, IOptionsMonitor options) - { - var opt = options.Get(optionName ?? DefaultOptionName); - var stream = new RollingFileStream(fileNameSelector, timestampPattern, rollSizeKB, opt); - this.streamWriter = new AsyncStreamLineMessageWriter(stream, opt); - } - - public ILogger CreateLogger(string categoryName) - { - return new AsyncProcessZLogger(categoryName, streamWriter); - } - - public void Dispose() - { - streamWriter.DisposeAsync().AsTask().Wait(); - } - } -} diff --git a/Plugins/ZLogger/Providers/ZLoggerRollingFileLoggerProvider.cs.meta b/Plugins/ZLogger/Providers/ZLoggerRollingFileLoggerProvider.cs.meta deleted file mode 100644 index 4a00905b..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerRollingFileLoggerProvider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ae925d6588d33394bb495c61966954e2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Providers/ZLoggerStreamLoggerProvider.cs b/Plugins/ZLogger/Providers/ZLoggerStreamLoggerProvider.cs deleted file mode 100644 index 6ef49a75..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerStreamLoggerProvider.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.IO; - -namespace ZLogger.Providers -{ - - [ProviderAlias("ZLoggerStream")] - public class ZLoggerStreamLoggerProvider : ILoggerProvider - { - internal const string DefaultOptionName = "ZLoggerStream.Default"; - - AsyncStreamLineMessageWriter streamWriter; - - public ZLoggerStreamLoggerProvider(Stream stream, IOptionsMonitor options) - : this(stream, DefaultOptionName, options) - { - } - - public ZLoggerStreamLoggerProvider(Stream stream, string optionName, IOptionsMonitor options) - { - this.streamWriter = new AsyncStreamLineMessageWriter(stream, options.Get(optionName ?? DefaultOptionName)); - } - - public ILogger CreateLogger(string categoryName) - { - return new AsyncProcessZLogger(categoryName, streamWriter); - } - - public void Dispose() - { - streamWriter.DisposeAsync().AsTask().Wait(); - } - } -} diff --git a/Plugins/ZLogger/Providers/ZLoggerStreamLoggerProvider.cs.meta b/Plugins/ZLogger/Providers/ZLoggerStreamLoggerProvider.cs.meta deleted file mode 100644 index 38876f78..00000000 --- a/Plugins/ZLogger/Providers/ZLoggerStreamLoggerProvider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eb83b6269b6b05e4e8cd1d5d854c7e30 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Shims.meta b/Plugins/ZLogger/Shims.meta deleted file mode 100644 index bb598308..00000000 --- a/Plugins/ZLogger/Shims.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: fa54f5785ca02c84e92dc09245ba3882 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Shims/NullableAttributes.cs b/Plugins/ZLogger/Shims/NullableAttributes.cs deleted file mode 100644 index 483cb031..00000000 --- a/Plugins/ZLogger/Shims/NullableAttributes.cs +++ /dev/null @@ -1,140 +0,0 @@ -#pragma warning disable MA0048 // File name must match type name -#define INTERNAL_NULLABLE_ATTRIBUTES -#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET6 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48|| UNITY_2018_3_OR_NEWER - -// https://github.com/dotnet/corefx/blob/48363ac826ccf66fbe31a5dcb1dc2aab9a7dd768/src/Common/src/CoreLib/System/Diagnostics/CodeAnalysis/NullableAttributes.cs - -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace System.Diagnostics.CodeAnalysis -{ - /// Specifies that null is allowed as an input even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class AllowNullAttribute : Attribute - { } - - /// Specifies that null is disallowed as an input even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class DisallowNullAttribute : Attribute - { } - - /// Specifies that an output may be null even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class MaybeNullAttribute : Attribute - { } - - /// Specifies that an output will not be null even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class NotNullAttribute : Attribute - { } - - /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class MaybeNullWhenAttribute : Attribute - { - /// Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter may be null. - /// - public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - - /// Gets the return value condition. - public bool ReturnValue { get; } - } - - /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class NotNullWhenAttribute : Attribute - { - /// Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - - /// Gets the return value condition. - public bool ReturnValue { get; } - } - - /// Specifies that the output will be non-null if the named parameter is non-null. - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class NotNullIfNotNullAttribute : Attribute - { - /// Initializes the attribute with the associated parameter name. - /// - /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. - /// - public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; - - /// Gets the associated parameter name. - public string ParameterName { get; } - } - - /// Applied to a method that will never return under any circumstance. - [AttributeUsage(AttributeTargets.Method, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class DoesNotReturnAttribute : Attribute - { } - - /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class DoesNotReturnIfAttribute : Attribute - { - /// Initializes the attribute with the specified parameter value. - /// - /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to - /// the associated parameter matches this value. - /// - public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; - - /// Gets the condition parameter value. - public bool ParameterValue { get; } - } -} -#endif \ No newline at end of file diff --git a/Plugins/ZLogger/Shims/NullableAttributes.cs.meta b/Plugins/ZLogger/Shims/NullableAttributes.cs.meta deleted file mode 100644 index e8fb5257..00000000 --- a/Plugins/ZLogger/Shims/NullableAttributes.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c13de2289cbdc5f42b238fb777d55054 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/StreamBufferWriter.cs b/Plugins/ZLogger/StreamBufferWriter.cs deleted file mode 100644 index 424045fa..00000000 --- a/Plugins/ZLogger/StreamBufferWriter.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Buffers; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Runtime.CompilerServices; - -namespace ZLogger -{ - internal class StreamBufferWriter : IBufferWriter - { - readonly Stream stream; - - byte[] buffer; - byte[] defaultBuffer; - int written; - - public StreamBufferWriter(Stream stream) - { - this.stream = stream; - this.defaultBuffer = this.buffer = new byte[65536]; - this.written = 0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Advance(int count) - { - written += count; - } - - public Memory GetMemory(int sizeHint = 0) - { - if (buffer != defaultBuffer) - { - Flush(); - } - - if (written + sizeHint > buffer.Length) - { - Flush(); - } - - if (buffer.Length - written < sizeHint) - { - Flush(); - buffer = ArrayPool.Shared.Rent(sizeHint); - } - - return new Memory(buffer, written, buffer.Length - written); - } - - public Span GetSpan(int sizeHint = 0) - { - return GetMemory(sizeHint).Span; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryGetForNewLine([NotNullWhen(true)]out byte[] rawBuffer, out int rawWritten) - { - if (buffer.Length - written > 2) - { - rawBuffer = buffer; - rawWritten = written; - return true; - } - else - { - rawBuffer = null; - rawWritten = 0; - return false; - } - } - - public void Flush() - { - if (written != 0) - { - // sync writer, ConsolePal does not support async write, use Write(byte[]) API is most primitive. - stream.Write(buffer, 0, written); - stream.Flush(); - written = 0; - - if (buffer != defaultBuffer) - { - ArrayPool.Shared.Return(buffer); - buffer = defaultBuffer; - } - } - } - } -} \ No newline at end of file diff --git a/Plugins/ZLogger/StreamBufferWriter.cs.meta b/Plugins/ZLogger/StreamBufferWriter.cs.meta deleted file mode 100644 index 8e149d3b..00000000 --- a/Plugins/ZLogger/StreamBufferWriter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6ff1ec2695083c9478b3414d4cecec0d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Unity.meta b/Plugins/ZLogger/Unity.meta deleted file mode 100644 index 31841191..00000000 --- a/Plugins/ZLogger/Unity.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4180a3e22e5858048a940d9991e725f0 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Unity/DiagnosticServiceProvider.cs b/Plugins/ZLogger/Unity/DiagnosticServiceProvider.cs deleted file mode 100644 index 9ca705fe..00000000 --- a/Plugins/ZLogger/Unity/DiagnosticServiceProvider.cs +++ /dev/null @@ -1,339 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; - -namespace ZLogger.Internal.Unity -{ - internal class DiagnosticServiceProvider : IServiceProvider, IDisposable - { - readonly Dictionary> items; - - public DiagnosticServiceProvider(IServiceCollection services) - { - items = new Dictionary>(); - foreach (var item in services) - { - if (!items.TryGetValue(item.ServiceType, out var list)) - { - list = new List(); - items.Add(item.ServiceType, list); - } - var serviceItem = new ServiceItem(item) - { - Item = item.ImplementationInstance - }; - - list.Add(serviceItem); - } - } - - public void Dispose() - { - foreach (var item in items) - { - foreach (var item2 in item.Value) - { - if (items is IDisposable d) - { - d.Dispose(); - } - } - } - } - - static bool IsEnumerable(Type type) - { - if (type.IsGenericType) - { - type = type.GetGenericTypeDefinition(); - if (type == typeof(IEnumerable<>)) - { - return true; - } - } - return false; - } - - public object GetService(Type serviceType) - { - return GetServiceCore1(serviceType, null); - } - - public object GetServiceCore1(Type serviceType, Type genericsType) - { - UnityEngine.Debug.Log("GetService:" + serviceType + ", genericsType?" + genericsType); - - List list = default; - - if (genericsType != null && serviceType.IsGenericTypeDefinition) - { - if (items.TryGetValue(serviceType.MakeGenericType(genericsType), out list)) - { - goto FOUND; - } - } - - if (!items.TryGetValue(serviceType, out list)) - { - if (IsEnumerable(serviceType)) - { - var elemType = serviceType.GetGenericArguments()[0]; - return GetServiceCore2(elemType, genericsType); - } - - Type useGenericsType = genericsType; - if (serviceType.IsConstructedGenericType) - { - var gen0 = serviceType.GetGenericArguments()[0]; - if (gen0.IsGenericParameter && gen0.IsConstructedGenericType) - { - useGenericsType = gen0; - } - else if (!gen0.IsGenericType && !gen0.IsGenericParameter) - { - useGenericsType = gen0; - } - } - - if (serviceType.IsGenericType) - { - var gendef = serviceType.GetGenericTypeDefinition(); - if (serviceType == gendef) - { - LogNullReturn(serviceType); - return null; - } - var innerService = GetServiceCore1(serviceType.GetGenericTypeDefinition(), useGenericsType); - return innerService; - } - - LogNullReturn(serviceType); - return null; - } - - FOUND: - return list.Last().Instantiate(this, genericsType); - } - - public object GetServiceCore2(Type serviceType, Type genericsType) - { - UnityEngine.Debug.Log("GetService2:" + serviceType + ", genericsType?" + genericsType); - - List list = default; - - if (genericsType != null && serviceType.IsGenericTypeDefinition) - { - var elementType = serviceType.MakeGenericType(genericsType); - if (elementType == null) - { - throw new InvalidOperationException("Can't create type by MakeGenericType:" + serviceType + " <" + genericsType + ">"); - } - - if (items.TryGetValue(elementType, out list)) - { - goto FOUND; - } - } - - if (!items.TryGetValue(serviceType, out list)) - { - if (IsEnumerable(serviceType)) - { - var elemType = serviceType.GetGenericArguments()[0]; - return GetServiceCore2(elemType, genericsType); - } - - Type useGenericsType = genericsType; - if (serviceType.IsConstructedGenericType) - { - var gen0 = serviceType.GetGenericArguments()[0]; - if (gen0.IsGenericParameter && gen0.IsConstructedGenericType) - { - useGenericsType = gen0; - } - else if (!gen0.IsGenericType && !gen0.IsGenericParameter) - { - useGenericsType = gen0; - } - } - - if (serviceType.IsGenericType && serviceType == serviceType.GetGenericTypeDefinition()) - { - throw new InvalidOperationException("Can not get service from: " + serviceType); - } - - if (serviceType.IsGenericType) - { - var gendef = serviceType.GetGenericTypeDefinition(); - if (serviceType == gendef) - { - throw new InvalidOperationException("Can not get service from: " + serviceType); - } - var innerService = GetServiceCore1(serviceType.GetGenericTypeDefinition(), useGenericsType); - if (innerService == null) - { - Type elementType; - if (genericsType != null && serviceType.IsGenericTypeDefinition) - { - elementType = serviceType.MakeGenericType(genericsType); - if (elementType == null) - { - throw new InvalidOperationException("Can't create type by MakeGenericType:" + serviceType + " <" + genericsType + ">"); - } - } - else - { - elementType = serviceType; - } - - return Array.CreateInstance(elementType, 0); - } - - var array = Array.CreateInstance(innerService.GetType(), 1); - array.SetValue(innerService, 0); - return array; - } - - return Array.CreateInstance(serviceType, 0); - } - FOUND: - { - Type elementType; - if (genericsType != null && serviceType.IsGenericTypeDefinition) - { - elementType = serviceType.MakeGenericType(genericsType); - if (elementType == null) - { - throw new InvalidOperationException("Can't create type by MakeGenericType:" + serviceType + " <" + genericsType + ">"); - } - } - else - { - elementType = serviceType; - } - - var array = Array.CreateInstance(elementType, list.Count); - if (array == null) - { - throw new InvalidOperationException("Can't create array: " + elementType + "[]"); - } - for (int i = 0; i < list.Count; i++) - { - array.SetValue(list[i].Instantiate(this, genericsType), i); - } - return array; - } - } - - static void LogNullReturn(Type serviceType) - { - UnityEngine.Debug.Log("DI can't find type:" + serviceType); - } - - class ServiceItem - { - public readonly ServiceDescriptor descriptor; - public object Item; - public Dictionary ItemPerGenerics; - - bool isGenericType; - - public ServiceItem(ServiceDescriptor descriptor) - { - this.descriptor = descriptor; - this.isGenericType = descriptor.ServiceType.IsGenericType && !descriptor.ServiceType.IsConstructedGenericType; - if (isGenericType) - { - ItemPerGenerics = new Dictionary(); - } - } - - public object Instantiate(DiagnosticServiceProvider provider, Type genericsElementType) - { - if (descriptor.Lifetime == ServiceLifetime.Singleton) - { - if (isGenericType && genericsElementType != null) - { - if (ItemPerGenerics.TryGetValue(genericsElementType, out var value)) - { - return value; - } - } - else - { - if (Item != null) - { - return Item; - } - } - } - - lock (this) - { - object instance; - if (descriptor.ImplementationFactory != null) - { - instance = descriptor.ImplementationFactory(provider); - } - else - { - var implType = descriptor.ImplementationType; - if (isGenericType && genericsElementType != null) - { - implType = implType.MakeGenericType(genericsElementType); - } - - var (ctor, args) = SelectConstructor(implType, genericsElementType, provider); - if (ctor == null) - { - throw new InvalidOperationException("IL2CPP issue, ctor is null. Type:" + implType); - } - - instance = ctor.Invoke(args); - } - - if (descriptor.Lifetime == ServiceLifetime.Singleton) - { - if (isGenericType && genericsElementType != null) - { - ItemPerGenerics[genericsElementType] = instance; - } - else - { - Item = instance; - } - return instance; - } - else - { - // Transient, Scoped(not supported, same as Transient). - return instance; - } - } - } - - (ConstructorInfo, object[]) SelectConstructor(Type implType, Type genericsElementType, DiagnosticServiceProvider provider) - { - var constructors = implType.GetConstructors().OrderByDescending(x => x.GetParameters().Length); - ConstructorInfo ctor = default; - object[] args = default; - foreach (var item in constructors) - { - ctor = item; - var parameters = ctor.GetParameters(); - args = parameters.Select(x => provider.GetServiceCore1(x.ParameterType, genericsElementType)).ToArray(); - - if (args.Any(x => x == null)) - { - continue; - } - break; - } - return (ctor, args); - } - } - } -} diff --git a/Plugins/ZLogger/Unity/DiagnosticServiceProvider.cs.meta b/Plugins/ZLogger/Unity/DiagnosticServiceProvider.cs.meta deleted file mode 100644 index 50bc445b..00000000 --- a/Plugins/ZLogger/Unity/DiagnosticServiceProvider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7deee3f726d9f6946a4d8895ae8b3c89 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Unity/JsonPackageShims.cs b/Plugins/ZLogger/Unity/JsonPackageShims.cs deleted file mode 100644 index a6d4a100..00000000 --- a/Plugins/ZLogger/Unity/JsonPackageShims.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Unicode; -using System.Threading.Tasks; - -namespace System.Text.Json -{ - public class Utf8JsonWriter - { - public Utf8JsonWriter(IBufferWriter writer, JsonWriterOptions options) - { - - } - - public void Flush() - { - } - - public void Reset() - { - } - - public void Reset(IBufferWriter writer) - { - } - - public void WriteString(JsonEncodedText text, ReadOnlySpan span) { } - public void WriteString(JsonEncodedText text, JsonEncodedText value) { } - public void WriteString(JsonEncodedText text, DateTimeOffset timestamp) { } - public void WriteString(JsonEncodedText text, string str) { } - public void WritePropertyName(JsonEncodedText text) { } - public void WriteNumber(JsonEncodedText text, int x) { } - public void WriteNullValue() { } - public void WriteStartObject() { } - public void WriteEndObject() { } - public void WriteNull(JsonEncodedText text) { } - } - - public static class JsonSerializer - { - public static void Serialize(Utf8JsonWriter writer, T payload, JsonSerializerOptions options) - { - } - } - - public readonly struct JsonEncodedText - { - public static JsonEncodedText Encode(string text) - { - return default(JsonEncodedText); - } - } - - public struct JsonWriterOptions - { - public bool Indented { get; set; } - public bool SkipValidation { get; set; } - public JavaScriptEncoder Encoder { get; set; } - } - - public sealed class JsonSerializerOptions - { - public bool WriteIndented { get; set; } - public bool IgnoreNullValues { get; set; } - public JavaScriptEncoder Encoder { get; set; } - } -} - -namespace System.Text.Encodings.Web -{ - public class JavaScriptEncoder - { - public static JavaScriptEncoder Create(UnicodeRange range) - { - return new JavaScriptEncoder(); - } - } -} - -namespace System.Text.Unicode -{ - public static class UnicodeRanges - { - public static UnicodeRange All { get; set; } - } - - public sealed class UnicodeRange - { - } -} diff --git a/Plugins/ZLogger/Unity/JsonPackageShims.cs.meta b/Plugins/ZLogger/Unity/JsonPackageShims.cs.meta deleted file mode 100644 index 0efd3b05..00000000 --- a/Plugins/ZLogger/Unity/JsonPackageShims.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 377497601a7470a4180839503a8907b1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Unity/UnityLoggerFactory.cs b/Plugins/ZLogger/Unity/UnityLoggerFactory.cs deleted file mode 100644 index 1d00157a..00000000 --- a/Plugins/ZLogger/Unity/UnityLoggerFactory.cs +++ /dev/null @@ -1,249 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Configuration; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using ZLogger.Providers; - -namespace ZLogger -{ - public static class UnityLoggerFactory - { - public static ILoggerFactory Create(Action configure) - { - var services = new ServiceCollection(); - - services.AddLogging(x => - { - AddBeforeConfiguration(x); // register singleton - configure(x); - AddAfterConfiguration(x); // remove and register enumerable - }); - - // use this for check IL2CPP type information. - //var provider = new DiagnosticServiceProvider(services); - - var provider = services.BuildServiceProvider(); - - var loggerFactory = provider.GetService(); - return new DisposingLoggerFactory(loggerFactory, provider); - } - - static void AddBeforeConfiguration(ILoggingBuilder builder) - { - builder.Services.TryAddSingleton(); - builder.Services.TryAddSingleton(typeof(ILoggerProviderConfiguration<>), typeof(LoggerProviderConfiguration<>)); - } - - static void AddAfterConfiguration(ILoggingBuilder builder) - { - var removeTargets = builder.Services.Where(item => ( - item.ServiceType == typeof(IConfigureOptions) - && (item?.ImplementationType?.FullName?.StartsWith("Microsoft.Extensions.Logging.Configuration.LoggerProviderConfigureOptions") ?? false))) - .ToArray(); - - foreach (var item in removeTargets) - { - builder.Services.Remove(item); - } - - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderConfigureOptions>()); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderConfigureOptions>()); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderConfigureOptions>()); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderConfigureOptions>()); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderConfigureOptions>()); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderConfigureOptions>()); - } - - // for IL2CPP. - static void TypeHint() - { - _ = new LoggerFactory(default(IEnumerable), default(LoggerFilterOptions)); - { - var setups = new IConfigureOptions[] { new ConfigureOptions(default) }.AsEnumerable(); - var postConfigure = new IPostConfigureOptions[] { new PostConfigureOptions(default, default) }.AsEnumerable(); - var optionFactory = new OptionsFactory(setups, postConfigure); - _ = new OptionsManager(optionFactory); - - var sources = new[] { new ConfigurationChangeTokenSource(default) }.AsEnumerable(); - var cache = new OptionsCache(); - _ = new OptionsMonitor(optionFactory, sources, cache); - } - { - var setups = new IConfigureOptions[] { new ConfigureOptions(default) }.AsEnumerable(); - var postConfigure = new IPostConfigureOptions[] { new PostConfigureOptions(default, default) }.AsEnumerable(); - var optionFactory = new OptionsFactory(setups, postConfigure); - _ = new OptionsManager(optionFactory); - - var sources = new[] { new ConfigurationChangeTokenSource(default) }.AsEnumerable(); - var cache = new OptionsCache(); - _ = new OptionsMonitor(optionFactory, sources, cache); - } - { - _ = Options.Create(new LoggerFilterOptions()); - _ = Options.Create(new ZLoggerOptions()); - _ = new ConfigureNamedOptions(default, default); - _ = new ConfigureNamedOptions(default, default); - } - - var loggingConfigurations = new[] { new LoggingConfiguration(default) }.AsEnumerable(); - var loggingProviderConfigurationFactory = new LoggerProviderConfigurationFactory(loggingConfigurations); - - { - { - var providerConfiguration = new LoggerProviderConfiguration(loggingProviderConfigurationFactory); - _ = new LoggerProviderConfigureOptions(providerConfiguration); - _ = new LoggerProviderOptionsChangeTokenSource(providerConfiguration); - } - { - var providerConfiguration = new LoggerProviderConfiguration(loggingProviderConfigurationFactory); - _ = new LoggerProviderConfigureOptions(providerConfiguration); - _ = new LoggerProviderOptionsChangeTokenSource(providerConfiguration); - } - { - var providerConfiguration = new LoggerProviderConfiguration(loggingProviderConfigurationFactory); - _ = new LoggerProviderConfigureOptions(providerConfiguration); - _ = new LoggerProviderOptionsChangeTokenSource(providerConfiguration); - } - { - var providerConfiguration = new LoggerProviderConfiguration(loggingProviderConfigurationFactory); - _ = new LoggerProviderConfigureOptions(providerConfiguration); - _ = new LoggerProviderOptionsChangeTokenSource(providerConfiguration); - } - { - var providerConfiguration = new LoggerProviderConfiguration(loggingProviderConfigurationFactory); - _ = new LoggerProviderConfigureOptions(providerConfiguration); - _ = new LoggerProviderOptionsChangeTokenSource(providerConfiguration); - } - { - var providerConfiguration = new LoggerProviderConfiguration(loggingProviderConfigurationFactory); - _ = new LoggerProviderConfigureOptions(providerConfiguration); - _ = new LoggerProviderOptionsChangeTokenSource(providerConfiguration); - } - } - } - - class LoggingConfiguration - { - public IConfiguration Configuration { get; } - - public LoggingConfiguration(IConfiguration configuration) - { - Configuration = configuration; - } - } - - class LoggerProviderConfiguration : ILoggerProviderConfiguration - { - public LoggerProviderConfiguration(ILoggerProviderConfigurationFactory providerConfigurationFactory) - { - Configuration = providerConfigurationFactory.GetConfiguration(typeof(T)); - } - - public IConfiguration Configuration { get; } - } - - class LoggerProviderConfigurationFactory : ILoggerProviderConfigurationFactory - { - private readonly IEnumerable _configurations; - - public LoggerProviderConfigurationFactory(IEnumerable configurations) - { - _configurations = configurations; - } - - public IConfiguration GetConfiguration(Type providerType) - { - if (providerType == null) - { - throw new ArgumentNullException(nameof(providerType)); - } - - var fullName = providerType.FullName; - var alias = ProviderAliasUtilities.GetAlias(providerType); - var configurationBuilder = new ConfigurationBuilder(); - foreach (var configuration in _configurations) - { - var sectionFromFullName = configuration.Configuration.GetSection(fullName); - configurationBuilder.AddConfiguration(sectionFromFullName); - - if (!string.IsNullOrWhiteSpace(alias)) - { - var sectionFromAlias = configuration.Configuration.GetSection(alias); - configurationBuilder.AddConfiguration(sectionFromAlias); - } - } - return configurationBuilder.Build(); - } - } - - class LoggerProviderConfigureOptions : ConfigureFromConfigurationOptions where TOptions : class - { - public LoggerProviderConfigureOptions(ILoggerProviderConfiguration providerConfiguration) - : base(providerConfiguration.Configuration) - { - } - } - - static class ProviderAliasUtilities - { - private const string AliasAttibuteTypeFullName = "Microsoft.Extensions.Logging.ProviderAliasAttribute"; - private const string AliasAttibuteAliasProperty = "Alias"; - - internal static string GetAlias(Type providerType) - { - foreach (var attribute in providerType.GetTypeInfo().GetCustomAttributes(inherit: false)) - { - if (attribute.GetType().FullName == AliasAttibuteTypeFullName) - { - var valueProperty = attribute - .GetType() - .GetProperty(AliasAttibuteAliasProperty, BindingFlags.Public | BindingFlags.Instance); - - if (valueProperty != null) - { - return valueProperty.GetValue(attribute) as string; - } - } - } - - return null; - } - } - - class DisposingLoggerFactory : ILoggerFactory, IDisposable - { - readonly ILoggerFactory loggerFactory; - readonly IServiceProvider serviceProvider; - - public DisposingLoggerFactory(ILoggerFactory loggerFactory, IServiceProvider serviceProvider) - { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); - if (serviceProvider == null) throw new ArgumentNullException(nameof(serviceProvider)); - - this.loggerFactory = loggerFactory; - this.serviceProvider = serviceProvider; - } - - public void Dispose() - { - (serviceProvider as IDisposable)?.Dispose(); - } - - public ILogger CreateLogger(string categoryName) - { - return loggerFactory.CreateLogger(categoryName); - } - - public void AddProvider(ILoggerProvider provider) - { - loggerFactory.AddProvider(provider); - } - } - } -} diff --git a/Plugins/ZLogger/Unity/UnityLoggerFactory.cs.meta b/Plugins/ZLogger/Unity/UnityLoggerFactory.cs.meta deleted file mode 100644 index c3cbede3..00000000 --- a/Plugins/ZLogger/Unity/UnityLoggerFactory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4224c23c5c181ff4fbccd2ce33edc761 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/Unity/ZLoggerUnityLoggerProvider.cs b/Plugins/ZLogger/Unity/ZLoggerUnityLoggerProvider.cs deleted file mode 100644 index 9df045e2..00000000 --- a/Plugins/ZLogger/Unity/ZLoggerUnityLoggerProvider.cs +++ /dev/null @@ -1,113 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Configuration; -using Microsoft.Extensions.Options; -using System; -using System.Threading.Tasks; -using ZLogger.Providers; - -namespace ZLogger.Providers -{ - [ProviderAlias("ZLoggerUnity")] - public class ZLoggerUnityLoggerProvider : ILoggerProvider - { - UnityDebugLogProcessor debugLogProcessor; - - public ZLoggerUnityLoggerProvider(IOptions options) - { - this.debugLogProcessor = new UnityDebugLogProcessor(options.Value); - } - - public ILogger CreateLogger(string categoryName) - { - return new AsyncProcessZLogger(categoryName, debugLogProcessor); - } - - public void Dispose() - { - } - } - - public class UnityDebugLogProcessor : IAsyncLogProcessor - { - readonly ZLoggerOptions options; - - public UnityDebugLogProcessor(ZLoggerOptions options) - { - this.options = options; - } - - public ValueTask DisposeAsync() - { - return default; - } - - public void Post(IZLoggerEntry log) - { - try - { - var msg = log.FormatToString(options, null); - switch (log.LogInfo.LogLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - case LogLevel.Information: - UnityEngine.Debug.Log(msg); - break; - case LogLevel.Warning: - case LogLevel.Critical: - UnityEngine.Debug.LogWarning(msg); - break; - case LogLevel.Error: - if (log.LogInfo.Exception != null) - { - UnityEngine.Debug.LogException(log.LogInfo.Exception); - } - else - { - UnityEngine.Debug.LogError(msg); - } - break; - case LogLevel.None: - break; - default: - break; - } - } - finally - { - log.Return(); - } - } - } -} - -namespace ZLogger -{ - public static class ZLoggerUnityExtensions - { - public static ILoggingBuilder AddZLoggerUnityDebug(this ILoggingBuilder builder) - { - builder.AddConfiguration(); - - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton(x => new ZLoggerUnityLoggerProvider(x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - return builder; - } - - public static ILoggingBuilder AddZLoggerUnityDebug(this ILoggingBuilder builder, Action configure) - { - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - builder.AddZLoggerUnityDebug(); - builder.Services.Configure(configure); - - return builder; - } - } -} diff --git a/Plugins/ZLogger/Unity/ZLoggerUnityLoggerProvider.cs.meta b/Plugins/ZLogger/Unity/ZLoggerUnityLoggerProvider.cs.meta deleted file mode 100644 index 48221991..00000000 --- a/Plugins/ZLogger/Unity/ZLoggerUnityLoggerProvider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 53d18bc7735175c4b88caa844aaecd4e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/WindowsConsoleMode.cs b/Plugins/ZLogger/WindowsConsoleMode.cs deleted file mode 100644 index 42bc8725..00000000 --- a/Plugins/ZLogger/WindowsConsoleMode.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace ZLogger -{ - internal static class WindowsConsoleMode - { - const string Kernel32 = "kernel32.dll"; - - // https://docs.microsoft.com/en-us/windows/console/getstdhandle - const int STD_OUTPUT_HANDLE = -11; - - // https://docs.microsoft.com/en-us/windows/console/setconsolemode - const int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004; - - [DllImport(Kernel32)] - internal static extern IntPtr GetStdHandle(int nStdHandle); - - [DllImport(Kernel32, SetLastError = true)] - internal static extern bool GetConsoleMode(IntPtr handle, out int mode); - - [DllImport(Kernel32, SetLastError = true)] - internal static extern bool SetConsoleMode(IntPtr handle, int mode); - - internal static bool TryEnableVirtualTerminalProcessing() - { - var handle = GetStdHandle(STD_OUTPUT_HANDLE); - if (GetConsoleMode(handle, out var mode)) - { - if (SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) - { - // OK to configure. - return true; - } - } - return false; - } - } -} diff --git a/Plugins/ZLogger/WindowsConsoleMode.cs.meta b/Plugins/ZLogger/WindowsConsoleMode.cs.meta deleted file mode 100644 index 183c658b..00000000 --- a/Plugins/ZLogger/WindowsConsoleMode.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1405b26fe28181a44bc1d22a80f9997f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/ZLogger.asmdef b/Plugins/ZLogger/ZLogger.asmdef deleted file mode 100644 index 7849f5bb..00000000 --- a/Plugins/ZLogger/ZLogger.asmdef +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "ZLogger", - "references": [ - "ZString" - ], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": true, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [] -} \ No newline at end of file diff --git a/Plugins/ZLogger/ZLogger.asmdef.meta b/Plugins/ZLogger/ZLogger.asmdef.meta deleted file mode 100644 index 1d125fdc..00000000 --- a/Plugins/ZLogger/ZLogger.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 19622d0c1901810479006eab0c2d3555 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/ZLoggerExtensions.cs b/Plugins/ZLogger/ZLoggerExtensions.cs deleted file mode 100644 index f230784d..00000000 --- a/Plugins/ZLogger/ZLoggerExtensions.cs +++ /dev/null @@ -1,4926 +0,0 @@ -using System; -using Cysharp.Text; -using Microsoft.Extensions.Logging; -using ZLogger.Entries; - -namespace ZLogger -{ - public static partial class ZLoggerExtensions - { - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1) - { - ZLog(logger, logLevel, default, null, format, arg1); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1) - { - ZLog(logger, logLevel, eventId, null, format, arg1); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1) - { - ZLog(logger, logLevel, default, exception, format, arg1); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, logLevel, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, logLevel, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, logLevel, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - logger.Log(logLevel, eventId, new FormatLogState(null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15, state.Arg16); - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, logLevel, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16), exception, (state, ex) => - { - return ZString.Format(state.Format, state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14, state.Arg15, state.Arg16); - }); - } - - public static void ZLogTrace(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Trace, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Trace, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Trace, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Trace, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Trace, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Trace, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Trace, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogDebug(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Debug, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Debug, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Debug, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Debug, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Debug, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Debug, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Debug, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogInformation(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Information, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Information, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Information, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Information, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Information, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Information, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Information, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWarning(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Warning, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Warning, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Warning, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Warning, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Warning, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Warning, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Warning, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogError(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Error, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Error, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogError(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Error, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Error, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Error, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Error, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Error, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogCritical(this ILogger logger, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Critical, default, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Critical, eventId, null, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Critical, default, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLog(logger, LogLevel.Critical, eventId, exception, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Critical, default, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, null, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Critical, default, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - ZLogWithPayload(logger, LogLevel.Critical, eventId, exception, payload, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - } - - - public static void ZLog(this ILogger logger, LogLevel logLevel, string message) - { - ZLog(logger, logLevel, default, null, message, null); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, string message) - { - ZLog(logger, logLevel, eventId, null, message, null); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, Exception exception, string message) - { - ZLog(logger, logLevel, default, exception, message, null); - } - - public static void ZLog(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string message) - { - logger.Log(logLevel, eventId, new FormatLogState(null, message, null), exception, (state, ex) => - { - return state.Format; - }); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, TPayload payload, string message) - { - ZLogWithPayload(logger, logLevel, default, null, payload, message); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, TPayload payload, string message) - { - ZLogWithPayload(logger, logLevel, eventId, null, payload, message); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, Exception exception, TPayload payload, string message) - { - ZLogWithPayload(logger, logLevel, default, exception, payload, message); - } - - public static void ZLogWithPayload(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, TPayload payload, string message) - { - logger.Log(logLevel, eventId, new FormatLogState(payload, message, null), exception, (state, ex) => - { - return message; - }); - } - - public static void ZLogTrace(this ILogger logger, string message) - { - ZLogTrace(logger, default(EventId), default(Exception), message); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, string message) - { - ZLogTrace(logger, eventId, default(Exception), message); - } - - public static void ZLogTrace(this ILogger logger, Exception exception, string message) - { - ZLogTrace(logger, default(EventId), exception, message); - } - - public static void ZLogTrace(this ILogger logger, EventId eventId, Exception exception, string message) - { - logger.Log(LogLevel.Trace, eventId, new MessageLogState(null, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogTraceWithPayload(this ILogger logger, TPayload payload, string message) - { - ZLogTraceWithPayload(logger, default, null, payload, message); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, TPayload payload, string message) - { - ZLogTraceWithPayload(logger, eventId, null, payload, message); - } - - public static void ZLogTraceWithPayload(this ILogger logger, Exception exception, TPayload payload, string message) - { - ZLogTraceWithPayload(logger, default, exception, payload, message); - } - - public static void ZLogTraceWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string message) - { - logger.Log(LogLevel.Trace, eventId, new MessageLogState(payload, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogDebug(this ILogger logger, string message) - { - ZLogDebug(logger, default(EventId), default(Exception), message); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, string message) - { - ZLogDebug(logger, eventId, default(Exception), message); - } - - public static void ZLogDebug(this ILogger logger, Exception exception, string message) - { - ZLogDebug(logger, default(EventId), exception, message); - } - - public static void ZLogDebug(this ILogger logger, EventId eventId, Exception exception, string message) - { - logger.Log(LogLevel.Debug, eventId, new MessageLogState(null, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogDebugWithPayload(this ILogger logger, TPayload payload, string message) - { - ZLogDebugWithPayload(logger, default, null, payload, message); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, TPayload payload, string message) - { - ZLogDebugWithPayload(logger, eventId, null, payload, message); - } - - public static void ZLogDebugWithPayload(this ILogger logger, Exception exception, TPayload payload, string message) - { - ZLogDebugWithPayload(logger, default, exception, payload, message); - } - - public static void ZLogDebugWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string message) - { - logger.Log(LogLevel.Debug, eventId, new MessageLogState(payload, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogInformation(this ILogger logger, string message) - { - ZLogInformation(logger, default(EventId), default(Exception), message); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, string message) - { - ZLogInformation(logger, eventId, default(Exception), message); - } - - public static void ZLogInformation(this ILogger logger, Exception exception, string message) - { - ZLogInformation(logger, default(EventId), exception, message); - } - - public static void ZLogInformation(this ILogger logger, EventId eventId, Exception exception, string message) - { - logger.Log(LogLevel.Information, eventId, new MessageLogState(null, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogInformationWithPayload(this ILogger logger, TPayload payload, string message) - { - ZLogInformationWithPayload(logger, default, null, payload, message); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, TPayload payload, string message) - { - ZLogInformationWithPayload(logger, eventId, null, payload, message); - } - - public static void ZLogInformationWithPayload(this ILogger logger, Exception exception, TPayload payload, string message) - { - ZLogInformationWithPayload(logger, default, exception, payload, message); - } - - public static void ZLogInformationWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string message) - { - logger.Log(LogLevel.Information, eventId, new MessageLogState(payload, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogWarning(this ILogger logger, string message) - { - ZLogWarning(logger, default(EventId), default(Exception), message); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, string message) - { - ZLogWarning(logger, eventId, default(Exception), message); - } - - public static void ZLogWarning(this ILogger logger, Exception exception, string message) - { - ZLogWarning(logger, default(EventId), exception, message); - } - - public static void ZLogWarning(this ILogger logger, EventId eventId, Exception exception, string message) - { - logger.Log(LogLevel.Warning, eventId, new MessageLogState(null, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogWarningWithPayload(this ILogger logger, TPayload payload, string message) - { - ZLogWarningWithPayload(logger, default, null, payload, message); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, TPayload payload, string message) - { - ZLogWarningWithPayload(logger, eventId, null, payload, message); - } - - public static void ZLogWarningWithPayload(this ILogger logger, Exception exception, TPayload payload, string message) - { - ZLogWarningWithPayload(logger, default, exception, payload, message); - } - - public static void ZLogWarningWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string message) - { - logger.Log(LogLevel.Warning, eventId, new MessageLogState(payload, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogError(this ILogger logger, string message) - { - ZLogError(logger, default(EventId), default(Exception), message); - } - - public static void ZLogError(this ILogger logger, EventId eventId, string message) - { - ZLogError(logger, eventId, default(Exception), message); - } - - public static void ZLogError(this ILogger logger, Exception exception, string message) - { - ZLogError(logger, default(EventId), exception, message); - } - - public static void ZLogError(this ILogger logger, EventId eventId, Exception exception, string message) - { - logger.Log(LogLevel.Error, eventId, new MessageLogState(null, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogErrorWithPayload(this ILogger logger, TPayload payload, string message) - { - ZLogErrorWithPayload(logger, default, null, payload, message); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, TPayload payload, string message) - { - ZLogErrorWithPayload(logger, eventId, null, payload, message); - } - - public static void ZLogErrorWithPayload(this ILogger logger, Exception exception, TPayload payload, string message) - { - ZLogErrorWithPayload(logger, default, exception, payload, message); - } - - public static void ZLogErrorWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string message) - { - logger.Log(LogLevel.Error, eventId, new MessageLogState(payload, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogCritical(this ILogger logger, string message) - { - ZLogCritical(logger, default(EventId), default(Exception), message); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, string message) - { - ZLogCritical(logger, eventId, default(Exception), message); - } - - public static void ZLogCritical(this ILogger logger, Exception exception, string message) - { - ZLogCritical(logger, default(EventId), exception, message); - } - - public static void ZLogCritical(this ILogger logger, EventId eventId, Exception exception, string message) - { - logger.Log(LogLevel.Critical, eventId, new MessageLogState(null, message), exception, (state, ex) => - { - return state.Message; - }); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, TPayload payload, string message) - { - ZLogCriticalWithPayload(logger, default, null, payload, message); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, TPayload payload, string message) - { - ZLogCriticalWithPayload(logger, eventId, null, payload, message); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, Exception exception, TPayload payload, string message) - { - ZLogCriticalWithPayload(logger, default, exception, payload, message); - } - - public static void ZLogCriticalWithPayload(this ILogger logger, EventId eventId, Exception exception, TPayload payload, string message) - { - logger.Log(LogLevel.Critical, eventId, new MessageLogState(payload, message), exception, (state, ex) => - { - return state.Message; - }); - } - - - } -} \ No newline at end of file diff --git a/Plugins/ZLogger/ZLoggerExtensions.cs.meta b/Plugins/ZLogger/ZLoggerExtensions.cs.meta deleted file mode 100644 index 7f5f1412..00000000 --- a/Plugins/ZLogger/ZLoggerExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 50c60414665681c41b046498de279eea -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/ZLoggerLoggingBuilderExtensions.cs b/Plugins/ZLogger/ZLoggerLoggingBuilderExtensions.cs deleted file mode 100644 index 694d4316..00000000 --- a/Plugins/ZLogger/ZLoggerLoggingBuilderExtensions.cs +++ /dev/null @@ -1,176 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Configuration; -using Microsoft.Extensions.Options; -using System; -using System.IO; -using System.Runtime.InteropServices; -using ZLogger.Providers; - -namespace ZLogger -{ - public static class ZLoggerLoggingBuilderExtensions - { - public static ILoggingBuilder AddZLoggerConsole(this ILoggingBuilder builder, bool consoleOutputEncodingToUtf8 = true, bool configureEnableAnsiEscapeCode = false) - { - if (configureEnableAnsiEscapeCode) - { - EnableAnsiEscapeCode(); - } - - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerConsoleLoggerProvider(consoleOutputEncodingToUtf8, null, x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - return builder; - } - - public static ILoggingBuilder AddZLoggerConsole(this ILoggingBuilder builder, Action configure, bool consoleOutputEncodingToUtf8 = true, bool configureEnableAnsiEscapeCode = false) - { - if (configureEnableAnsiEscapeCode) - { - EnableAnsiEscapeCode(); - } - - return AddZLoggerConsole(builder, ZLoggerConsoleLoggerProvider.DefaultOptionName, configure, consoleOutputEncodingToUtf8); - } - - public static ILoggingBuilder AddZLoggerConsole(this ILoggingBuilder builder, string optionName, Action configure, bool consoleOutputEncodingToUtf8 = true, bool configureEnableAnsiEscapeCode = false) - { - if (configureEnableAnsiEscapeCode) - { - EnableAnsiEscapeCode(); - } - - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerConsoleLoggerProvider(consoleOutputEncodingToUtf8, optionName, x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - builder.Services.AddOptions(optionName).Configure(configure); - - return builder; - } - - static void EnableAnsiEscapeCode() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - WindowsConsoleMode.TryEnableVirtualTerminalProcessing(); - } - } - - public static ILoggingBuilder AddZLoggerStream(this ILoggingBuilder builder, Stream stream) - { - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerStreamLoggerProvider(stream, x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - return builder; - } - - public static ILoggingBuilder AddZLoggerStream(this ILoggingBuilder builder, Stream stream, Action configure) - { - return AddZLoggerStream(builder, stream, ZLoggerStreamLoggerProvider.DefaultOptionName, configure); - } - - public static ILoggingBuilder AddZLoggerStream(this ILoggingBuilder builder, Stream stream, string optionName, Action configure) - { - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerStreamLoggerProvider(stream, optionName, x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - builder.Services.AddOptions(optionName).Configure(configure); - - return builder; - } - - public static ILoggingBuilder AddZLoggerLogProcessor(this ILoggingBuilder builder, IAsyncLogProcessor logProcessor) - { - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerLogProcessorLoggerProvider(logProcessor))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - return builder; - } - - public static ILoggingBuilder AddZLoggerFile(this ILoggingBuilder builder, string fileName) - { - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerFileLoggerProvider(fileName, x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - return builder; - } - - public static ILoggingBuilder AddZLoggerFile(this ILoggingBuilder builder, string fileName, Action configure) - { - return AddZLoggerFile(builder, fileName, ZLoggerFileLoggerProvider.DefaultOptionName, configure); - } - - public static ILoggingBuilder AddZLoggerFile(this ILoggingBuilder builder, string fileName, string optionName, Action configure) - { - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerFileLoggerProvider(fileName, optionName, x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - builder.Services.AddOptions(optionName).Configure(configure); - - return builder; - } - - /// DateTimeOffset is date of file open time(UTC), int is number sequence. - /// DateTimeOffset is write time of message(UTC). If pattern is different previously then roll new file. - /// Limit size of single file. - public static ILoggingBuilder AddZLoggerRollingFile(this ILoggingBuilder builder, Func fileNameSelector, Func timestampPattern, int rollSizeKB) - { - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerRollingFileLoggerProvider(fileNameSelector, timestampPattern, rollSizeKB, x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - return builder; - } - - /// DateTimeOffset is date of file open time(UTC), int is number sequence. - /// DateTimeOffset is write time of message(UTC). If pattern is different previously then roll new file. - /// Limit size of single file. - public static ILoggingBuilder AddZLoggerRollingFile(this ILoggingBuilder builder, Func fileNameSelector, Func timestampPattern, int rollSizeKB, Action configure) - { - return AddZLoggerRollingFile(builder, fileNameSelector, timestampPattern, rollSizeKB, ZLoggerRollingFileLoggerProvider.DefaultOptionName, configure); - } - - /// DateTimeOffset is date of file open time(UTC), int is number sequence. - /// DateTimeOffset is write time of message(UTC). If pattern is different previously then roll new file. - /// Limit size of single file. - public static ILoggingBuilder AddZLoggerRollingFile(this ILoggingBuilder builder, Func fileNameSelector, Func timestampPattern, int rollSizeKB, string optionName, Action configure) - { - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - builder.AddConfiguration(); - builder.Services.Add(ServiceDescriptor.Singleton(x => new ZLoggerRollingFileLoggerProvider(fileNameSelector, timestampPattern, rollSizeKB, optionName, x.GetService>()))); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - builder.Services.AddOptions(optionName).Configure(configure); - - return builder; - } - } -} \ No newline at end of file diff --git a/Plugins/ZLogger/ZLoggerLoggingBuilderExtensions.cs.meta b/Plugins/ZLogger/ZLoggerLoggingBuilderExtensions.cs.meta deleted file mode 100644 index 6dfaadee..00000000 --- a/Plugins/ZLogger/ZLoggerLoggingBuilderExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e700e352376b6dd4dacc7704d7f7a5eb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/ZLoggerMessage.cs b/Plugins/ZLogger/ZLoggerMessage.cs deleted file mode 100644 index 6314fb7b..00000000 --- a/Plugins/ZLogger/ZLoggerMessage.cs +++ /dev/null @@ -1,373 +0,0 @@ -using Cysharp.Text; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Text; -using ZLogger.Entries; - -namespace ZLogger -{ - public static class ZLoggerMessage - { - public static Action Define(LogLevel logLevel, EventId eventId, string message) - { - return (ILogger logger, Exception ex) => - { - logger.ZLog(logLevel, eventId, ex, message); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1), ex, (state, _) => - { - return state.Format.Format(state.Arg1); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13); - }); - }; - } - - public static Action Define(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(null, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13, state.Arg14); - }); - }; - } - - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1), ex, (state, _) => - { - return state.Format.Format(state.Arg1); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5, arg6), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12); - }); - }; - } - - public static Action DefineWithPayload(LogLevel logLevel, EventId eventId, string format) - { - var prepared = ZString.PrepareUtf8(format); - - return (ILogger logger, TPayload payload, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, Exception ex) => - { - logger.Log(logLevel, eventId, new PreparedFormatLogState(payload, prepared, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13), ex, (state, _) => - { - return state.Format.Format(state.Arg1, state.Arg2, state.Arg3, state.Arg4, state.Arg5, state.Arg6, state.Arg7, state.Arg8, state.Arg9, state.Arg10, state.Arg11, state.Arg12, state.Arg13); - }); - }; - } - - } -} diff --git a/Plugins/ZLogger/ZLoggerMessage.cs.meta b/Plugins/ZLogger/ZLoggerMessage.cs.meta deleted file mode 100644 index 983dd321..00000000 --- a/Plugins/ZLogger/ZLoggerMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 15f5bd6388398ed41be9fdc905f37010 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/ZLoggerOptions.cs b/Plugins/ZLogger/ZLoggerOptions.cs deleted file mode 100644 index 18c44e18..00000000 --- a/Plugins/ZLogger/ZLoggerOptions.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Buffers; -using System.Runtime.InteropServices; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Text.Unicode; -using System.Threading; - -namespace ZLogger -{ - public class ZLoggerOptions - { - public Action InternalErrorLogger { get; set; } - public TimeSpan? FlushRate { get; set; } - - // Options for Text logging - public Action, LogInfo> PrefixFormatter { get; set; } - public Action, LogInfo> SuffixFormatter { get; set; } - public Action, Exception> ExceptionFormatter { get; set; } = DefaultExceptionLoggingFormatter; - - // Options for Structured Logging - public bool EnableStructuredLogging { get; set; } - public Action StructuredLoggingFormatter { get; set; } = DefaultStructuredLoggingFormatter; - public JsonEncodedText MessagePropertyName { get; set; } = JsonEncodedText.Encode("Message"); - public JsonEncodedText PayloadPropertyName { get; set; } = JsonEncodedText.Encode("Payload"); - - public JsonSerializerOptions JsonSerializerOptions { get; set; } = new JsonSerializerOptions - { - WriteIndented = false, - IgnoreNullValues = false, - Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) - }; - - [ThreadStatic] - static Utf8JsonWriter jsonWriter; - - internal Utf8JsonWriter GetThreadStaticUtf8JsonWriter(IBufferWriter buffer) - { - Utf8JsonWriter writer; - if (jsonWriter == null) - { - writer = jsonWriter = new Utf8JsonWriter(buffer, new JsonWriterOptions - { - Indented = this.JsonSerializerOptions.WriteIndented, - SkipValidation = true, - Encoder = this.JsonSerializerOptions.Encoder - }); - } - else - { - writer = jsonWriter; - writer.Reset(buffer); - } - - return writer; - } - - static void DefaultStructuredLoggingFormatter(Utf8JsonWriter writer, LogInfo info) - { - info.WriteToJsonWriter(writer); - } - - static byte[] newLine = Encoding.UTF8.GetBytes(Environment.NewLine); - - static void DefaultExceptionLoggingFormatter(IBufferWriter writer, Exception exception) - { - // \n + exception - Write(writer, Environment.NewLine); - WriteExceptionLoggingCore(writer, exception); - } - - static void WriteExceptionLoggingCore(IBufferWriter writer, Exception exception) - { - // className: message - // ---> InnerException - // InnerException StackTrace - // --- End of inner exception stack trace --- - // StackTrace - - var className = exception.GetType().FullName; - var message = exception.Message; - var innerException = exception.InnerException; - var stackTrace = exception.StackTrace; // allocating stacktrace string but okay(shoganai). - - Write(writer, className, ": ", message ?? ""); - if (innerException != null) - { - Write(writer, Environment.NewLine, " ---> "); - WriteExceptionLoggingCore(writer, innerException); - Write(writer, Environment.NewLine, " --- End of inner exception stack trace ---"); - } - - if (stackTrace != null) - { - Write(writer, Environment.NewLine, stackTrace); - } - } - - static void Write(IBufferWriter writer, string message) - { - var memory = writer.GetMemory(Encoding.UTF8.GetMaxByteCount(message.Length)); - if (MemoryMarshal.TryGetArray(memory, out var array) && array.Array != null) - { - var written = Encoding.UTF8.GetBytes(message, 0, message.Length, array.Array, array.Offset); - writer.Advance(written); - } - } - - static void Write(IBufferWriter writer, string message1, string message2) - { - var memory = writer.GetMemory(Encoding.UTF8.GetMaxByteCount(message1.Length + message2.Length)); - if (MemoryMarshal.TryGetArray(memory, out var array) && array.Array != null) - { - var written1 = Encoding.UTF8.GetBytes(message1, 0, message1.Length, array.Array, array.Offset); - var written2 = Encoding.UTF8.GetBytes(message2, 0, message2.Length, array.Array, array.Offset + written1); - writer.Advance(written1 + written2); - } - } - - static void Write(IBufferWriter writer, string message1, string message2, string message3) - { - var memory = writer.GetMemory(Encoding.UTF8.GetMaxByteCount(message1.Length + message2.Length + message3.Length)); - if (MemoryMarshal.TryGetArray(memory, out var array) && array.Array != null) - { - var written1 = Encoding.UTF8.GetBytes(message1, 0, message1.Length, array.Array, array.Offset); - var written2 = Encoding.UTF8.GetBytes(message2, 0, message2.Length, array.Array, array.Offset + written1); - var written3 = Encoding.UTF8.GetBytes(message3, 0, message3.Length, array.Array, array.Offset + written1 + written2); - writer.Advance(written1 + written2 + written3); - } - } - } -} diff --git a/Plugins/ZLogger/ZLoggerOptions.cs.meta b/Plugins/ZLogger/ZLoggerOptions.cs.meta deleted file mode 100644 index abc290d4..00000000 --- a/Plugins/ZLogger/ZLoggerOptions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6b2009f6bd6ed184fa977a146c64f87d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZLogger/package.json b/Plugins/ZLogger/package.json deleted file mode 100644 index 886568a3..00000000 --- a/Plugins/ZLogger/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "com.cysharp.zlogger", - "displayName": "ZLogger", - "version": "1.5.1", - "unity": "2018.3", - "description": "Zero Allocation Text/Strcutured Logger for .NET Core and Unity, built on top of a Microsoft.Extensions.Logging.", - "keywords": ["logging"], - "license": "MIT", - "category": "Logger", - "dependencies": {}, - "samples": [ - { - "displayName": "Import Managed DLL Dependencies to Plugins", - "description": "Install Required Managed dlls(System.*.dll, Microsoft.*.dll).", - "path": "Samples~/RequiredManagedDLLs" - } - ] -} \ No newline at end of file diff --git a/Plugins/ZLogger/package.json.meta b/Plugins/ZLogger/package.json.meta deleted file mode 100644 index 48656f5a..00000000 --- a/Plugins/ZLogger/package.json.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: e041803658eba4c40b8148658bfb7d55 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString.meta b/Plugins/ZString.meta deleted file mode 100644 index b9c23707..00000000 --- a/Plugins/ZString.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d6c6e065a6e87bf4e9331908e7275cf3 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/EnumUtil.cs b/Plugins/ZString/EnumUtil.cs deleted file mode 100644 index 548a58bc..00000000 --- a/Plugins/ZString/EnumUtil.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text -{ - internal static class EnumUtil - { - const string InvalidName = "$"; - - static readonly Dictionary names; - static readonly Dictionary utf8names; - - static EnumUtil() - { - var enumNames = Enum.GetNames(typeof(T)); - var values = Enum.GetValues(typeof(T)); - names = new Dictionary(enumNames.Length); - utf8names = new Dictionary(enumNames.Length); - for (int i = 0; i < enumNames.Length; i++) - { - if (names.ContainsKey((T)values.GetValue(i))) - { - // already registered = invalid. - names[(T)values.GetValue(i)] = InvalidName; - utf8names[(T)values.GetValue(i)] = Array.Empty(); // byte[0] == Invalid. - } - else - { - names.Add((T)values.GetValue(i), enumNames[i]); - utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i])); - } - } - } - - public static bool TryFormatUtf16(T value, Span dest, out int written, ReadOnlySpan _) - { - if (!names.TryGetValue(value, out var v) || v == InvalidName) - { - v = value.ToString(); - } - - written = v.Length; - return v.AsSpan().TryCopyTo(dest); - } - - public static bool TryFormatUtf8(T value, Span dest, out int written, StandardFormat _) - { - if (!utf8names.TryGetValue(value, out var v) || v.Length == 0) - { - v = Encoding.UTF8.GetBytes(value.ToString()); - } - - written = v.Length; - return v.AsSpan().TryCopyTo(dest); - } - } -} diff --git a/Plugins/ZString/EnumUtil.cs.meta b/Plugins/ZString/EnumUtil.cs.meta deleted file mode 100644 index f545c639..00000000 --- a/Plugins/ZString/EnumUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d12377b4cfb6e604592941b9cdfbcc92 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ExceptionUtil.cs b/Plugins/ZString/ExceptionUtil.cs deleted file mode 100644 index 401e1c65..00000000 --- a/Plugins/ZString/ExceptionUtil.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text -{ - internal static class ExceptionUtil - { - internal static void ThrowArgumentException(string paramName) - { - throw new ArgumentException("Can't format argument.", paramName); - } - - internal static void ThrowFormatException() - { - throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); - } - - internal static void ThrowFormatError() - { - throw new FormatException("Input string was not in a correct format."); - } - } -} diff --git a/Plugins/ZString/ExceptionUtil.cs.meta b/Plugins/ZString/ExceptionUtil.cs.meta deleted file mode 100644 index 72aeb775..00000000 --- a/Plugins/ZString/ExceptionUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c69ccd87e4d4ef74eaf019d0603195e6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/FastNumberWriter.cs b/Plugins/ZString/FastNumberWriter.cs deleted file mode 100644 index bd84dd41..00000000 --- a/Plugins/ZString/FastNumberWriter.cs +++ /dev/null @@ -1,299 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text -{ - internal static class FastNumberWriter - { - // Faster than .NET Core .TryFormat without format string. - - public static bool TryWriteInt64(Span buffer, out int charsWritten, long value) - { - var offset = 0; - charsWritten = 0; - long num1 = value, num2, num3, num4, num5, div; - - if (value < 0) - { - if (value == long.MinValue) // -9223372036854775808 - { - if (buffer.Length < 20) { return false; } - buffer[offset++] = (char)'-'; - buffer[offset++] = (char)'9'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'0'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'6'; - buffer[offset++] = (char)'8'; - buffer[offset++] = (char)'5'; - buffer[offset++] = (char)'4'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'5'; - buffer[offset++] = (char)'8'; - buffer[offset++] = (char)'0'; - buffer[offset++] = (char)'8'; - charsWritten = offset; - return true; - } - - if (buffer.Length < 1) { return false; } - buffer[offset++] = (char)'-'; - num1 = unchecked(-value); - } - - // WriteUInt64(inlined) - - if (num1 < 10000) - { - if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } - if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } - if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } - if (buffer.Length < 4) { return false; } - goto L4; - } - else - { - num2 = num1 / 10000; - num1 -= num2 * 10000; - if (num2 < 10000) - { - if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } - if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } - if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } - if (buffer.Length < 8) { return false; } - goto L8; - } - else - { - num3 = num2 / 10000; - num2 -= num3 * 10000; - if (num3 < 10000) - { - if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } - if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } - if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } - if (buffer.Length < 12) { return false; } - goto L12; - } - else - { - num4 = num3 / 10000; - num3 -= num4 * 10000; - if (num4 < 10000) - { - if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } - if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } - if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } - if (buffer.Length < 16) { return false; } - goto L16; - } - else - { - num5 = num4 / 10000; - num4 -= num5 * 10000; - if (num5 < 10000) - { - if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } - if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } - if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } - if (buffer.Length < 20) { return false; } - goto L20; - } - L20: - buffer[offset++] = (char)('0' + (div = (num5 * 8389L) >> 23)); - num5 -= div * 1000; - L19: - buffer[offset++] = (char)('0' + (div = (num5 * 5243L) >> 19)); - num5 -= div * 100; - L18: - buffer[offset++] = (char)('0' + (div = (num5 * 6554L) >> 16)); - num5 -= div * 10; - L17: - buffer[offset++] = (char)('0' + (num5)); - } - L16: - buffer[offset++] = (char)('0' + (div = (num4 * 8389L) >> 23)); - num4 -= div * 1000; - L15: - buffer[offset++] = (char)('0' + (div = (num4 * 5243L) >> 19)); - num4 -= div * 100; - L14: - buffer[offset++] = (char)('0' + (div = (num4 * 6554L) >> 16)); - num4 -= div * 10; - L13: - buffer[offset++] = (char)('0' + (num4)); - } - L12: - buffer[offset++] = (char)('0' + (div = (num3 * 8389L) >> 23)); - num3 -= div * 1000; - L11: - buffer[offset++] = (char)('0' + (div = (num3 * 5243L) >> 19)); - num3 -= div * 100; - L10: - buffer[offset++] = (char)('0' + (div = (num3 * 6554L) >> 16)); - num3 -= div * 10; - L9: - buffer[offset++] = (char)('0' + (num3)); - } - L8: - buffer[offset++] = (char)('0' + (div = (num2 * 8389L) >> 23)); - num2 -= div * 1000; - L7: - buffer[offset++] = (char)('0' + (div = (num2 * 5243L) >> 19)); - num2 -= div * 100; - L6: - buffer[offset++] = (char)('0' + (div = (num2 * 6554L) >> 16)); - num2 -= div * 10; - L5: - buffer[offset++] = (char)('0' + (num2)); - } - L4: - buffer[offset++] = (char)('0' + (div = (num1 * 8389L) >> 23)); - num1 -= div * 1000; - L3: - buffer[offset++] = (char)('0' + (div = (num1 * 5243L) >> 19)); - num1 -= div * 100; - L2: - buffer[offset++] = (char)('0' + (div = (num1 * 6554L) >> 16)); - num1 -= div * 10; - L1: - buffer[offset++] = (char)('0' + (num1)); - - charsWritten = offset; - return true; - } - - public static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) - { - ulong num1 = value, num2, num3, num4, num5, div; - charsWritten = 0; - var offset = 0; - - if (num1 < 10000) - { - if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } - if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } - if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } - if (buffer.Length < 4) { return false; } - goto L4; - } - else - { - num2 = num1 / 10000; - num1 -= num2 * 10000; - if (num2 < 10000) - { - if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } - if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } - if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } - if (buffer.Length < 8) { return false; } - goto L8; - } - else - { - num3 = num2 / 10000; - num2 -= num3 * 10000; - if (num3 < 10000) - { - if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } - if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } - if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } - if (buffer.Length < 12) { return false; } - goto L12; - } - else - { - num4 = num3 / 10000; - num3 -= num4 * 10000; - if (num4 < 10000) - { - if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } - if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } - if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } - if (buffer.Length < 16) { return false; } - goto L16; - } - else - { - num5 = num4 / 10000; - num4 -= num5 * 10000; - if (num5 < 10000) - { - if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } - if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } - if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } - if (buffer.Length < 20) { return false; } - goto L20; - } - L20: - buffer[offset++] = (char)('0' + (div = (num5 * 8389UL) >> 23)); - num5 -= div * 1000; - L19: - buffer[offset++] = (char)('0' + (div = (num5 * 5243UL) >> 19)); - num5 -= div * 100; - L18: - buffer[offset++] = (char)('0' + (div = (num5 * 6554UL) >> 16)); - num5 -= div * 10; - L17: - buffer[offset++] = (char)('0' + (num5)); - } - L16: - buffer[offset++] = (char)('0' + (div = (num4 * 8389UL) >> 23)); - num4 -= div * 1000; - L15: - buffer[offset++] = (char)('0' + (div = (num4 * 5243UL) >> 19)); - num4 -= div * 100; - L14: - buffer[offset++] = (char)('0' + (div = (num4 * 6554UL) >> 16)); - num4 -= div * 10; - L13: - buffer[offset++] = (char)('0' + (num4)); - } - L12: - buffer[offset++] = (char)('0' + (div = (num3 * 8389UL) >> 23)); - num3 -= div * 1000; - L11: - buffer[offset++] = (char)('0' + (div = (num3 * 5243UL) >> 19)); - num3 -= div * 100; - L10: - buffer[offset++] = (char)('0' + (div = (num3 * 6554UL) >> 16)); - num3 -= div * 10; - L9: - buffer[offset++] = (char)('0' + (num3)); - } - L8: - buffer[offset++] = (char)('0' + (div = (num2 * 8389UL) >> 23)); - num2 -= div * 1000; - L7: - buffer[offset++] = (char)('0' + (div = (num2 * 5243UL) >> 19)); - num2 -= div * 100; - L6: - buffer[offset++] = (char)('0' + (div = (num2 * 6554UL) >> 16)); - num2 -= div * 10; - L5: - buffer[offset++] = (char)('0' + (num2)); - } - L4: - buffer[offset++] = (char)('0' + (div = (num1 * 8389UL) >> 23)); - num1 -= div * 1000; - L3: - buffer[offset++] = (char)('0' + (div = (num1 * 5243UL) >> 19)); - num1 -= div * 100; - L2: - buffer[offset++] = (char)('0' + (div = (num1 * 6554UL) >> 16)); - num1 -= div * 10; - L1: - buffer[offset++] = (char)('0' + (num1)); - - charsWritten = offset; - return true; - } - } -} diff --git a/Plugins/ZString/FastNumberWriter.cs.meta b/Plugins/ZString/FastNumberWriter.cs.meta deleted file mode 100644 index 9c82a4eb..00000000 --- a/Plugins/ZString/FastNumberWriter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dd857f99f11ce484c8a3b600614fd1d3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/FormatHelper.cs b/Plugins/ZString/FormatHelper.cs deleted file mode 100644 index de9846ca..00000000 --- a/Plugins/ZString/FormatHelper.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System; -using System.Text; -using System.Buffers; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - internal static partial class Utf16FormatHelper - { - const char sp = (char)' '; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void FormatTo(ref TBufferWriter sb, T arg, int width, ReadOnlySpan format, string argName) - where TBufferWriter : IBufferWriter - { - if (width <= 0) // leftJustify - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out argWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - sb.Advance(argWritten); - - width *= -1; - int padding = width - argWritten; - if (width > 0 && padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } - } - else - { - FormatToRightJustify(ref sb, arg, width, format, argName); - } - } - - private static void FormatToRightJustify(ref TBufferWriter sb, T arg, int width, ReadOnlySpan format, string argName) - where TBufferWriter : IBufferWriter - { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } - - var span = sb.GetSpan(s.Length); - s.AsSpan().CopyTo(span); - sb.Advance(s.Length); - } - else - { - Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc char[s.Length * 2]; - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - - int padding = width - charsWritten; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } - - var span = sb.GetSpan(charsWritten); - s.CopyTo(span); - sb.Advance(charsWritten); - } - } - } - - internal static partial class Utf8FormatHelper - { - const byte sp = (byte)' '; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void FormatTo(ref TBufferWriter sb, T arg, int width, StandardFormat format, string argName) - where TBufferWriter : IBufferWriter - { - if (width <= 0) // leftJustify - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out argWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - sb.Advance(argWritten); - - width *= -1; - int padding = width - argWritten; - if (width > 0 && padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } - } - else - { - FormatToRightJustify(ref sb, arg, width, format, argName); - } - } - - private static void FormatToRightJustify(ref TBufferWriter sb, T arg, int width, StandardFormat format, string argName) - where TBufferWriter : IBufferWriter - { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } - - ZString.AppendChars(ref sb, s.AsSpan()); - } - else - { - Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc byte[s.Length * 2]; - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - - int padding = width - charsWritten; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } - - var span = sb.GetSpan(charsWritten); - s.CopyTo(span); - sb.Advance(charsWritten); - } - } - } - -} \ No newline at end of file diff --git a/Plugins/ZString/FormatHelper.cs.meta b/Plugins/ZString/FormatHelper.cs.meta deleted file mode 100644 index 37046650..00000000 --- a/Plugins/ZString/FormatHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4e46453b986ebf4428a5c23fb3cbb175 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/FormatParser.cs b/Plugins/ZString/FormatParser.cs deleted file mode 100644 index a9552815..00000000 --- a/Plugins/ZString/FormatParser.cs +++ /dev/null @@ -1,218 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - internal static class FormatParser - { - // {index[,alignment][:formatString]} - - public readonly ref struct ParseResult - { - public readonly int Index; - public readonly ReadOnlySpan FormatString; - public readonly int LastIndex; - public readonly int Alignment; - - public ParseResult(int index, ReadOnlySpan formatString, int lastIndex, int alignment) - { - Index = index; - FormatString = formatString; - LastIndex = lastIndex; - Alignment = alignment; - } - } - - internal const int ArgLengthLimit = 16; - internal const int WidthLimit = 1000; // Note: -WidthLimit < ArgAlign < WidthLimit - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ParserScanResult ScanFormatString(ReadOnlySpan format, ref int i) - { - var len = format.Length; - char c = format[i]; - - i++; // points netxt char - if (c == '}') - { - // skip escaped '}' - if (i < len && format[i] == '}') - { - i++; - return ParserScanResult.EscapedChar; - } - else - { - ExceptionUtil.ThrowFormatError(); - return ParserScanResult.NormalChar; // NOTE Don't reached - } - } - else if (c == '{') - { - // skip escaped '{' - if (i < len && format[i] == '{') - { - i++; - return ParserScanResult.EscapedChar; - } - else - { - i--; - return ParserScanResult.BraceOpen; - } - } - else - { - // ch is the normal char OR end of text - return ParserScanResult.NormalChar; - } - } - - // Accept only non-unicode numbers - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool IsDigit(char c) => '0' <= c && c <= '9'; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ParseResult Parse(string format, int i) - { - char c = default; - var len = format.Length; - - i++; // Skip `{` - - // === Index Component === - // ('0'-'9')+ WS* - - if (i == len || !IsDigit(c = format[i])) - { - ExceptionUtil.ThrowFormatError(); - } - - int paramIndex = 0; - do - { - paramIndex = (paramIndex * 10) + c - '0'; - - if (++i == len) - ExceptionUtil.ThrowFormatError(); - - c = format[i]; - } - while (IsDigit(c) && paramIndex < ArgLengthLimit); - - if (paramIndex >= ArgLengthLimit) - { - ExceptionUtil.ThrowFormatException(); - } - - // skip whitespace. - while (i < len && (c = format[i]) == ' ') - i++; - - // === Alignment Component === - // comma WS* minus? ('0'-'9')+ WS* - - int alignment = 0; - - if (c == ',') - { - i++; - - // skip whitespace. - while (i < len && (c = format[i]) == ' ') - i++; - - if (i == len) - { - ExceptionUtil.ThrowFormatError(); - } - - var leftJustify = false; - if (c == '-') - { - leftJustify = true; - - if (++i == len) - ExceptionUtil.ThrowFormatError(); - - c = format[i]; - } - - if (!IsDigit(c)) - { - ExceptionUtil.ThrowFormatError(); - } - - do - { - alignment = (alignment * 10) + c - '0'; - - if (++i == len) - ExceptionUtil.ThrowFormatError(); - - c = format[i]; - } - while (IsDigit(c) && alignment < WidthLimit); - - if (leftJustify) - alignment *= -1; - } - - // skip whitespace. - while (i < len && (c = format[i]) == ' ') - i++; - - // === Format String Component === - - ReadOnlySpan itemFormatSpan = default; - - if (c == ':') - { - i++; - int formatStart = i; - - while (true) - { - if (i == len) - { - ExceptionUtil.ThrowFormatError(); - } - c = format[i]; - - if (c == '}') - { - break; - } - else if (c == '{') - { - ExceptionUtil.ThrowFormatError(); - } - - i++; - } - - // has format - if (i > formatStart) - { - itemFormatSpan = format.AsSpan(formatStart, i - formatStart); - } - } - else if (c != '}') - { - // Unexpected character - ExceptionUtil.ThrowFormatError(); - } - - i++; // Skip `}` - return new ParseResult(paramIndex, itemFormatSpan, i, alignment); - } - } - internal enum ParserScanResult - { - BraceOpen, - EscapedChar, - NormalChar, - } - -} diff --git a/Plugins/ZString/FormatParser.cs.meta b/Plugins/ZString/FormatParser.cs.meta deleted file mode 100644 index ca880114..00000000 --- a/Plugins/ZString/FormatParser.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a3676d0a8288bd1469a9162fec83cf5a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/IResettableBufferWriter.cs b/Plugins/ZString/IResettableBufferWriter.cs deleted file mode 100644 index bcdb1524..00000000 --- a/Plugins/ZString/IResettableBufferWriter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text -{ - public interface IResettableBufferWriter : IBufferWriter - { - void Reset(); - } -} diff --git a/Plugins/ZString/IResettableBufferWriter.cs.meta b/Plugins/ZString/IResettableBufferWriter.cs.meta deleted file mode 100644 index 22b2e64b..00000000 --- a/Plugins/ZString/IResettableBufferWriter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c853a6364ab3cd3489eaaab75fbb2f5b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/NestedStringBuilderCreationException.cs b/Plugins/ZString/NestedStringBuilderCreationException.cs deleted file mode 100644 index 4f263d94..00000000 --- a/Plugins/ZString/NestedStringBuilderCreationException.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace Cysharp.Text -{ - // Currently, this class is internals. - internal class NestedStringBuilderCreationException : InvalidOperationException - { - private NestedStringBuilderCreationException() - { - } - - internal protected NestedStringBuilderCreationException(string typeName, string extraMessage = "") - : base($"A nested call with `notNested: true`, or Either You forgot to call {typeName}.Dispose() of in the past.{extraMessage}") - { - } - - internal protected NestedStringBuilderCreationException(string message, Exception innerException) : base(message, innerException) - { - } - - } -} diff --git a/Plugins/ZString/NestedStringBuilderCreationException.cs.meta b/Plugins/ZString/NestedStringBuilderCreationException.cs.meta deleted file mode 100644 index 0e5262e5..00000000 --- a/Plugins/ZString/NestedStringBuilderCreationException.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c2e6121a89e941e4d8388e6842ad3551 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number.meta b/Plugins/ZString/Number.meta deleted file mode 100644 index 679db252..00000000 --- a/Plugins/ZString/Number.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 0da3402c85681804ebc1170c0d3fa7f2 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/BitOperations.cs b/Plugins/ZString/Number/BitOperations.cs deleted file mode 100644 index 978a99cb..00000000 --- a/Plugins/ZString/Number/BitOperations.cs +++ /dev/null @@ -1,284 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Some routines inspired by the Stanford Bit Twiddling Hacks by Sean Eron Anderson: -// http://graphics.stanford.edu/~seander/bithacks.html - -namespace System.Numerics -{ - /// - /// Utility methods for intrinsic bit-twiddling operations. - /// The methods use hardware intrinsics when available on the underlying platform, - /// otherwise they use optimized software fallbacks. - /// - public static class BitOperations - { - // C# no-alloc optimization that directly wraps the data section of the dll (similar to string constants) - // https://github.com/dotnet/roslyn/pull/24621 - - private static ReadOnlySpan TrailingZeroCountDeBruijn => new byte[32] - { - 00, 01, 28, 02, 29, 14, 24, 03, - 30, 22, 20, 15, 25, 17, 04, 08, - 31, 27, 13, 23, 21, 19, 16, 07, - 26, 12, 18, 06, 11, 05, 10, 09 - }; - - private static ReadOnlySpan Log2DeBruijn => new byte[32] - { - 00, 09, 01, 10, 13, 21, 02, 29, - 11, 14, 16, 18, 22, 25, 03, 30, - 08, 12, 20, 28, 15, 17, 24, 07, - 19, 27, 23, 06, 26, 05, 04, 31 - }; - - /// - /// Count the number of leading zero bits in a mask. - /// Similar in behavior to the x86 instruction LZCNT. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LeadingZeroCount(uint value) - { - // Unguarded fallback contract is 0->31 - if (value == 0) - { - return 32; - } - - return 31 - Log2SoftwareFallback(value); - } - - /// - /// Count the number of leading zero bits in a mask. - /// Similar in behavior to the x86 instruction LZCNT. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LeadingZeroCount(ulong value) - { - uint hi = (uint)(value >> 32); - - if (hi == 0) - { - return 32 + LeadingZeroCount((uint)value); - } - - return LeadingZeroCount(hi); - } - - /// - /// Returns the integer (floor) log of the specified value, base 2. - /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Log2(uint value) - { - // Fallback contract is 0->0 - return Log2SoftwareFallback(value); - } - - /// - /// Returns the integer (floor) log of the specified value, base 2. - /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Log2(ulong value) - { - uint hi = (uint)(value >> 32); - - if (hi == 0) - { - return Log2((uint)value); - } - - return 32 + Log2(hi); - } - - /// - /// Returns the integer (floor) log of the specified value, base 2. - /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. - /// Does not directly use any hardware intrinsics, nor does it incur branching. - /// - /// The value. - private static int Log2SoftwareFallback(uint value) - { - // No AggressiveInlining due to large method size - // Has conventional contract 0->0 (Log(0) is undefined) - - // Fill trailing zeros with ones, eg 00010010 becomes 00011111 - value |= value >> 01; - value |= value >> 02; - value |= value >> 04; - value |= value >> 08; - value |= value >> 16; - - // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check - return Unsafe.AddByteOffset( - // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_1100_0100_1010_1100_1101_1101u - ref MemoryMarshal.GetReference(Log2DeBruijn), - // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here - (IntPtr)(int)((value * 0x07C4ACDDu) >> 27)); - } - - /// - /// Returns the population count (number of bits set) of a mask. - /// Similar in behavior to the x86 instruction POPCNT. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int PopCount(uint value) - { - const uint c1 = 0x_55555555u; - const uint c2 = 0x_33333333u; - const uint c3 = 0x_0F0F0F0Fu; - const uint c4 = 0x_01010101u; - - value -= (value >> 1) & c1; - value = (value & c2) + ((value >> 2) & c2); - value = (((value + (value >> 4)) & c3) * c4) >> 24; - - return (int)value; - } - - /// - /// Returns the population count (number of bits set) of a mask. - /// Similar in behavior to the x86 instruction POPCNT. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int PopCount(ulong value) - { - if (IntPtr.Size == 4) - { - return PopCount((uint)value) // lo - + PopCount((uint)(value >> 32)); // hi - } - else - { - const ulong c1 = 0x_55555555_55555555ul; - const ulong c2 = 0x_33333333_33333333ul; - const ulong c3 = 0x_0F0F0F0F_0F0F0F0Ful; - const ulong c4 = 0x_01010101_01010101ul; - - value -= (value >> 1) & c1; - value = (value & c2) + ((value >> 2) & c2); - value = (((value + (value >> 4)) & c3) * c4) >> 56; - - return (int)value; - } - } - - /// - /// Count the number of trailing zero bits in an integer value. - /// Similar in behavior to the x86 instruction TZCNT. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int TrailingZeroCount(int value) - => TrailingZeroCount((uint)value); - - /// - /// Count the number of trailing zero bits in an integer value. - /// Similar in behavior to the x86 instruction TZCNT. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int TrailingZeroCount(uint value) - { - // Unguarded fallback contract is 0->0 - if (value == 0) - { - return 32; - } - - // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check - return Unsafe.AddByteOffset( - // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_0111_1100_1011_0101_0011_0001u - ref MemoryMarshal.GetReference(TrailingZeroCountDeBruijn), - // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here - (IntPtr)(int)(((value & (uint)-(int)value) * 0x077CB531u) >> 27)); // Multi-cast mitigates redundant conv.u8 - } - - /// - /// Count the number of trailing zero bits in a mask. - /// Similar in behavior to the x86 instruction TZCNT. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int TrailingZeroCount(long value) - => TrailingZeroCount((ulong)value); - - /// - /// Count the number of trailing zero bits in a mask. - /// Similar in behavior to the x86 instruction TZCNT. - /// - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int TrailingZeroCount(ulong value) - { - uint lo = (uint)value; - - if (lo == 0) - { - return 32 + TrailingZeroCount((uint)(value >> 32)); - } - - return TrailingZeroCount(lo); - } - - /// - /// Rotates the specified value left by the specified number of bits. - /// Similar in behavior to the x86 instruction ROL. - /// - /// The value to rotate. - /// The number of bits to rotate by. - /// Any value outside the range [0..31] is treated as congruent mod 32. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateLeft(uint value, int offset) - => (value << offset) | (value >> (32 - offset)); - - /// - /// Rotates the specified value left by the specified number of bits. - /// Similar in behavior to the x86 instruction ROL. - /// - /// The value to rotate. - /// The number of bits to rotate by. - /// Any value outside the range [0..63] is treated as congruent mod 64. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong RotateLeft(ulong value, int offset) - => (value << offset) | (value >> (64 - offset)); - - /// - /// Rotates the specified value right by the specified number of bits. - /// Similar in behavior to the x86 instruction ROR. - /// - /// The value to rotate. - /// The number of bits to rotate by. - /// Any value outside the range [0..31] is treated as congruent mod 32. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateRight(uint value, int offset) - => (value >> offset) | (value << (32 - offset)); - - /// - /// Rotates the specified value right by the specified number of bits. - /// Similar in behavior to the x86 instruction ROR. - /// - /// The value to rotate. - /// The number of bits to rotate by. - /// Any value outside the range [0..63] is treated as congruent mod 64. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong RotateRight(ulong value, int offset) - => (value >> offset) | (value << (64 - offset)); - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/BitOperations.cs.meta b/Plugins/ZString/Number/BitOperations.cs.meta deleted file mode 100644 index 20f8d31c..00000000 --- a/Plugins/ZString/Number/BitOperations.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 84f68d164ca4db04082e956ba20ee5b4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/BufferEx.cs b/Plugins/ZString/Number/BufferEx.cs deleted file mode 100644 index 0b96bda3..00000000 --- a/Plugins/ZString/Number/BufferEx.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace System -{ - internal static class BufferEx - { - internal static unsafe void ZeroMemory(byte* dest, uint len) - { - if (len == 0) return; - - for (int i = 0; i < len; i++) - { - dest[i] = 0; - } - } - - internal static unsafe void Memcpy(byte* dest, byte* src, int len) - { - if (len == 0) return; - for (int i = 0; i < len; i++) - { - dest[i] = src[i]; - } - } - } -} diff --git a/Plugins/ZString/Number/BufferEx.cs.meta b/Plugins/ZString/Number/BufferEx.cs.meta deleted file mode 100644 index 4d1fe4ce..00000000 --- a/Plugins/ZString/Number/BufferEx.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 02503aa3b1ee88741822361d3f10e8b7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/DecimalEx.cs b/Plugins/ZString/Number/DecimalEx.cs deleted file mode 100644 index 95125476..00000000 --- a/Plugins/ZString/Number/DecimalEx.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace System -{ - internal static class DecimalEx - { - [StructLayout(LayoutKind.Explicit)] - private struct DecimalBits - { - [FieldOffset(0)] - public int flags; - [FieldOffset(4)] - public int hi; - [FieldOffset(8)] - public int lo; - [FieldOffset(12)] - public int mid; - } - - [StructLayout(LayoutKind.Explicit)] - private struct DecCalc - { - private const uint TenToPowerNine = 1000000000; - - // NOTE: Do not change the offsets of these fields. This structure must have the same layout as Decimal. - [FieldOffset(0)] - public uint uflags; - [FieldOffset(4)] - public uint uhi; - [FieldOffset(8)] - public uint ulo; - [FieldOffset(12)] - public uint umid; - - /// - /// The low and mid fields combined in little-endian order - /// - [FieldOffset(8)] - private ulong ulomidLE; - - internal static uint DecDivMod1E9(ref DecCalc value) - { - ulong high64 = ((ulong)value.uhi << 32) + value.umid; - ulong div64 = high64 / TenToPowerNine; - value.uhi = (uint)(div64 >> 32); - value.umid = (uint)div64; - - ulong num = ((high64 - (uint)div64 * TenToPowerNine) << 32) + value.ulo; - uint div = (uint)(num / TenToPowerNine); - value.ulo = div; - return (uint)num - div * TenToPowerNine; - } - } - - private const int ScaleShift = 16; - - static ref DecCalc AsMutable(ref decimal d) => ref Unsafe.As(ref d); - - internal static uint High(this decimal value) - { - return Unsafe.As(ref value).uhi; - } - - internal static uint Low(this decimal value) - { - return Unsafe.As(ref value).ulo; - } - - internal static uint Mid(this decimal value) - { - return Unsafe.As(ref value).umid; - } - - internal static bool IsNegative(this decimal value) - { - return Unsafe.As(ref value).flags < 0; - } - - internal static int Scale(this decimal value) - { - return (byte)(Unsafe.As(ref value).flags >> ScaleShift); - } - - internal static uint DecDivMod1E9(ref decimal value) - { - return DecCalc.DecDivMod1E9(ref AsMutable(ref value)); - } - } -} diff --git a/Plugins/ZString/Number/DecimalEx.cs.meta b/Plugins/ZString/Number/DecimalEx.cs.meta deleted file mode 100644 index e9b80f77..00000000 --- a/Plugins/ZString/Number/DecimalEx.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: adc39bbd83ade844e9823e44bb8b5445 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/FloatEx.cs b/Plugins/ZString/Number/FloatEx.cs deleted file mode 100644 index bdc9280f..00000000 --- a/Plugins/ZString/Number/FloatEx.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Text; - -namespace System -{ - internal static class FloatEx - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe bool IsFinite(double d) - { - long bits = BitConverter.DoubleToInt64Bits(d); - return (bits & 0x7FFFFFFFFFFFFFFF) < 0x7FF0000000000000; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe bool IsNegative(double d) - { - return BitConverter.DoubleToInt64Bits(d) < 0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsFinite(float f) - { - int bits = SingleToInt32Bits(f); - return (bits & 0x7FFFFFFF) < 0x7F800000; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe bool IsNegative(float f) - { - return SingleToInt32Bits(f) < 0; - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int SingleToInt32Bits(float value) - { - return *((int*)&value); - } - } -} diff --git a/Plugins/ZString/Number/FloatEx.cs.meta b/Plugins/ZString/Number/FloatEx.cs.meta deleted file mode 100644 index 79196459..00000000 --- a/Plugins/ZString/Number/FloatEx.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e1bfcfb70d615f24fb88dc092457b6c8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/FormattingHelpers.cs b/Plugins/ZString/Number/FormattingHelpers.cs deleted file mode 100644 index 7072b315..00000000 --- a/Plugins/ZString/Number/FormattingHelpers.cs +++ /dev/null @@ -1,138 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Numerics; -using System.Runtime.CompilerServices; - -namespace System.Buffers.Text -{ - internal static partial class FormattingHelpers - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountDigits(ulong value) - { - int digits = 1; - uint part; - if (value >= 10000000) - { - if (value >= 100000000000000) - { - part = (uint)(value / 100000000000000); - digits += 14; - } - else - { - part = (uint)(value / 10000000); - digits += 7; - } - } - else - { - part = (uint)value; - } - - if (part < 10) - { - // no-op - } - else if (part < 100) - { - digits++; - } - else if (part < 1000) - { - digits += 2; - } - else if (part < 10000) - { - digits += 3; - } - else if (part < 100000) - { - digits += 4; - } - else if (part < 1000000) - { - digits += 5; - } - else - { - Debug.Assert(part < 10000000); - digits += 6; - } - - return digits; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountDigits(uint value) - { - int digits = 1; - if (value >= 100000) - { - value /= 100000; - digits += 5; - } - - if (value < 10) - { - // no-op - } - else if (value < 100) - { - digits++; - } - else if (value < 1000) - { - digits += 2; - } - else if (value < 10000) - { - digits += 3; - } - else - { - Debug.Assert(value < 100000); - digits += 4; - } - - return digits; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountHexDigits(ulong value) - { - return (64 - BitOperations.LeadingZeroCount(value | 1) + 3) >> 2; - } - - // Counts the number of trailing '0' digits in a decimal number. - // e.g., value = 0 => retVal = 0, valueWithoutTrailingZeros = 0 - // value = 1234 => retVal = 0, valueWithoutTrailingZeros = 1234 - // value = 320900 => retVal = 2, valueWithoutTrailingZeros = 3209 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountDecimalTrailingZeros(uint value, out uint valueWithoutTrailingZeros) - { - int zeroCount = 0; - - if (value != 0) - { - while (true) - { - uint temp = value / 10; - if (value != (temp * 10)) - { - break; - } - - value = temp; - zeroCount++; - } - } - - valueWithoutTrailingZeros = value; - return zeroCount; - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/FormattingHelpers.cs.meta b/Plugins/ZString/Number/FormattingHelpers.cs.meta deleted file mode 100644 index f954cbe4..00000000 --- a/Plugins/ZString/Number/FormattingHelpers.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2e18ceaad90d7f5438604312d93b703b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/GuidEx.cs b/Plugins/ZString/Number/GuidEx.cs deleted file mode 100644 index 7444a5e0..00000000 --- a/Plugins/ZString/Number/GuidEx.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System.Runtime.InteropServices; - -namespace System -{ - [StructLayout(LayoutKind.Sequential)] - internal struct GuidEx - { - private int _a; // Do not rename (binary serialization) - private short _b; // Do not rename (binary serialization) - private short _c; // Do not rename (binary serialization) - private byte _d; // Do not rename (binary serialization) - private byte _e; // Do not rename (binary serialization) - private byte _f; // Do not rename (binary serialization) - private byte _g; // Do not rename (binary serialization) - private byte _h; // Do not rename (binary serialization) - private byte _i; // Do not rename (binary serialization) - private byte _j; // Do not rename (binary serialization) - private byte _k; // Do not rename (binary serialization) - - private static unsafe int HexsToChars(char* guidChars, int a, int b) - { - guidChars[0] = HexConverter.ToCharLower(a >> 4); - guidChars[1] = HexConverter.ToCharLower(a); - - guidChars[2] = HexConverter.ToCharLower(b >> 4); - guidChars[3] = HexConverter.ToCharLower(b); - - return 4; - } - - private static unsafe int HexsToCharsHexOutput(char* guidChars, int a, int b) - { - guidChars[0] = '0'; - guidChars[1] = 'x'; - - guidChars[2] = HexConverter.ToCharLower(a >> 4); - guidChars[3] = HexConverter.ToCharLower(a); - - guidChars[4] = ','; - guidChars[5] = '0'; - guidChars[6] = 'x'; - - guidChars[7] = HexConverter.ToCharLower(b >> 4); - guidChars[8] = HexConverter.ToCharLower(b); - - return 9; - } - - public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - format = "D".AsSpan(); - } - // all acceptable format strings are of length 1 - if (format.Length != 1) - { - throw new FormatException("InvalidGuidFormatSpecification"); - } - - bool dash = true; - bool hex = false; - int braces = 0; - - int guidSize; - - switch (format[0]) - { - case 'D': - case 'd': - guidSize = 36; - break; - case 'N': - case 'n': - dash = false; - guidSize = 32; - break; - case 'B': - case 'b': - braces = '{' + ('}' << 16); - guidSize = 38; - break; - case 'P': - case 'p': - braces = '(' + (')' << 16); - guidSize = 38; - break; - case 'X': - case 'x': - braces = '{' + ('}' << 16); - dash = false; - hex = true; - guidSize = 68; - break; - default: - throw new FormatException("InvalidGuidFormatSpecification"); - } - - if (destination.Length < guidSize) - { - charsWritten = 0; - return false; - } - - unsafe - { - fixed (char* guidChars = &MemoryMarshal.GetReference(destination)) - { - char* p = guidChars; - - if (braces != 0) - *p++ = (char)braces; - - if (hex) - { - // {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}} - *p++ = '0'; - *p++ = 'x'; - p += HexsToChars(p, _a >> 24, _a >> 16); - p += HexsToChars(p, _a >> 8, _a); - *p++ = ','; - *p++ = '0'; - *p++ = 'x'; - p += HexsToChars(p, _b >> 8, _b); - *p++ = ','; - *p++ = '0'; - *p++ = 'x'; - p += HexsToChars(p, _c >> 8, _c); - *p++ = ','; - *p++ = '{'; - p += HexsToCharsHexOutput(p, _d, _e); - *p++ = ','; - p += HexsToCharsHexOutput(p, _f, _g); - *p++ = ','; - p += HexsToCharsHexOutput(p, _h, _i); - *p++ = ','; - p += HexsToCharsHexOutput(p, _j, _k); - *p++ = '}'; - } - else - { - // [{|(]dddddddd[-]dddd[-]dddd[-]dddd[-]dddddddddddd[}|)] - p += HexsToChars(p, _a >> 24, _a >> 16); - p += HexsToChars(p, _a >> 8, _a); - if (dash) - *p++ = '-'; - p += HexsToChars(p, _b >> 8, _b); - if (dash) - *p++ = '-'; - p += HexsToChars(p, _c >> 8, _c); - if (dash) - *p++ = '-'; - p += HexsToChars(p, _d, _e); - if (dash) - *p++ = '-'; - p += HexsToChars(p, _f, _g); - p += HexsToChars(p, _h, _i); - p += HexsToChars(p, _j, _k); - } - - if (braces != 0) - *p++ = (char)(braces >> 16); - } - } - - charsWritten = guidSize; - return true; - } - } -} diff --git a/Plugins/ZString/Number/GuidEx.cs.meta b/Plugins/ZString/Number/GuidEx.cs.meta deleted file mode 100644 index 3ea64d25..00000000 --- a/Plugins/ZString/Number/GuidEx.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1b4d23acb4f60434ea9257c7cc2a1815 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/HexConverter.cs b/Plugins/ZString/Number/HexConverter.cs deleted file mode 100644 index 4e4e3a72..00000000 --- a/Plugins/ZString/Number/HexConverter.cs +++ /dev/null @@ -1,133 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Runtime.CompilerServices; - -namespace System -{ - internal static class HexConverter - { - public enum Casing : uint - { - // Output [ '0' .. '9' ] and [ 'A' .. 'F' ]. - Upper = 0, - - // Output [ '0' .. '9' ] and [ 'a' .. 'f' ]. - // This works because values in the range [ 0x30 .. 0x39 ] ([ '0' .. '9' ]) - // already have the 0x20 bit set, so ORing them with 0x20 is a no-op, - // while outputs in the range [ 0x41 .. 0x46 ] ([ 'A' .. 'F' ]) - // don't have the 0x20 bit set, so ORing them maps to - // [ 0x61 .. 0x66 ] ([ 'a' .. 'f' ]), which is what we want. - Lower = 0x2020U, - } - - // We want to pack the incoming byte into a single integer [ 0000 HHHH 0000 LLLL ], - // where HHHH and LLLL are the high and low nibbles of the incoming byte. Then - // subtract this integer from a constant minuend as shown below. - // - // [ 1000 1001 1000 1001 ] - // - [ 0000 HHHH 0000 LLLL ] - // ========================= - // [ *YYY **** *ZZZ **** ] - // - // The end result of this is that YYY is 0b000 if HHHH <= 9, and YYY is 0b111 if HHHH >= 10. - // Similarly, ZZZ is 0b000 if LLLL <= 9, and ZZZ is 0b111 if LLLL >= 10. - // (We don't care about the value of asterisked bits.) - // - // To turn a nibble in the range [ 0 .. 9 ] into hex, we calculate hex := nibble + 48 (ascii '0'). - // To turn a nibble in the range [ 10 .. 15 ] into hex, we calculate hex := nibble - 10 + 65 (ascii 'A'). - // => hex := nibble + 55. - // The difference in the starting ASCII offset is (55 - 48) = 7, depending on whether the nibble is <= 9 or >= 10. - // Since 7 is 0b111, this conveniently matches the YYY or ZZZ value computed during the earlier subtraction. - - // The commented out code below is code that directly implements the logic described above. - - // uint packedOriginalValues = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU); - // uint difference = 0x8989U - packedOriginalValues; - // uint add7Mask = (difference & 0x7070U) >> 4; // line YYY and ZZZ back up with the packed values - // uint packedResult = packedOriginalValues + add7Mask + 0x3030U /* ascii '0' */; - - // The code below is equivalent to the commented out code above but has been tweaked - // to allow codegen to make some extra optimizations. - - // The low byte of the packed result contains the hex representation of the incoming byte's low nibble. - // The adjacent byte of the packed result contains the hex representation of the incoming byte's high nibble. - - // Finally, write to the output buffer starting with the *highest* index so that codegen can - // elide all but the first bounds check. (This only works if 'startingIndex' is a compile-time constant.) - - // The JIT can elide bounds checks if 'startingIndex' is constant and if the caller is - // writing to a span of known length (or the caller has already checked the bounds of the - // furthest access). - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ToBytesBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) - { - uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; - uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; - - buffer[startingIndex + 1] = (byte)packedResult; - buffer[startingIndex] = (byte)(packedResult >> 8); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ToCharsBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) - { - uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; - uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; - - buffer[startingIndex + 1] = (char)(packedResult & 0xFF); - buffer[startingIndex] = (char)(packedResult >> 8); - } - - public static unsafe string ToString(ReadOnlySpan bytes, Casing casing = Casing.Upper) - { - Span result = stackalloc char[0]; - if (bytes.Length > 16) - { - var array = new char[bytes.Length * 2]; - result = array.AsSpan(); - } - else - { - result = stackalloc char[bytes.Length * 2]; - } - - int pos = 0; - foreach (byte b in bytes) - { - ToCharsBuffer(b, result, pos, casing); - pos += 2; - } - return result.ToString(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static char ToCharUpper(int value) - { - value &= 0xF; - value += '0'; - - if (value > '9') - { - value += ('A' - ('9' + 1)); - } - - return (char)value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static char ToCharLower(int value) - { - value &= 0xF; - value += '0'; - - if (value > '9') - { - value += ('a' - ('9' + 1)); - } - - return (char)value; - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/HexConverter.cs.meta b/Plugins/ZString/Number/HexConverter.cs.meta deleted file mode 100644 index 6d873d76..00000000 --- a/Plugins/ZString/Number/HexConverter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bc55fbf8adb9a284398481db6426b327 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/InternalSpanEx.cs b/Plugins/ZString/Number/InternalSpanEx.cs deleted file mode 100644 index 326bc0c7..00000000 --- a/Plugins/ZString/Number/InternalSpanEx.cs +++ /dev/null @@ -1,237 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace System -{ - internal static class InternalSpanEx - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool EqualsOrdinalIgnoreCase(this ReadOnlySpan span, ReadOnlySpan value) - { - if (span.Length != value.Length) - return false; - if (value.Length == 0) // span.Length == value.Length == 0 - return true; - - - - return EqualsOrdinalIgnoreCase(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), span.Length); - } - - static bool EqualsOrdinalIgnoreCase(ref char charA, ref char charB, int length) - { - IntPtr byteOffset = IntPtr.Zero; - - if (IntPtr.Size == 8) - { - // Read 4 chars (64 bits) at a time from each string - while ((uint)length >= 4) - { - ulong valueA = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charA, byteOffset))); - ulong valueB = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charB, byteOffset))); - - // A 32-bit test - even with the bit-twiddling here - is more efficient than a 64-bit test. - ulong temp = valueA | valueB; - if (!AllCharsInUInt32AreAscii((uint)temp | (uint)(temp >> 32))) - { - goto NonAscii; // one of the inputs contains non-ASCII data - } - - // Generally, the caller has likely performed a first-pass check that the input strings - // are likely equal. Consider a dictionary which computes the hash code of its key before - // performing a proper deep equality check of the string contents. We want to optimize for - // the case where the equality check is likely to succeed, which means that we want to avoid - // branching within this loop unless we're about to exit the loop, either due to failure or - // due to us running out of input data. - - if (!UInt64OrdinalIgnoreCaseAscii(valueA, valueB)) - { - return false; - } - - byteOffset += 8; - length -= 4; - } - } - - // Read 2 chars (32 bits) at a time from each string - while ((uint)length >= 2) - { - uint valueA = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charA, byteOffset))); - uint valueB = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charB, byteOffset))); - - if (!AllCharsInUInt32AreAscii(valueA | valueB)) - { - goto NonAscii; // one of the inputs contains non-ASCII data - } - - // Generally, the caller has likely performed a first-pass check that the input strings - // are likely equal. Consider a dictionary which computes the hash code of its key before - // performing a proper deep equality check of the string contents. We want to optimize for - // the case where the equality check is likely to succeed, which means that we want to avoid - // branching within this loop unless we're about to exit the loop, either due to failure or - // due to us running out of input data. - - if (!UInt32OrdinalIgnoreCaseAscii(valueA, valueB)) - { - return false; - } - - byteOffset += 4; - length -= 2; - } - - if (length != 0) - { - Debug.Assert(length == 1); - - uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset); - uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset); - - if ((valueA | valueB) > 0x7Fu) - { - goto NonAscii; // one of the inputs contains non-ASCII data - } - - if (valueA == valueB) - { - return true; // exact match - } - - valueA |= 0x20u; - if ((uint)(valueA - 'a') > (uint)('z' - 'a')) - { - return false; // not exact match, and first input isn't in [A-Za-z] - } - - // The ternary operator below seems redundant but helps RyuJIT generate more optimal code. - // See https://github.com/dotnet/coreclr/issues/914. - return (valueA == (valueB | 0x20u)) ? true : false; - } - - Debug.Assert(length == 0); - return true; - - NonAscii: - // The non-ASCII case is factored out into its own helper method so that the JIT - // doesn't need to emit a complex prolog for its caller (this method). - return EqualsOrdinalIgnoreCaseNonAscii(ref Unsafe.AddByteOffset(ref charA, byteOffset), ref Unsafe.AddByteOffset(ref charB, byteOffset), length); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool AllCharsInUInt32AreAscii(uint value) - { - return (value & ~0x007F_007Fu) == 0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool AllCharsInUInt64AreAscii(ulong value) - { - return (value & ~0x007F_007F_007F_007Ful) == 0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool UInt32OrdinalIgnoreCaseAscii(uint valueA, uint valueB) - { - // ASSUMPTION: Caller has validated that input values are ASCII. - Debug.Assert(AllCharsInUInt32AreAscii(valueA)); - Debug.Assert(AllCharsInUInt32AreAscii(valueB)); - - // a mask of all bits which are different between A and B - uint differentBits = valueA ^ valueB; - - // the 0x80 bit of each word of 'lowerIndicator' will be set iff the word has value < 'A' - uint lowerIndicator = valueA + 0x0100_0100u - 0x0041_0041u; - - // the 0x80 bit of each word of 'upperIndicator' will be set iff (word | 0x20) has value > 'z' - uint upperIndicator = (valueA | 0x0020_0020u) + 0x0080_0080u - 0x007B_007Bu; - - // the 0x80 bit of each word of 'combinedIndicator' will be set iff the word is *not* [A-Za-z] - uint combinedIndicator = lowerIndicator | upperIndicator; - - // Shift all the 0x80 bits of 'combinedIndicator' into the 0x20 positions, then set all bits - // aside from 0x20. This creates a mask where all bits are set *except* for the 0x20 bits - // which correspond to alpha chars (either lower or upper). For these alpha chars only, the - // 0x20 bit is allowed to differ between the two input values. Every other char must be an - // exact bitwise match between the two input values. In other words, (valueA & mask) will - // convert valueA to uppercase, so (valueA & mask) == (valueB & mask) answers "is the uppercase - // form of valueA equal to the uppercase form of valueB?" (Technically if valueA has an alpha - // char in the same position as a non-alpha char in valueB, or vice versa, this operation will - // result in nonsense, but it'll still compute as inequal regardless, which is what we want ultimately.) - // The line below is a more efficient way of doing the same check taking advantage of the XOR - // computation we performed at the beginning of the method. - - return (((combinedIndicator >> 2) | ~0x0020_0020u) & differentBits) == 0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool UInt64OrdinalIgnoreCaseAscii(ulong valueA, ulong valueB) - { - // ASSUMPTION: Caller has validated that input values are ASCII. - Debug.Assert(AllCharsInUInt64AreAscii(valueA)); - Debug.Assert(AllCharsInUInt64AreAscii(valueB)); - - // the 0x80 bit of each word of 'lowerIndicator' will be set iff the word has value >= 'A' - ulong lowerIndicator = valueA + 0x0080_0080_0080_0080ul - 0x0041_0041_0041_0041ul; - - // the 0x80 bit of each word of 'upperIndicator' will be set iff (word | 0x20) has value <= 'z' - ulong upperIndicator = (valueA | 0x0020_0020_0020_0020ul) + 0x0100_0100_0100_0100ul - 0x007B_007B_007B_007Bul; - - // the 0x20 bit of each word of 'combinedIndicator' will be set iff the word is [A-Za-z] - ulong combinedIndicator = (0x0080_0080_0080_0080ul & lowerIndicator & upperIndicator) >> 2; - - // Convert both values to lowercase (using the combined indicator from the first value) - // and compare for equality. It's possible that the first value will contain an alpha character - // where the second value doesn't (or vice versa), and applying the combined indicator will - // create nonsensical data, but the comparison would have failed anyway in this case so it's - // a safe operation to perform. - // - // This 64-bit method is similar to the 32-bit method, but it performs the equivalent of convert-to- - // lowercase-then-compare rather than convert-to-uppercase-and-compare. This particular operation - // happens to be faster on x64. - - return (valueA | combinedIndicator) == (valueB | combinedIndicator); - } - - private static bool EqualsOrdinalIgnoreCaseNonAscii(ref char charA, ref char charB, int length) - { - //if (!GlobalizationMode.Invariant) - //{ - // return CompareStringOrdinalIgnoreCase(ref charA, length, ref charB, length) == 0; - //} - //else - { - // If we don't have localization tables to consult, we'll still perform a case-insensitive - // check for ASCII characters, but if we see anything outside the ASCII range we'll immediately - // fail if it doesn't have true bitwise equality. - - IntPtr byteOffset = IntPtr.Zero; - while (length != 0) - { - // Ordinal equals or lowercase equals if the result ends up in the a-z range - uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset); - uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset); - - if (valueA == valueB || - ((valueA | 0x20) == (valueB | 0x20) && - (uint)((valueA | 0x20) - 'a') <= (uint)('z' - 'a'))) - { - byteOffset += 2; - length--; - } - else - { - return false; - } - } - - return true; - } - } - } -} diff --git a/Plugins/ZString/Number/InternalSpanEx.cs.meta b/Plugins/ZString/Number/InternalSpanEx.cs.meta deleted file mode 100644 index 2a5d4c61..00000000 --- a/Plugins/ZString/Number/InternalSpanEx.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 35ddb60e00efb154aa26c3d822b656eb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/MathEx.cs b/Plugins/ZString/Number/MathEx.cs deleted file mode 100644 index b3a047c9..00000000 --- a/Plugins/ZString/Number/MathEx.cs +++ /dev/null @@ -1,263 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Text; - -namespace System -{ - internal static class MathEx - { - public static uint DivRem(uint a, uint b, out uint result) - { - uint div = a / b; - result = a - (div * b); - return div; - } - - public static ulong DivRem(ulong a, ulong b, out ulong result) - { - ulong div = a / b; - result = a - (div * b); - return div; - } - - public static int DivRem(int a, int b, out int result) - { - int div = a / b; - result = a - (div * b); - return div; - } - - public static long DivRem(long a, long b, out long result) - { - long div = a / b; - result = a - (div * b); - return div; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte Clamp(byte value, byte min, byte max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static decimal Clamp(decimal value, decimal min, decimal max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Clamp(double value, double min, double max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short Clamp(short value, short min, short max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Clamp(int value, int min, int max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long Clamp(long value, long min, long max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static sbyte Clamp(sbyte value, sbyte min, sbyte max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Clamp(float value, float min, float max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort Clamp(ushort value, ushort min, ushort max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint Clamp(uint value, uint min, uint max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong Clamp(ulong value, ulong min, ulong max) - { - if (min > max) - { - ThrowMinMaxException(min, max); - } - - if (value < min) - { - return min; - } - else if (value > max) - { - return max; - } - - return value; - } - - private static void ThrowMinMaxException(T min, T max) - { - throw new ArgumentException($"Argument_MinMaxValue, min:{min} max:{max}"); - } - } -} diff --git a/Plugins/ZString/Number/MathEx.cs.meta b/Plugins/ZString/Number/MathEx.cs.meta deleted file mode 100644 index 224255b0..00000000 --- a/Plugins/ZString/Number/MathEx.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7b74132cfedcf0e428e2b0760181072f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/Number.BigInteger.cs b/Plugins/ZString/Number/Number.BigInteger.cs deleted file mode 100644 index 686367d0..00000000 --- a/Plugins/ZString/Number/Number.BigInteger.cs +++ /dev/null @@ -1,1222 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System -{ - internal static partial class Number - { - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal unsafe ref struct BigInteger - { - // The longest binary mantissa requires: explicit mantissa bits + abs(min exponent) - // * Half: 10 + 14 = 24 - // * Single: 23 + 126 = 149 - // * Double: 52 + 1022 = 1074 - // * Quad: 112 + 16382 = 16494 - private const int BitsForLongestBinaryMantissa = 1074; - - // The longest digit sequence requires: ceil(log2(pow(10, max significant digits + 1 rounding digit))) - // * Half: ceil(log2(pow(10, 21 + 1))) = 74 - // * Single: ceil(log2(pow(10, 112 + 1))) = 376 - // * Double: ceil(log2(pow(10, 767 + 1))) = 2552 - // * Quad: ceil(log2(pow(10, 11563 + 1))) = 38415 - private const int BitsForLongestDigitSequence = 2552; - - // We require BitsPerBlock additional bits for shift space used during the pre-division preparation - private const int MaxBits = BitsForLongestBinaryMantissa + BitsForLongestDigitSequence + BitsPerBlock; - - private const int BitsPerBlock = sizeof(int) * 8; - private const int MaxBlockCount = (MaxBits + (BitsPerBlock - 1)) / BitsPerBlock; - - private static readonly uint[] s_Pow10UInt32Table = new uint[] - { - 1, // 10^0 - 10, // 10^1 - 100, // 10^2 - 1000, // 10^3 - 10000, // 10^4 - 100000, // 10^5 - 1000000, // 10^6 - 10000000, // 10^7 - }; - - private static readonly int[] s_Pow10BigNumTableIndices = new int[] - { - 0, // 10^8 - 2, // 10^16 - 5, // 10^32 - 10, // 10^64 - 18, // 10^128 - 33, // 10^256 - 61, // 10^512 - 116, // 10^1024 - }; - - private static readonly uint[] s_Pow10BigNumTable = new uint[] - { - // 10^8 - 1, // _length - 100000000, // _blocks - - // 10^16 - 2, // _length - 0x6FC10000, // _blocks - 0x002386F2, - - // 10^32 - 4, // _length - 0x00000000, // _blocks - 0x85ACEF81, - 0x2D6D415B, - 0x000004EE, - - // 10^64 - 7, // _length - 0x00000000, // _blocks - 0x00000000, - 0xBF6A1F01, - 0x6E38ED64, - 0xDAA797ED, - 0xE93FF9F4, - 0x00184F03, - - // 10^128 - 14, // _length - 0x00000000, // _blocks - 0x00000000, - 0x00000000, - 0x00000000, - 0x2E953E01, - 0x03DF9909, - 0x0F1538FD, - 0x2374E42F, - 0xD3CFF5EC, - 0xC404DC08, - 0xBCCDB0DA, - 0xA6337F19, - 0xE91F2603, - 0x0000024E, - - // 10^256 - 27, // _length - 0x00000000, // _blocks - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x982E7C01, - 0xBED3875B, - 0xD8D99F72, - 0x12152F87, - 0x6BDE50C6, - 0xCF4A6E70, - 0xD595D80F, - 0x26B2716E, - 0xADC666B0, - 0x1D153624, - 0x3C42D35A, - 0x63FF540E, - 0xCC5573C0, - 0x65F9EF17, - 0x55BC28F2, - 0x80DCC7F7, - 0xF46EEDDC, - 0x5FDCEFCE, - 0x000553F7, - - // 10^512 - 54, // _length - 0x00000000, // _blocks - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xFC6CF801, - 0x77F27267, - 0x8F9546DC, - 0x5D96976F, - 0xB83A8A97, - 0xC31E1AD9, - 0x46C40513, - 0x94E65747, - 0xC88976C1, - 0x4475B579, - 0x28F8733B, - 0xAA1DA1BF, - 0x703ED321, - 0x1E25CFEA, - 0xB21A2F22, - 0xBC51FB2E, - 0x96E14F5D, - 0xBFA3EDAC, - 0x329C57AE, - 0xE7FC7153, - 0xC3FC0695, - 0x85A91924, - 0xF95F635E, - 0xB2908EE0, - 0x93ABADE4, - 0x1366732A, - 0x9449775C, - 0x69BE5B0E, - 0x7343AFAC, - 0xB099BC81, - 0x45A71D46, - 0xA2699748, - 0x8CB07303, - 0x8A0B1F13, - 0x8CAB8A97, - 0xC1D238D9, - 0x633415D4, - 0x0000001C, - - // 10^1024 - 107, // _length - 0x00000000, // _blocks - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x2919F001, - 0xF55B2B72, - 0x6E7C215B, - 0x1EC29F86, - 0x991C4E87, - 0x15C51A88, - 0x140AC535, - 0x4C7D1E1A, - 0xCC2CD819, - 0x0ED1440E, - 0x896634EE, - 0x7DE16CFB, - 0x1E43F61F, - 0x9FCE837D, - 0x231D2B9C, - 0x233E55C7, - 0x65DC60D7, - 0xF451218B, - 0x1C5CD134, - 0xC9635986, - 0x922BBB9F, - 0xA7E89431, - 0x9F9F2A07, - 0x62BE695A, - 0x8E1042C4, - 0x045B7A74, - 0x1ABE1DE3, - 0x8AD822A5, - 0xBA34C411, - 0xD814B505, - 0xBF3FDEB3, - 0x8FC51A16, - 0xB1B896BC, - 0xF56DEEEC, - 0x31FB6BFD, - 0xB6F4654B, - 0x101A3616, - 0x6B7595FB, - 0xDC1A47FE, - 0x80D98089, - 0x80BDA5A5, - 0x9A202882, - 0x31EB0F66, - 0xFC8F1F90, - 0x976A3310, - 0xE26A7B7E, - 0xDF68368A, - 0x3CE3A0B8, - 0x8E4262CE, - 0x75A351A2, - 0x6CB0B6C9, - 0x44597583, - 0x31B5653F, - 0xC356E38A, - 0x35FAABA6, - 0x0190FBA0, - 0x9FC4ED52, - 0x88BC491B, - 0x1640114A, - 0x005B8041, - 0xF4F3235E, - 0x1E8D4649, - 0x36A8DE06, - 0x73C55349, - 0xA7E6BD2A, - 0xC1A6970C, - 0x47187094, - 0xD2DB49EF, - 0x926C3F5B, - 0xAE6209D4, - 0x2D433949, - 0x34F4A3C6, - 0xD4305D94, - 0xD9D61A05, - 0x00000325, - - // 9 Trailing blocks to ensure MaxBlockCount - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - }; - - private int _length; - private fixed uint _blocks[MaxBlockCount]; - - public static void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result) - { - // determine which operand has the smaller length - ref BigInteger large = ref (lhs._length < rhs._length) ? ref rhs : ref lhs; - ref BigInteger small = ref (lhs._length < rhs._length) ? ref lhs : ref rhs; - - int largeLength = large._length; - int smallLength = small._length; - - // The output will be at least as long as the largest input - result._length = largeLength; - - // Add each block and add carry the overflow to the next block - ulong carry = 0; - - int largeIndex = 0; - int smallIndex = 0; - int resultIndex = 0; - - while (smallIndex < smallLength) - { - ulong sum = carry + large._blocks[largeIndex] + small._blocks[smallIndex]; - carry = sum >> 32; - result._blocks[resultIndex] = (uint)(sum); - - largeIndex++; - smallIndex++; - resultIndex++; - } - - // Add the carry to any blocks that only exist in the large operand - while (largeIndex < largeLength) - { - ulong sum = carry + large._blocks[largeIndex]; - carry = sum >> 32; - result._blocks[resultIndex] = (uint)(sum); - - largeIndex++; - resultIndex++; - } - - // If there's still a carry, append a new block - if (carry != 0) - { - Debug.Assert(carry == 1); - Debug.Assert((resultIndex == largeLength) && (largeLength < MaxBlockCount)); - - result._blocks[resultIndex] = 1; - result._length++; - } - } - - public static int Compare(ref BigInteger lhs, ref BigInteger rhs) - { - Debug.Assert(unchecked((uint)(lhs._length)) <= MaxBlockCount); - Debug.Assert(unchecked((uint)(rhs._length)) <= MaxBlockCount); - - int lhsLength = lhs._length; - int rhsLength = rhs._length; - - int lengthDelta = (lhsLength - rhsLength); - - if (lengthDelta != 0) - { - return lengthDelta; - } - - if (lhsLength == 0) - { - Debug.Assert(rhsLength == 0); - return 0; - } - - for (int index = (lhsLength - 1); index >= 0; index--) - { - long delta = (long)(lhs._blocks[index]) - rhs._blocks[index]; - - if (delta != 0) - { - return delta > 0 ? 1 : -1; - } - } - - return 0; - } - - public static uint CountSignificantBits(uint value) - { - return 32 - (uint)BitOperations.LeadingZeroCount(value); - } - - public static uint CountSignificantBits(ulong value) - { - return 64 - (uint)BitOperations.LeadingZeroCount(value); - } - - public static uint CountSignificantBits(ref BigInteger value) - { - if (value.IsZero()) - { - return 0; - } - - // We don't track any unused blocks, so we only need to do a BSR on the - // last index and add that to the number of bits we skipped. - - uint lastIndex = (uint)(value._length - 1); - return (lastIndex * BitsPerBlock) + CountSignificantBits(value._blocks[lastIndex]); - } - - public static void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger quo, out BigInteger rem) - { - // This is modified from the libraries BigIntegerCalculator.DivRem.cs implementation: - // https://github.com/dotnet/runtime/blob/master/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs - - Debug.Assert(!rhs.IsZero()); - - if (lhs.IsZero()) - { - SetZero(out quo); - SetZero(out rem); - return; - } - - int lhsLength = lhs._length; - int rhsLength = rhs._length; - - if ((lhsLength == 1) && (rhsLength == 1)) - { - uint quotient = MathEx.DivRem(lhs._blocks[0], rhs._blocks[0], out uint remainder); - SetUInt32(out quo, quotient); - SetUInt32(out rem, remainder); - return; - } - - if (rhsLength == 1) - { - // We can make the computation much simpler if the rhs is only one block - - int quoLength = lhsLength; - - ulong rhsValue = rhs._blocks[0]; - ulong carry = 0; - - for (int i = quoLength - 1; i >= 0; i--) - { - ulong value = (carry << 32) | lhs._blocks[i]; - ulong digit = MathEx.DivRem(value, rhsValue, out carry); - - if ((digit == 0) && (i == (quoLength - 1))) - { - quoLength--; - } - else - { - quo._blocks[i] = (uint)(digit); - } - } - - quo._length = quoLength; - SetUInt32(out rem, (uint)(carry)); - - return; - } - else if (rhsLength > lhsLength) - { - // Handle the case where we have no quotient - SetZero(out quo); - SetValue(out rem, ref lhs); - return; - } - else - { - int quoLength = lhsLength - rhsLength + 1; - SetValue(out rem, ref lhs); - int remLength = lhsLength; - - // Executes the "grammar-school" algorithm for computing q = a / b. - // Before calculating q_i, we get more bits into the highest bit - // block of the divisor. Thus, guessing digits of the quotient - // will be more precise. Additionally we'll get r = a % b. - - uint divHi = rhs._blocks[rhsLength - 1]; - uint divLo = rhs._blocks[rhsLength - 2]; - - // We measure the leading zeros of the divisor - int shiftLeft = BitOperations.LeadingZeroCount(divHi); - int shiftRight = 32 - shiftLeft; - - // And, we make sure the most significant bit is set - if (shiftLeft > 0) - { - divHi = (divHi << shiftLeft) | (divLo >> shiftRight); - divLo <<= shiftLeft; - - if (rhsLength > 2) - { - divLo |= (rhs._blocks[rhsLength - 3] >> shiftRight); - } - } - - // Then, we divide all of the bits as we would do it using - // pen and paper: guessing the next digit, subtracting, ... - for (int i = lhsLength; i >= rhsLength; i--) - { - int n = i - rhsLength; - uint t = i < lhsLength ? rem._blocks[i] : 0; - - ulong valHi = ((ulong)(t) << 32) | rem._blocks[i - 1]; - uint valLo = i > 1 ? rem._blocks[i - 2] : 0; - - // We shifted the divisor, we shift the dividend too - if (shiftLeft > 0) - { - valHi = (valHi << shiftLeft) | (valLo >> shiftRight); - valLo <<= shiftLeft; - - if (i > 2) - { - valLo |= (rem._blocks[i - 3] >> shiftRight); - } - } - - // First guess for the current digit of the quotient, - // which naturally must have only 32 bits... - ulong digit = valHi / divHi; - - if (digit > uint.MaxValue) - { - digit = uint.MaxValue; - } - - // Our first guess may be a little bit to big - while (DivideGuessTooBig(digit, valHi, valLo, divHi, divLo)) - { - digit--; - } - - if (digit > 0) - { - // Now it's time to subtract our current quotient - uint carry = SubtractDivisor(ref rem, n, ref rhs, digit); - - if (carry != t) - { - Debug.Assert(carry == t + 1); - - // Our guess was still exactly one too high - carry = AddDivisor(ref rem, n, ref rhs); - digit--; - - Debug.Assert(carry == 1); - } - } - - // We have the digit! - if (quoLength != 0) - { - if ((digit == 0) && (n == (quoLength - 1))) - { - quoLength--; - } - else - { - quo._blocks[n] = (uint)(digit); - } - } - - if (i < remLength) - { - remLength--; - } - } - - quo._length = quoLength; - - // We need to check for the case where remainder is zero - - for (int i = remLength - 1; i >= 0; i--) - { - if (rem._blocks[i] == 0) - { - remLength--; - } - } - - rem._length = remLength; - } - } - - public static uint HeuristicDivide(ref BigInteger dividend, ref BigInteger divisor) - { - int divisorLength = divisor._length; - - if (dividend._length < divisorLength) - { - return 0; - } - - // This is an estimated quotient. Its error should be less than 2. - // Reference inequality: - // a/b - floor(floor(a)/(floor(b) + 1)) < 2 - int lastIndex = (divisorLength - 1); - uint quotient = dividend._blocks[lastIndex] / (divisor._blocks[lastIndex] + 1); - - if (quotient != 0) - { - // Now we use our estimated quotient to update each block of dividend. - // dividend = dividend - divisor * quotient - int index = 0; - - ulong borrow = 0; - ulong carry = 0; - - do - { - ulong product = ((ulong)(divisor._blocks[index]) * quotient) + carry; - carry = product >> 32; - - ulong difference = (ulong)(dividend._blocks[index]) - (uint)(product) - borrow; - borrow = (difference >> 32) & 1; - - dividend._blocks[index] = (uint)(difference); - - index++; - } - while (index < divisorLength); - - // Remove all leading zero blocks from dividend - while ((divisorLength > 0) && (dividend._blocks[divisorLength - 1] == 0)) - { - divisorLength--; - } - - dividend._length = divisorLength; - } - - // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct, - // we increment the quotient and subtract one more divisor from the dividend (Because we guaranteed the error range). - if (Compare(ref dividend, ref divisor) >= 0) - { - quotient++; - - // dividend = dividend - divisor - int index = 0; - ulong borrow = 0; - - do - { - ulong difference = (ulong)(dividend._blocks[index]) - divisor._blocks[index] - borrow; - borrow = (difference >> 32) & 1; - - dividend._blocks[index] = (uint)(difference); - - index++; - } - while (index < divisorLength); - - // Remove all leading zero blocks from dividend - while ((divisorLength > 0) && (dividend._blocks[divisorLength - 1] == 0)) - { - divisorLength--; - } - - dividend._length = divisorLength; - } - - return quotient; - } - - public static void Multiply(ref BigInteger lhs, uint value, out BigInteger result) - { - if (lhs.IsZero() || (value == 1)) - { - SetValue(out result, ref lhs); - return; - } - - if (value == 0) - { - SetZero(out result); - return; - } - - int lhsLength = lhs._length; - int index = 0; - uint carry = 0; - - while (index < lhsLength) - { - ulong product = ((ulong)(lhs._blocks[index]) * value) + carry; - result._blocks[index] = (uint)(product); - carry = (uint)(product >> 32); - - index++; - } - - if (carry != 0) - { - Debug.Assert(unchecked((uint)(lhsLength)) + 1 <= MaxBlockCount); - result._blocks[index] = carry; - result._length = (lhsLength + 1); - } - else - { - result._length = lhsLength; - } - } - - public static void Multiply(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result) - { - if (lhs.IsZero() || rhs.IsOne()) - { - SetValue(out result, ref lhs); - return; - } - - if (rhs.IsZero()) - { - SetZero(out result); - return; - } - - ref readonly BigInteger large = ref lhs; - int largeLength = lhs._length; - - ref readonly BigInteger small = ref rhs; - int smallLength = rhs._length; - - if (largeLength < smallLength) - { - large = ref rhs; - largeLength = rhs._length; - - small = ref lhs; - smallLength = lhs._length; - } - - int maxResultLength = smallLength + largeLength; - Debug.Assert(unchecked((uint)(maxResultLength)) <= MaxBlockCount); - - // Zero out result internal blocks. - result._length = maxResultLength; - BufferEx.ZeroMemory((byte*)result.GetBlocksPointer(), (uint)maxResultLength * sizeof(uint)); - - int smallIndex = 0; - int resultStartIndex = 0; - - while (smallIndex < smallLength) - { - // Multiply each block of large BigNum. - if (small._blocks[smallIndex] != 0) - { - int largeIndex = 0; - int resultIndex = resultStartIndex; - - ulong carry = 0; - - do - { - ulong product = result._blocks[resultIndex] + ((ulong)(small._blocks[smallIndex]) * large._blocks[largeIndex]) + carry; - carry = product >> 32; - result._blocks[resultIndex] = (uint)(product); - - resultIndex++; - largeIndex++; - } - while (largeIndex < largeLength); - - result._blocks[resultIndex] = (uint)(carry); - } - - smallIndex++; - resultStartIndex++; - } - - if ((maxResultLength > 0) && (result._blocks[maxResultLength - 1] == 0)) - { - result._length--; - } - } - - public static void Pow2(uint exponent, out BigInteger result) - { - uint blocksToShift = DivRem32(exponent, out uint remainingBitsToShift); - result._length = (int)blocksToShift + 1; - Debug.Assert(unchecked((uint)result._length) <= MaxBlockCount); - if (blocksToShift > 0) - { - BufferEx.ZeroMemory((byte*)result.GetBlocksPointer(), blocksToShift * sizeof(uint)); - } - result._blocks[blocksToShift] = 1U << (int)(remainingBitsToShift); - } - - public static void Pow10(uint exponent, out BigInteger result) - { - // We leverage two arrays - s_Pow10UInt32Table and s_Pow10BigNumTable to speed up the Pow10 calculation. - // - // s_Pow10UInt32Table stores the results of 10^0 to 10^7. - // s_Pow10BigNumTable stores the results of 10^8, 10^16, 10^32, 10^64, 10^128, 10^256, and 10^512 - // - // For example, let's say exp = 0b111111. We can split the exp to two parts, one is small exp, - // which 10^smallExp can be represented as uint, another part is 10^bigExp, which must be represented as BigNum. - // So the result should be 10^smallExp * 10^bigExp. - // - // Calculating 10^smallExp is simple, we just lookup the 10^smallExp from s_Pow10UInt32Table. - // But here's a bad news: although uint can represent 10^9, exp 9's binary representation is 1001. - // That means 10^(1011), 10^(1101), 10^(1111) all cannot be stored as uint, we cannot easily say something like: - // "Any bits <= 3 is small exp, any bits > 3 is big exp". So instead of involving 10^8, 10^9 to s_Pow10UInt32Table, - // consider 10^8 and 10^9 as a bigNum, so they fall into s_Pow10BigNumTable. Now we can have a simple rule: - // "Any bits <= 3 is small exp, any bits > 3 is big exp". - // - // For 0b111111, we first calculate 10^(smallExp), which is 10^(7), now we can shift right 3 bits, prepare to calculate the bigExp part, - // the exp now becomes 0b000111. - // - // Apparently the lowest bit of bigExp should represent 10^8 because we have already shifted 3 bits for smallExp, so s_Pow10BigNumTable[0] = 10^8. - // Now let's shift exp right 1 bit, the lowest bit should represent 10^(8 * 2) = 10^16, and so on... - // - // That's why we just need the values of s_Pow10BigNumTable be power of 2. - // - // More details of this implementation can be found at: https://github.com/dotnet/coreclr/pull/12894#discussion_r128890596 - - // Validate that `s_Pow10BigNumTable` has exactly enough trailing elements to fill a BigInteger (which contains MaxBlockCount + 1 elements) - // We validate here, since this is the only current consumer of the array - Debug.Assert((s_Pow10BigNumTableIndices[s_Pow10BigNumTableIndices.Length - 1] + MaxBlockCount + 2) == s_Pow10BigNumTable.Length); - - SetUInt32(out BigInteger temp1, s_Pow10UInt32Table[exponent & 0x7]); - ref BigInteger lhs = ref temp1; - - SetZero(out BigInteger temp2); - ref BigInteger product = ref temp2; - - exponent >>= 3; - uint index = 0; - - while (exponent != 0) - { - // If the current bit is set, multiply it with the corresponding power of 10 - if ((exponent & 1) != 0) - { - // Multiply into the next temporary - fixed (uint* pBigNumEntry = &s_Pow10BigNumTable[s_Pow10BigNumTableIndices[index]]) - { - ref BigInteger rhs = ref *(BigInteger*)(pBigNumEntry); - Multiply(ref lhs, ref rhs, out product); - } - - // Swap to the next temporary - ref BigInteger temp = ref product; - product = ref lhs; - lhs = ref temp; - } - - // Advance to the next bit - ++index; - exponent >>= 1; - } - - SetValue(out result, ref lhs); - } - - private static uint AddDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs) - { - int lhsLength = lhs._length; - int rhsLength = rhs._length; - - Debug.Assert(lhsLength >= 0); - Debug.Assert(rhsLength >= 0); - Debug.Assert(lhsLength >= rhsLength); - - // Repairs the dividend, if the last subtract was too much - - ulong carry = 0UL; - - for (int i = 0; i < rhsLength; i++) - { - ref uint lhsValue = ref lhs._blocks[lhsStartIndex + i]; - - ulong digit = lhsValue + carry + rhs._blocks[i]; - lhsValue = unchecked((uint)digit); - carry = digit >> 32; - } - - return (uint)(carry); - } - - private static bool DivideGuessTooBig(ulong q, ulong valHi, uint valLo, uint divHi, uint divLo) - { - Debug.Assert(q <= 0xFFFFFFFF); - - // We multiply the two most significant limbs of the divisor - // with the current guess for the quotient. If those are bigger - // than the three most significant limbs of the current dividend - // we return true, which means the current guess is still too big. - - ulong chkHi = divHi * q; - ulong chkLo = divLo * q; - - chkHi += (chkLo >> 32); - chkLo &= uint.MaxValue; - - if (chkHi < valHi) - return false; - - if (chkHi > valHi) - return true; - - if (chkLo < valLo) - return false; - - if (chkLo > valLo) - return true; - - return false; - } - - private static uint SubtractDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs, ulong q) - { - int lhsLength = lhs._length - lhsStartIndex; - int rhsLength = rhs._length; - - Debug.Assert(lhsLength >= 0); - Debug.Assert(rhsLength >= 0); - Debug.Assert(lhsLength >= rhsLength); - Debug.Assert(q <= uint.MaxValue); - - // Combines a subtract and a multiply operation, which is naturally - // more efficient than multiplying and then subtracting... - - ulong carry = 0; - - for (int i = 0; i < rhsLength; i++) - { - carry += rhs._blocks[i] * q; - uint digit = unchecked((uint)carry); - carry >>= 32; - - ref uint lhsValue = ref lhs._blocks[lhsStartIndex + i]; - - if (lhsValue < digit) - { - carry++; - } - - lhsValue = unchecked(lhsValue - digit); - } - - return (uint)(carry); - } - - public void Add(uint value) - { - int length = _length; - if (length == 0) - { - SetUInt32(out this, value); - return; - } - - _blocks[0] += value; - if (_blocks[0] >= value) - { - // No carry - return; - } - - for (int index = 1; index < length; index++) - { - _blocks[index]++; - if (_blocks[index] > 0) - { - // No carry - return; - } - } - - Debug.Assert(unchecked((uint)(length)) + 1 <= MaxBlockCount); - _blocks[length] = 1; - _length = length + 1; - } - - public uint GetBlock(uint index) - { - Debug.Assert(index < _length); - return _blocks[index]; - } - - public int GetLength() - { - return _length; - } - - public bool IsOne() - { - return (_length == 1) - && (_blocks[0] == 1); - } - - public bool IsZero() - { - return _length == 0; - } - - public void Multiply(uint value) - { - Multiply(ref this, value, out this); - } - - public void Multiply(ref BigInteger value) - { - SetValue(out BigInteger temp, ref this); - Multiply(ref temp, ref value, out this); - } - - public void Multiply10() - { - if (IsZero()) - { - return; - } - - int index = 0; - int length = _length; - ulong carry = 0; - - while (index < length) - { - ulong block = (ulong)(_blocks[index]); - ulong product = (block << 3) + (block << 1) + carry; - carry = product >> 32; - _blocks[index] = (uint)(product); - - index++; - } - - if (carry != 0) - { - Debug.Assert(unchecked((uint)(_length)) + 1 <= MaxBlockCount); - _blocks[index] = (uint)carry; - _length++; - } - } - - public void MultiplyPow10(uint exponent) - { - if (IsZero()) - { - return; - } - - Pow10(exponent, out BigInteger poweredValue); - - if (poweredValue._length == 1) - { - Multiply(poweredValue._blocks[0]); - } - else - { - Multiply(ref poweredValue); - } - } - - public static void SetUInt32(out BigInteger result, uint value) - { - if (value == 0) - { - SetZero(out result); - } - else - { - result._blocks[0] = value; - result._length = 1; - } - } - - public static void SetUInt64(out BigInteger result, ulong value) - { - if (value <= uint.MaxValue) - { - SetUInt32(out result, (uint)(value)); - } - else - { - result._blocks[0] = (uint)(value); - result._blocks[1] = (uint)(value >> 32); - - result._length = 2; - } - } - - public static void SetValue(out BigInteger result, ref BigInteger value) - { - int rhsLength = value._length; - result._length = rhsLength; - BufferEx.Memcpy((byte*)result.GetBlocksPointer(), (byte*)value.GetBlocksPointer(), rhsLength * sizeof(uint)); - } - - public static void SetZero(out BigInteger result) - { - result._length = 0; - } - - public void ShiftLeft(uint shift) - { - // Process blocks high to low so that we can safely process in place - int length = _length; - - if ((length == 0) || (shift == 0)) - { - return; - } - - uint blocksToShift = DivRem32(shift, out uint remainingBitsToShift); - - // Copy blocks from high to low - int readIndex = (length - 1); - int writeIndex = readIndex + (int)(blocksToShift); - - // Check if the shift is block aligned - if (remainingBitsToShift == 0) - { - Debug.Assert(writeIndex < MaxBlockCount); - - while (readIndex >= 0) - { - _blocks[writeIndex] = _blocks[readIndex]; - readIndex--; - writeIndex--; - } - - _length += (int)(blocksToShift); - - // Zero the remaining low blocks - BufferEx.ZeroMemory((byte*)GetBlocksPointer(), blocksToShift * sizeof(uint)); - } - else - { - // We need an extra block for the partial shift - writeIndex++; - Debug.Assert(writeIndex < MaxBlockCount); - - // Set the length to hold the shifted blocks - _length = writeIndex + 1; - - // Output the initial blocks - uint lowBitsShift = (32 - remainingBitsToShift); - uint highBits = 0; - uint block = _blocks[readIndex]; - uint lowBits = block >> (int)(lowBitsShift); - while (readIndex > 0) - { - _blocks[writeIndex] = highBits | lowBits; - highBits = block << (int)(remainingBitsToShift); - - --readIndex; - --writeIndex; - - block = _blocks[readIndex]; - lowBits = block >> (int)lowBitsShift; - } - - // Output the final blocks - _blocks[writeIndex] = highBits | lowBits; - _blocks[writeIndex - 1] = block << (int)(remainingBitsToShift); - - // Zero the remaining low blocks - BufferEx.ZeroMemory((byte*)GetBlocksPointer(), blocksToShift * sizeof(uint)); - - // Check if the terminating block has no set bits - if (_blocks[_length - 1] == 0) - { - _length--; - } - } - } - - public ulong ToUInt64() - { - if (_length > 1) - { - return ((ulong)(_blocks[1]) << 32) + _blocks[0]; - } - - if (_length > 0) - { - return _blocks[0]; - } - - return 0; - } - - private uint* GetBlocksPointer() - { - // This is safe to do since we are a ref struct - return (uint*)(Unsafe.AsPointer(ref _blocks[0])); - } - - private static uint DivRem32(uint value, out uint remainder) - { - remainder = value & 31; - return value >> 5; - } - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/Number.BigInteger.cs.meta b/Plugins/ZString/Number/Number.BigInteger.cs.meta deleted file mode 100644 index e4bf867f..00000000 --- a/Plugins/ZString/Number/Number.BigInteger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6ee7ab6f12adee945a329388c6efd7cb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/Number.DiyFp.cs b/Plugins/ZString/Number/Number.DiyFp.cs deleted file mode 100644 index 562dd9a1..00000000 --- a/Plugins/ZString/Number/Number.DiyFp.cs +++ /dev/null @@ -1,157 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Numerics; - -namespace System -{ - internal static partial class Number - { - // This is a port of the `DiyFp` implementation here: https://github.com/google/double-conversion/blob/a711666ddd063eb1e4b181a6cb981d39a1fc8bac/double-conversion/diy-fp.h - // The backing structure and how it is used is described in more detail here: http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf - - // This "Do It Yourself Floating Point" class implements a floating-point number with a ulong significand and an int exponent. - // Normalized DiyFp numbers will have the most significant bit of the significand set. - // Multiplication and Subtraction do not normalize their results. - // DiyFp are not designed to contain special doubles (NaN and Infinity). - internal readonly ref struct DiyFp - { - public const int DoubleImplicitBitIndex = 52; - public const int SingleImplicitBitIndex = 23; - - public const int SignificandSize = 64; - - public readonly ulong f; - public readonly int e; - - // Computes the two boundaries of value. - // - // The bigger boundary (mPlus) is normalized. - // The lower boundary has the same exponent as mPlus. - // - // Precondition: - // The value encoded by value must be greater than 0. - public static DiyFp CreateAndGetBoundaries(double value, out DiyFp mMinus, out DiyFp mPlus) - { - var result = new DiyFp(value); - result.GetBoundaries(DoubleImplicitBitIndex, out mMinus, out mPlus); - return result; - } - - // Computes the two boundaries of value. - // - // The bigger boundary (mPlus) is normalized. - // The lower boundary has the same exponent as mPlus. - // - // Precondition: - // The value encoded by value must be greater than 0. - public static DiyFp CreateAndGetBoundaries(float value, out DiyFp mMinus, out DiyFp mPlus) - { - var result = new DiyFp(value); - result.GetBoundaries(SingleImplicitBitIndex, out mMinus, out mPlus); - return result; - } - - public DiyFp(double value) - { - //Debug.Assert(double.IsFinite(value)); - Debug.Assert(value > 0.0); - f = ExtractFractionAndBiasedExponent(value, out e); - } - - public DiyFp(float value) - { - //Debug.Assert(float.IsFinite(value)); - Debug.Assert(value > 0.0f); - f = ExtractFractionAndBiasedExponent(value, out e); - } - - public DiyFp(ulong f, int e) - { - this.f = f; - this.e = e; - } - - public DiyFp Multiply(in DiyFp other) - { - // Simply "emulates" a 128-bit multiplication - // - // However: the resulting number only contains 64-bits. The least - // signficant 64-bits are only used for rounding the most significant - // 64-bits. - - uint a = (uint)(f >> 32); - uint b = (uint)(f); - - uint c = (uint)(other.f >> 32); - uint d = (uint)(other.f); - - ulong ac = ((ulong)(a) * c); - ulong bc = ((ulong)(b) * c); - ulong ad = ((ulong)(a) * d); - ulong bd = ((ulong)(b) * d); - - ulong tmp = (bd >> 32) + (uint)(ad) + (uint)(bc); - - // By adding (1UL << 31) to tmp, we round the final result. - // Halfway cases will be rounded up. - - tmp += (1U << 31); - - return new DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + other.e + SignificandSize); - } - - public DiyFp Normalize() - { - // This method is mainly called for normalizing boundaries. - // - // We deviate from the reference implementation by just using - // our LeadingZeroCount function so that we only need to shift - // and subtract once. - - Debug.Assert(f != 0); - int lzcnt = BitOperations.LeadingZeroCount(f); - return new DiyFp(f << lzcnt, e - lzcnt); - } - - // The exponents of both numbers must be the same. - // The significand of 'this' must be bigger than the significand of 'other'. - // The result will not be normalized. - public DiyFp Subtract(in DiyFp other) - { - Debug.Assert(e == other.e); - Debug.Assert(f >= other.f); - return new DiyFp(f - other.f, e); - } - - private void GetBoundaries(int implicitBitIndex, out DiyFp mMinus, out DiyFp mPlus) - { - mPlus = new DiyFp((f << 1) + 1, e - 1).Normalize(); - - // The boundary is closer if the sigificand is of the form: - // f == 2^p-1 - // - // Think of v = 1000e10 and v- = 9999e9 - // Then the boundary == (v - v-) / 2 is not just at a distance of 1e9 but at a distance of 1e8. - // The only exception is for the smallest normal, where the largest denormal is at the same distance as its successor. - // - // Note: denormals have the same exponent as the smallest normals. - - // We deviate from the reference implementation by just checking if the significand has only the implicit bit set. - // In this scenario, we know that all the explicit bits are 0 and that the unbiased exponent is non-zero. - if (f == (1UL << implicitBitIndex)) - { - mMinus = new DiyFp((f << 2) - 1, e - 2); - } - else - { - mMinus = new DiyFp((f << 1) - 1, e - 1); - } - - mMinus = new DiyFp(mMinus.f << (mMinus.e - mPlus.e), mPlus.e); - } - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/Number.DiyFp.cs.meta b/Plugins/ZString/Number/Number.DiyFp.cs.meta deleted file mode 100644 index 240645de..00000000 --- a/Plugins/ZString/Number/Number.DiyFp.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 18a3c3c91bd4899498562233c482e696 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/Number.Dragon4.cs b/Plugins/ZString/Number/Number.Dragon4.cs deleted file mode 100644 index 4831987f..00000000 --- a/Plugins/ZString/Number/Number.Dragon4.cs +++ /dev/null @@ -1,525 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Numerics; -using System.Runtime.CompilerServices; - -namespace System -{ - // This is a port of the `Dragon4` implementation here: http://www.ryanjuckett.com/programming/printing-floating-point-numbers/part-2/ - // The backing algorithm and the proofs behind it are described in more detail here: https://www.cs.indiana.edu/~dyb/pubs/FP-Printing-PLDI96.pdf - internal static partial class Number - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static unsafe bool IsNegative(double d) - { - return BitConverter.DoubleToInt64Bits(d) < 0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe bool IsNegativeInfinity(float f) - { - return f == float.NegativeInfinity; - } - - public static void Dragon4Double(double value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number) - { - double v = IsNegative(value) ? -value : value; - - Debug.Assert(v > 0); - // Debug.Assert(double.IsFinite(v)); - - ulong mantissa = ExtractFractionAndBiasedExponent(value, out int exponent); - - uint mantissaHighBitIdx; - bool hasUnequalMargins = false; - - if ((mantissa >> DiyFp.DoubleImplicitBitIndex) != 0) - { - mantissaHighBitIdx = DiyFp.DoubleImplicitBitIndex; - hasUnequalMargins = (mantissa == (1UL << DiyFp.DoubleImplicitBitIndex)); - } - else - { - Debug.Assert(mantissa != 0); - mantissaHighBitIdx = (uint)BitOperations.Log2(mantissa); - } - - int length = (int)(Dragon4(mantissa, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out int decimalExponent)); - - number.Scale = decimalExponent + 1; - number.Digits[length] = (byte)('\0'); - number.DigitsCount = length; - } - - public static unsafe void Dragon4Single(float value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number) - { - float v = IsNegative(value) ? -value : value; - - Debug.Assert(v > 0); - // Debug.Assert(float.IsFinite(v)); - - uint mantissa = ExtractFractionAndBiasedExponent(value, out int exponent); - - uint mantissaHighBitIdx; - bool hasUnequalMargins = false; - - if ((mantissa >> DiyFp.SingleImplicitBitIndex) != 0) - { - mantissaHighBitIdx = DiyFp.SingleImplicitBitIndex; - hasUnequalMargins = (mantissa == (1U << DiyFp.SingleImplicitBitIndex)); - } - else - { - Debug.Assert(mantissa != 0); - mantissaHighBitIdx = (uint)BitOperations.Log2(mantissa); - } - - int length = (int)(Dragon4(mantissa, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out int decimalExponent)); - - number.Scale = decimalExponent + 1; - number.Digits[length] = (byte)('\0'); - number.DigitsCount = length; - } - - // This is an implementation of the Dragon4 algorithm to convert a binary number in floating-point format to a decimal number in string format. - // The function returns the number of digits written to the output buffer and the output is not NUL terminated. - // - // The floating point input value is (mantissa * 2^exponent). - // - // See the following papers for more information on the algorithm: - // "How to Print Floating-Point Numbers Accurately" - // Steele and White - // http://kurtstephens.com/files/p372-steele.pdf - // "Printing Floating-Point Numbers Quickly and Accurately" - // Burger and Dybvig - // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf - private static unsafe uint Dragon4(ulong mantissa, int exponent, uint mantissaHighBitIdx, bool hasUnequalMargins, int cutoffNumber, bool isSignificantDigits, Span buffer, out int decimalExponent) - { - int curDigit = 0; - - Debug.Assert(buffer.Length > 0); - - // We deviate from the original algorithm and just assert that the mantissa - // is not zero. Comparing to zero is fine since the caller should have set - // the implicit bit of the mantissa, meaning it would only ever be zero if - // the extracted exponent was also zero. And the assertion is fine since we - // require that the DoubleToNumber handle zero itself. - Debug.Assert(mantissa != 0); - - // Compute the initial state in integral form such that - // value = scaledValue / scale - // marginLow = scaledMarginLow / scale - - BigInteger scale; // positive scale applied to value and margin such that they can be represented as whole numbers - BigInteger scaledValue; // scale * mantissa - BigInteger scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its immediate lower value) - - // For normalized IEEE floating-point values, each time the exponent is incremented the margin also doubles. - // That creates a subset of transition numbers where the high margin is twice the size of the low margin. - BigInteger* pScaledMarginHigh; - BigInteger optionalMarginHigh; - - if (hasUnequalMargins) - { - if (exponent > 0) // We have no fractional component - { - // 1) Expand the input value by multiplying out the mantissa and exponent. - // This represents the input value in its whole number representation. - // 2) Apply an additional scale of 2 such that later comparisons against the margin values are simplified. - // 3) Set the margin value to the loweset mantissa bit's scale. - - // scaledValue = 2 * 2 * mantissa * 2^exponent - BigInteger.SetUInt64(out scaledValue, 4 * mantissa); - scaledValue.ShiftLeft((uint)(exponent)); - - // scale = 2 * 2 * 1 - BigInteger.SetUInt32(out scale, 4); - - // scaledMarginLow = 2 * 2^(exponent - 1) - BigInteger.Pow2((uint)(exponent), out scaledMarginLow); - - // scaledMarginHigh = 2 * 2 * 2^(exponent + 1) - BigInteger.Pow2((uint)(exponent + 1), out optionalMarginHigh); - } - else // We have a fractional exponent - { - // In order to track the mantissa data as an integer, we store it as is with a large scale - - // scaledValue = 2 * 2 * mantissa - BigInteger.SetUInt64(out scaledValue, 4 * mantissa); - - // scale = 2 * 2 * 2^(-exponent) - BigInteger.Pow2((uint)(-exponent + 2), out scale); - - // scaledMarginLow = 2 * 2^(-1) - BigInteger.SetUInt32(out scaledMarginLow, 1); - - // scaledMarginHigh = 2 * 2 * 2^(-1) - BigInteger.SetUInt32(out optionalMarginHigh, 2); - } - - // The high and low margins are different - pScaledMarginHigh = &optionalMarginHigh; - } - else - { - if (exponent > 0) // We have no fractional component - { - // 1) Expand the input value by multiplying out the mantissa and exponent. - // This represents the input value in its whole number representation. - // 2) Apply an additional scale of 2 such that later comparisons against the margin values are simplified. - // 3) Set the margin value to the lowest mantissa bit's scale. - - // scaledValue = 2 * mantissa*2^exponent - BigInteger.SetUInt64(out scaledValue, 2 * mantissa); - scaledValue.ShiftLeft((uint)(exponent)); - - // scale = 2 * 1 - BigInteger.SetUInt32(out scale, 2); - - // scaledMarginLow = 2 * 2^(exponent-1) - BigInteger.Pow2((uint)(exponent), out scaledMarginLow); - } - else // We have a fractional exponent - { - // In order to track the mantissa data as an integer, we store it as is with a large scale - - // scaledValue = 2 * mantissa - BigInteger.SetUInt64(out scaledValue, 2 * mantissa); - - // scale = 2 * 2^(-exponent) - BigInteger.Pow2((uint)(-exponent + 1), out scale); - - // scaledMarginLow = 2 * 2^(-1) - BigInteger.SetUInt32(out scaledMarginLow, 1); - } - - // The high and low margins are equal - pScaledMarginHigh = &scaledMarginLow; - } - - // Compute an estimate for digitExponent that will be correct or undershoot by one. - // - // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately" by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf - // - // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate because that lets us take a faster branch in the code. - // 0.69 is chosen because 0.69 + log10(2) is less than one by a reasonable epsilon that will account for any floating point error. - // - // We want to set digitExponent to floor(log10(v)) + 1 - // v = mantissa * 2^exponent - // log2(v) = log2(mantissa) + exponent; - // log10(v) = log2(v) * log10(2) - // floor(log2(v)) = mantissaHighBitIdx + exponent; - // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v) - // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2) - // floor(log10(v)) < ceil((mantissaHighBitIdx + exponent) * log10(2)) <= floor(log10(v)) + 1 - const double Log10V2 = 0.30102999566398119521373889472449; - int digitExponent = (int)(Math.Ceiling(((int)(mantissaHighBitIdx) + exponent) * Log10V2 - 0.69)); - - // Divide value by 10^digitExponent. - if (digitExponent > 0) - { - // The exponent is positive creating a division so we multiply up the scale. - scale.MultiplyPow10((uint)(digitExponent)); - } - else if (digitExponent < 0) - { - // The exponent is negative creating a multiplication so we multiply up the scaledValue, scaledMarginLow and scaledMarginHigh. - - BigInteger.Pow10((uint)(-digitExponent), out BigInteger pow10); - - scaledValue.Multiply(ref pow10); - scaledMarginLow.Multiply(ref pow10); - - if (pScaledMarginHigh != &scaledMarginLow) - { - BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); - } - } - - bool isEven = (mantissa % 2) == 0; - bool estimateTooLow = false; - - if (cutoffNumber == -1) - { - // When printing the shortest possible string, we want to - // take IEEE unbiased rounding into account so we can return - // shorter strings for various edge case values like 1.23E+22 - - BigInteger.Add(ref scaledValue, ref *pScaledMarginHigh, out BigInteger scaledValueHigh); - int cmpHigh = BigInteger.Compare(ref scaledValueHigh, ref scale); - estimateTooLow = isEven ? (cmpHigh >= 0) : (cmpHigh > 0); - } - else - { - estimateTooLow = BigInteger.Compare(ref scaledValue, ref scale) >= 0; - } - - // Was our estimate for digitExponent was too low? - if (estimateTooLow) - { - // The exponent estimate was incorrect. - // Increment the exponent and don't perform the premultiply needed for the first loop iteration. - digitExponent++; - } - else - { - // The exponent estimate was correct. - // Multiply larger by the output base to prepare for the first loop iteration. - scaledValue.Multiply10(); - scaledMarginLow.Multiply10(); - - if (pScaledMarginHigh != &scaledMarginLow) - { - BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); - } - } - - // Compute the cutoff exponent (the exponent of the final digit to print). - // Default to the maximum size of the output buffer. - int cutoffExponent = digitExponent - buffer.Length; - - if (cutoffNumber != -1) - { - int desiredCutoffExponent = 0; - - if (isSignificantDigits) - { - // We asked for a specific number of significant digits. - Debug.Assert(cutoffNumber > 0); - desiredCutoffExponent = digitExponent - cutoffNumber; - } - else - { - // We asked for a specific number of fractional digits. - Debug.Assert(cutoffNumber >= 0); - desiredCutoffExponent = -cutoffNumber; - } - - if (desiredCutoffExponent > cutoffExponent) - { - // Only select the new cutoffExponent if it won't overflow the destination buffer. - cutoffExponent = desiredCutoffExponent; - } - } - - // Output the exponent of the first digit we will print - decimalExponent = --digitExponent; - - // In preparation for calling BigInteger.HeuristicDivie(), we need to scale up our values such that the highest block of the denominator is greater than or equal to 8. - // We also need to guarantee that the numerator can never have a length greater than the denominator after each loop iteration. - // This requires the highest block of the denominator to be less than or equal to 429496729 which is the highest number that can be multiplied by 10 without overflowing to a new block. - - Debug.Assert(scale.GetLength() > 0); - uint hiBlock = scale.GetBlock((uint)(scale.GetLength() - 1)); - - if ((hiBlock < 8) || (hiBlock > 429496729)) - { - // Perform a bit shift on all values to get the highest block of the denominator into the range [8,429496729]. - // We are more likely to make accurate quotient estimations in BigInteger.HeuristicDivide() with higher denominator values so we shift the denominator to place the highest bit at index 27 of the highest block. - // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. - // This means that all values with a highest bit at index 27 are within range. - Debug.Assert(hiBlock != 0); - uint hiBlockLog2 = (uint)BitOperations.Log2(hiBlock); - Debug.Assert((hiBlockLog2 < 3) || (hiBlockLog2 > 27)); - uint shift = (32 + 27 - hiBlockLog2) % 32; - - scale.ShiftLeft(shift); - scaledValue.ShiftLeft(shift); - scaledMarginLow.ShiftLeft(shift); - - if (pScaledMarginHigh != &scaledMarginLow) - { - BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); - } - } - - // These values are used to inspect why the print loop terminated so we can properly round the final digit. - bool low; // did the value get within marginLow distance from zero - bool high; // did the value get within marginHigh distance from one - uint outputDigit; // current digit being output - - if (cutoffNumber == -1) - { - Debug.Assert(isSignificantDigits); - Debug.Assert(digitExponent >= cutoffExponent); - - // For the unique cutoff mode, we will try to print until we have reached a level of precision that uniquely distinguishes this value from its neighbors. - // If we run out of space in the output buffer, we terminate early. - - while (true) - { - // divide out the scale to extract the digit - outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); - Debug.Assert(outputDigit < 10); - - // update the high end of the value - BigInteger.Add(ref scaledValue, ref *pScaledMarginHigh, out BigInteger scaledValueHigh); - - // stop looping if we are far enough away from our neighboring values or if we have reached the cutoff digit - int cmpLow = BigInteger.Compare(ref scaledValue, ref scaledMarginLow); - int cmpHigh = BigInteger.Compare(ref scaledValueHigh, ref scale); - - if (isEven) - { - low = (cmpLow <= 0); - high = (cmpHigh >= 0); - } - else - { - low = (cmpLow < 0); - high = (cmpHigh > 0); - } - - if (low || high || (digitExponent == cutoffExponent)) - { - break; - } - - // store the output digit - buffer[curDigit] = (byte)('0' + outputDigit); - curDigit++; - - // multiply larger by the output base - scaledValue.Multiply10(); - scaledMarginLow.Multiply10(); - - if (pScaledMarginHigh != &scaledMarginLow) - { - BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); - } - - digitExponent--; - } - } - else if (digitExponent >= cutoffExponent) - { - Debug.Assert((cutoffNumber > 0) || ((cutoffNumber == 0) && !isSignificantDigits)); - - // For length based cutoff modes, we will try to print until we have exhausted all precision (i.e. all remaining digits are zeros) or until we reach the desired cutoff digit. - low = false; - high = false; - - while (true) - { - // divide out the scale to extract the digit - outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); - Debug.Assert(outputDigit < 10); - - if (scaledValue.IsZero() || (digitExponent <= cutoffExponent)) - { - break; - } - - // store the output digit - buffer[curDigit] = (byte)('0' + outputDigit); - curDigit++; - - // multiply larger by the output base - scaledValue.Multiply10(); - digitExponent--; - } - } - else - { - // In the scenario where the first significant digit is after the cutoff, we want to treat that - // first significant digit as the rounding digit. If the first significant would cause the next - // digit to round, we will increase the decimalExponent by one and set the previous digit to one. - // This ensures we correctly handle the case where the first significant digit is exactly one after - // the cutoff, it is a 4, and the subsequent digit would round that to 5 inducing a double rounding - // bug when NumberToString does its own rounding checks. However, if the first significant digit - // would not cause the next one to round, we preserve that digit as is. - - // divide out the scale to extract the digit - outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); - Debug.Assert((0 < outputDigit) && (outputDigit < 10)); - - if ((outputDigit > 5) || ((outputDigit == 5) && !scaledValue.IsZero())) - { - decimalExponent++; - outputDigit = 1; - } - - buffer[curDigit] = (byte)('0' + outputDigit); - curDigit++; - - // return the number of digits output - return (uint)curDigit; - } - - // round off the final digit - // default to rounding down if value got too close to 0 - bool roundDown = low; - - if (low == high) // is it legal to round up and down - { - // round to the closest digit by comparing value with 0.5. - // - // To do this we need to convert the inequality to large integer values. - // compare(value, 0.5) - // compare(scale * value, scale * 0.5) - // compare(2 * scale * value, scale) - scaledValue.ShiftLeft(1); // Multiply by 2 - int compare = BigInteger.Compare(ref scaledValue, ref scale); - roundDown = compare < 0; - - // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules) - if (compare == 0) - { - roundDown = (outputDigit & 1) == 0; - } - } - - // print the rounded digit - if (roundDown) - { - buffer[curDigit] = (byte)('0' + outputDigit); - curDigit++; - } - else if (outputDigit == 9) // handle rounding up - { - // find the first non-nine prior digit - while (true) - { - // if we are at the first digit - if (curDigit == 0) - { - // output 1 at the next highest exponent - - buffer[curDigit] = (byte)('1'); - curDigit++; - decimalExponent++; - - break; - } - - curDigit--; - - if (buffer[curDigit] != '9') - { - // increment the digit - - buffer[curDigit]++; - curDigit++; - - break; - } - } - } - else - { - // values in the range [0,8] can perform a simple round up - buffer[curDigit] = (byte)('0' + outputDigit + 1); - curDigit++; - } - - // return the number of digits output - uint outputLen = (uint)curDigit; - Debug.Assert(outputLen <= buffer.Length); - return outputLen; - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/Number.Dragon4.cs.meta b/Plugins/ZString/Number/Number.Dragon4.cs.meta deleted file mode 100644 index 6b50e876..00000000 --- a/Plugins/ZString/Number/Number.Dragon4.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c85d12eb4f5572c45baa13de29cee602 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/Number.Formatting.cs b/Plugins/ZString/Number/Number.Formatting.cs deleted file mode 100644 index eb2d402f..00000000 --- a/Plugins/ZString/Number/Number.Formatting.cs +++ /dev/null @@ -1,2544 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Buffers.Text; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace System -{ - // The Format methods provided by the numeric classes convert - // the numeric value to a string using the format string given by the - // format parameter. If the format parameter is null or - // an empty string, the number is formatted as if the string "G" (general - // format) was specified. The info parameter specifies the - // NumberFormatInfo instance to use when formatting the number. If the - // info parameter is null or omitted, the numeric formatting information - // is obtained from the current culture. The NumberFormatInfo supplies - // such information as the characters to use for decimal and thousand - // separators, and the spelling and placement of currency symbols in monetary - // values. - // - // Format strings fall into two categories: Standard format strings and - // user-defined format strings. A format string consisting of a single - // alphabetic character (A-Z or a-z), optionally followed by a sequence of - // digits (0-9), is a standard format string. All other format strings are - // used-defined format strings. - // - // A standard format string takes the form Axx, where A is an - // alphabetic character called the format specifier and xx is a - // sequence of digits called the precision specifier. The format - // specifier controls the type of formatting applied to the number and the - // precision specifier controls the number of significant digits or decimal - // places of the formatting operation. The following table describes the - // supported standard formats. - // - // C c - Currency format. The number is - // converted to a string that represents a currency amount. The conversion is - // controlled by the currency format information of the NumberFormatInfo - // used to format the number. The precision specifier indicates the desired - // number of decimal places. If the precision specifier is omitted, the default - // currency precision given by the NumberFormatInfo is used. - // - // D d - Decimal format. This format is - // supported for integral types only. The number is converted to a string of - // decimal digits, prefixed by a minus sign if the number is negative. The - // precision specifier indicates the minimum number of digits desired in the - // resulting string. If required, the number will be left-padded with zeros to - // produce the number of digits given by the precision specifier. - // - // E e Engineering (scientific) format. - // The number is converted to a string of the form - // "-d.ddd...E+ddd" or "-d.ddd...e+ddd", where each - // 'd' indicates a digit (0-9). The string starts with a minus sign if the - // number is negative, and one digit always precedes the decimal point. The - // precision specifier indicates the desired number of digits after the decimal - // point. If the precision specifier is omitted, a default of 6 digits after - // the decimal point is used. The format specifier indicates whether to prefix - // the exponent with an 'E' or an 'e'. The exponent is always consists of a - // plus or minus sign and three digits. - // - // F f Fixed point format. The number is - // converted to a string of the form "-ddd.ddd....", where each - // 'd' indicates a digit (0-9). The string starts with a minus sign if the - // number is negative. The precision specifier indicates the desired number of - // decimal places. If the precision specifier is omitted, the default numeric - // precision given by the NumberFormatInfo is used. - // - // G g - General format. The number is - // converted to the shortest possible decimal representation using fixed point - // or scientific format. The precision specifier determines the number of - // significant digits in the resulting string. If the precision specifier is - // omitted, the number of significant digits is determined by the type of the - // number being converted (10 for int, 19 for long, 7 for - // float, 15 for double, 19 for Currency, and 29 for - // Decimal). Trailing zeros after the decimal point are removed, and the - // resulting string contains a decimal point only if required. The resulting - // string uses fixed point format if the exponent of the number is less than - // the number of significant digits and greater than or equal to -4. Otherwise, - // the resulting string uses scientific format, and the case of the format - // specifier controls whether the exponent is prefixed with an 'E' or an 'e'. - // - // N n Number format. The number is - // converted to a string of the form "-d,ddd,ddd.ddd....", where - // each 'd' indicates a digit (0-9). The string starts with a minus sign if the - // number is negative. Thousand separators are inserted between each group of - // three digits to the left of the decimal point. The precision specifier - // indicates the desired number of decimal places. If the precision specifier - // is omitted, the default numeric precision given by the - // NumberFormatInfo is used. - // - // X x - Hexadecimal format. This format is - // supported for integral types only. The number is converted to a string of - // hexadecimal digits. The format specifier indicates whether to use upper or - // lower case characters for the hexadecimal digits above 9 ('X' for 'ABCDEF', - // and 'x' for 'abcdef'). The precision specifier indicates the minimum number - // of digits desired in the resulting string. If required, the number will be - // left-padded with zeros to produce the number of digits given by the - // precision specifier. - // - // Some examples of standard format strings and their results are shown in the - // table below. (The examples all assume a default NumberFormatInfo.) - // - // Value Format Result - // 12345.6789 C $12,345.68 - // -12345.6789 C ($12,345.68) - // 12345 D 12345 - // 12345 D8 00012345 - // 12345.6789 E 1.234568E+004 - // 12345.6789 E10 1.2345678900E+004 - // 12345.6789 e4 1.2346e+004 - // 12345.6789 F 12345.68 - // 12345.6789 F0 12346 - // 12345.6789 F6 12345.678900 - // 12345.6789 G 12345.6789 - // 12345.6789 G7 12345.68 - // 123456789 G7 1.234568E8 - // 12345.6789 N 12,345.68 - // 123456789 N4 123,456,789.0000 - // 0x2c45e x 2c45e - // 0x2c45e X 2C45E - // 0x2c45e X8 0002C45E - // - // Format strings that do not start with an alphabetic character, or that start - // with an alphabetic character followed by a non-digit, are called - // user-defined format strings. The following table describes the formatting - // characters that are supported in user defined format strings. - // - // - // 0 - Digit placeholder. If the value being - // formatted has a digit in the position where the '0' appears in the format - // string, then that digit is copied to the output string. Otherwise, a '0' is - // stored in that position in the output string. The position of the leftmost - // '0' before the decimal point and the rightmost '0' after the decimal point - // determines the range of digits that are always present in the output - // string. - // - // # - Digit placeholder. If the value being - // formatted has a digit in the position where the '#' appears in the format - // string, then that digit is copied to the output string. Otherwise, nothing - // is stored in that position in the output string. - // - // . - Decimal point. The first '.' character - // in the format string determines the location of the decimal separator in the - // formatted value; any additional '.' characters are ignored. The actual - // character used as a the decimal separator in the output string is given by - // the NumberFormatInfo used to format the number. - // - // , - Thousand separator and number scaling. - // The ',' character serves two purposes. First, if the format string contains - // a ',' character between two digit placeholders (0 or #) and to the left of - // the decimal point if one is present, then the output will have thousand - // separators inserted between each group of three digits to the left of the - // decimal separator. The actual character used as a the decimal separator in - // the output string is given by the NumberFormatInfo used to format the - // number. Second, if the format string contains one or more ',' characters - // immediately to the left of the decimal point, or after the last digit - // placeholder if there is no decimal point, then the number will be divided by - // 1000 times the number of ',' characters before it is formatted. For example, - // the format string '0,,' will represent 100 million as just 100. Use of the - // ',' character to indicate scaling does not also cause the formatted number - // to have thousand separators. Thus, to scale a number by 1 million and insert - // thousand separators you would use the format string '#,##0,,'. - // - // % - Percentage placeholder. The presence of - // a '%' character in the format string causes the number to be multiplied by - // 100 before it is formatted. The '%' character itself is inserted in the - // output string where it appears in the format string. - // - // E+ E- e+ e- - Scientific notation. - // If any of the strings 'E+', 'E-', 'e+', or 'e-' are present in the format - // string and are immediately followed by at least one '0' character, then the - // number is formatted using scientific notation with an 'E' or 'e' inserted - // between the number and the exponent. The number of '0' characters following - // the scientific notation indicator determines the minimum number of digits to - // output for the exponent. The 'E+' and 'e+' formats indicate that a sign - // character (plus or minus) should always precede the exponent. The 'E-' and - // 'e-' formats indicate that a sign character should only precede negative - // exponents. - // - // \ - Literal character. A backslash character - // causes the next character in the format string to be copied to the output - // string as-is. The backslash itself isn't copied, so to place a backslash - // character in the output string, use two backslashes (\\) in the format - // string. - // - // 'ABC' "ABC" - Literal string. Characters - // enclosed in single or double quotation marks are copied to the output string - // as-is and do not affect formatting. - // - // ; - Section separator. The ';' character is - // used to separate sections for positive, negative, and zero numbers in the - // format string. - // - // Other - All other characters are copied to - // the output string in the position they appear. - // - // For fixed point formats (formats not containing an 'E+', 'E-', 'e+', or - // 'e-'), the number is rounded to as many decimal places as there are digit - // placeholders to the right of the decimal point. If the format string does - // not contain a decimal point, the number is rounded to the nearest - // integer. If the number has more digits than there are digit placeholders to - // the left of the decimal point, the extra digits are copied to the output - // string immediately before the first digit placeholder. - // - // For scientific formats, the number is rounded to as many significant digits - // as there are digit placeholders in the format string. - // - // To allow for different formatting of positive, negative, and zero values, a - // user-defined format string may contain up to three sections separated by - // semicolons. The results of having one, two, or three sections in the format - // string are described in the table below. - // - // Sections: - // - // One - The format string applies to all values. - // - // Two - The first section applies to positive values - // and zeros, and the second section applies to negative values. If the number - // to be formatted is negative, but becomes zero after rounding according to - // the format in the second section, then the resulting zero is formatted - // according to the first section. - // - // Three - The first section applies to positive - // values, the second section applies to negative values, and the third section - // applies to zeros. The second section may be left empty (by having no - // characters between the semicolons), in which case the first section applies - // to all non-zero values. If the number to be formatted is non-zero, but - // becomes zero after rounding according to the format in the first or second - // section, then the resulting zero is formatted according to the third - // section. - // - // For both standard and user-defined formatting operations on values of type - // float and double, if the value being formatted is a NaN (Not - // a Number) or a positive or negative infinity, then regardless of the format - // string, the resulting string is given by the NaNSymbol, - // PositiveInfinitySymbol, or NegativeInfinitySymbol property of - // the NumberFormatInfo used to format the number. - - internal static partial class Number - { - internal const int DecimalPrecision = 29; // Decimal.DecCalc also uses this value - - // SinglePrecision and DoublePrecision represent the maximum number of digits required - // to guarantee that any given Single or Double can roundtrip. Some numbers may require - // less, but none will require more. - private const int SinglePrecision = 9; - private const int DoublePrecision = 17; - - // SinglePrecisionCustomFormat and DoublePrecisionCustomFormat are used to ensure that - // custom format strings return the same string as in previous releases when the format - // would return x digits or less (where x is the value of the corresponding constant). - // In order to support more digits, we would need to update ParseFormatSpecifier to pre-parse - // the format and determine exactly how many digits are being requested and whether they - // represent "significant digits" or "digits after the decimal point". - private const int SinglePrecisionCustomFormat = 7; - private const int DoublePrecisionCustomFormat = 15; - - private const int DefaultPrecisionExponentialFormat = 6; - - private const int MaxUInt32DecDigits = 10; - private const int CharStackBufferSize = 32; - private const string PosNumberFormat = "#"; - - private static readonly string[] s_singleDigitStringCache = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - - private static readonly string[] s_posCurrencyFormats = - { - "$#", "#$", "$ #", "# $" - }; - - private static readonly string[] s_negCurrencyFormats = - { - "($#)", "-$#", "$-#", "$#-", - "(#$)", "-#$", "#-$", "#$-", - "-# $", "-$ #", "# $-", "$ #-", - "$ -#", "#- $", "($ #)", "(# $)" - }; - - private static readonly string[] s_posPercentFormats = - { - "# %", "#%", "%#", "% #" - }; - - private static readonly string[] s_negPercentFormats = - { - "-# %", "-#%", "-%#", - "%-#", "%#-", - "#-%", "#%-", - "-% #", "# %-", "% #-", - "% -#", "#- %" - }; - - private static readonly string[] s_negNumberFormats = - { - "(#)", "-#", "- #", "#-", "# -", - }; - - public static unsafe string FormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info) - { - char fmt = ParseFormatSpecifier(format, out int digits); - - byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); - - DecimalToNumber(ref value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - - return sb.ToString(); - } - - public static unsafe bool TryFormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) - { - char fmt = ParseFormatSpecifier(format, out int digits); - - byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); - - DecimalToNumber(ref value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - - return sb.TryCopyTo(destination, out charsWritten); - } - - internal static unsafe void DecimalToNumber(ref decimal d, ref NumberBuffer number) - { - byte* buffer = number.GetDigitsPointer(); - number.DigitsCount = DecimalPrecision; - number.IsNegative = d.IsNegative(); - - byte* p = buffer + DecimalPrecision; - while ((d.Mid() | d.High()) != 0) - { - p = UInt32ToDecChars(p, DecimalEx.DecDivMod1E9(ref d), 9); - } - p = UInt32ToDecChars(p, d.Low(), 0); - - int i = (int)((buffer + DecimalPrecision) - p); - - number.DigitsCount = i; - number.Scale = i - d.Scale(); - - byte* dst = number.GetDigitsPointer(); - while (--i >= 0) - { - *dst++ = *p++; - } - *dst = (byte)('\0'); - - number.CheckConsistency(); - } - - public static string FormatDouble(double value, string format, NumberFormatInfo info) - { - Span stackBuffer = stackalloc char[CharStackBufferSize]; - var sb = new ValueStringBuilder(stackBuffer); - return FormatDouble(ref sb, value, format.AsSpan(), info) ?? sb.ToString(); - } - - public static bool TryFormatDouble(double value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) - { - Span stackBuffer = stackalloc char[CharStackBufferSize]; - var sb = new ValueStringBuilder(stackBuffer); - string s = FormatDouble(ref sb, value, format, info); - return s != null ? - TryCopyTo(s, destination, out charsWritten) : - sb.TryCopyTo(destination, out charsWritten); - } - - private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int precision, NumberFormatInfo info, out bool isSignificantDigits) - { - if (fmt == 0) - { - isSignificantDigits = true; - return precision; - } - - int maxDigits = precision; - - switch (fmt) - { - case 'C': - case 'c': - { - // The currency format uses the precision specifier to indicate the number of - // decimal digits to format. This defaults to NumberFormatInfo.CurrencyDecimalDigits. - - if (precision == -1) - { - precision = info.CurrencyDecimalDigits; - } - isSignificantDigits = false; - - break; - } - - case 'E': - case 'e': - { - // The exponential format uses the precision specifier to indicate the number of - // decimal digits to format. This defaults to 6. However, the exponential format - // also always formats a single integral digit, so we need to increase the precision - // specifier and treat it as the number of significant digits to account for this. - - if (precision == -1) - { - precision = DefaultPrecisionExponentialFormat; - } - - precision++; - isSignificantDigits = true; - - break; - } - - case 'F': - case 'f': - case 'N': - case 'n': - { - // The fixed-point and number formats use the precision specifier to indicate the number - // of decimal digits to format. This defaults to NumberFormatInfo.NumberDecimalDigits. - - if (precision == -1) - { - precision = info.NumberDecimalDigits; - } - isSignificantDigits = false; - - break; - } - - case 'G': - case 'g': - { - // The general format uses the precision specifier to indicate the number of significant - // digits to format. This defaults to the shortest roundtrippable string. Additionally, - // given that we can't return zero significant digits, we treat 0 as returning the shortest - // roundtrippable string as well. - - if (precision == 0) - { - precision = -1; - } - isSignificantDigits = true; - - break; - } - - case 'P': - case 'p': - { - // The percent format uses the precision specifier to indicate the number of - // decimal digits to format. This defaults to NumberFormatInfo.PercentDecimalDigits. - // However, the percent format also always multiplies the number by 100, so we need - // to increase the precision specifier to ensure we get the appropriate number of digits. - - if (precision == -1) - { - precision = info.PercentDecimalDigits; - } - - precision += 2; - isSignificantDigits = false; - - break; - } - - case 'R': - case 'r': - { - // The roundtrip format ignores the precision specifier and always returns the shortest - // roundtrippable string. - - precision = -1; - isSignificantDigits = true; - - break; - } - - default: - { - throw new FormatException("SR.Argument_BadFormatSpecifier"); - } - } - - return maxDigits; - } - - /// Formats the specified value according to the specified format and info. - /// - /// Non-null if an existing string can be returned, in which case the builder will be unmodified. - /// Null if no existing string was returned, in which case the formatted output is in the builder. - /// - private static unsafe string FormatDouble(ref ValueStringBuilder sb, double value, ReadOnlySpan format, NumberFormatInfo info) - { - if (!FloatEx.IsFinite(value)) - { - if (double.IsNaN(value)) - { - return info.NaNSymbol; - } - - return FloatEx.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; - } - - char fmt = ParseFormatSpecifier(format, out int precision); - byte* pDigits = stackalloc byte[DoubleNumberBufferLength]; - - if (fmt == '\0') - { - // For back-compat we currently specially treat the precision for custom - // format specifiers. The constant has more details as to why. - precision = DoublePrecisionCustomFormat; - } - - NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, DoubleNumberBufferLength); - number.IsNegative = FloatEx.IsNegative(value); - - // We need to track the original precision requested since some formats - // accept values like 0 and others may require additional fixups. - int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(fmt, ref precision, info, out bool isSignificantDigits); - - if ((value != 0.0) && (!isSignificantDigits || !Grisu3.TryRunDouble(value, precision, ref number))) - { - Dragon4Double(value, precision, isSignificantDigits, ref number); - } - - number.CheckConsistency(); - - // When the number is known to be roundtrippable (either because we requested it be, or - // because we know we have enough digits to satisfy roundtrippability), we should validate - // that the number actually roundtrips back to the original result. - - Debug.Assert(((precision != -1) && (precision < DoublePrecision)) || (BitConverter.DoubleToInt64Bits(value) == BitConverter.DoubleToInt64Bits(NumberToDouble(ref number)))); - - if (fmt != 0) - { - if (precision == -1) - { - Debug.Assert((fmt == 'G') || (fmt == 'g') || (fmt == 'R') || (fmt == 'r')); - - // For the roundtrip and general format specifiers, when returning the shortest roundtrippable - // string, we need to update the maximum number of digits to be the greater of number.DigitsCount - // or DoublePrecision. This ensures that we continue returning "pretty" strings for values with - // less digits. One example this fixes is "-60", which would otherwise be formatted as "-6E+01" - // since DigitsCount would be 1 and the formatter would almost immediately switch to scientific notation. - - nMaxDigits = Math.Max(number.DigitsCount, DoublePrecision); - } - NumberToString(ref sb, ref number, fmt, nMaxDigits, info); - } - else - { - Debug.Assert(precision == DoublePrecisionCustomFormat); - NumberToStringFormat(ref sb, ref number, format, info); - } - return null; - } - - public static string FormatSingle(float value, string format, NumberFormatInfo info) - { - Span stackBuffer = stackalloc char[CharStackBufferSize]; - var sb = new ValueStringBuilder(stackBuffer); - return FormatSingle(ref sb, value, format.AsSpan(), info) ?? sb.ToString(); - } - - public static bool TryFormatSingle(float value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) - { - Span stackBuffer = stackalloc char[CharStackBufferSize]; - var sb = new ValueStringBuilder(stackBuffer); - string s = FormatSingle(ref sb, value, format, info); - return s != null ? - TryCopyTo(s, destination, out charsWritten) : - sb.TryCopyTo(destination, out charsWritten); - } - - /// Formats the specified value according to the specified format and info. - /// - /// Non-null if an existing string can be returned, in which case the builder will be unmodified. - /// Null if no existing string was returned, in which case the formatted output is in the builder. - /// - private static unsafe string FormatSingle(ref ValueStringBuilder sb, float value, ReadOnlySpan format, NumberFormatInfo info) - { - if (!FloatEx.IsFinite(value)) - { - if (float.IsNaN(value)) - { - return info.NaNSymbol; - } - - return FloatEx.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; - } - - char fmt = ParseFormatSpecifier(format, out int precision); - byte* pDigits = stackalloc byte[SingleNumberBufferLength]; - - if (fmt == '\0') - { - // For back-compat we currently specially treat the precision for custom - // format specifiers. The constant has more details as to why. - precision = SinglePrecisionCustomFormat; - } - - NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, SingleNumberBufferLength); - number.IsNegative = FloatEx.IsNegative(value); - - // We need to track the original precision requested since some formats - // accept values like 0 and others may require additional fixups. - int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(fmt, ref precision, info, out bool isSignificantDigits); - - if ((value != 0.0f) && (!isSignificantDigits || !Grisu3.TryRunSingle(value, precision, ref number))) - { - Dragon4Single(value, precision, isSignificantDigits, ref number); - } - - number.CheckConsistency(); - - // When the number is known to be roundtrippable (either because we requested it be, or - // because we know we have enough digits to satisfy roundtrippability), we should validate - // that the number actually roundtrips back to the original result. - - Debug.Assert(((precision != -1) && (precision < SinglePrecision)) || (SingleToInt32Bits(value) == SingleToInt32Bits(NumberToSingle(ref number)))); - - if (fmt != 0) - { - if (precision == -1) - { - Debug.Assert((fmt == 'G') || (fmt == 'g') || (fmt == 'R') || (fmt == 'r')); - - // For the roundtrip and general format specifiers, when returning the shortest roundtrippable - // string, we need to update the maximum number of digits to be the greater of number.DigitsCount - // or SinglePrecision. This ensures that we continue returning "pretty" strings for values with - // less digits. One example this fixes is "-60", which would otherwise be formatted as "-6E+01" - // since DigitsCount would be 1 and the formatter would almost immediately switch to scientific notation. - - nMaxDigits = Math.Max(number.DigitsCount, SinglePrecision); - } - NumberToString(ref sb, ref number, fmt, nMaxDigits, info); - } - else - { - Debug.Assert(precision == SinglePrecisionCustomFormat); - NumberToStringFormat(ref sb, ref number, format, info); - } - return null; - } - - private static bool TryCopyTo(string source, Span destination, out int charsWritten) - { - Debug.Assert(source != null); - - if (source.AsSpan().TryCopyTo(destination)) - { - charsWritten = source.Length; - return true; - } - - charsWritten = 0; - return false; - } - - public static unsafe string FormatInt32(int value, ReadOnlySpan format, IFormatProvider provider) - { - // Fast path for default format with a non-negative value - if (value >= 0 && format.Length == 0) - { - return UInt32ToDecStr((uint)value, digits: -1); - } - - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') - { - return value >= 0 ? - UInt32ToDecStr((uint)value, digits) : - NegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign); - } - else if (fmtUpper == 'X') - { - // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase - // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code produces lowercase. - return Int32ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[Int32NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); - - Int32ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - return sb.ToString(); - } - } - - public static unsafe bool TryFormatInt32(int value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) - { - // Fast path for default format with a non-negative value - if (value >= 0 && format.Length == 0) - { - return TryUInt32ToDecStr((uint)value, digits: -1, destination, out charsWritten); - } - - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') - { - return value >= 0 ? - TryUInt32ToDecStr((uint)value, digits, destination, out charsWritten) : - TryNegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign, destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase - // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code produces lowercase. - return TryInt32ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[Int32NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); - - Int32ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - return sb.TryCopyTo(destination, out charsWritten); - } - } - - public static unsafe string FormatUInt32(uint value, ReadOnlySpan format, IFormatProvider provider) - { - // Fast path for default format - if (format.Length == 0) - { - return UInt32ToDecStr(value, digits: -1); - } - - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') - { - return UInt32ToDecStr(value, digits); - } - else if (fmtUpper == 'X') - { - // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase - // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code produces lowercase. - return Int32ToHexStr((int)value, (char)(fmt - ('X' - 'A' + 10)), digits); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); - - UInt32ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - return sb.ToString(); - } - } - - public static unsafe bool TryFormatUInt32(uint value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) - { - // Fast path for default format - if (format.Length == 0) - { - return TryUInt32ToDecStr(value, digits: -1, destination, out charsWritten); - } - - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') - { - return TryUInt32ToDecStr(value, digits, destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase - // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code produces lowercase. - return TryInt32ToHexStr((int)value, (char)(fmt - ('X' - 'A' + 10)), digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); - - UInt32ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - return sb.TryCopyTo(destination, out charsWritten); - } - } - - public static unsafe string FormatInt64(long value, ReadOnlySpan format, IFormatProvider provider) - { - // Fast path for default format with a non-negative value - if (value >= 0 && format.Length == 0) - { - return UInt64ToDecStr((ulong)value, digits: -1); - } - - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') - { - return value >= 0 ? - UInt64ToDecStr((ulong)value, digits) : - NegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign); - } - else if (fmtUpper == 'X') - { - // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase - // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code - // produces lowercase. - return Int64ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[Int64NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); - - Int64ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - return sb.ToString(); - } - } - - public static unsafe bool TryFormatInt64(long value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) - { - // Fast path for default format with a non-negative value - if (value >= 0 && format.Length == 0) - { - return TryUInt64ToDecStr((ulong)value, digits: -1, destination, out charsWritten); - } - - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') - { - return value >= 0 ? - TryUInt64ToDecStr((ulong)value, digits, destination, out charsWritten) : - TryNegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign, destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase - // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code - // produces lowercase. - return TryInt64ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[Int64NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); - - Int64ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - return sb.TryCopyTo(destination, out charsWritten); - } - } - - public static unsafe string FormatUInt64(ulong value, ReadOnlySpan format, IFormatProvider provider) - { - // Fast path for default format - if (format.Length == 0) - { - return UInt64ToDecStr(value, digits: -1); - } - - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') - { - return UInt64ToDecStr(value, digits); - } - else if (fmtUpper == 'X') - { - // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase - // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code - // produces lowercase. - return Int64ToHexStr((long)value, (char)(fmt - ('X' - 'A' + 10)), digits); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); - - UInt64ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - return sb.ToString(); - } - } - - public static unsafe bool TryFormatUInt64(ulong value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) - { - // Fast path for default format - if (format.Length == 0) - { - return TryUInt64ToDecStr(value, digits: -1, destination, out charsWritten); - } - - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') - { - return TryUInt64ToDecStr(value, digits, destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase - // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code - // produces lowercase. - return TryInt64ToHexStr((long)value, (char)(fmt - ('X' - 'A' + 10)), digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); - - UInt64ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref sb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref sb, ref number, format, info); - } - return sb.TryCopyTo(destination, out charsWritten); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] // called from only one location - private static unsafe void Int32ToNumber(int value, ref NumberBuffer number) - { - number.DigitsCount = Int32Precision; - - if (value >= 0) - { - number.IsNegative = false; - } - else - { - number.IsNegative = true; - value = -value; - } - - byte* buffer = number.GetDigitsPointer(); - byte* p = UInt32ToDecChars(buffer + Int32Precision, (uint)value, 0); - - int i = (int)(buffer + Int32Precision - p); - - number.DigitsCount = i; - number.Scale = i; - - byte* dst = number.GetDigitsPointer(); - while (--i >= 0) - *dst++ = *p++; - *dst = (byte)('\0'); - - number.CheckConsistency(); - } - - private static unsafe string NegativeInt32ToDecStr(int value, int digits, string sNegative) - { - Debug.Assert(value < 0); - - if (digits < 1) - digits = 1; - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; - string result = FastAllocateString(bufferLength); - fixed (char* buffer = result) - { - char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); - Debug.Assert(p == buffer + sNegative.Length); - - for (int i = sNegative.Length - 1; i >= 0; i--) - { - *(--p) = sNegative[i]; - } - Debug.Assert(p == buffer); - } - return result; - } - - private static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, string sNegative, Span destination, out int charsWritten) - { - Debug.Assert(value < 0); - - if (digits < 1) - digits = 1; - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (char* buffer = &MemoryMarshal.GetReference(destination)) - { - char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); - Debug.Assert(p == buffer + sNegative.Length); - - for (int i = sNegative.Length - 1; i >= 0; i--) - { - *(--p) = sNegative[i]; - } - Debug.Assert(p == buffer); - } - return true; - } - - private static unsafe string Int32ToHexStr(int value, char hexBase, int digits) - { - if (digits < 1) - digits = 1; - - int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); - string result = FastAllocateString(bufferLength); - fixed (char* buffer = result) - { - char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); - Debug.Assert(p == buffer); - } - return result; - } - - private static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span destination, out int charsWritten) - { - if (digits < 1) - digits = 1; - - int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (char* buffer = &MemoryMarshal.GetReference(destination)) - { - char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); - Debug.Assert(p == buffer); - } - return true; - } - - private static unsafe char* Int32ToHexChars(char* buffer, uint value, int hexBase, int digits) - { - while (--digits >= 0 || value != 0) - { - byte digit = (byte)(value & 0xF); - *(--buffer) = (char)(digit + (digit < 10 ? (byte)'0' : hexBase)); - value >>= 4; - } - return buffer; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] // called from only one location - private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) - { - number.DigitsCount = UInt32Precision; - number.IsNegative = false; - - byte* buffer = number.GetDigitsPointer(); - byte* p = UInt32ToDecChars(buffer + UInt32Precision, value, 0); - - int i = (int)(buffer + UInt32Precision - p); - - number.DigitsCount = i; - number.Scale = i; - - byte* dst = number.GetDigitsPointer(); - while (--i >= 0) - *dst++ = *p++; - *dst = (byte)('\0'); - - number.CheckConsistency(); - } - - internal static unsafe byte* UInt32ToDecChars(byte* bufferEnd, uint value, int digits) - { - while (--digits >= 0 || value != 0) - { - value = MathEx.DivRem(value, 10, out uint remainder); - *(--bufferEnd) = (byte)(remainder + '0'); - } - return bufferEnd; - } - - internal static unsafe char* UInt32ToDecChars(char* bufferEnd, uint value, int digits) - { - while (--digits >= 0 || value != 0) - { - value = MathEx.DivRem(value, 10, out uint remainder); - *(--bufferEnd) = (char)(remainder + '0'); - } - return bufferEnd; - } - - internal static unsafe string UInt32ToDecStr(uint value, int digits) - { - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); - - // For single-digit values that are very common, especially 0 and 1, just return cached strings. - if (bufferLength == 1) - { - return s_singleDigitStringCache[value]; - } - - string result = FastAllocateString(bufferLength); - fixed (char* buffer = result) - { - char* p = buffer + bufferLength; - if (digits <= 1) - { - do - { - value = MathEx.DivRem(value, 10, out uint remainder); - *(--p) = (char)(remainder + '0'); - } - while (value != 0); - } - else - { - p = UInt32ToDecChars(p, value, digits); - } - Debug.Assert(p == buffer); - } - return result; - } - - private static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span destination, out int charsWritten) - { - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (char* buffer = &MemoryMarshal.GetReference(destination)) - { - char* p = buffer + bufferLength; - if (digits <= 1) - { - do - { - value = MathEx.DivRem(value, 10, out uint remainder); - *(--p) = (char)(remainder + '0'); - } - while (value != 0); - } - else - { - p = UInt32ToDecChars(p, value, digits); - } - Debug.Assert(p == buffer); - } - return true; - } - - private static unsafe void Int64ToNumber(long input, ref NumberBuffer number) - { - ulong value = (ulong)input; - number.IsNegative = input < 0; - number.DigitsCount = Int64Precision; - if (number.IsNegative) - { - value = (ulong)(-input); - } - - byte* buffer = number.GetDigitsPointer(); - byte* p = buffer + Int64Precision; - while (High32(value) != 0) - p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); - p = UInt32ToDecChars(p, Low32(value), 0); - - int i = (int)(buffer + Int64Precision - p); - - number.DigitsCount = i; - number.Scale = i; - - byte* dst = number.GetDigitsPointer(); - while (--i >= 0) - *dst++ = *p++; - *dst = (byte)('\0'); - - number.CheckConsistency(); - } - - private static unsafe string NegativeInt64ToDecStr(long input, int digits, string sNegative) - { - Debug.Assert(input < 0); - - if (digits < 1) - { - digits = 1; - } - - ulong value = (ulong)(-input); - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)) + sNegative.Length; - string result = FastAllocateString(bufferLength); - fixed (char* buffer = result) - { - char* p = buffer + bufferLength; - while (High32(value) != 0) - { - p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); - digits -= 9; - } - p = UInt32ToDecChars(p, Low32(value), digits); - Debug.Assert(p == buffer + sNegative.Length); - - for (int i = sNegative.Length - 1; i >= 0; i--) - { - *(--p) = sNegative[i]; - } - Debug.Assert(p == buffer); - } - return result; - } - - private static unsafe bool TryNegativeInt64ToDecStr(long input, int digits, string sNegative, Span destination, out int charsWritten) - { - Debug.Assert(input < 0); - - if (digits < 1) - { - digits = 1; - } - - ulong value = (ulong)(-input); - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((ulong)(-input))) + sNegative.Length; - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (char* buffer = &MemoryMarshal.GetReference(destination)) - { - char* p = buffer + bufferLength; - while (High32(value) != 0) - { - p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); - digits -= 9; - } - p = UInt32ToDecChars(p, Low32(value), digits); - Debug.Assert(p == buffer + sNegative.Length); - - for (int i = sNegative.Length - 1; i >= 0; i--) - { - *(--p) = sNegative[i]; - } - Debug.Assert(p == buffer); - } - return true; - } - - private static unsafe string Int64ToHexStr(long value, char hexBase, int digits) - { - int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); - string result = FastAllocateString(bufferLength); - fixed (char* buffer = result) - { - char* p = buffer + bufferLength; - if (High32((ulong)value) != 0) - { - p = Int32ToHexChars(p, Low32((ulong)value), hexBase, 8); - p = Int32ToHexChars(p, High32((ulong)value), hexBase, digits - 8); - } - else - { - p = Int32ToHexChars(p, Low32((ulong)value), hexBase, Math.Max(digits, 1)); - } - Debug.Assert(p == buffer); - } - return result; - } - - private static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span destination, out int charsWritten) - { - int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (char* buffer = &MemoryMarshal.GetReference(destination)) - { - char* p = buffer + bufferLength; - if (High32((ulong)value) != 0) - { - p = Int32ToHexChars(p, Low32((ulong)value), hexBase, 8); - p = Int32ToHexChars(p, High32((ulong)value), hexBase, digits - 8); - } - else - { - p = Int32ToHexChars(p, Low32((ulong)value), hexBase, Math.Max(digits, 1)); - } - Debug.Assert(p == buffer); - } - return true; - } - - private static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number) - { - number.DigitsCount = UInt64Precision; - number.IsNegative = false; - - byte* buffer = number.GetDigitsPointer(); - byte* p = buffer + UInt64Precision; - - while (High32(value) != 0) - p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); - p = UInt32ToDecChars(p, Low32(value), 0); - - int i = (int)(buffer + UInt64Precision - p); - - number.DigitsCount = i; - number.Scale = i; - - byte* dst = number.GetDigitsPointer(); - while (--i >= 0) - *dst++ = *p++; - *dst = (byte)('\0'); - - number.CheckConsistency(); - } - - internal static unsafe string UInt64ToDecStr(ulong value, int digits) - { - if (digits < 1) - digits = 1; - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); - - // For single-digit values that are very common, especially 0 and 1, just return cached strings. - if (bufferLength == 1) - { - return s_singleDigitStringCache[value]; - } - - string result = FastAllocateString(bufferLength); - fixed (char* buffer = result) - { - char* p = buffer + bufferLength; - while (High32(value) != 0) - { - p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); - digits -= 9; - } - p = UInt32ToDecChars(p, Low32(value), digits); - Debug.Assert(p == buffer); - } - return result; - } - - private static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span destination, out int charsWritten) - { - if (digits < 1) - digits = 1; - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (char* buffer = &MemoryMarshal.GetReference(destination)) - { - char* p = buffer + bufferLength; - while (High32(value) != 0) - { - p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); - digits -= 9; - } - p = UInt32ToDecChars(p, Low32(value), digits); - Debug.Assert(p == buffer); - } - return true; - } - - internal static unsafe char ParseFormatSpecifier(ReadOnlySpan format, out int digits) - { - char c = default; - if (format.Length > 0) - { - // If the format begins with a symbol, see if it's a standard format - // with or without a specified number of digits. - c = format[0]; - if ((uint)(c - 'A') <= 'Z' - 'A' || - (uint)(c - 'a') <= 'z' - 'a') - { - // Fast path for sole symbol, e.g. "D" - if (format.Length == 1) - { - digits = -1; - return c; - } - - if (format.Length == 2) - { - // Fast path for symbol and single digit, e.g. "X4" - int d = format[1] - '0'; - if ((uint)d < 10) - { - digits = d; - return c; - } - } - else if (format.Length == 3) - { - // Fast path for symbol and double digit, e.g. "F12" - int d1 = format[1] - '0', d2 = format[2] - '0'; - if ((uint)d1 < 10 && (uint)d2 < 10) - { - digits = d1 * 10 + d2; - return c; - } - } - - // Fallback for symbol and any length digits. The digits value must be >= 0 && <= 99, - // but it can begin with any number of 0s, and thus we may need to check more than two - // digits. Further, for compat, we need to stop when we hit a null char. - int n = 0; - int i = 1; - while (i < format.Length && (((uint)format[i] - '0') < 10) && n < 10) - { - n = (n * 10) + format[i++] - '0'; - } - - // If we're at the end of the digits rather than having stopped because we hit something - // other than a digit or overflowed, return the standard format info. - if (i == format.Length || format[i] == '\0') - { - digits = n; - return c; - } - } - } - - // Default empty format to be "G"; custom format is signified with '\0'. - digits = -1; - return format.Length == 0 || c == '\0' ? // For compat, treat '\0' as the end of the specifier, even if the specifier extends beyond it. - 'G' : - '\0'; - } - - internal static unsafe void NumberToString(ref ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info) - { - number.CheckConsistency(); - bool isCorrectlyRounded = (number.Kind == NumberBufferKind.FloatingPoint); - - switch (format) - { - case 'C': - case 'c': - { - if (nMaxDigits < 0) - nMaxDigits = info.CurrencyDecimalDigits; - - RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); // Don't change this line to use digPos since digCount could have its sign changed. - - FormatCurrency(ref sb, ref number, nMaxDigits, info); - - break; - } - - case 'F': - case 'f': - { - if (nMaxDigits < 0) - nMaxDigits = info.NumberDecimalDigits; - - RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); - - if (number.IsNegative) - sb.Append(info.NegativeSign); - - FormatFixed(ref sb, ref number, nMaxDigits, null, info.NumberDecimalSeparator, null); - - break; - } - - case 'N': - case 'n': - { - if (nMaxDigits < 0) - nMaxDigits = info.NumberDecimalDigits; // Since we are using digits in our calculation - - RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); - - FormatNumber(ref sb, ref number, nMaxDigits, info); - - break; - } - - case 'E': - case 'e': - { - if (nMaxDigits < 0) - nMaxDigits = DefaultPrecisionExponentialFormat; - nMaxDigits++; - - RoundNumber(ref number, nMaxDigits, isCorrectlyRounded); - - if (number.IsNegative) - sb.Append(info.NegativeSign); - - FormatScientific(ref sb, ref number, nMaxDigits, info, format); - - break; - } - - case 'G': - case 'g': - { - bool noRounding = false; - if (nMaxDigits < 1) - { - if ((number.Kind == NumberBufferKind.Decimal) && (nMaxDigits == -1)) - { - noRounding = true; // Turn off rounding for ECMA compliance to output trailing 0's after decimal as significant - - if (number.Digits[0] == 0) - { - // -0 should be formatted as 0 for decimal. This is normally handled by RoundNumber (which we are skipping) - goto SkipSign; - } - - goto SkipRounding; - } - else - { - // This ensures that the PAL code pads out to the correct place even when we use the default precision - nMaxDigits = number.DigitsCount; - } - } - - RoundNumber(ref number, nMaxDigits, isCorrectlyRounded); - - SkipRounding: - if (number.IsNegative) - sb.Append(info.NegativeSign); - - SkipSign: - FormatGeneral(ref sb, ref number, nMaxDigits, info, (char)(format - ('G' - 'E')), noRounding); - - break; - } - - case 'P': - case 'p': - { - if (nMaxDigits < 0) - nMaxDigits = info.PercentDecimalDigits; - number.Scale += 2; - - RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); - - FormatPercent(ref sb, ref number, nMaxDigits, info); - - break; - } - - case 'R': - case 'r': - { - if (number.Kind != NumberBufferKind.FloatingPoint) - { - goto default; - } - - format = (char)(format - ('R' - 'G')); - Debug.Assert((format == 'G') || (format == 'g')); - goto case 'G'; - } - - default: - throw new FormatException("SR.Argument_BadFormatSpecifier"); - } - } - - internal static unsafe void NumberToStringFormat(ref ValueStringBuilder sb, ref NumberBuffer number, ReadOnlySpan format, NumberFormatInfo info) - { - number.CheckConsistency(); - - int digitCount; - int decimalPos; - int firstDigit; - int lastDigit; - int digPos; - bool scientific; - int thousandPos; - int thousandCount = 0; - bool thousandSeps; - int scaleAdjust; - int adjust; - - int section; - int src; - byte* dig = number.GetDigitsPointer(); - char ch; - - section = FindSection(format, dig[0] == 0 ? 2 : number.IsNegative ? 1 : 0); - - while (true) - { - digitCount = 0; - decimalPos = -1; - firstDigit = 0x7FFFFFFF; - lastDigit = 0; - scientific = false; - thousandPos = -1; - thousandSeps = false; - scaleAdjust = 0; - src = section; - - fixed (char* pFormat = &MemoryMarshal.GetReference(format)) - { - while (src < format.Length && (ch = pFormat[src++]) != 0 && ch != ';') - { - switch (ch) - { - case '#': - digitCount++; - break; - case '0': - if (firstDigit == 0x7FFFFFFF) - firstDigit = digitCount; - digitCount++; - lastDigit = digitCount; - break; - case '.': - if (decimalPos < 0) - decimalPos = digitCount; - break; - case ',': - if (digitCount > 0 && decimalPos < 0) - { - if (thousandPos >= 0) - { - if (thousandPos == digitCount) - { - thousandCount++; - break; - } - thousandSeps = true; - } - thousandPos = digitCount; - thousandCount = 1; - } - break; - case '%': - scaleAdjust += 2; - break; - case '\x2030': - scaleAdjust += 3; - break; - case '\'': - case '"': - while (src < format.Length && pFormat[src] != 0 && pFormat[src++] != ch) - ; - break; - case '\\': - if (src < format.Length && pFormat[src] != 0) - src++; - break; - case 'E': - case 'e': - if ((src < format.Length && pFormat[src] == '0') || - (src + 1 < format.Length && (pFormat[src] == '+' || pFormat[src] == '-') && pFormat[src + 1] == '0')) - { - while (++src < format.Length && pFormat[src] == '0') - ; - scientific = true; - } - break; - } - } - } - - if (decimalPos < 0) - decimalPos = digitCount; - - if (thousandPos >= 0) - { - if (thousandPos == decimalPos) - scaleAdjust -= thousandCount * 3; - else - thousandSeps = true; - } - - if (dig[0] != 0) - { - number.Scale += scaleAdjust; - int pos = scientific ? digitCount : number.Scale + digitCount - decimalPos; - RoundNumber(ref number, pos, isCorrectlyRounded: false); - if (dig[0] == 0) - { - src = FindSection(format, 2); - if (src != section) - { - section = src; - continue; - } - } - } - else - { - if (number.Kind != NumberBufferKind.FloatingPoint) - { - // The integer types don't have a concept of -0 and decimal always format -0 as 0 - number.IsNegative = false; - } - number.Scale = 0; // Decimals with scale ('0.00') should be rounded. - } - - break; - } - - firstDigit = firstDigit < decimalPos ? decimalPos - firstDigit : 0; - lastDigit = lastDigit > decimalPos ? decimalPos - lastDigit : 0; - if (scientific) - { - digPos = decimalPos; - adjust = 0; - } - else - { - digPos = number.Scale > decimalPos ? number.Scale : decimalPos; - adjust = number.Scale - decimalPos; - } - src = section; - - // Adjust can be negative, so we make this an int instead of an unsigned int. - // Adjust represents the number of characters over the formatting e.g. format string is "0000" and you are trying to - // format 100000 (6 digits). Means adjust will be 2. On the other hand if you are trying to format 10 adjust will be - // -2 and we'll need to fixup these digits with 0 padding if we have 0 formatting as in this example. - Span thousandsSepPos = stackalloc int[4]; - int thousandsSepCtr = -1; - - if (thousandSeps) - { - // We need to precompute this outside the number formatting loop - if (info.NumberGroupSeparator.Length > 0) - { - // We need this array to figure out where to insert the thousands separator. We would have to traverse the string - // backwards. PIC formatting always traverses forwards. These indices are precomputed to tell us where to insert - // the thousands separator so we can get away with traversing forwards. Note we only have to compute up to digPos. - // The max is not bound since you can have formatting strings of the form "000,000..", and this - // should handle that case too. - - int[] groupDigits = info.NumberGroupSizes; - - int groupSizeIndex = 0; // Index into the groupDigits array. - int groupTotalSizeCount = 0; - int groupSizeLen = groupDigits.Length; // The length of groupDigits array. - if (groupSizeLen != 0) - groupTotalSizeCount = groupDigits[groupSizeIndex]; // The current running total of group size. - int groupSize = groupTotalSizeCount; - - int totalDigits = digPos + ((adjust < 0) ? adjust : 0); // Actual number of digits in o/p - int numDigits = (firstDigit > totalDigits) ? firstDigit : totalDigits; - while (numDigits > groupTotalSizeCount) - { - if (groupSize == 0) - break; - ++thousandsSepCtr; - if (thousandsSepCtr >= thousandsSepPos.Length) - { - var newThousandsSepPos = new int[thousandsSepPos.Length * 2]; - thousandsSepPos.CopyTo(newThousandsSepPos); - thousandsSepPos = newThousandsSepPos; - } - - thousandsSepPos[thousandsSepCtr] = groupTotalSizeCount; - if (groupSizeIndex < groupSizeLen - 1) - { - groupSizeIndex++; - groupSize = groupDigits[groupSizeIndex]; - } - groupTotalSizeCount += groupSize; - } - } - } - - if (number.IsNegative && (section == 0) && (number.Scale != 0)) - sb.Append(info.NegativeSign); - - bool decimalWritten = false; - - fixed (char* pFormat = &MemoryMarshal.GetReference(format)) - { - byte* cur = dig; - - while (src < format.Length && (ch = pFormat[src++]) != 0 && ch != ';') - { - if (adjust > 0) - { - switch (ch) - { - case '#': - case '0': - case '.': - while (adjust > 0) - { - // digPos will be one greater than thousandsSepPos[thousandsSepCtr] since we are at - // the character after which the groupSeparator needs to be appended. - sb.Append(*cur != 0 ? (char)(*cur++) : '0'); - if (thousandSeps && digPos > 1 && thousandsSepCtr >= 0) - { - if (digPos == thousandsSepPos[thousandsSepCtr] + 1) - { - sb.Append(info.NumberGroupSeparator); - thousandsSepCtr--; - } - } - digPos--; - adjust--; - } - break; - } - } - - switch (ch) - { - case '#': - case '0': - { - if (adjust < 0) - { - adjust++; - ch = digPos <= firstDigit ? '0' : '\0'; - } - else - { - ch = *cur != 0 ? (char)(*cur++) : digPos > lastDigit ? '0' : '\0'; - } - if (ch != 0) - { - sb.Append(ch); - if (thousandSeps && digPos > 1 && thousandsSepCtr >= 0) - { - if (digPos == thousandsSepPos[thousandsSepCtr] + 1) - { - sb.Append(info.NumberGroupSeparator); - thousandsSepCtr--; - } - } - } - - digPos--; - break; - } - case '.': - { - if (digPos != 0 || decimalWritten) - { - // For compatibility, don't echo repeated decimals - break; - } - // If the format has trailing zeros or the format has a decimal and digits remain - if (lastDigit < 0 || (decimalPos < digitCount && *cur != 0)) - { - sb.Append(info.NumberDecimalSeparator); - decimalWritten = true; - } - break; - } - case '\x2030': - sb.Append(info.PerMilleSymbol); - break; - case '%': - sb.Append(info.PercentSymbol); - break; - case ',': - break; - case '\'': - case '"': - while (src < format.Length && pFormat[src] != 0 && pFormat[src] != ch) - sb.Append(pFormat[src++]); - if (src < format.Length && pFormat[src] != 0) - src++; - break; - case '\\': - if (src < format.Length && pFormat[src] != 0) - sb.Append(pFormat[src++]); - break; - case 'E': - case 'e': - { - bool positiveSign = false; - int i = 0; - if (scientific) - { - if (src < format.Length && pFormat[src] == '0') - { - // Handles E0, which should format the same as E-0 - i++; - } - else if (src + 1 < format.Length && pFormat[src] == '+' && pFormat[src + 1] == '0') - { - // Handles E+0 - positiveSign = true; - } - else if (src + 1 < format.Length && pFormat[src] == '-' && pFormat[src + 1] == '0') - { - // Handles E-0 - // Do nothing, this is just a place holder s.t. we don't break out of the loop. - } - else - { - sb.Append(ch); - break; - } - - while (++src < format.Length && pFormat[src] == '0') - i++; - if (i > 10) - i = 10; - - int exp = dig[0] == 0 ? 0 : number.Scale - decimalPos; - FormatExponent(ref sb, info, exp, ch, i, positiveSign); - scientific = false; - } - else - { - sb.Append(ch); // Copy E or e to output - if (src < format.Length) - { - if (pFormat[src] == '+' || pFormat[src] == '-') - sb.Append(pFormat[src++]); - while (src < format.Length && pFormat[src] == '0') - sb.Append(pFormat[src++]); - } - } - break; - } - default: - sb.Append(ch); - break; - } - } - } - - if (number.IsNegative && (section == 0) && (number.Scale == 0) && (sb.Length > 0)) - sb.Insert(0, info.NegativeSign); - } - - private static void FormatCurrency(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) - { - string fmt = number.IsNegative ? - s_negCurrencyFormats[info.CurrencyNegativePattern] : - s_posCurrencyFormats[info.CurrencyPositivePattern]; - - foreach (char ch in fmt) - { - switch (ch) - { - case '#': - FormatFixed(ref sb, ref number, nMaxDigits, info.CurrencyGroupSizes, info.CurrencyDecimalSeparator, info.CurrencyGroupSeparator); - break; - case '-': - sb.Append(info.NegativeSign); - break; - case '$': - sb.Append(info.CurrencySymbol); - break; - default: - sb.Append(ch); - break; - } - } - } - - private static unsafe void FormatFixed(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, int[] groupDigits, string sDecimal, string sGroup) - { - int digPos = number.Scale; - byte* dig = number.GetDigitsPointer(); - - if (digPos > 0) - { - if (groupDigits != null) - { - Debug.Assert(sGroup != null, "Must be nulll when groupDigits != null"); - int groupSizeIndex = 0; // Index into the groupDigits array. - int bufferSize = digPos; // The length of the result buffer string. - int groupSize = 0; // The current group size. - - // Find out the size of the string buffer for the result. - if (groupDigits.Length != 0) // You can pass in 0 length arrays - { - int groupSizeCount = groupDigits[groupSizeIndex]; // The current total of group size. - - while (digPos > groupSizeCount) - { - groupSize = groupDigits[groupSizeIndex]; - if (groupSize == 0) - break; - - bufferSize += sGroup.Length; - if (groupSizeIndex < groupDigits.Length - 1) - groupSizeIndex++; - - groupSizeCount += groupDigits[groupSizeIndex]; - if (groupSizeCount < 0 || bufferSize < 0) - throw new ArgumentOutOfRangeException(); // If we overflow - } - - groupSize = groupSizeCount == 0 ? 0 : groupDigits[0]; // If you passed in an array with one entry as 0, groupSizeCount == 0 - } - - groupSizeIndex = 0; - int digitCount = 0; - int digLength = number.DigitsCount; - int digStart = (digPos < digLength) ? digPos : digLength; - fixed (char* spanPtr = &MemoryMarshal.GetReference(sb.AppendSpan(bufferSize))) - { - char* p = spanPtr + bufferSize - 1; - for (int i = digPos - 1; i >= 0; i--) - { - *(p--) = (i < digStart) ? (char)(dig[i]) : '0'; - - if (groupSize > 0) - { - digitCount++; - if ((digitCount == groupSize) && (i != 0)) - { - for (int j = sGroup.Length - 1; j >= 0; j--) - *(p--) = sGroup[j]; - - if (groupSizeIndex < groupDigits.Length - 1) - { - groupSizeIndex++; - groupSize = groupDigits[groupSizeIndex]; - } - digitCount = 0; - } - } - } - - Debug.Assert(p >= spanPtr - 1, "Underflow"); - dig += digStart; - } - } - else - { - do - { - sb.Append(*dig != 0 ? (char)(*dig++) : '0'); - } - while (--digPos > 0); - } - } - else - { - sb.Append('0'); - } - - if (nMaxDigits > 0) - { - Debug.Assert(sDecimal != null); - sb.Append(sDecimal); - if ((digPos < 0) && (nMaxDigits > 0)) - { - int zeroes = Math.Min(-digPos, nMaxDigits); - sb.Append('0', zeroes); - digPos += zeroes; - nMaxDigits -= zeroes; - } - - while (nMaxDigits > 0) - { - sb.Append((*dig != 0) ? (char)(*dig++) : '0'); - nMaxDigits--; - } - } - } - - private static void FormatNumber(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) - { - string fmt = number.IsNegative ? - s_negNumberFormats[info.NumberNegativePattern] : - PosNumberFormat; - - foreach (char ch in fmt) - { - switch (ch) - { - case '#': - FormatFixed(ref sb, ref number, nMaxDigits, info.NumberGroupSizes, info.NumberDecimalSeparator, info.NumberGroupSeparator); - break; - case '-': - sb.Append(info.NegativeSign); - break; - default: - sb.Append(ch); - break; - } - } - } - - private static unsafe void FormatScientific(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar) - { - byte* dig = number.GetDigitsPointer(); - - sb.Append((*dig != 0) ? (char)(*dig++) : '0'); - - if (nMaxDigits != 1) // For E0 we would like to suppress the decimal point - sb.Append(info.NumberDecimalSeparator); - - while (--nMaxDigits > 0) - sb.Append((*dig != 0) ? (char)(*dig++) : '0'); - - int e = number.Digits[0] == 0 ? 0 : number.Scale - 1; - FormatExponent(ref sb, info, e, expChar, 3, true); - } - - private static unsafe void FormatExponent(ref ValueStringBuilder sb, NumberFormatInfo info, int value, char expChar, int minDigits, bool positiveSign) - { - sb.Append(expChar); - - if (value < 0) - { - sb.Append(info.NegativeSign); - value = -value; - } - else - { - if (positiveSign) - sb.Append(info.PositiveSign); - } - - char* digits = stackalloc char[MaxUInt32DecDigits]; - char* p = UInt32ToDecChars(digits + MaxUInt32DecDigits, (uint)value, minDigits); - sb.Append(p, (int)(digits + MaxUInt32DecDigits - p)); - } - - private static unsafe void FormatGeneral(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar, bool bSuppressScientific) - { - int digPos = number.Scale; - bool scientific = false; - - if (!bSuppressScientific) - { - // Don't switch to scientific notation - if (digPos > nMaxDigits || digPos < -3) - { - digPos = 1; - scientific = true; - } - } - - byte* dig = number.GetDigitsPointer(); - - if (digPos > 0) - { - do - { - sb.Append((*dig != 0) ? (char)(*dig++) : '0'); - } while (--digPos > 0); - } - else - { - sb.Append('0'); - } - - if (*dig != 0 || digPos < 0) - { - sb.Append(info.NumberDecimalSeparator); - - while (digPos < 0) - { - sb.Append('0'); - digPos++; - } - - while (*dig != 0) - sb.Append((char)(*dig++)); - } - - if (scientific) - FormatExponent(ref sb, info, number.Scale - 1, expChar, 2, true); - } - - private static void FormatPercent(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) - { - string fmt = number.IsNegative ? - s_negPercentFormats[info.PercentNegativePattern] : - s_posPercentFormats[info.PercentPositivePattern]; - - foreach (char ch in fmt) - { - switch (ch) - { - case '#': - FormatFixed(ref sb, ref number, nMaxDigits, info.PercentGroupSizes, info.PercentDecimalSeparator, info.PercentGroupSeparator); - break; - case '-': - sb.Append(info.NegativeSign); - break; - case '%': - sb.Append(info.PercentSymbol); - break; - default: - sb.Append(ch); - break; - } - } - } - - internal static unsafe void RoundNumber(ref NumberBuffer number, int pos, bool isCorrectlyRounded) - { - byte* dig = number.GetDigitsPointer(); - - int i = 0; - while (i < pos && dig[i] != '\0') - i++; - - if ((i == pos) && ShouldRoundUp(dig, i, number.Kind, isCorrectlyRounded)) - { - while (i > 0 && dig[i - 1] == '9') - i--; - - if (i > 0) - { - dig[i - 1]++; - } - else - { - number.Scale++; - dig[0] = (byte)('1'); - i = 1; - } - } - else - { - while (i > 0 && dig[i - 1] == '0') - i--; - } - - if (i == 0) - { - if (number.Kind != NumberBufferKind.FloatingPoint) - { - // The integer types don't have a concept of -0 and decimal always format -0 as 0 - number.IsNegative = false; - } - number.Scale = 0; // Decimals with scale ('0.00') should be rounded. - } - - dig[i] = (byte)('\0'); - number.DigitsCount = i; - number.CheckConsistency(); - - bool ShouldRoundUp(byte* _dig, int _i, NumberBufferKind numberKind, bool _isCorrectlyRounded) - { - // We only want to round up if the digit is greater than or equal to 5 and we are - // not rounding a floating-point number. If we are rounding a floating-point number - // we have one of two cases. - // - // In the case of a standard numeric-format specifier, the exact and correctly rounded - // string will have been produced. In this scenario, pos will have pointed to the - // terminating null for the buffer and so this will return false. - // - // However, in the case of a custom numeric-format specifier, we currently fall back - // to generating Single/DoublePrecisionCustomFormat digits and then rely on this - // function to round correctly instead. This can unfortunately lead to double-rounding - // bugs but is the best we have right now due to back-compat concerns. - - byte digit = _dig[_i]; - - if ((digit == '\0') || _isCorrectlyRounded) - { - // Fast path for the common case with no rounding - return false; - } - - // Values greater than or equal to 5 should round up, otherwise we round down. The IEEE - // 754 spec actually dictates that ties (exactly 5) should round to the nearest even number - // but that can have undesired behavior for custom numeric format strings. This probably - // needs further thought for .NET 5 so that we can be spec compliant and so that users - // can get the desired rounding behavior for their needs. - - return digit >= '5'; - } - } - - private static unsafe int FindSection(ReadOnlySpan format, int section) - { - int src; - char ch; - - if (section == 0) - return 0; - - fixed (char* pFormat = &MemoryMarshal.GetReference(format)) - { - src = 0; - while (true) - { - if (src >= format.Length) - { - return 0; - } - - switch (ch = pFormat[src++]) - { - case '\'': - case '"': - while (src < format.Length && pFormat[src] != 0 && pFormat[src++] != ch) ; - break; - case '\\': - if (src < format.Length && pFormat[src] != 0) - src++; - break; - case ';': - if (--section != 0) - break; - if (src < format.Length && pFormat[src] != 0 && pFormat[src] != ';') - return src; - goto case '\0'; - case '\0': - return 0; - } - } - } - } - - private static uint Low32(ulong value) => (uint)value; - - private static uint High32(ulong value) => (uint)((value & 0xFFFFFFFF00000000) >> 32); - - private static uint Int64DivMod1E9(ref ulong value) - { - uint rem = (uint)(value % 1000000000); - value /= 1000000000; - return rem; - } - - private static ulong ExtractFractionAndBiasedExponent(double value, out int exponent) - { - ulong bits = (ulong)(BitConverter.DoubleToInt64Bits(value)); - ulong fraction = (bits & 0xFFFFFFFFFFFFF); - exponent = ((int)(bits >> 52) & 0x7FF); - - if (exponent != 0) - { - // For normalized value, according to https://en.wikipedia.org/wiki/Double-precision_floating-point_format - // value = 1.fraction * 2^(exp - 1023) - // = (1 + mantissa / 2^52) * 2^(exp - 1023) - // = (2^52 + mantissa) * 2^(exp - 1023 - 52) - // - // So f = (2^52 + mantissa), e = exp - 1075; - - fraction |= (1UL << 52); - exponent -= 1075; - } - else - { - // For denormalized value, according to https://en.wikipedia.org/wiki/Double-precision_floating-point_format - // value = 0.fraction * 2^(1 - 1023) - // = (mantissa / 2^52) * 2^(-1022) - // = mantissa * 2^(-1022 - 52) - // = mantissa * 2^(-1074) - // So f = mantissa, e = -1074 - exponent = -1074; - } - - return fraction; - } - - private static uint ExtractFractionAndBiasedExponent(float value, out int exponent) - { - uint bits = (uint)(SingleToInt32Bits(value)); - uint fraction = (bits & 0x7FFFFF); - exponent = ((int)(bits >> 23) & 0xFF); - - if (exponent != 0) - { - // For normalized value, according to https://en.wikipedia.org/wiki/Single-precision_floating-point_format - // value = 1.fraction * 2^(exp - 127) - // = (1 + mantissa / 2^23) * 2^(exp - 127) - // = (2^23 + mantissa) * 2^(exp - 127 - 23) - // - // So f = (2^23 + mantissa), e = exp - 150; - - fraction |= (1U << 23); - exponent -= 150; - } - else - { - // For denormalized value, according to https://en.wikipedia.org/wiki/Single-precision_floating-point_format - // value = 0.fraction * 2^(1 - 127) - // = (mantissa / 2^23) * 2^(-126) - // = mantissa * 2^(-126 - 23) - // = mantissa * 2^(-149) - // So f = mantissa, e = -149 - exponent = -149; - } - - return fraction; - } - - static string FastAllocateString(int length) - { - return new string('\0', length); - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/Number.Formatting.cs.meta b/Plugins/ZString/Number/Number.Formatting.cs.meta deleted file mode 100644 index 5fec6865..00000000 --- a/Plugins/ZString/Number/Number.Formatting.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5424f58089802e74383c0f5c73ef3e33 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/Number.Grisu3.cs b/Plugins/ZString/Number/Number.Grisu3.cs deleted file mode 100644 index 49573aa2..00000000 --- a/Plugins/ZString/Number/Number.Grisu3.cs +++ /dev/null @@ -1,1067 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace System -{ - internal static partial class Number - { - // This is a port of the `Grisu3` implementation here: https://github.com/google/double-conversion/blob/a711666ddd063eb1e4b181a6cb981d39a1fc8bac/double-conversion/fast-dtoa.cc - // The backing algorithm and the proofs behind it are described in more detail here: http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf - // ======================================================================================================================================== - // - // Overview: - // - // The general idea behind Grisu3 is to leverage additional bits and cached powers of ten to generate the correct digits. - // The algorithm is imprecise for some numbers. Fortunately, the algorithm itself can determine this scenario and gives us - // a result indicating success or failure. We must fallback to a different algorithm for the failing scenario. - internal static class Grisu3 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static unsafe bool IsNegative(double d) - { - return BitConverter.DoubleToInt64Bits(d) < 0; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static unsafe bool IsNegativeInfinity(float f) - { - return f == float.NegativeInfinity; - } - - private const int CachedPowersDecimalExponentDistance = 8; - private const int CachedPowersMinDecimalExponent = -348; - private const int CachedPowersPowerMaxDecimalExponent = 340; - private const int CachedPowersOffset = -CachedPowersMinDecimalExponent; - - // 1 / Log2(10) - private const double D1Log210 = 0.301029995663981195; - - // The minimal and maximal target exponents define the range of w's binary exponent, - // where w is the result of multiplying the input by a cached power of ten. - // - // A different range might be chosen on a different platform, to optimize digit generation, - // but a smaller range requires more powers of ten to be cached. - private const int MaximalTargetExponent = -32; - private const int MinimalTargetExponent = -60; - - private static readonly short[] s_CachedPowersBinaryExponent = new short[] - { - -1220, - -1193, - -1166, - -1140, - -1113, - -1087, - -1060, - -1034, - -1007, - -980, - -954, - -927, - -901, - -874, - -847, - -821, - -794, - -768, - -741, - -715, - -688, - -661, - -635, - -608, - -582, - -555, - -529, - -502, - -475, - -449, - -422, - -396, - -369, - -343, - -316, - -289, - -263, - -236, - -210, - -183, - -157, - -130, - -103, - -77, - -50, - -24, - 3, - 30, - 56, - 83, - 109, - 136, - 162, - 189, - 216, - 242, - 269, - 295, - 322, - 348, - 375, - 402, - 428, - 455, - 481, - 508, - 534, - 561, - 588, - 614, - 641, - 667, - 694, - 720, - 747, - 774, - 800, - 827, - 853, - 880, - 907, - 933, - 960, - 986, - 1013, - 1039, - 1066, - }; - - private static readonly short[] s_CachedPowersDecimalExponent = new short[] - { - CachedPowersMinDecimalExponent, - -340, - -332, - -324, - -316, - -308, - -300, - -292, - -284, - -276, - -268, - -260, - -252, - -244, - -236, - -228, - -220, - -212, - -204, - -196, - -188, - -180, - -172, - -164, - -156, - -148, - -140, - -132, - -124, - -116, - -108, - -100, - -92, - -84, - -76, - -68, - -60, - -52, - -44, - -36, - -28, - -20, - -12, - -4, - 4, - 12, - 20, - 28, - 36, - 44, - 52, - 60, - 68, - 76, - 84, - 92, - 100, - 108, - 116, - 124, - 132, - 140, - 148, - 156, - 164, - 172, - 180, - 188, - 196, - 204, - 212, - 220, - 228, - 236, - 244, - 252, - 260, - 268, - 276, - 284, - 292, - 300, - 308, - 316, - 324, - 332, - CachedPowersPowerMaxDecimalExponent, - }; - - private static readonly ulong[] s_CachedPowersSignificand = new ulong[] - { - 0xFA8FD5A0081C0288, - 0xBAAEE17FA23EBF76, - 0x8B16FB203055AC76, - 0xCF42894A5DCE35EA, - 0x9A6BB0AA55653B2D, - 0xE61ACF033D1A45DF, - 0xAB70FE17C79AC6CA, - 0xFF77B1FCBEBCDC4F, - 0xBE5691EF416BD60C, - 0x8DD01FAD907FFC3C, - 0xD3515C2831559A83, - 0x9D71AC8FADA6C9B5, - 0xEA9C227723EE8BCB, - 0xAECC49914078536D, - 0x823C12795DB6CE57, - 0xC21094364DFB5637, - 0x9096EA6F3848984F, - 0xD77485CB25823AC7, - 0xA086CFCD97BF97F4, - 0xEF340A98172AACE5, - 0xB23867FB2A35B28E, - 0x84C8D4DFD2C63F3B, - 0xC5DD44271AD3CDBA, - 0x936B9FCEBB25C996, - 0xDBAC6C247D62A584, - 0xA3AB66580D5FDAF6, - 0xF3E2F893DEC3F126, - 0xB5B5ADA8AAFF80B8, - 0x87625F056C7C4A8B, - 0xC9BCFF6034C13053, - 0x964E858C91BA2655, - 0xDFF9772470297EBD, - 0xA6DFBD9FB8E5B88F, - 0xF8A95FCF88747D94, - 0xB94470938FA89BCF, - 0x8A08F0F8BF0F156B, - 0xCDB02555653131B6, - 0x993FE2C6D07B7FAC, - 0xE45C10C42A2B3B06, - 0xAA242499697392D3, - 0xFD87B5F28300CA0E, - 0xBCE5086492111AEB, - 0x8CBCCC096F5088CC, - 0xD1B71758E219652C, - 0x9C40000000000000, - 0xE8D4A51000000000, - 0xAD78EBC5AC620000, - 0x813F3978F8940984, - 0xC097CE7BC90715B3, - 0x8F7E32CE7BEA5C70, - 0xD5D238A4ABE98068, - 0x9F4F2726179A2245, - 0xED63A231D4C4FB27, - 0xB0DE65388CC8ADA8, - 0x83C7088E1AAB65DB, - 0xC45D1DF942711D9A, - 0x924D692CA61BE758, - 0xDA01EE641A708DEA, - 0xA26DA3999AEF774A, - 0xF209787BB47D6B85, - 0xB454E4A179DD1877, - 0x865B86925B9BC5C2, - 0xC83553C5C8965D3D, - 0x952AB45CFA97A0B3, - 0xDE469FBD99A05FE3, - 0xA59BC234DB398C25, - 0xF6C69A72A3989F5C, - 0xB7DCBF5354E9BECE, - 0x88FCF317F22241E2, - 0xCC20CE9BD35C78A5, - 0x98165AF37B2153DF, - 0xE2A0B5DC971F303A, - 0xA8D9D1535CE3B396, - 0xFB9B7CD9A4A7443C, - 0xBB764C4CA7A44410, - 0x8BAB8EEFB6409C1A, - 0xD01FEF10A657842C, - 0x9B10A4E5E9913129, - 0xE7109BFBA19C0C9D, - 0xAC2820D9623BF429, - 0x80444B5E7AA7CF85, - 0xBF21E44003ACDD2D, - 0x8E679C2F5E44FF8F, - 0xD433179D9C8CB841, - 0x9E19DB92B4E31BA9, - 0xEB96BF6EBADF77D9, - 0xAF87023B9BF0EE6B, - }; - - private static readonly uint[] s_SmallPowersOfTen = new uint[] - { - 1, // 10^0 - 10, // 10^1 - 100, // 10^2 - 1000, // 10^3 - 10000, // 10^4 - 100000, // 10^5 - 1000000, // 10^6 - 10000000, // 10^7 - 100000000, // 10^8 - 1000000000, // 10^9 - }; - - public static bool TryRunDouble(double value, int requestedDigits, ref NumberBuffer number) - { - double v = IsNegative(value) ? -value : value; - - Debug.Assert(v > 0); - //Debug.Assert(double.IsFinite(v)); - - int length; - int decimalExponent; - bool result; - - if (requestedDigits == -1) - { - DiyFp w = DiyFp.CreateAndGetBoundaries(v, out DiyFp boundaryMinus, out DiyFp boundaryPlus).Normalize(); - result = TryRunShortest(in boundaryMinus, in w, in boundaryPlus, number.Digits, out length, out decimalExponent); - } - else - { - DiyFp w = new DiyFp(v).Normalize(); - result = TryRunCounted(in w, requestedDigits, number.Digits, out length, out decimalExponent); - } - - if (result) - { - Debug.Assert((requestedDigits == -1) || (length == requestedDigits)); - - number.Scale = length + decimalExponent; - number.Digits[length] = (byte)('\0'); - number.DigitsCount = length; - } - - return result; - } - - public static bool TryRunSingle(float value, int requestedDigits, ref NumberBuffer number) - { - float v = IsNegative(value) ? -value : value; - - Debug.Assert(v > 0); - //Debug.Assert(float.IsFinite(v)); - - int length; - int decimalExponent; - bool result; - - if (requestedDigits == -1) - { - DiyFp w = DiyFp.CreateAndGetBoundaries(v, out DiyFp boundaryMinus, out DiyFp boundaryPlus).Normalize(); - result = TryRunShortest(in boundaryMinus, in w, in boundaryPlus, number.Digits, out length, out decimalExponent); - } - else - { - DiyFp w = new DiyFp(v).Normalize(); - result = TryRunCounted(in w, requestedDigits, number.Digits, out length, out decimalExponent); - } - - if (result) - { - Debug.Assert((requestedDigits == -1) || (length == requestedDigits)); - - number.Scale = length + decimalExponent; - number.Digits[length] = (byte)('\0'); - number.DigitsCount = length; - } - - return result; - } - - // The counted version of Grisu3 only generates requestedDigits number of digits. - // This version does not generate the shortest representation, and with enough requested digits 0.1 will at some point print as 0.9999999... - // Grisu3 is too imprecise for real halfway cases (1.5 will not work) and therefore the rounding strategy for halfway cases is irrelevant. - private static bool TryRunCounted(in DiyFp w, int requestedDigits, Span buffer, out int length, out int decimalExponent) - { - Debug.Assert(requestedDigits > 0); - - int tenMkMinimalBinaryExponent = MinimalTargetExponent - (w.e + DiyFp.SignificandSize); - int tenMkMaximalBinaryExponent = MaximalTargetExponent - (w.e + DiyFp.SignificandSize); - - DiyFp tenMk = GetCachedPowerForBinaryExponentRange(tenMkMinimalBinaryExponent, tenMkMaximalBinaryExponent, out int mk); - - Debug.Assert(MinimalTargetExponent <= (w.e + tenMk.e + DiyFp.SignificandSize)); - Debug.Assert(MaximalTargetExponent >= (w.e + tenMk.e + DiyFp.SignificandSize)); - - // Note that tenMk is only an approximation of 10^-k. - // A DiyFp only contains a 64-bit significand and tenMk is thus only precise up to 64-bits. - - // The DiyFp.Multiply procedure rounds its result and tenMk is approximated too. - // The variable scaledW (as well as scaledBoundaryMinus/Plus) are now off by a small amount. - // - // In fact, scaledW - (w * 10^k) < 1ulp (unit in last place) of scaledW. - // In other words, let f = scaledW.f and e = scaledW.e, then: - // (f - 1) * 2^e < (w * 10^k) < (f + 1) * 2^e - - DiyFp scaledW = w.Multiply(in tenMk); - - // We now have (double)(scaledW * 10^-mk). - // - // DigitGenCounted will generate the first requestedDigits of scaledW and return together with a kappa such that: - // scaledW ~= buffer * 10^kappa. - // - // It will not always be exactly the same since DigitGenCounted only produces a limited number of digits. - - bool result = TryDigitGenCounted(in scaledW, requestedDigits, buffer, out length, out int kappa); - decimalExponent = -mk + kappa; - return result; - } - - // Provides a decimal representation of v. - // Returns true if it succeeds; otherwise, the result cannot be trusted. - // - // There will be length digits inside the buffer (not null-terminated). - // If the function returns true then: - // v == (double)(buffer * 10^decimalExponent) - // - // The digits in the buffer are the shortest represenation possible (no 0.09999999999999999 instead of 0.1). - // The shorter representation will even be chosen if the longer one would be closer to v. - // - // The last digit will be closest to the actual v. - // That is, even if several digits might correctly yield 'v' when read again, the closest will be computed. - private static bool TryRunShortest(in DiyFp boundaryMinus, in DiyFp w, in DiyFp boundaryPlus, Span buffer, out int length, out int decimalExponent) - { - // boundaryMinus and boundaryPlus are the boundaries between v and its closest floating-point neighbors. - // Any number strictly between boundaryMinus and boundaryPlus will round to v when converted to a double. - // Grisu3 will never output representations that lie exactly on a boundary. - - Debug.Assert(boundaryPlus.e == w.e); - - int tenMkMinimalBinaryExponent = MinimalTargetExponent - (w.e + DiyFp.SignificandSize); - int tenMkMaximalBinaryExponent = MaximalTargetExponent - (w.e + DiyFp.SignificandSize); - - DiyFp tenMk = GetCachedPowerForBinaryExponentRange(tenMkMinimalBinaryExponent, tenMkMaximalBinaryExponent, out int mk); - - Debug.Assert(MinimalTargetExponent <= (w.e + tenMk.e + DiyFp.SignificandSize)); - Debug.Assert(MaximalTargetExponent >= (w.e + tenMk.e + DiyFp.SignificandSize)); - - // Note that tenMk is only an approximation of 10^-k. - // A DiyFp only contains a 64-bit significan and tenMk is thus only precise up to 64-bits. - - // The DiyFp.Multiply procedure rounds its result and tenMk is approximated too. - // The variable scaledW (as well as scaledBoundaryMinus/Plus) are now off by a small amount. - // - // In fact, scaledW - (w * 10^k) < 1ulp (unit in last place) of scaledW. - // In other words, let f = scaledW.f and e = scaledW.e, then: - // (f - 1) * 2^e < (w * 10^k) < (f + 1) * 2^e - - DiyFp scaledW = w.Multiply(in tenMk); - Debug.Assert(scaledW.e == (boundaryPlus.e + tenMk.e + DiyFp.SignificandSize)); - - // In theory, it would be possible to avoid some recomputations by computing the difference between w - // and boundaryMinus/Plus (a power of 2) and to compute scaledBoundaryMinus/Plus by subtracting/adding - // from scaledW. However, the code becomes much less readable and the speed enhancements are not terrific. - - DiyFp scaledBoundaryMinus = boundaryMinus.Multiply(in tenMk); - DiyFp scaledBoundaryPlus = boundaryPlus.Multiply(in tenMk); - - // DigitGen will generate the digits of scaledW. Therefore, we have: - // v == (double)(scaledW * 10^-mk) - // - // Set decimalExponent == -mk and pass it to DigitGen and if scaledW is not an integer than it will be updated. - // For instance, if scaledW == 1.23 then the buffer will be filled with "123" and the decimalExponent will be decreased by 2. - - bool result = TryDigitGenShortest(in scaledBoundaryMinus, in scaledW, in scaledBoundaryPlus, buffer, out length, out int kappa); - decimalExponent = -mk + kappa; - return result; - } - - // Returns the biggest power of ten that is less than or equal to the given number. - // We furthermore receive the maximum number of bits 'number' has. - // - // Returns power == 10^(exponent) such that - // power <= number < power * 10 - // If numberBits == 0, then 0^(0-1) is returned. - // The number of bits must be <= 32. - // - // Preconditions: - // number < (1 << (numberBits + 1)) - private static uint BiggestPowerTen(uint number, int numberBits, out int exponentPlusOne) - { - // Inspired by the method for finding an integer log base 10 from here: - // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - - Debug.Assert(number < (1U << (numberBits + 1))); - - // 1233/4096 is approximately 1/log2(10) - int exponentGuess = ((numberBits + 1) * 1233) >> 12; - Debug.Assert((uint)(exponentGuess) < s_SmallPowersOfTen.Length); - - uint power = s_SmallPowersOfTen[exponentGuess]; - - // We don't have any guarantees that 2^numberBits <= number - if (number < power) - { - exponentGuess--; - power = s_SmallPowersOfTen[exponentGuess]; - } - - exponentPlusOne = exponentGuess + 1; - return power; - } - - // Generates (at most) requestedDigits of input number w. - // - // w is a floating-point number (DiyFp), consisting of a significand and an exponent. - // Its exponent is bounded by MinimalTargetExponent and MaximalTargetExponent, hence: - // -60 <= w.e <= -32 - // - // Returns false if it fails, in which case the generated digits in the buffer should not be used. - // - // Preconditions: - // w is correct up to 1 ulp (unit in last place). That is, its error must be strictly less than a unit of its last digit. - // MinimalTargetExponent <= w.e <= MaximalTargetExponent - // - // Postconditions: - // Returns false if the procedure fails; otherwise: - // * buffer is not null-terminated, but length contains the number of digits. - // * The representation in buffer is the most precise representation of requestedDigits digits. - // * buffer contains at most requestedDigits digits of w. If there are less than requestedDigits digits then some trailing '0's have been removed. - // * kappa is such that w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2. - // - // This procedure takes into account the imprecision of its input numbers. - // If the precision is not enough to guarantee all the postconditions, then false is returned. - // This usually happens rarely, but the failure-rate increases with higher requestedDigits - private static bool TryDigitGenCounted(in DiyFp w, int requestedDigits, Span buffer, out int length, out int kappa) - { - Debug.Assert(MinimalTargetExponent <= w.e); - Debug.Assert(w.e <= MaximalTargetExponent); - Debug.Assert(MinimalTargetExponent >= -60); - Debug.Assert(MaximalTargetExponent <= -32); - - // w is assumed to have an error less than 1 unit. - // Whenever w is scaled we also scale its error. - ulong wError = 1; - - // We cut the input number into two parts: the integral digits and the fractional digits. - // We don't emit any decimal separator, but adapt kapp instead. - // For example: instead of writing "1.2", we put "12" into the buffer and increase kappa by 1. - var one = new DiyFp(1UL << -w.e, w.e); - - // Division by one is a shift. - uint integrals = (uint)(w.f >> -one.e); - - // Modulo by one is an and. - ulong fractionals = w.f & (one.f - 1); - - // We deviate from the original algorithm here and do some early checks to determine if we can satisfy requestedDigits. - // If we determine that we can't, we exit early and avoid most of the heavy lifting that the algorithm otherwise does. - // - // When fractionals is zero, we can easily determine if integrals can satisfy requested digits: - // If requestedDigits >= 11, integrals is not able to exhaust the count by itself since 10^(11 -1) > uint.MaxValue >= integrals. - // If integrals < 10^(requestedDigits - 1), integrals cannot exhaust the count. - // Otherwise, integrals might be able to exhaust the count and we need to execute the rest of the code. - if ((fractionals == 0) && ((requestedDigits >= 11) || (integrals < s_SmallPowersOfTen[requestedDigits - 1]))) - { - Debug.Assert(buffer[0] == '\0'); - length = 0; - kappa = 0; - return false; - } - - uint divisor = BiggestPowerTen(integrals, DiyFp.SignificandSize - (-one.e), out kappa); - length = 0; - - // Loop invariant: - // buffer = w / 10^kappa (integer division) - // These invariants hold for the first iteration: - // kappa has been initialized with the divisor exponent + 1 - // The divisor is the biggest power of ten that is smaller than integrals - while (kappa > 0) - { - uint digit = MathEx.DivRem(integrals, divisor, out integrals); - Debug.Assert(digit <= 9); - buffer[length] = (byte)('0' + digit); - - length++; - requestedDigits--; - kappa--; - - // Note that kappa now equals the exponent of the - // divisor and that the invariant thus holds again. - if (requestedDigits == 0) - { - break; - } - - divisor /= 10; - } - - if (requestedDigits == 0) - { - ulong rest = ((ulong)(integrals) << -one.e) + fractionals; - return TryRoundWeedCounted( - buffer, - length, - rest, - tenKappa: ((ulong)(divisor)) << -one.e, - unit: wError, - ref kappa - ); - } - - // The integrals have been generated and we are at the point of the decimal separator. - // In the following loop, we simply multiply the remaining digits by 10 and divide by one. - // We just need to pay attention to multiply associated data (the unit), too. - // Note that the multiplication by 10 does not overflow because: - // w.e >= -60 and thus one.e >= -60 - - Debug.Assert(one.e >= MinimalTargetExponent); - Debug.Assert(fractionals < one.f); - Debug.Assert((ulong.MaxValue / 10) >= one.f); - - while ((requestedDigits > 0) && (fractionals > wError)) - { - fractionals *= 10; - wError *= 10; - - // Integer division by one. - uint digit = (uint)(fractionals >> -one.e); - Debug.Assert(digit <= 9); - buffer[length] = (byte)('0' + digit); - - length++; - requestedDigits--; - kappa--; - - // Modulo by one. - fractionals &= (one.f - 1); - } - - if (requestedDigits != 0) - { - buffer[0] = (byte)('\0'); - length = 0; - kappa = 0; - return false; - } - - return TryRoundWeedCounted( - buffer, - length, - rest: fractionals, - tenKappa: one.f, - unit: wError, - ref kappa - ); - } - - // Generates the digits of input number w. - // - // w is a floating-point number (DiyFp), consisting of a significand and an exponent. - // Its exponent is bounded by kMinimalTargetExponent and kMaximalTargetExponent, hence: - // -60 <= w.e() <= -32. - // - // Returns false if it fails, in which case the generated digits in the buffer should not be used. - // - // Preconditions: - // low, w and high are correct up to 1 ulp (unit in the last place). That is, their error must be less than a unit of their last digits. - // low.e() == w.e() == high.e() - // low < w < high, and taking into account their error: low~ <= high~ - // kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent - // - // Postconditions: - // Returns false if procedure fails; otherwise: - // * buffer is not null-terminated, but len contains the number of digits. - // * buffer contains the shortest possible decimal digit-sequence such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the correct values of low and high (without their error). - // * If more than one decimal representation gives the minimal number of decimal digits then the one closest to W (where W is the correct value of w) is chosen. - // - // This procedure takes into account the imprecision of its input numbers. - // If the precision is not enough to guarantee all the postconditions then false is returned. - // This usually happens rarely (~0.5%). - // - // Say, for the sake of example, that: - // w.e() == -48, and w.f() == 0x1234567890abcdef - // - // w's value can be computed by w.f() * 2^w.e() - // - // We can obtain w's integral digits by simply shifting w.f() by -w.e(). - // -> w's integral part is 0x1234 - // w's fractional part is therefore 0x567890abcdef. - // - // Printing w's integral part is easy (simply print 0x1234 in decimal). - // - // In order to print its fraction we repeatedly multiply the fraction by 10 and get each digit. - // For example, the first digit after the point would be computed by - // (0x567890abcdef * 10) >> 48. -> 3 - // - // The whole thing becomes slightly more complicated because we want to stop once we have enough digits. - // That is, once the digits inside the buffer represent 'w' we can stop. - // - // Everything inside the interval low - high represents w. - // However we have to pay attention to low, high and w's imprecision. - private static bool TryDigitGenShortest(in DiyFp low, in DiyFp w, in DiyFp high, Span buffer, out int length, out int kappa) - { - Debug.Assert(low.e == w.e); - Debug.Assert(w.e == high.e); - - Debug.Assert((low.f + 1) <= (high.f - 1)); - - Debug.Assert(MinimalTargetExponent <= w.e); - Debug.Assert(w.e <= MaximalTargetExponent); - - // low, w, and high are imprecise, but by less than one ulp (unit in the last place). - // - // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that the new numbers - // are outside of the interval we want the final representation to lie in. - // - // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield numbers that - // are certain to lie in the interval. We will use this fact later on. - // - // We will now start by generating the digits within the uncertain interval. - // Later, we will weed out representations that lie outside the safe interval and thus might lie outside the correct interval. - - ulong unit = 1; - - var tooLow = new DiyFp(low.f - unit, low.e); - var tooHigh = new DiyFp(high.f + unit, high.e); - - // tooLow and tooHigh are guaranteed to lie outside the interval we want the generated number in. - - DiyFp unsafeInterval = tooHigh.Subtract(in tooLow); - - // We now cut the input number into two parts: the integral digits and the fractional digits. - // We will not write any decimal separator, but adapt kappa instead. - // - // Reminder: we are currently computing the digits (Stored inside the buffer) such that: - // tooLow < buffer * 10^kappa < tooHigh - // - // We use tooHigh for the digitGeneration and stop as soon as possible. - // If we stop early, we effectively round down. - - var one = new DiyFp(1UL << -w.e, w.e); - - // Division by one is a shift. - uint integrals = (uint)(tooHigh.f >> -one.e); - - // Modulo by one is an and. - ulong fractionals = tooHigh.f & (one.f - 1); - - uint divisor = BiggestPowerTen(integrals, DiyFp.SignificandSize - (-one.e), out kappa); - length = 0; - - // Loop invariant: - // buffer = tooHigh / 10^kappa (integer division) - // These invariants hold for the first iteration: - // kappa has been initialized with the divisor exponent + 1 - // The divisor is the biggest power of ten that is smaller than integrals - while (kappa > 0) - { - uint digit = MathEx.DivRem(integrals, divisor, out integrals); - Debug.Assert(digit <= 9); - buffer[length] = (byte)('0' + digit); - - length++; - kappa--; - - // Note that kappa now equals the exponent of the - // divisor and that the invariant thus holds again. - - ulong rest = ((ulong)(integrals) << -one.e) + fractionals; - - // Invariant: tooHigh = buffer * 10^kappa + DiyFp(rest, one.e) - // Reminder: unsafeInterval.e == one.e - - if (rest < unsafeInterval.f) - { - // Rounding down (by not emitting the remaining digits) - // yields a number that lies within the unsafe interval - - return TryRoundWeedShortest( - buffer, - length, - tooHigh.Subtract(w).f, - unsafeInterval.f, - rest, - tenKappa: ((ulong)(divisor)) << -one.e, - unit - ); - } - - divisor /= 10; - } - - // The integrals have been generated and we are at the point of the decimal separator. - // In the following loop, we simply multiply the remaining digits by 10 and divide by one. - // We just need to pay attention to multiply associated data (the unit), too. - // Note that the multiplication by 10 does not overflow because: - // w.e >= -60 and thus one.e >= -60 - - Debug.Assert(one.e >= MinimalTargetExponent); - Debug.Assert(fractionals < one.f); - Debug.Assert((ulong.MaxValue / 10) >= one.f); - - while (true) - { - fractionals *= 10; - unit *= 10; - - unsafeInterval = new DiyFp(unsafeInterval.f * 10, unsafeInterval.e); - - // Integer division by one. - uint digit = (uint)(fractionals >> -one.e); - Debug.Assert(digit <= 9); - buffer[length] = (byte)('0' + digit); - - length++; - kappa--; - - // Modulo by one. - fractionals &= (one.f - 1); - - if (fractionals < unsafeInterval.f) - { - return TryRoundWeedShortest( - buffer, - length, - tooHigh.Subtract(w).f * unit, - unsafeInterval.f, - rest: fractionals, - tenKappa: one.f, - unit - ); - } - } - } - - // Returns a cached power-of-ten with a binary exponent in the range [minExponent; maxExponent] (boundaries included). - private static DiyFp GetCachedPowerForBinaryExponentRange(int minExponent, int maxExponent, out int decimalExponent) - { - Debug.Assert(s_CachedPowersSignificand.Length == s_CachedPowersBinaryExponent.Length); - Debug.Assert(s_CachedPowersSignificand.Length == s_CachedPowersDecimalExponent.Length); - - double k = Math.Ceiling((minExponent + DiyFp.SignificandSize - 1) * D1Log210); - int index = ((CachedPowersOffset + (int)(k) - 1) / CachedPowersDecimalExponentDistance) + 1; - - Debug.Assert((uint)(index) < s_CachedPowersSignificand.Length); - - Debug.Assert(minExponent <= s_CachedPowersBinaryExponent[index]); - Debug.Assert(s_CachedPowersBinaryExponent[index] <= maxExponent); - - decimalExponent = s_CachedPowersDecimalExponent[index]; - return new DiyFp(s_CachedPowersSignificand[index], s_CachedPowersBinaryExponent[index]); - } - - // Rounds the buffer upwards if the result is closer to v by possibly adding 1 to the buffer. - // If the precision of the calculation is not sufficient to round correctly, return false. - // - // The rounding might shift the whole buffer, in which case, the kappy is adjusted. - // For example "99", kappa = 3 might become "10", kappa = 4. - // - // If (2 * rest) > tenKappa then the buffer needs to be round up. - // rest can have an error of +/- 1 unit. - // This function accounts for the imprecision and returns false if the rounding direction cannot be unambiguously determined. - // - // Preconditions: - // rest < tenKappa - private static bool TryRoundWeedCounted(Span buffer, int length, ulong rest, ulong tenKappa, ulong unit, ref int kappa) - { - Debug.Assert(rest < tenKappa); - - // The following tests are done in a specific order to avoid overflows. - // They will work correctly with any ulong values of rest < tenKappa and unit. - // - // If the unit is too big, then we don't know which way to round. - // For example, a unit of 50 means that the real number lies within rest +/- 50. - // If 10^kappa == 40, then there is no way to tell which way to round. - // - // Even if unit is just half the size of 10^kappa we are already completely lost. - // And after the previous test, we know that the expression will not over/underflow. - if ((unit >= tenKappa) || ((tenKappa - unit) <= unit)) - { - return false; - } - - // If 2 * (rest + unit) <= 10^kappa, we can safely round down. - if (((tenKappa - rest) > rest) && ((tenKappa - (2 * rest)) >= (2 * unit))) - { - return true; - } - - // If 2 * (rest - unit) >= 10^kappa, we can safely round up. - if ((rest > unit) && (tenKappa <= (rest - unit) || ((tenKappa - (rest - unit)) <= (rest - unit)))) - { - // Increment the last digit recursively until we find a non '9' digit. - buffer[length - 1]++; - - for (int i = (length - 1); i > 0; i--) - { - if (buffer[i] != ('0' + 10)) - { - break; - } - - buffer[i] = (byte)('0'); - buffer[i - 1]++; - } - - // If the first digit is now '0'+10, we had a buffer with all '9's. - // With the exception of the first digit, all digits are now '0'. - // Simply switch the first digit to '1' and adjust the kappa. - // For example, "99" becomes "10" and the power (the kappa) is increased. - if (buffer[0] == ('0' + 10)) - { - buffer[0] = (byte)('1'); - kappa++; - } - - return true; - } - - return false; - } - - // Adjusts the last digit of the generated number and screens out generated solutions that may be inaccurate. - // A solution may be inaccurate if it is outside the safe interval or if we cannot provide that it is closer to the input than a neighboring representation of the same length. - // - // Input: - // buffer containing the digits of tooHigh / 10^kappa - // the buffer's length - // distanceTooHighW == (tooHigh - w).f * unit - // unsafeInterval == (tooHigh - tooLow).f * unit - // rest = (tooHigh - buffer * 10^kapp).f * unit - // tenKappa = 10^kappa * unit - // unit = the common multiplier - // - // Output: - // Returns true if the buffer is guaranteed to contain the closest representable number to the input. - // - // Modifies the generated digits in the buffer to approach (round towards) w. - private static bool TryRoundWeedShortest(Span buffer, int length, ulong distanceTooHighW, ulong unsafeInterval, ulong rest, ulong tenKappa, ulong unit) - { - ulong smallDistance = distanceTooHighW - unit; - ulong bigDistance = distanceTooHighW + unit; - - // Let wLow = tooHigh - bigDistance, and wHigh = tooHigh - smallDistance. - // - // Note: wLow < w < wHigh - // - // The real w * unit must lie somewhere inside the interval - // ]w_low; w_high[ (often written as "(w_low; w_high)") - - // Basically the buffer currently contains a number in the unsafe interval - // ]too_low; too_high[ with too_low < w < too_high - // - // tooHigh - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ^v 1 unit ^ ^ ^ ^ - // boundaryHigh --------------------- . . . . - // ^v 1 unit . . . . - // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . - // . . ^ . . - // . bigDistance . . . - // . . . . rest - // smallDistance . . . . - // v . . . . - // wHigh - - - - - - - - - - - - - - - - - - . . . . - // ^v 1 unit . . . . - // w --------------------------------------- . . . . - // ^v 1 unit v . . . - // wLow - - - - - - - - - - - - - - - - - - - - - . . . - // . . v - // buffer -------------------------------------------------+-------+-------- - // . . - // safeInterval . - // v . - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . - // ^v 1 unit . - // boundaryLow ------------------------- unsafeInterval - // ^v 1 unit v - // tooLow - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - // - // Note that the value of buffer could lie anywhere inside the range tooLow to tooHigh. - // - // boundaryLow, boundaryHigh and w are approximations of the real boundaries and v (the input number). - // They are guaranteed to be precise up to one unit. - // In fact the error is guaranteed to be strictly less than one unit. - // - // Anything that lies outside the unsafe interval is guaranteed not to round to v when read again. - // Anything that lies inside the safe interval is guaranteed to round to v when read again. - // - // If the number inside the buffer lies inside the unsafe interval but not inside the safe interval - // then we simply do not know and bail out (returning false). - // - // Similarly we have to take into account the imprecision of 'w' when finding the closest representation of 'w'. - // If we have two potential representations, and one is closer to both wLow and wHigh, then we know it is closer to the actual value v. - // - // By generating the digits of tooHigh we got the largest (closest to tooHigh) buffer that is still in the unsafe interval. - // In the case where wHigh < buffer < tooHigh we try to decrement the buffer. - // This way the buffer approaches (rounds towards) w. - // - // There are 3 conditions that stop the decrementation process: - // 1) the buffer is already below wHigh - // 2) decrementing the buffer would make it leave the unsafe interval - // 3) decrementing the buffer would yield a number below wHigh and farther away than the current number. - // - // In other words: - // (buffer{-1} < wHigh) && wHigh - buffer{-1} > buffer - wHigh - // - // Instead of using the buffer directly we use its distance to tooHigh. - // - // Conceptually rest ~= tooHigh - buffer - // - // We need to do the following tests in this order to avoid over- and underflows. - - Debug.Assert(rest <= unsafeInterval); - - while ((rest < smallDistance) && ((unsafeInterval - rest) >= tenKappa) && (((rest + tenKappa) < smallDistance) || ((smallDistance - rest) >= (rest + tenKappa - smallDistance)))) - { - buffer[length - 1]--; - rest += tenKappa; - } - - // We have approached w+ as much as possible. - // We now test if approaching w- would require changing the buffer. - // If yes, then we have two possible representations close to w, but we cannot decide which one is closer. - if ((rest < bigDistance) && ((unsafeInterval - rest) >= tenKappa) && (((rest + tenKappa) < bigDistance) || ((bigDistance - rest) > (rest + tenKappa - bigDistance)))) - { - return false; - } - - // Weeding test. - // - // The safe interval is [tooLow + 2 ulp; tooHigh - 2 ulp] - // Since tooLow = tooHigh - unsafeInterval this is equivalent to - // [tooHigh - unsafeInterval + 4 ulp; tooHigh - 2 ulp] - // - // Conceptually we have: rest ~= tooHigh - buffer - return ((2 * unit) <= rest) && (rest <= (unsafeInterval - 4 * unit)); - } - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/Number.Grisu3.cs.meta b/Plugins/ZString/Number/Number.Grisu3.cs.meta deleted file mode 100644 index 3fa3f024..00000000 --- a/Plugins/ZString/Number/Number.Grisu3.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5447d418e8d20414f941dc0316a0af97 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/Number.NumberBuffer.cs b/Plugins/ZString/Number/Number.NumberBuffer.cs deleted file mode 100644 index b9350468..00000000 --- a/Plugins/ZString/Number/Number.NumberBuffer.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Text; - -namespace System -{ - internal static partial class Number - { - // We need 1 additional byte, per length, for the terminating null - internal const int DecimalNumberBufferLength = 29 + 1 + 1; // 29 for the longest input + 1 for rounding - internal const int DoubleNumberBufferLength = 767 + 1 + 1; // 767 for the longest input + 1 for rounding: 4.9406564584124654E-324 - internal const int Int32NumberBufferLength = 10 + 1; // 10 for the longest input: 2,147,483,647 - internal const int Int64NumberBufferLength = 19 + 1; // 19 for the longest input: 9,223,372,036,854,775,807 - internal const int SingleNumberBufferLength = 112 + 1 + 1; // 112 for the longest input + 1 for rounding: 1.40129846E-45 - internal const int UInt32NumberBufferLength = 10 + 1; // 10 for the longest input: 4,294,967,295 - internal const int UInt64NumberBufferLength = 20 + 1; // 20 for the longest input: 18,446,744,073,709,551,615 - - internal unsafe ref struct NumberBuffer - { - public int DigitsCount; - public int Scale; - public bool IsNegative; - public bool HasNonZeroTail; - public NumberBufferKind Kind; - public Span Digits; - - public NumberBuffer(NumberBufferKind kind, byte* digits, int digitsLength) - { - Debug.Assert(digits != null); - Debug.Assert(digitsLength > 0); - - DigitsCount = 0; - Scale = 0; - IsNegative = false; - HasNonZeroTail = false; - Kind = kind; - Digits = new Span(digits, digitsLength); - -#if DEBUG - Digits.Fill(0xCC); -#endif - - Digits[0] = (byte)('\0'); - CheckConsistency(); - } - - [Conditional("DEBUG")] - public void CheckConsistency() - { -#if DEBUG - Debug.Assert((Kind == NumberBufferKind.Integer) || (Kind == NumberBufferKind.Decimal) || (Kind == NumberBufferKind.FloatingPoint)); - Debug.Assert(Digits[0] != '0', "Leading zeros should never be stored in a Number"); - - int numDigits; - for (numDigits = 0; numDigits < Digits.Length; numDigits++) - { - byte digit = Digits[numDigits]; - - if (digit == 0) - { - break; - } - - Debug.Assert((digit >= '0') && (digit <= '9'), "Unexpected character found in Number"); - } - - Debug.Assert(numDigits == DigitsCount, "Null terminator found in unexpected location in Number"); - Debug.Assert(numDigits < Digits.Length, "Null terminator not found in Number"); -#endif // DEBUG - } - - public byte* GetDigitsPointer() - { - // This is safe to do since we are a ref struct - return (byte*)(Unsafe.AsPointer(ref Digits[0])); - } - - // - // Code coverage note: This only exists so that Number displays nicely in the VS watch window. So yes, I know it works. - // - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - - sb.Append('['); - sb.Append('"'); - - for (int i = 0; i < Digits.Length; i++) - { - byte digit = Digits[i]; - - if (digit == 0) - { - break; - } - - sb.Append((char)(digit)); - } - - sb.Append('"'); - sb.Append(", Length = ").Append(DigitsCount); - sb.Append(", Scale = ").Append(Scale); - sb.Append(", IsNegative = ").Append(IsNegative); - sb.Append(", HasNonZeroTail = ").Append(HasNonZeroTail); - sb.Append(", Kind = ").Append(Kind); - sb.Append(']'); - - return sb.ToString(); - } - } - - internal enum NumberBufferKind : byte - { - Unknown = 0, - Integer = 1, - Decimal = 2, - FloatingPoint = 3, - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/Number.NumberBuffer.cs.meta b/Plugins/ZString/Number/Number.NumberBuffer.cs.meta deleted file mode 100644 index f0209ca2..00000000 --- a/Plugins/ZString/Number/Number.NumberBuffer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 87bdf9f8d442e2842b3821eea6b35164 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/Number.NumberToFloatingPointBits.cs b/Plugins/ZString/Number/Number.NumberToFloatingPointBits.cs deleted file mode 100644 index d0bf894c..00000000 --- a/Plugins/ZString/Number/Number.NumberToFloatingPointBits.cs +++ /dev/null @@ -1,637 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace System -{ - internal unsafe partial class Number - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static unsafe int SingleToInt32Bits(float value) - { - return *((int*)&value); - } - - public readonly struct FloatingPointInfo - { - public static readonly FloatingPointInfo Double = new FloatingPointInfo( - denormalMantissaBits: 52, - exponentBits: 11, - maxBinaryExponent: 1023, - exponentBias: 1023, - infinityBits: 0x7FF00000_00000000 - ); - - public static readonly FloatingPointInfo Single = new FloatingPointInfo( - denormalMantissaBits: 23, - exponentBits: 8, - maxBinaryExponent: 127, - exponentBias: 127, - infinityBits: 0x7F800000 - ); - - public ulong ZeroBits { get; } - public ulong InfinityBits { get; } - - public ulong NormalMantissaMask { get; } - public ulong DenormalMantissaMask { get; } - - public int MinBinaryExponent { get; } - public int MaxBinaryExponent { get; } - - public int ExponentBias { get; } - public int OverflowDecimalExponent { get; } - - public ushort NormalMantissaBits { get; } - public ushort DenormalMantissaBits { get; } - - public ushort ExponentBits { get; } - - public FloatingPointInfo(ushort denormalMantissaBits, ushort exponentBits, int maxBinaryExponent, int exponentBias, ulong infinityBits) - { - ExponentBits = exponentBits; - - DenormalMantissaBits = denormalMantissaBits; - NormalMantissaBits = (ushort)(denormalMantissaBits + 1); // we get an extra (hidden) bit for normal mantissas - - OverflowDecimalExponent = (maxBinaryExponent + 2 * NormalMantissaBits) / 3; - ExponentBias = exponentBias; - - MaxBinaryExponent = maxBinaryExponent; - MinBinaryExponent = 1 - maxBinaryExponent; - - DenormalMantissaMask = (1UL << denormalMantissaBits) - 1; - NormalMantissaMask = (1UL << NormalMantissaBits) - 1; - - InfinityBits = infinityBits; - ZeroBits = 0; - } - } - - private static readonly float[] s_Pow10SingleTable = new float[] - { - 1e0f, // 10^0 - 1e1f, // 10^1 - 1e2f, // 10^2 - 1e3f, // 10^3 - 1e4f, // 10^4 - 1e5f, // 10^5 - 1e6f, // 10^6 - 1e7f, // 10^7 - 1e8f, // 10^8 - 1e9f, // 10^9 - 1e10f, // 10^10 - }; - - private static readonly double[] s_Pow10DoubleTable = new double[] - { - 1e0, // 10^0 - 1e1, // 10^1 - 1e2, // 10^2 - 1e3, // 10^3 - 1e4, // 10^4 - 1e5, // 10^5 - 1e6, // 10^6 - 1e7, // 10^7 - 1e8, // 10^8 - 1e9, // 10^9 - 1e10, // 10^10 - 1e11, // 10^11 - 1e12, // 10^12 - 1e13, // 10^13 - 1e14, // 10^14 - 1e15, // 10^15 - 1e16, // 10^16 - 1e17, // 10^17 - 1e18, // 10^18 - 1e19, // 10^19 - 1e20, // 10^20 - 1e21, // 10^21 - 1e22, // 10^22 - }; - - private static void AccumulateDecimalDigitsIntoBigInteger(ref NumberBuffer number, uint firstIndex, uint lastIndex, out BigInteger result) - { - BigInteger.SetZero(out result); - - byte* src = number.GetDigitsPointer() + firstIndex; - uint remaining = lastIndex - firstIndex; - - while (remaining != 0) - { - uint count = Math.Min(remaining, 9); - uint value = DigitsToUInt32(src, (int)(count)); - - result.MultiplyPow10(count); - result.Add(value); - - src += count; - remaining -= count; - } - } - - private static ulong AssembleFloatingPointBits(in FloatingPointInfo info, ulong initialMantissa, int initialExponent, bool hasZeroTail) - { - // number of bits by which we must adjust the mantissa to shift it into the - // correct position, and compute the resulting base two exponent for the - // normalized mantissa: - uint initialMantissaBits = BigInteger.CountSignificantBits(initialMantissa); - int normalMantissaShift = info.NormalMantissaBits - (int)(initialMantissaBits); - int normalExponent = initialExponent - normalMantissaShift; - - ulong mantissa = initialMantissa; - int exponent = normalExponent; - - if (normalExponent > info.MaxBinaryExponent) - { - // The exponent is too large to be represented by the floating point - // type; report the overflow condition: - return info.InfinityBits; - } - else if (normalExponent < info.MinBinaryExponent) - { - // The exponent is too small to be represented by the floating point - // type as a normal value, but it may be representable as a denormal - // value. Compute the number of bits by which we need to shift the - // mantissa in order to form a denormal number. (The subtraction of - // an extra 1 is to account for the hidden bit of the mantissa that - // is not available for use when representing a denormal.) - int denormalMantissaShift = normalMantissaShift + normalExponent + info.ExponentBias - 1; - - // Denormal values have an exponent of zero, so the debiased exponent is - // the negation of the exponent bias: - exponent = -info.ExponentBias; - - if (denormalMantissaShift < 0) - { - // Use two steps for right shifts: for a shift of N bits, we first - // shift by N-1 bits, then shift the last bit and use its value to - // round the mantissa. - mantissa = RightShiftWithRounding(mantissa, -denormalMantissaShift, hasZeroTail); - - // If the mantissa is now zero, we have underflowed: - if (mantissa == 0) - { - return info.ZeroBits; - } - - // When we round the mantissa, the result may be so large that the - // number becomes a normal value. For example, consider the single - // precision case where the mantissa is 0x01ffffff and a right shift - // of 2 is required to shift the value into position. We perform the - // shift in two steps: we shift by one bit, then we shift again and - // round using the dropped bit. The initial shift yields 0x00ffffff. - // The rounding shift then yields 0x007fffff and because the least - // significant bit was 1, we add 1 to this number to round it. The - // final result is 0x00800000. - // - // 0x00800000 is 24 bits, which is more than the 23 bits available - // in the mantissa. Thus, we have rounded our denormal number into - // a normal number. - // - // We detect this case here and re-adjust the mantissa and exponent - // appropriately, to form a normal number: - if (mantissa > info.DenormalMantissaMask) - { - // We add one to the denormal_mantissa_shift to account for the - // hidden mantissa bit (we subtracted one to account for this bit - // when we computed the denormal_mantissa_shift above). - exponent = initialExponent - (denormalMantissaShift + 1) - normalMantissaShift; - } - } - else - { - mantissa <<= denormalMantissaShift; - } - } - else - { - if (normalMantissaShift < 0) - { - // Use two steps for right shifts: for a shift of N bits, we first - // shift by N-1 bits, then shift the last bit and use its value to - // round the mantissa. - mantissa = RightShiftWithRounding(mantissa, -normalMantissaShift, hasZeroTail); - - // When we round the mantissa, it may produce a result that is too - // large. In this case, we divide the mantissa by two and increment - // the exponent (this does not change the value). - if (mantissa > info.NormalMantissaMask) - { - mantissa >>= 1; - exponent++; - - // The increment of the exponent may have generated a value too - // large to be represented. In this case, report the overflow: - if (exponent > info.MaxBinaryExponent) - { - return info.InfinityBits; - } - } - } - else if (normalMantissaShift > 0) - { - mantissa <<= normalMantissaShift; - } - } - - // Unset the hidden bit in the mantissa and assemble the floating point value - // from the computed components: - mantissa &= info.DenormalMantissaMask; - - Debug.Assert((info.DenormalMantissaMask & (1UL << info.DenormalMantissaBits)) == 0); - ulong shiftedExponent = ((ulong)(exponent + info.ExponentBias)) << info.DenormalMantissaBits; - Debug.Assert((shiftedExponent & info.DenormalMantissaMask) == 0); - Debug.Assert((mantissa & ~info.DenormalMantissaMask) == 0); - Debug.Assert((shiftedExponent & ~(((1UL << info.ExponentBits) - 1) << info.DenormalMantissaBits)) == 0); // exponent fits in its place - - return shiftedExponent | mantissa; - } - - private static ulong ConvertBigIntegerToFloatingPointBits(ref BigInteger value, in FloatingPointInfo info, uint integerBitsOfPrecision, bool hasNonZeroFractionalPart) - { - int baseExponent = info.DenormalMantissaBits; - - // When we have 64-bits or less of precision, we can just get the mantissa directly - if (integerBitsOfPrecision <= 64) - { - return AssembleFloatingPointBits(in info, value.ToUInt64(), baseExponent, !hasNonZeroFractionalPart); - } - - uint topBlockIndex = MathEx.DivRem(integerBitsOfPrecision, 32, out uint topBlockBits); - uint middleBlockIndex = topBlockIndex - 1; - uint bottomBlockIndex = middleBlockIndex - 1; - - ulong mantissa; - int exponent = baseExponent + ((int)(bottomBlockIndex) * 32); - bool hasZeroTail = !hasNonZeroFractionalPart; - - // When the top 64-bits perfectly span two blocks, we can get those blocks directly - if (topBlockBits == 0) - { - mantissa = ((ulong)(value.GetBlock(middleBlockIndex)) << 32) + value.GetBlock(bottomBlockIndex); - } - else - { - // Otherwise, we need to read three blocks and combine them into a 64-bit mantissa - - int bottomBlockShift = (int)(topBlockBits); - int topBlockShift = 64 - bottomBlockShift; - int middleBlockShift = topBlockShift - 32; - - exponent += (int)(topBlockBits); - - uint bottomBlock = value.GetBlock(bottomBlockIndex); - uint bottomBits = bottomBlock >> bottomBlockShift; - - ulong middleBits = (ulong)(value.GetBlock(middleBlockIndex)) << middleBlockShift; - ulong topBits = (ulong)(value.GetBlock(topBlockIndex)) << topBlockShift; - - mantissa = topBits + middleBits + bottomBits; - - uint unusedBottomBlockBitsMask = (1u << (int)(topBlockBits)) - 1; - hasZeroTail &= (bottomBlock & unusedBottomBlockBitsMask) == 0; - } - - for (uint i = 0; i != bottomBlockIndex; i++) - { - hasZeroTail &= (value.GetBlock(i) == 0); - } - - return AssembleFloatingPointBits(in info, mantissa, exponent, hasZeroTail); - } - - // get 32-bit integer from at most 9 digits - private static uint DigitsToUInt32(byte* p, int count) - { - Debug.Assert((1 <= count) && (count <= 9)); - - byte* end = (p + count); - uint res = (uint)(p[0] - '0'); - - for (p++; p < end; p++) - { - res = (10 * res) + p[0] - '0'; - } - - return res; - } - - // get 64-bit integer from at most 19 digits - private static ulong DigitsToUInt64(byte* p, int count) - { - Debug.Assert((1 <= count) && (count <= 19)); - - byte* end = (p + count); - ulong res = (ulong)(p[0] - '0'); - - for (p++; p < end; p++) - { - res = (10 * res) + p[0] - '0'; - } - - return res; - } - - private static ulong NumberToFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info) - { - Debug.Assert(number.GetDigitsPointer()[0] != '0'); - - Debug.Assert(number.Scale <= FloatingPointMaxExponent); - Debug.Assert(number.Scale >= FloatingPointMinExponent); - - Debug.Assert(number.DigitsCount != 0); - - // The input is of the form 0.Mantissa x 10^Exponent, where 'Mantissa' are - // the decimal digits of the mantissa and 'Exponent' is the decimal exponent. - // We decompose the mantissa into two parts: an integer part and a fractional - // part. If the exponent is positive, then the integer part consists of the - // first 'exponent' digits, or all present digits if there are fewer digits. - // If the exponent is zero or negative, then the integer part is empty. In - // either case, the remaining digits form the fractional part of the mantissa. - - uint totalDigits = (uint)(number.DigitsCount); - uint positiveExponent = (uint)(Math.Max(0, number.Scale)); - - uint integerDigitsPresent = Math.Min(positiveExponent, totalDigits); - uint fractionalDigitsPresent = totalDigits - integerDigitsPresent; - - uint fastExponent = (uint)(Math.Abs(number.Scale - integerDigitsPresent - fractionalDigitsPresent)); - - // When the number of significant digits is less than or equal to 15 and the - // scale is less than or equal to 22, we can take some shortcuts and just rely - // on floating-point arithmetic to compute the correct result. This is - // because each floating-point precision values allows us to exactly represent - // different whole integers and certain powers of 10, depending on the underlying - // formats exact range. Additionally, IEEE operations dictate that the result is - // computed to the infinitely precise result and then rounded, which means that - // we can rely on it to produce the correct result when both inputs are exact. - - byte* src = number.GetDigitsPointer(); - - if ((info.DenormalMantissaBits == 23) && (totalDigits <= 7) && (fastExponent <= 10)) - { - // It is only valid to do this optimization for single-precision floating-point - // values since we can lose some of the mantissa bits and would return the - // wrong value when upcasting to double. - - float result = DigitsToUInt32(src, (int)(totalDigits)); - float scale = s_Pow10SingleTable[fastExponent]; - - if (fractionalDigitsPresent != 0) - { - result /= scale; - } - else - { - result *= scale; - } - - return (uint)(SingleToInt32Bits(result)); - } - - if ((totalDigits <= 15) && (fastExponent <= 22)) - { - double result = DigitsToUInt64(src, (int)(totalDigits)); - double scale = s_Pow10DoubleTable[fastExponent]; - - if (fractionalDigitsPresent != 0) - { - result /= scale; - } - else - { - result *= scale; - } - - if (info.DenormalMantissaBits == 52) - { - return (ulong)(BitConverter.DoubleToInt64Bits(result)); - } - else - { - Debug.Assert(info.DenormalMantissaBits == 23); - return (uint)(SingleToInt32Bits((float)(result))); - } - } - - return NumberToFloatingPointBitsSlow(ref number, in info, positiveExponent, integerDigitsPresent, fractionalDigitsPresent); - } - - private static ulong NumberToFloatingPointBitsSlow(ref NumberBuffer number, in FloatingPointInfo info, uint positiveExponent, uint integerDigitsPresent, uint fractionalDigitsPresent) - { - // To generate an N bit mantissa we require N + 1 bits of precision. The - // extra bit is used to correctly round the mantissa (if there are fewer bits - // than this available, then that's totally okay; in that case we use what we - // have and we don't need to round). - uint requiredBitsOfPrecision = (uint)(info.NormalMantissaBits + 1); - - uint totalDigits = (uint)(number.DigitsCount); - uint integerDigitsMissing = positiveExponent - integerDigitsPresent; - - const uint IntegerFirstIndex = 0; - uint integerLastIndex = integerDigitsPresent; - - uint fractionalFirstIndex = integerLastIndex; - uint fractionalLastIndex = totalDigits; - - // First, we accumulate the integer part of the mantissa into a big_integer: - AccumulateDecimalDigitsIntoBigInteger(ref number, IntegerFirstIndex, integerLastIndex, out BigInteger integerValue); - - if (integerDigitsMissing > 0) - { - if (integerDigitsMissing > info.OverflowDecimalExponent) - { - return info.InfinityBits; - } - - integerValue.MultiplyPow10(integerDigitsMissing); - } - - // At this point, the integer_value contains the value of the integer part - // of the mantissa. If either [1] this number has more than the required - // number of bits of precision or [2] the mantissa has no fractional part, - // then we can assemble the result immediately: - uint integerBitsOfPrecision = BigInteger.CountSignificantBits(ref integerValue); - - if ((integerBitsOfPrecision >= requiredBitsOfPrecision) || (fractionalDigitsPresent == 0)) - { - return ConvertBigIntegerToFloatingPointBits( - ref integerValue, - in info, - integerBitsOfPrecision, - fractionalDigitsPresent != 0 - ); - } - - // Otherwise, we did not get enough bits of precision from the integer part, - // and the mantissa has a fractional part. We parse the fractional part of - // the mantissa to obtain more bits of precision. To do this, we convert - // the fractional part into an actual fraction N/M, where the numerator N is - // computed from the digits of the fractional part, and the denominator M is - // computed as the power of 10 such that N/M is equal to the value of the - // fractional part of the mantissa. - - uint fractionalDenominatorExponent = fractionalDigitsPresent; - - if (number.Scale < 0) - { - fractionalDenominatorExponent += (uint)(-number.Scale); - } - - if ((integerBitsOfPrecision == 0) && (fractionalDenominatorExponent - (int)(totalDigits)) > info.OverflowDecimalExponent) - { - // If there were any digits in the integer part, it is impossible to - // underflow (because the exponent cannot possibly be small enough), - // so if we underflow here it is a true underflow and we return zero. - return info.ZeroBits; - } - - AccumulateDecimalDigitsIntoBigInteger(ref number, fractionalFirstIndex, fractionalLastIndex, out BigInteger fractionalNumerator); - - if (fractionalNumerator.IsZero()) - { - return ConvertBigIntegerToFloatingPointBits( - ref integerValue, - in info, - integerBitsOfPrecision, - fractionalDigitsPresent != 0 - ); - } - - BigInteger.Pow10(fractionalDenominatorExponent, out BigInteger fractionalDenominator); - - // Because we are using only the fractional part of the mantissa here, the - // numerator is guaranteed to be smaller than the denominator. We normalize - // the fraction such that the most significant bit of the numerator is in - // the same position as the most significant bit in the denominator. This - // ensures that when we later shift the numerator N bits to the left, we - // will produce N bits of precision. - uint fractionalNumeratorBits = BigInteger.CountSignificantBits(ref fractionalNumerator); - uint fractionalDenominatorBits = BigInteger.CountSignificantBits(ref fractionalDenominator); - - uint fractionalShift = 0; - - if (fractionalDenominatorBits > fractionalNumeratorBits) - { - fractionalShift = fractionalDenominatorBits - fractionalNumeratorBits; - } - - if (fractionalShift > 0) - { - fractionalNumerator.ShiftLeft(fractionalShift); - } - - uint requiredFractionalBitsOfPrecision = requiredBitsOfPrecision - integerBitsOfPrecision; - uint remainingBitsOfPrecisionRequired = requiredFractionalBitsOfPrecision; - - if (integerBitsOfPrecision > 0) - { - // If the fractional part of the mantissa provides no bits of precision - // and cannot affect rounding, we can just take whatever bits we got from - // the integer part of the mantissa. This is the case for numbers like - // 5.0000000000000000000001, where the significant digits of the fractional - // part start so far to the right that they do not affect the floating - // point representation. - // - // If the fractional shift is exactly equal to the number of bits of - // precision that we require, then no fractional bits will be part of the - // result, but the result may affect rounding. This is e.g. the case for - // large, odd integers with a fractional part greater than or equal to .5. - // Thus, we need to do the division to correctly round the result. - if (fractionalShift > remainingBitsOfPrecisionRequired) - { - return ConvertBigIntegerToFloatingPointBits( - ref integerValue, - in info, - integerBitsOfPrecision, - fractionalDigitsPresent != 0 - ); - } - - remainingBitsOfPrecisionRequired -= fractionalShift; - } - - // If there was no integer part of the mantissa, we will need to compute the - // exponent from the fractional part. The fractional exponent is the power - // of two by which we must multiply the fractional part to move it into the - // range [1.0, 2.0). This will either be the same as the shift we computed - // earlier, or one greater than that shift: - uint fractionalExponent = fractionalShift; - - if (BigInteger.Compare(ref fractionalNumerator, ref fractionalDenominator) < 0) - { - fractionalExponent++; - } - - fractionalNumerator.ShiftLeft(remainingBitsOfPrecisionRequired); - - BigInteger.DivRem(ref fractionalNumerator, ref fractionalDenominator, out BigInteger bigFractionalMantissa, out BigInteger fractionalRemainder); - ulong fractionalMantissa = bigFractionalMantissa.ToUInt64(); - bool hasZeroTail = !number.HasNonZeroTail && fractionalRemainder.IsZero(); - - // We may have produced more bits of precision than were required. Check, - // and remove any "extra" bits: - uint fractionalMantissaBits = BigInteger.CountSignificantBits(fractionalMantissa); - - if (fractionalMantissaBits > requiredFractionalBitsOfPrecision) - { - int shift = (int)(fractionalMantissaBits - requiredFractionalBitsOfPrecision); - hasZeroTail = hasZeroTail && (fractionalMantissa & ((1UL << shift) - 1)) == 0; - fractionalMantissa >>= shift; - } - - // Compose the mantissa from the integer and fractional parts: - ulong integerMantissa = integerValue.ToUInt64(); - ulong completeMantissa = (integerMantissa << (int)(requiredFractionalBitsOfPrecision)) + fractionalMantissa; - - // Compute the final exponent: - // * If the mantissa had an integer part, then the exponent is one less than - // the number of bits we obtained from the integer part. (It's one less - // because we are converting to the form 1.11111, with one 1 to the left - // of the decimal point.) - // * If the mantissa had no integer part, then the exponent is the fractional - // exponent that we computed. - // Then, in both cases, we subtract an additional one from the exponent, to - // account for the fact that we've generated an extra bit of precision, for - // use in rounding. - int finalExponent = (integerBitsOfPrecision > 0) ? (int)(integerBitsOfPrecision) - 2 : -(int)(fractionalExponent) - 1; - - return AssembleFloatingPointBits(in info, completeMantissa, finalExponent, hasZeroTail); - } - - private static ulong RightShiftWithRounding(ulong value, int shift, bool hasZeroTail) - { - // If we'd need to shift further than it is possible to shift, the answer - // is always zero: - if (shift >= 64) - { - return 0; - } - - ulong extraBitsMask = (1UL << (shift - 1)) - 1; - ulong roundBitMask = (1UL << (shift - 1)); - ulong lsbBitMask = 1UL << shift; - - bool lsbBit = (value & lsbBitMask) != 0; - bool roundBit = (value & roundBitMask) != 0; - bool hasTailBits = !hasZeroTail || (value & extraBitsMask) != 0; - - return (value >> shift) + (ShouldRoundUp(lsbBit, roundBit, hasTailBits) ? 1UL : 0); - } - - private static bool ShouldRoundUp(bool lsbBit, bool roundBit, bool hasTailBits) - { - // If there are insignificant set bits, we need to round to the - // nearest; there are two cases: - // we round up if either [1] the value is slightly greater than the midpoint - // between two exactly representable values or [2] the value is exactly the - // midpoint between two exactly representable values and the greater of the - // two is even (this is "round-to-even"). - return roundBit && (hasTailBits || lsbBit); - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/Number.NumberToFloatingPointBits.cs.meta b/Plugins/ZString/Number/Number.NumberToFloatingPointBits.cs.meta deleted file mode 100644 index 49f8f238..00000000 --- a/Plugins/ZString/Number/Number.NumberToFloatingPointBits.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 73257159620332b4aa8656f1ba5a86b3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/Number.Parsing.cs b/Plugins/ZString/Number/Number.Parsing.cs deleted file mode 100644 index 42924699..00000000 --- a/Plugins/ZString/Number/Number.Parsing.cs +++ /dev/null @@ -1,2028 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System -{ - // The Parse methods provided by the numeric classes convert a - // string to a numeric value. The optional style parameter specifies the - // permitted style of the numeric string. It must be a combination of bit flags - // from the NumberStyles enumeration. The optional info parameter - // specifies the NumberFormatInfo instance to use when parsing the - // string. If the info parameter is null or omitted, the numeric - // formatting information is obtained from the current culture. - // - // Numeric strings produced by the Format methods using the Currency, - // Decimal, Engineering, Fixed point, General, or Number standard formats - // (the C, D, E, F, G, and N format specifiers) are guaranteed to be parseable - // by the Parse methods if the NumberStyles.Any style is - // specified. Note, however, that the Parse methods do not accept - // NaNs or Infinities. - - internal static partial class Number - { - private const int Int32Precision = 10; - private const int UInt32Precision = Int32Precision; - private const int Int64Precision = 19; - private const int UInt64Precision = 20; - - private const int DoubleMaxExponent = 309; - private const int DoubleMinExponent = -324; - - private const int FloatingPointMaxExponent = DoubleMaxExponent; - private const int FloatingPointMinExponent = DoubleMinExponent; - - private const int SingleMaxExponent = 39; - private const int SingleMinExponent = -45; - - /// Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit. - internal static ReadOnlySpan CharToHexLookup => new byte[] - { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 15 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 31 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 47 - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 63 - 0xFF, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 79 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 95 - 0xFF, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf // 102 - }; - - private static unsafe bool TryNumberToInt32(ref NumberBuffer number, ref int value) - { - number.CheckConsistency(); - - int i = number.Scale; - if (i > Int32Precision || i < number.DigitsCount) - { - return false; - } - byte* p = number.GetDigitsPointer(); - Debug.Assert(p != null); - int n = 0; - while (--i >= 0) - { - if ((uint)n > (0x7FFFFFFF / 10)) - { - return false; - } - n *= 10; - if (*p != '\0') - { - n += (*p++ - '0'); - } - } - if (number.IsNegative) - { - n = -n; - if (n > 0) - { - return false; - } - } - else - { - if (n < 0) - { - return false; - } - } - value = n; - return true; - } - - private static unsafe bool TryNumberToInt64(ref NumberBuffer number, ref long value) - { - number.CheckConsistency(); - - int i = number.Scale; - if (i > Int64Precision || i < number.DigitsCount) - { - return false; - } - byte* p = number.GetDigitsPointer(); - Debug.Assert(p != null); - long n = 0; - while (--i >= 0) - { - if ((ulong)n > (0x7FFFFFFFFFFFFFFF / 10)) - { - return false; - } - n *= 10; - if (*p != '\0') - { - n += (*p++ - '0'); - } - } - if (number.IsNegative) - { - n = -n; - if (n > 0) - { - return false; - } - } - else - { - if (n < 0) - { - return false; - } - } - value = n; - return true; - } - - private static unsafe bool TryNumberToUInt32(ref NumberBuffer number, ref uint value) - { - number.CheckConsistency(); - - int i = number.Scale; - if (i > UInt32Precision || i < number.DigitsCount || number.IsNegative) - { - return false; - } - byte* p = number.GetDigitsPointer(); - Debug.Assert(p != null); - uint n = 0; - while (--i >= 0) - { - if (n > (0xFFFFFFFF / 10)) - { - return false; - } - n *= 10; - if (*p != '\0') - { - uint newN = n + (uint)(*p++ - '0'); - // Detect an overflow here... - if (newN < n) - { - return false; - } - n = newN; - } - } - value = n; - return true; - } - - private static unsafe bool TryNumberToUInt64(ref NumberBuffer number, ref ulong value) - { - number.CheckConsistency(); - - int i = number.Scale; - if (i > UInt64Precision || i < number.DigitsCount || number.IsNegative) - { - return false; - } - byte* p = number.GetDigitsPointer(); - Debug.Assert(p != null); - ulong n = 0; - while (--i >= 0) - { - if (n > (0xFFFFFFFFFFFFFFFF / 10)) - { - return false; - } - n *= 10; - if (*p != '\0') - { - ulong newN = n + (ulong)(*p++ - '0'); - // Detect an overflow here... - if (newN < n) - { - return false; - } - n = newN; - } - } - value = n; - return true; - } - - internal static int ParseInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) - { - ParsingStatus status = TryParseInt32(value, styles, info, out int result); - if (status != ParsingStatus.OK) - { - ThrowOverflowOrFormatException(status, TypeCode.Int32); - } - - return result; - } - - internal static long ParseInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) - { - ParsingStatus status = TryParseInt64(value, styles, info, out long result); - if (status != ParsingStatus.OK) - { - ThrowOverflowOrFormatException(status, TypeCode.Int64); - } - - return result; - } - - internal static uint ParseUInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) - { - ParsingStatus status = TryParseUInt32(value, styles, info, out uint result); - if (status != ParsingStatus.OK) - { - ThrowOverflowOrFormatException(status, TypeCode.UInt32); - } - - return result; - } - - internal static ulong ParseUInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) - { - ParsingStatus status = TryParseUInt64(value, styles, info, out ulong result); - if (status != ParsingStatus.OK) - { - ThrowOverflowOrFormatException(status, TypeCode.UInt64); - } - - return result; - } - - private static unsafe bool TryParseNumber(ref char* str, char* strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info) - { - Debug.Assert(str != null); - Debug.Assert(strEnd != null); - Debug.Assert(str <= strEnd); - Debug.Assert((styles & NumberStyles.AllowHexSpecifier) == 0); - - const int StateSign = 0x0001; - const int StateParens = 0x0002; - const int StateDigits = 0x0004; - const int StateNonZero = 0x0008; - const int StateDecimal = 0x0010; - const int StateCurrency = 0x0020; - - Debug.Assert(number.DigitsCount == 0); - Debug.Assert(number.Scale == 0); - Debug.Assert(!number.IsNegative); - Debug.Assert(!number.HasNonZeroTail); - - number.CheckConsistency(); - - string decSep; // decimal separator from NumberFormatInfo. - string groupSep; // group separator from NumberFormatInfo. - string currSymbol = null; // currency symbol from NumberFormatInfo. - - bool parsingCurrency = false; - if ((styles & NumberStyles.AllowCurrencySymbol) != 0) - { - currSymbol = info.CurrencySymbol; - - // The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast. - // The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part). - decSep = info.CurrencyDecimalSeparator; - groupSep = info.CurrencyGroupSeparator; - parsingCurrency = true; - } - else - { - decSep = info.NumberDecimalSeparator; - groupSep = info.NumberGroupSeparator; - } - - int state = 0; - char* p = str; - char ch = p < strEnd ? *p : '\0'; - char* next; - - while (true) - { - // Eat whitespace unless we've found a sign which isn't followed by a currency symbol. - // "-Kr 1231.47" is legal but "- 1231.47" is not. - if (!IsWhite(ch) || (styles & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && info.NumberNegativePattern != 2))) - { - if ((((styles & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || ((next = MatchChars(p, strEnd, info.NegativeSign)) != null && (number.IsNegative = true)))) - { - state |= StateSign; - p = next - 1; - } - else if (ch == '(' && ((styles & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0)) - { - state |= StateSign | StateParens; - number.IsNegative = true; - } - else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) - { - state |= StateCurrency; - currSymbol = null; - // We already found the currency symbol. There should not be more currency symbols. Set - // currSymbol to NULL so that we won't search it again in the later code path. - p = next - 1; - } - else - { - break; - } - } - ch = ++p < strEnd ? *p : '\0'; - } - - int digCount = 0; - int digEnd = 0; - int maxDigCount = number.Digits.Length - 1; - - while (true) - { - if (IsDigit(ch)) - { - state |= StateDigits; - - if (ch != '0' || (state & StateNonZero) != 0) - { - if (digCount < maxDigCount) - { - number.Digits[digCount++] = (byte)(ch); - if ((ch != '0') || (number.Kind != NumberBufferKind.Integer)) - { - digEnd = digCount; - } - } - else if (ch != '0') - { - // For decimal and binary floating-point numbers, we only - // need to store digits up to maxDigCount. However, we still - // need to keep track of whether any additional digits past - // maxDigCount were non-zero, as that can impact rounding - // for an input that falls evenly between two representable - // results. - - number.HasNonZeroTail = true; - } - - if ((state & StateDecimal) == 0) - { - number.Scale++; - } - state |= StateNonZero; - } - else if ((state & StateDecimal) != 0) - { - number.Scale--; - } - } - else if (((styles & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, decSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberDecimalSeparator)) != null)) - { - state |= StateDecimal; - p = next - 1; - } - else if (((styles & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, groupSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberGroupSeparator)) != null)) - { - p = next - 1; - } - else - { - break; - } - ch = ++p < strEnd ? *p : '\0'; - } - - bool negExp = false; - number.DigitsCount = digEnd; - number.Digits[digEnd] = (byte)('\0'); - if ((state & StateDigits) != 0) - { - if ((ch == 'E' || ch == 'e') && ((styles & NumberStyles.AllowExponent) != 0)) - { - char* temp = p; - ch = ++p < strEnd ? *p : '\0'; - if ((next = MatchChars(p, strEnd, info.PositiveSign)) != null) - { - ch = (p = next) < strEnd ? *p : '\0'; - } - else if ((next = MatchChars(p, strEnd, info.NegativeSign)) != null) - { - ch = (p = next) < strEnd ? *p : '\0'; - negExp = true; - } - if (IsDigit(ch)) - { - int exp = 0; - do - { - exp = exp * 10 + (ch - '0'); - ch = ++p < strEnd ? *p : '\0'; - if (exp > 1000) - { - exp = 9999; - while (IsDigit(ch)) - { - ch = ++p < strEnd ? *p : '\0'; - } - } - } while (IsDigit(ch)); - if (negExp) - { - exp = -exp; - } - number.Scale += exp; - } - else - { - p = temp; - ch = p < strEnd ? *p : '\0'; - } - } - while (true) - { - if (!IsWhite(ch) || (styles & NumberStyles.AllowTrailingWhite) == 0) - { - if ((styles & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || (((next = MatchChars(p, strEnd, info.NegativeSign)) != null) && (number.IsNegative = true)))) - { - state |= StateSign; - p = next - 1; - } - else if (ch == ')' && ((state & StateParens) != 0)) - { - state &= ~StateParens; - } - else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) - { - currSymbol = null; - p = next - 1; - } - else - { - break; - } - } - ch = ++p < strEnd ? *p : '\0'; - } - if ((state & StateParens) == 0) - { - if ((state & StateNonZero) == 0) - { - if (number.Kind != NumberBufferKind.Decimal) - { - number.Scale = 0; - } - if ((number.Kind == NumberBufferKind.Integer) && (state & StateDecimal) == 0) - { - number.IsNegative = false; - } - } - str = p; - return true; - } - } - str = p; - return false; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static ParsingStatus TryParseInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) - { - if ((styles & ~NumberStyles.Integer) == 0) - { - // Optimized path for the common case of anything that's allowed for integer style. - return TryParseInt32IntegerStyle(value, styles, info, out result); - } - - if ((styles & NumberStyles.AllowHexSpecifier) != 0) - { - result = 0; - return TryParseUInt32HexNumberStyle(value, styles, out Unsafe.As(ref result)); - } - - return TryParseInt32Number(value, styles, info, out result); - } - - private static unsafe ParsingStatus TryParseInt32Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) - { - result = 0; - byte* pDigits = stackalloc byte[Int32NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); - - if (!TryStringToNumber(value, styles, ref number, info)) - { - return ParsingStatus.Failed; - } - - if (!TryNumberToInt32(ref number, ref result)) - { - return ParsingStatus.Overflow; - } - - return ParsingStatus.OK; - } - - /// Parses int limited to styles that make up NumberStyles.Integer. - internal static ParsingStatus TryParseInt32IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) - { - Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); - - if (value.IsEmpty) - goto FalseExit; - - int index = 0; - int num = value[0]; - - // Skip past any whitespace at the beginning. - if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - while (IsWhite(num)); - } - - // Parse leading sign. - int sign = 1; - if ((styles & NumberStyles.AllowLeadingSign) != 0) - { - if (info.HasInvariantNumberSigns()) - { - if (num == '-') - { - sign = -1; - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - else if (num == '+') - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - } - else - { - value = value.Slice(index); - index = 0; - string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; - if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) - { - index += positiveSign.Length; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) - { - sign = -1; - index += negativeSign.Length; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - } - } - - bool overflow = false; - int answer = 0; - - if (IsDigit(num)) - { - // Skip past leading zeros. - if (num == '0') - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - } while (num == '0'); - if (!IsDigit(num)) - goto HasTrailingChars; - } - - // Parse most digits, up to the potential for overflow, which can't happen until after 9 digits. - answer = num - '0'; // first digit - index++; - for (int i = 0; i < 8; i++) // next 8 digits can't overflow - { - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - if (!IsDigit(num)) - goto HasTrailingChars; - index++; - answer = 10 * answer + num - '0'; - } - - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - if (!IsDigit(num)) - goto HasTrailingChars; - index++; - // Potential overflow now processing the 10th digit. - overflow = answer > int.MaxValue / 10; - answer = answer * 10 + num - '0'; - overflow |= (uint)answer > int.MaxValue + (((uint)sign) >> 31); - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - - // At this point, we're either overflowing or hitting a formatting error. - // Format errors take precedence for compatibility. - num = value[index]; - while (IsDigit(num)) - { - overflow = true; - index++; - if ((uint)index >= (uint)value.Length) - goto OverflowExit; - num = value[index]; - } - goto HasTrailingChars; - } - goto FalseExit; - - DoneAtEndButPotentialOverflow: - if (overflow) - { - goto OverflowExit; - } - DoneAtEnd: - result = answer * sign; - ParsingStatus status = ParsingStatus.OK; - Exit: - return status; - - FalseExit: // parsing failed - result = 0; - status = ParsingStatus.Failed; - goto Exit; - OverflowExit: - result = 0; - status = ParsingStatus.Overflow; - goto Exit; - - HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span - // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. - if (IsWhite(num)) - { - if ((styles & NumberStyles.AllowTrailingWhite) == 0) - goto FalseExit; - for (index++; index < value.Length; index++) - { - if (!IsWhite(value[index])) - break; - } - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - } - - if (!TrailingZeros(value, index)) - goto FalseExit; - - goto DoneAtEndButPotentialOverflow; - } - - /// Parses long inputs limited to styles that make up NumberStyles.Integer. - internal static ParsingStatus TryParseInt64IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) - { - Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); - - if (value.IsEmpty) - goto FalseExit; - - int index = 0; - int num = value[0]; - - // Skip past any whitespace at the beginning. - if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - while (IsWhite(num)); - } - - // Parse leading sign. - int sign = 1; - if ((styles & NumberStyles.AllowLeadingSign) != 0) - { - if (info.HasInvariantNumberSigns()) - { - if (num == '-') - { - sign = -1; - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - else if (num == '+') - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - } - else - { - value = value.Slice(index); - index = 0; - string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; - if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) - { - index += positiveSign.Length; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) - { - sign = -1; - index += negativeSign.Length; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - } - } - - bool overflow = false; - long answer = 0; - - if (IsDigit(num)) - { - // Skip past leading zeros. - if (num == '0') - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - } while (num == '0'); - if (!IsDigit(num)) - goto HasTrailingChars; - } - - // Parse most digits, up to the potential for overflow, which can't happen until after 18 digits. - answer = num - '0'; // first digit - index++; - for (int i = 0; i < 17; i++) // next 17 digits can't overflow - { - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - if (!IsDigit(num)) - goto HasTrailingChars; - index++; - answer = 10 * answer + num - '0'; - } - - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - if (!IsDigit(num)) - goto HasTrailingChars; - index++; - // Potential overflow now processing the 19th digit. - overflow = answer > long.MaxValue / 10; - answer = answer * 10 + num - '0'; - overflow |= (ulong)answer > (ulong)long.MaxValue + (((uint)sign) >> 31); - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - - // At this point, we're either overflowing or hitting a formatting error. - // Format errors take precedence for compatibility. - num = value[index]; - while (IsDigit(num)) - { - overflow = true; - index++; - if ((uint)index >= (uint)value.Length) - goto OverflowExit; - num = value[index]; - } - goto HasTrailingChars; - } - goto FalseExit; - - DoneAtEndButPotentialOverflow: - if (overflow) - { - goto OverflowExit; - } - DoneAtEnd: - result = answer * sign; - ParsingStatus status = ParsingStatus.OK; - Exit: - return status; - - FalseExit: // parsing failed - result = 0; - status = ParsingStatus.Failed; - goto Exit; - OverflowExit: - result = 0; - status = ParsingStatus.Overflow; - goto Exit; - - HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span - // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. - if (IsWhite(num)) - { - if ((styles & NumberStyles.AllowTrailingWhite) == 0) - goto FalseExit; - for (index++; index < value.Length; index++) - { - if (!IsWhite(value[index])) - break; - } - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - } - - if (!TrailingZeros(value, index)) - goto FalseExit; - - goto DoneAtEndButPotentialOverflow; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static ParsingStatus TryParseInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) - { - if ((styles & ~NumberStyles.Integer) == 0) - { - // Optimized path for the common case of anything that's allowed for integer style. - return TryParseInt64IntegerStyle(value, styles, info, out result); - } - - if ((styles & NumberStyles.AllowHexSpecifier) != 0) - { - result = 0; - return TryParseUInt64HexNumberStyle(value, styles, out Unsafe.As(ref result)); - } - - return TryParseInt64Number(value, styles, info, out result); - } - - private static unsafe ParsingStatus TryParseInt64Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) - { - result = 0; - byte* pDigits = stackalloc byte[Int64NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); - - if (!TryStringToNumber(value, styles, ref number, info)) - { - return ParsingStatus.Failed; - } - - if (!TryNumberToInt64(ref number, ref result)) - { - return ParsingStatus.Overflow; - } - - return ParsingStatus.OK; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static ParsingStatus TryParseUInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) - { - if ((styles & ~NumberStyles.Integer) == 0) - { - // Optimized path for the common case of anything that's allowed for integer style. - return TryParseUInt32IntegerStyle(value, styles, info, out result); - } - - if ((styles & NumberStyles.AllowHexSpecifier) != 0) - { - return TryParseUInt32HexNumberStyle(value, styles, out result); - } - - return TryParseUInt32Number(value, styles, info, out result); - } - - private static unsafe ParsingStatus TryParseUInt32Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) - { - result = 0; - byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); - - if (!TryStringToNumber(value, styles, ref number, info)) - { - return ParsingStatus.Failed; - } - - if (!TryNumberToUInt32(ref number, ref result)) - { - return ParsingStatus.Overflow; - } - - return ParsingStatus.OK; - } - - /// Parses uint limited to styles that make up NumberStyles.Integer. - internal static ParsingStatus TryParseUInt32IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) - { - Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); - - if (value.IsEmpty) - goto FalseExit; - - int index = 0; - int num = value[0]; - - // Skip past any whitespace at the beginning. - if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - while (IsWhite(num)); - } - - // Parse leading sign. - bool overflow = false; - if ((styles & NumberStyles.AllowLeadingSign) != 0) - { - if (info.HasInvariantNumberSigns()) - { - if (num == '+') - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - else if (num == '-') - { - overflow = true; - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - } - else - { - value = value.Slice(index); - index = 0; - string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; - if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) - { - index += positiveSign.Length; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) - { - overflow = true; - index += negativeSign.Length; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - } - } - - int answer = 0; - - if (IsDigit(num)) - { - // Skip past leading zeros. - if (num == '0') - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - } while (num == '0'); - if (!IsDigit(num)) - goto HasTrailingCharsZero; - } - - // Parse most digits, up to the potential for overflow, which can't happen until after 9 digits. - answer = num - '0'; // first digit - index++; - for (int i = 0; i < 8; i++) // next 8 digits can't overflow - { - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - num = value[index]; - if (!IsDigit(num)) - goto HasTrailingChars; - index++; - answer = 10 * answer + num - '0'; - } - - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - num = value[index]; - if (!IsDigit(num)) - goto HasTrailingChars; - index++; - // Potential overflow now processing the 10th digit. - overflow |= (uint)answer > uint.MaxValue / 10 || ((uint)answer == uint.MaxValue / 10 && num > '5'); - answer = answer * 10 + num - '0'; - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - - // At this point, we're either overflowing or hitting a formatting error. - // Format errors take precedence for compatibility. - num = value[index]; - while (IsDigit(num)) - { - overflow = true; - index++; - if ((uint)index >= (uint)value.Length) - goto OverflowExit; - num = value[index]; - } - goto HasTrailingChars; - } - goto FalseExit; - - DoneAtEndButPotentialOverflow: - if (overflow) - { - goto OverflowExit; - } - DoneAtEnd: - result = (uint)answer; - ParsingStatus status = ParsingStatus.OK; - Exit: - return status; - - FalseExit: // parsing failed - result = 0; - status = ParsingStatus.Failed; - goto Exit; - OverflowExit: - result = 0; - status = ParsingStatus.Overflow; - goto Exit; - - HasTrailingCharsZero: - overflow = false; - HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span - // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. - if (IsWhite(num)) - { - if ((styles & NumberStyles.AllowTrailingWhite) == 0) - goto FalseExit; - for (index++; index < value.Length; index++) - { - if (!IsWhite(value[index])) - break; - } - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - } - - if (!TrailingZeros(value, index)) - goto FalseExit; - - goto DoneAtEndButPotentialOverflow; - } - - /// Parses uint limited to styles that make up NumberStyles.HexNumber. - private static ParsingStatus TryParseUInt32HexNumberStyle(ReadOnlySpan value, NumberStyles styles, out uint result) - { - Debug.Assert((styles & ~NumberStyles.HexNumber) == 0, "Only handles subsets of HexNumber format"); - - if (value.IsEmpty) - goto FalseExit; - - int index = 0; - int num = value[0]; - - // Skip past any whitespace at the beginning. - if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - while (IsWhite(num)); - } - - bool overflow = false; - uint answer = 0; - ReadOnlySpan charToHexLookup = CharToHexLookup; - - if ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF) - { - // Skip past leading zeros. - if (num == '0') - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - } while (num == '0'); - if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) - goto HasTrailingChars; - } - - // Parse up through 8 digits, as no overflow is possible - answer = charToHexLookup[num]; // first digit - index++; - for (int i = 0; i < 7; i++) // next 7 digits can't overflow - { - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - - uint numValue; - if ((uint)num >= (uint)charToHexLookup.Length || (numValue = charToHexLookup[num]) == 0xFF) - goto HasTrailingChars; - index++; - answer = 16 * answer + numValue; - } - - // If there's another digit, it's an overflow. - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) - goto HasTrailingChars; - - // At this point, we're either overflowing or hitting a formatting error. - // Format errors take precedence for compatibility. Read through any remaining digits. - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto OverflowExit; - num = value[index]; - } while ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF); - overflow = true; - goto HasTrailingChars; - } - goto FalseExit; - - DoneAtEndButPotentialOverflow: - if (overflow) - { - goto OverflowExit; - } - DoneAtEnd: - result = answer; - ParsingStatus status = ParsingStatus.OK; - Exit: - return status; - - FalseExit: // parsing failed - result = 0; - status = ParsingStatus.Failed; - goto Exit; - OverflowExit: - result = 0; - status = ParsingStatus.Overflow; - goto Exit; - - HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span - // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. - if (IsWhite(num)) - { - if ((styles & NumberStyles.AllowTrailingWhite) == 0) - goto FalseExit; - for (index++; index < value.Length; index++) - { - if (!IsWhite(value[index])) - break; - } - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - } - - if (!TrailingZeros(value, index)) - goto FalseExit; - - goto DoneAtEndButPotentialOverflow; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static ParsingStatus TryParseUInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) - { - if ((styles & ~NumberStyles.Integer) == 0) - { - // Optimized path for the common case of anything that's allowed for integer style. - return TryParseUInt64IntegerStyle(value, styles, info, out result); - } - - if ((styles & NumberStyles.AllowHexSpecifier) != 0) - { - return TryParseUInt64HexNumberStyle(value, styles, out result); - } - - return TryParseUInt64Number(value, styles, info, out result); - } - - private static unsafe ParsingStatus TryParseUInt64Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) - { - result = 0; - byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); - - if (!TryStringToNumber(value, styles, ref number, info)) - { - return ParsingStatus.Failed; - } - - if (!TryNumberToUInt64(ref number, ref result)) - { - return ParsingStatus.Overflow; - } - - return ParsingStatus.OK; - } - - /// Parses ulong limited to styles that make up NumberStyles.Integer. - internal static ParsingStatus TryParseUInt64IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) - { - Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); - - if (value.IsEmpty) - goto FalseExit; - - int index = 0; - int num = value[0]; - - // Skip past any whitespace at the beginning. - if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - while (IsWhite(num)); - } - - // Parse leading sign. - bool overflow = false; - if ((styles & NumberStyles.AllowLeadingSign) != 0) - { - if (info.HasInvariantNumberSigns()) - { - if (num == '+') - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - else if (num == '-') - { - overflow = true; - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - } - else - { - value = value.Slice(index); - index = 0; - string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; - if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) - { - index += positiveSign.Length; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) - { - overflow = true; - index += negativeSign.Length; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - } - } - - long answer = 0; - - if (IsDigit(num)) - { - // Skip past leading zeros. - if (num == '0') - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - } while (num == '0'); - if (!IsDigit(num)) - goto HasTrailingCharsZero; - } - - // Parse most digits, up to the potential for overflow, which can't happen until after 19 digits. - answer = num - '0'; // first digit - index++; - for (int i = 0; i < 18; i++) // next 18 digits can't overflow - { - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - num = value[index]; - if (!IsDigit(num)) - goto HasTrailingChars; - index++; - answer = 10 * answer + num - '0'; - } - - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - num = value[index]; - if (!IsDigit(num)) - goto HasTrailingChars; - index++; - // Potential overflow now processing the 20th digit. - overflow |= (ulong)answer > ulong.MaxValue / 10 || ((ulong)answer == ulong.MaxValue / 10 && num > '5'); - answer = answer * 10 + num - '0'; - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - - // At this point, we're either overflowing or hitting a formatting error. - // Format errors take precedence for compatibility. - num = value[index]; - while (IsDigit(num)) - { - overflow = true; - index++; - if ((uint)index >= (uint)value.Length) - goto OverflowExit; - num = value[index]; - } - goto HasTrailingChars; - } - goto FalseExit; - - DoneAtEndButPotentialOverflow: - if (overflow) - { - goto OverflowExit; - } - DoneAtEnd: - result = (ulong)answer; - ParsingStatus status = ParsingStatus.OK; - Exit: - return status; - - FalseExit: // parsing failed - result = 0; - status = ParsingStatus.Failed; - goto Exit; - OverflowExit: - result = 0; - status = ParsingStatus.Overflow; - goto Exit; - - HasTrailingCharsZero: - overflow = false; - HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span - // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. - if (IsWhite(num)) - { - if ((styles & NumberStyles.AllowTrailingWhite) == 0) - goto FalseExit; - for (index++; index < value.Length; index++) - { - if (!IsWhite(value[index])) - break; - } - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - } - - if (!TrailingZeros(value, index)) - goto FalseExit; - - goto DoneAtEndButPotentialOverflow; - } - - /// Parses ulong limited to styles that make up NumberStyles.HexNumber. - private static ParsingStatus TryParseUInt64HexNumberStyle(ReadOnlySpan value, NumberStyles styles, out ulong result) - { - Debug.Assert((styles & ~NumberStyles.HexNumber) == 0, "Only handles subsets of HexNumber format"); - - if (value.IsEmpty) - goto FalseExit; - - int index = 0; - int num = value[0]; - - // Skip past any whitespace at the beginning. - if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto FalseExit; - num = value[index]; - } - while (IsWhite(num)); - } - - bool overflow = false; - ulong answer = 0; - ReadOnlySpan charToHexLookup = CharToHexLookup; - - if ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF) - { - // Skip past leading zeros. - if (num == '0') - { - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - } while (num == '0'); - if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) - goto HasTrailingChars; - } - - // Parse up through 16 digits, as no overflow is possible - answer = charToHexLookup[num]; // first digit - index++; - for (int i = 0; i < 15; i++) // next 15 digits can't overflow - { - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - - uint numValue; - if ((uint)num >= (uint)charToHexLookup.Length || (numValue = charToHexLookup[num]) == 0xFF) - goto HasTrailingChars; - index++; - answer = 16 * answer + numValue; - } - - // If there's another digit, it's an overflow. - if ((uint)index >= (uint)value.Length) - goto DoneAtEnd; - num = value[index]; - if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) - goto HasTrailingChars; - - // At this point, we're either overflowing or hitting a formatting error. - // Format errors take precedence for compatibility. Read through any remaining digits. - do - { - index++; - if ((uint)index >= (uint)value.Length) - goto OverflowExit; - num = value[index]; - } while ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF); - overflow = true; - goto HasTrailingChars; - } - goto FalseExit; - - DoneAtEndButPotentialOverflow: - if (overflow) - { - goto OverflowExit; - } - DoneAtEnd: - result = answer; - ParsingStatus status = ParsingStatus.OK; - Exit: - return status; - - FalseExit: // parsing failed - result = 0; - status = ParsingStatus.Failed; - goto Exit; - OverflowExit: - result = 0; - status = ParsingStatus.Overflow; - goto Exit; - - HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span - // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. - if (IsWhite(num)) - { - if ((styles & NumberStyles.AllowTrailingWhite) == 0) - goto FalseExit; - for (index++; index < value.Length; index++) - { - if (!IsWhite(value[index])) - break; - } - if ((uint)index >= (uint)value.Length) - goto DoneAtEndButPotentialOverflow; - } - - if (!TrailingZeros(value, index)) - goto FalseExit; - - goto DoneAtEndButPotentialOverflow; - } - - internal static decimal ParseDecimal(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) - { - ParsingStatus status = TryParseDecimal(value, styles, info, out decimal result); - if (status != ParsingStatus.OK) - { - ThrowOverflowOrFormatException(status, TypeCode.Decimal); - } - - return result; - } - - internal static unsafe bool TryNumberToDecimal(ref NumberBuffer number, ref decimal value) - { - number.CheckConsistency(); - - byte* p = number.GetDigitsPointer(); - int e = number.Scale; - bool sign = number.IsNegative; - uint c = *p; - if (c == 0) - { - // To avoid risking an app-compat issue with pre 4.5 (where some app was illegally using Reflection to examine the internal scale bits), we'll only force - // the scale to 0 if the scale was previously positive (previously, such cases were unparsable to a bug.) - value = new decimal(0, 0, 0, sign, (byte)MathEx.Clamp(-e, 0, 28)); - return true; - } - - if (e > DecimalPrecision) - return false; - - ulong low64 = 0; - while (e > -28) - { - e--; - low64 *= 10; - low64 += c - '0'; - c = *++p; - if (low64 >= ulong.MaxValue / 10) - break; - if (c == 0) - { - while (e > 0) - { - e--; - low64 *= 10; - if (low64 >= ulong.MaxValue / 10) - break; - } - break; - } - } - - uint high = 0; - while ((e > 0 || (c != 0 && e > -28)) && - (high < uint.MaxValue / 10 || (high == uint.MaxValue / 10 && (low64 < 0x99999999_99999999 || (low64 == 0x99999999_99999999 && c <= '5'))))) - { - // multiply by 10 - ulong tmpLow = (uint)low64 * 10UL; - ulong tmp64 = (uint)(low64 >> 32) * 10UL + (tmpLow >> 32); - low64 = (uint)tmpLow + (tmp64 << 32); - high = (uint)(tmp64 >> 32) + high * 10; - - if (c != 0) - { - c -= '0'; - low64 += c; - if (low64 < c) - high++; - c = *++p; - } - e--; - } - - if (c >= '5') - { - if ((c == '5') && ((low64 & 1) == 0)) - { - c = *++p; - - bool hasZeroTail = !number.HasNonZeroTail; - - // We might still have some additional digits, in which case they need - // to be considered as part of hasZeroTail. Some examples of this are: - // * 3.0500000000000000000001e-27 - // * 3.05000000000000000000001e-27 - // In these cases, we will have processed 3 and 0, and ended on 5. The - // buffer, however, will still contain a number of trailing zeros and - // a trailing non-zero number. - - while ((c != 0) && hasZeroTail) - { - hasZeroTail &= (c == '0'); - c = *++p; - } - - // We should either be at the end of the stream or have a non-zero tail - Debug.Assert((c == 0) || !hasZeroTail); - - if (hasZeroTail) - { - // When the next digit is 5, the number is even, and all following - // digits are zero we don't need to round. - goto NoRounding; - } - } - - if (++low64 == 0 && ++high == 0) - { - low64 = 0x99999999_9999999A; - high = uint.MaxValue / 10; - e++; - } - } - NoRounding: - - if (e > 0) - return false; - - if (e <= -DecimalPrecision) - { - // Parsing a large scale zero can give you more precision than fits in the decimal. - // This should only happen for actual zeros or very small numbers that round to zero. - value = new decimal(0, 0, 0, sign, DecimalPrecision - 1); - } - else - { - value = new decimal((int)low64, (int)(low64 >> 32), (int)high, sign, (byte)-e); - } - return true; - } - - internal static double ParseDouble(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) - { - if (!TryParseDouble(value, styles, info, out double result)) - { - ThrowOverflowOrFormatException(ParsingStatus.Failed); - } - - return result; - } - - internal static float ParseSingle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) - { - if (!TryParseSingle(value, styles, info, out float result)) - { - ThrowOverflowOrFormatException(ParsingStatus.Failed); - } - - return result; - } - - internal static unsafe ParsingStatus TryParseDecimal(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out decimal result) - { - byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); - - result = 0; - - if (!TryStringToNumber(value, styles, ref number, info)) - { - return ParsingStatus.Failed; - } - - if (!TryNumberToDecimal(ref number, ref result)) - { - return ParsingStatus.Overflow; - } - - return ParsingStatus.OK; - } - - internal static unsafe bool TryParseDouble(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out double result) - { - byte* pDigits = stackalloc byte[DoubleNumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, DoubleNumberBufferLength); - - if (!TryStringToNumber(value, styles, ref number, info)) - { - ReadOnlySpan valueTrim = value.Trim(); - - // This code would be simpler if we only had the concept of `InfinitySymbol`, but - // we don't so we'll check the existing cases first and then handle `PositiveSign` + - // `PositiveInfinitySymbol` and `PositiveSign/NegativeSign` + `NaNSymbol` last. - - if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) - { - result = double.PositiveInfinity; - } - else if (valueTrim.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol.AsSpan())) - { - result = double.NegativeInfinity; - } - else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) - { - result = double.NaN; - } - else if (valueTrim.StartsWith(info.PositiveSign.AsSpan(), StringComparison.OrdinalIgnoreCase)) - { - valueTrim = valueTrim.Slice(info.PositiveSign.Length); - - if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) - { - result = double.PositiveInfinity; - } - else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) - { - result = double.NaN; - } - else - { - result = 0; - return false; - } - } - else if (valueTrim.StartsWith(info.NegativeSign.AsSpan(), StringComparison.OrdinalIgnoreCase) && - valueTrim.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) - { - result = double.NaN; - } - else - { - result = 0; - return false; // We really failed - } - } - else - { - result = NumberToDouble(ref number); - } - - return true; - } - - internal static unsafe bool TryParseSingle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out float result) - { - byte* pDigits = stackalloc byte[SingleNumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, SingleNumberBufferLength); - - if (!TryStringToNumber(value, styles, ref number, info)) - { - ReadOnlySpan valueTrim = value.Trim(); - - // This code would be simpler if we only had the concept of `InfinitySymbol`, but - // we don't so we'll check the existing cases first and then handle `PositiveSign` + - // `PositiveInfinitySymbol` and `PositiveSign/NegativeSign` + `NaNSymbol` last. - // - // Additionally, since some cultures ("wo") actually define `PositiveInfinitySymbol` - // to include `PositiveSign`, we need to check whether `PositiveInfinitySymbol` fits - // that case so that we don't start parsing things like `++infini`. - - if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) - { - result = float.PositiveInfinity; - } - else if (valueTrim.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol.AsSpan())) - { - result = float.NegativeInfinity; - } - else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) - { - result = float.NaN; - } - else if (valueTrim.StartsWith(info.PositiveSign.AsSpan(), StringComparison.OrdinalIgnoreCase)) - { - valueTrim = valueTrim.Slice(info.PositiveSign.Length); - - if (!info.PositiveInfinitySymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) && valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) - { - result = float.PositiveInfinity; - } - else if (!info.NaNSymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) && valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) - { - result = float.NaN; - } - else - { - result = 0; - return false; - } - } - else if (valueTrim.StartsWith(info.NegativeSign.AsSpan(), StringComparison.OrdinalIgnoreCase) && - !info.NaNSymbol.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) && - valueTrim.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) - { - result = float.NaN; - } - else - { - result = 0; - return false; // We really failed - } - } - else - { - result = NumberToSingle(ref number); - } - - return true; - } - - internal static unsafe bool TryStringToNumber(ReadOnlySpan value, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info) - { - Debug.Assert(info != null); - fixed (char* stringPointer = &MemoryMarshal.GetReference(value)) - { - char* p = stringPointer; - if (!TryParseNumber(ref p, p + value.Length, styles, ref number, info) - || ((int)(p - stringPointer) < value.Length && !TrailingZeros(value, (int)(p - stringPointer)))) - { - number.CheckConsistency(); - return false; - } - } - - number.CheckConsistency(); - return true; - } - - private static bool TrailingZeros(ReadOnlySpan value, int index) - { - // For compatibility, we need to allow trailing zeros at the end of a number string - for (int i = index; (uint)i < (uint)value.Length; i++) - { - if (value[i] != '\0') - { - return false; - } - } - - return true; - } - - private static bool IsSpaceReplacingChar(char c) => c == '\u00a0' || c == '\u202f'; - - private static unsafe char* MatchChars(char* p, char* pEnd, string value) - { - Debug.Assert(p != null && pEnd != null && p <= pEnd && value != null); - fixed (char* stringPointer = value) - { - char* str = stringPointer; - if (*str != '\0') - { - // We only hurt the failure case - // This fix is for French or Kazakh cultures. Since a user cannot type 0xA0 or 0x202F as a - // space character we use 0x20 space character instead to mean the same. - while (true) - { - char cp = p < pEnd ? *p : '\0'; - if (cp != *str && !(IsSpaceReplacingChar(*str) && cp == '\u0020')) - { - break; - } - p++; - str++; - if (*str == '\0') - return p; - } - } - } - - return null; - } - - // Ternary op is a workaround for https://github.com/dotnet/coreclr/issues/914 - private static bool IsWhite(int ch) => ch == 0x20 || (uint)(ch - 0x09) <= (0x0D - 0x09) ? true : false; - - private static bool IsDigit(int ch) => ((uint)ch - '0') <= 9; - - internal enum ParsingStatus - { - OK, - Failed, - Overflow - } - - internal static void ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type = 0) => throw GetException(status, type); - - internal static void ThrowOverflowException(TypeCode type) => throw GetException(ParsingStatus.Overflow, type); - - private static Exception GetException(ParsingStatus status, TypeCode type) - { - if (status == ParsingStatus.Failed) - return new FormatException(); - - string s; - switch (type) - { - case TypeCode.SByte: - s = "SR.Overflow_SByte"; - break; - case TypeCode.Byte: - s = "SR.Overflow_Byte"; - break; - case TypeCode.Int16: - s = "SR.Overflow_Int16"; - break; - case TypeCode.UInt16: - s = "SR.Overflow_UInt16"; - break; - case TypeCode.Int32: - s = "SR.Overflow_Int32"; - break; - case TypeCode.UInt32: - s = "SR.Overflow_UInt32"; - break; - case TypeCode.Int64: - s = "SR.Overflow_Int64"; - break; - case TypeCode.UInt64: - s = "SR.Overflow_UInt64"; - break; - default: - Debug.Assert(type == TypeCode.Decimal); - s = "SR.Overflow_Decimal"; - break; - } - return new OverflowException(s); - } - - internal static double NumberToDouble(ref NumberBuffer number) - { - number.CheckConsistency(); - double result; - - if ((number.DigitsCount == 0) || (number.Scale < DoubleMinExponent)) - { - result = 0; - } - else if (number.Scale > DoubleMaxExponent) - { - result = double.PositiveInfinity; - } - else - { - ulong bits = NumberToFloatingPointBits(ref number, in FloatingPointInfo.Double); - result = BitConverter.Int64BitsToDouble((long)(bits)); - } - - return number.IsNegative ? -result : result; - } - - internal static float NumberToSingle(ref NumberBuffer number) - { - number.CheckConsistency(); - float result; - - if ((number.DigitsCount == 0) || (number.Scale < SingleMinExponent)) - { - result = 0; - } - else if (number.Scale > SingleMaxExponent) - { - result = float.PositiveInfinity; - } - else - { - uint bits = (uint)(NumberToFloatingPointBits(ref number, in FloatingPointInfo.Single)); - result = Int32BitsToSingle((int)(bits)); - } - - return number.IsNegative ? -result : result; - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static unsafe float Int32BitsToSingle(int value) - { - return *((float*)&value); - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/Number.Parsing.cs.meta b/Plugins/ZString/Number/Number.Parsing.cs.meta deleted file mode 100644 index c8d2b987..00000000 --- a/Plugins/ZString/Number/Number.Parsing.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b6559ed9c353778499e24e59333cc89f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/NumberFormatInfoEx.cs b/Plugins/ZString/Number/NumberFormatInfoEx.cs deleted file mode 100644 index 785c6764..00000000 --- a/Plugins/ZString/Number/NumberFormatInfoEx.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Text; - -namespace System -{ - internal static class NumberFormatInfoEx - { - internal static bool HasInvariantNumberSigns(this NumberFormatInfo info) - { - return info.PositiveSign == "+" && info.NegativeSign == "-"; - } - } -} diff --git a/Plugins/ZString/Number/NumberFormatInfoEx.cs.meta b/Plugins/ZString/Number/NumberFormatInfoEx.cs.meta deleted file mode 100644 index 444aba80..00000000 --- a/Plugins/ZString/Number/NumberFormatInfoEx.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0550e632456d8424e8b871651efa0bf2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Number/ValueStringBuilder.cs b/Plugins/ZString/Number/ValueStringBuilder.cs deleted file mode 100644 index 38afec71..00000000 --- a/Plugins/ZString/Number/ValueStringBuilder.cs +++ /dev/null @@ -1,309 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Buffers; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System.Text -{ - internal ref partial struct ValueStringBuilder - { - private char[] _arrayToReturnToPool; - private Span _chars; - private int _pos; - - public ValueStringBuilder(Span initialBuffer) - { - _arrayToReturnToPool = null; - _chars = initialBuffer; - _pos = 0; - } - - public ValueStringBuilder(int initialCapacity) - { - _arrayToReturnToPool = ArrayPool.Shared.Rent(initialCapacity); - _chars = _arrayToReturnToPool; - _pos = 0; - } - - public int Length - { - get => _pos; - set - { - Debug.Assert(value >= 0); - Debug.Assert(value <= _chars.Length); - _pos = value; - } - } - - public int Capacity => _chars.Length; - - public void EnsureCapacity(int capacity) - { - if (capacity > _chars.Length) - Grow(capacity - _pos); - } - - /// - /// Get a pinnable reference to the builder. - /// Does not ensure there is a null char after - /// This overload is pattern matched in the C# 7.3+ compiler so you can omit - /// the explicit method call, and write eg "fixed (char* c = builder)" - /// - public ref char GetPinnableReference() - { - return ref MemoryMarshal.GetReference(_chars); - } - - /// - /// Get a pinnable reference to the builder. - /// - /// Ensures that the builder has a null char after - public ref char GetPinnableReference(bool terminate) - { - if (terminate) - { - EnsureCapacity(Length + 1); - _chars[Length] = '\0'; - } - return ref MemoryMarshal.GetReference(_chars); - } - - public ref char this[int index] - { - get - { - Debug.Assert(index < _pos); - return ref _chars[index]; - } - } - - public override string ToString() - { - string s = _chars.Slice(0, _pos).ToString(); - Dispose(); - return s; - } - - /// Returns the underlying storage of the builder. - public Span RawChars => _chars; - - /// - /// Returns a span around the contents of the builder. - /// - /// Ensures that the builder has a null char after - public ReadOnlySpan AsSpan(bool terminate) - { - if (terminate) - { - EnsureCapacity(Length + 1); - _chars[Length] = '\0'; - } - return _chars.Slice(0, _pos); - } - - public ReadOnlySpan AsSpan() => _chars.Slice(0, _pos); - public ReadOnlySpan AsSpan(int start) => _chars.Slice(start, _pos - start); - public ReadOnlySpan AsSpan(int start, int length) => _chars.Slice(start, length); - - public bool TryCopyTo(Span destination, out int charsWritten) - { - if (_chars.Slice(0, _pos).TryCopyTo(destination)) - { - charsWritten = _pos; - Dispose(); - return true; - } - else - { - charsWritten = 0; - Dispose(); - return false; - } - } - - public void Insert(int index, char value, int count) - { - if (_pos > _chars.Length - count) - { - Grow(count); - } - - int remaining = _pos - index; - _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); - _chars.Slice(index, count).Fill(value); - _pos += count; - } - - public void Insert(int index, string s) - { - if (s == null) - { - return; - } - - int count = s.Length; - - if (_pos > (_chars.Length - count)) - { - Grow(count); - } - - int remaining = _pos - index; - _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); - s.AsSpan().CopyTo(_chars.Slice(index)); - _pos += count; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(char c) - { - int pos = _pos; - if ((uint)pos < (uint)_chars.Length) - { - _chars[pos] = c; - _pos = pos + 1; - } - else - { - GrowAndAppend(c); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(string s) - { - if (s == null) - { - return; - } - - int pos = _pos; - if (s.Length == 1 && (uint)pos < (uint)_chars.Length) // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. - { - _chars[pos] = s[0]; - _pos = pos + 1; - } - else - { - AppendSlow(s); - } - } - - private void AppendSlow(string s) - { - int pos = _pos; - if (pos > _chars.Length - s.Length) - { - Grow(s.Length); - } - - s.AsSpan().CopyTo(_chars.Slice(pos)); - _pos += s.Length; - } - - public void Append(char c, int count) - { - if (_pos > _chars.Length - count) - { - Grow(count); - } - - Span dst = _chars.Slice(_pos, count); - for (int i = 0; i < dst.Length; i++) - { - dst[i] = c; - } - _pos += count; - } - - public unsafe void Append(char* value, int length) - { - int pos = _pos; - if (pos > _chars.Length - length) - { - Grow(length); - } - - Span dst = _chars.Slice(_pos, length); - for (int i = 0; i < dst.Length; i++) - { - dst[i] = *value++; - } - _pos += length; - } - - public void Append(ReadOnlySpan value) - { - int pos = _pos; - if (pos > _chars.Length - value.Length) - { - Grow(value.Length); - } - - value.CopyTo(_chars.Slice(_pos)); - _pos += value.Length; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AppendSpan(int length) - { - int origPos = _pos; - if (origPos > _chars.Length - length) - { - Grow(length); - } - - _pos = origPos + length; - return _chars.Slice(origPos, length); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void GrowAndAppend(char c) - { - Grow(1); - Append(c); - } - - /// - /// Resize the internal buffer either by doubling current buffer size or - /// by adding to - /// whichever is greater. - /// - /// - /// Number of chars requested beyond current position. - /// - [MethodImpl(MethodImplOptions.NoInlining)] - private void Grow(int additionalCapacityBeyondPos) - { - Debug.Assert(additionalCapacityBeyondPos > 0); - Debug.Assert(_pos > _chars.Length - additionalCapacityBeyondPos, "Grow called incorrectly, no resize is needed."); - - char[] poolArray = ArrayPool.Shared.Rent(Math.Max(_pos + additionalCapacityBeyondPos, _chars.Length * 2)); - - _chars.Slice(0, _pos).CopyTo(poolArray); - - char[] toReturn = _arrayToReturnToPool; - _chars = _arrayToReturnToPool = poolArray; - if (toReturn != null) - { - ArrayPool.Shared.Return(toReturn); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() - { - char[] toReturn = _arrayToReturnToPool; - this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again - if (toReturn != null) - { - ArrayPool.Shared.Return(toReturn); - } - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Number/ValueStringBuilder.cs.meta b/Plugins/ZString/Number/ValueStringBuilder.cs.meta deleted file mode 100644 index 771e1834..00000000 --- a/Plugins/ZString/Number/ValueStringBuilder.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4c5602223bfb1324ba376e5508ae9134 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/PreparedFormat.cs b/Plugins/ZString/PreparedFormat.cs deleted file mode 100644 index 955c5ca6..00000000 --- a/Plugins/ZString/PreparedFormat.cs +++ /dev/null @@ -1,3303 +0,0 @@ -using System; -using System.Text; -using System.Buffers; - -namespace Cysharp.Text -{ - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - case 8: - { - Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - case 8: - { - Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); - break; - } - case 9: - { - Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - case 8: - { - Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); - break; - } - case 9: - { - Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); - break; - } - case 10: - { - Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - case 8: - { - Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); - break; - } - case 9: - { - Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); - break; - } - case 10: - { - Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); - break; - } - case 11: - { - Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - case 8: - { - Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); - break; - } - case 9: - { - Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); - break; - } - case 10: - { - Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); - break; - } - case 11: - { - Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); - break; - } - case 12: - { - Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - case 8: - { - Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); - break; - } - case 9: - { - Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); - break; - } - case 10: - { - Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); - break; - } - case 11: - { - Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); - break; - } - case 12: - { - Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); - break; - } - case 13: - { - Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - case 8: - { - Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); - break; - } - case 9: - { - Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); - break; - } - case 10: - { - Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); - break; - } - case 11: - { - Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); - break; - } - case 12: - { - Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); - break; - } - case 13: - { - Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); - break; - } - case 14: - { - Utf16FormatHelper.FormatTo(ref sb, arg15, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg15)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf16PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf16FormatSegment[] segments; - - public Utf16PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf16Parse(format); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - where TBufferWriter : IBufferWriter - { - var formatSpan = FormatString.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf16FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); - break; - } - case 1: - { - Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); - break; - } - case 2: - { - Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); - break; - } - case 3: - { - Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); - break; - } - case 4: - { - Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); - break; - } - case 5: - { - Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); - break; - } - case 6: - { - Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); - break; - } - case 7: - { - Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); - break; - } - case 8: - { - Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); - break; - } - case 9: - { - Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); - break; - } - case 10: - { - Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); - break; - } - case 11: - { - Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); - break; - } - case 12: - { - Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); - break; - } - case 13: - { - Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); - break; - } - case 14: - { - Utf16FormatHelper.FormatTo(ref sb, arg15, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg15)); - break; - } - case 15: - { - Utf16FormatHelper.FormatTo(ref sb, arg16, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg16)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - case 8: - { - Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - case 8: - { - Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); - break; - } - case 9: - { - Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - case 8: - { - Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); - break; - } - case 9: - { - Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); - break; - } - case 10: - { - Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - case 8: - { - Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); - break; - } - case 9: - { - Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); - break; - } - case 10: - { - Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); - break; - } - case 11: - { - Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - case 8: - { - Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); - break; - } - case 9: - { - Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); - break; - } - case 10: - { - Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); - break; - } - case 11: - { - Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); - break; - } - case 12: - { - Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - case 8: - { - Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); - break; - } - case 9: - { - Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); - break; - } - case 10: - { - Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); - break; - } - case 11: - { - Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); - break; - } - case 12: - { - Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); - break; - } - case 13: - { - Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - case 8: - { - Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); - break; - } - case 9: - { - Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); - break; - } - case 10: - { - Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); - break; - } - case 11: - { - Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); - break; - } - case 12: - { - Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); - break; - } - case 13: - { - Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); - break; - } - case 14: - { - Utf8FormatHelper.FormatTo(ref sb, arg15, item.Alignment, item.StandardFormat, nameof(arg15)); - break; - } - default: - break; - } - } - } - } - public sealed partial class Utf8PreparedFormat - { - public string FormatString { get; } - public int MinSize { get; } - - readonly Utf8FormatSegment[] segments; - readonly byte[] utf8PreEncodedbuffer; - - public Utf8PreparedFormat(string format) - { - this.FormatString = format; - this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); - - var size = 0; - foreach (var item in segments) - { - if (!item.IsFormatArgument) - { - size += item.Count; - } - } - this.MinSize = size; - } - - public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - var sb = new Utf8ValueStringBuilder(true); - try - { - FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - where TBufferWriter : IBufferWriter - { - var formatSpan = utf8PreEncodedbuffer.AsSpan(); - - foreach (var item in segments) - { - switch (item.FormatIndex) - { - case Utf8FormatSegment.NotFormatIndex: - { - var strSpan = formatSpan.Slice(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - break; - } - case 0: - { - Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); - break; - } - case 1: - { - Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); - break; - } - case 2: - { - Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); - break; - } - case 3: - { - Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); - break; - } - case 4: - { - Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); - break; - } - case 5: - { - Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); - break; - } - case 6: - { - Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); - break; - } - case 7: - { - Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); - break; - } - case 8: - { - Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); - break; - } - case 9: - { - Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); - break; - } - case 10: - { - Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); - break; - } - case 11: - { - Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); - break; - } - case 12: - { - Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); - break; - } - case 13: - { - Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); - break; - } - case 14: - { - Utf8FormatHelper.FormatTo(ref sb, arg15, item.Alignment, item.StandardFormat, nameof(arg15)); - break; - } - case 15: - { - Utf8FormatHelper.FormatTo(ref sb, arg16, item.Alignment, item.StandardFormat, nameof(arg16)); - break; - } - default: - break; - } - } - } - } -} diff --git a/Plugins/ZString/PreparedFormat.cs.meta b/Plugins/ZString/PreparedFormat.cs.meta deleted file mode 100644 index 9ee42407..00000000 --- a/Plugins/ZString/PreparedFormat.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b2d2a7b702a661244a4045fcf67fe6ca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/PreparedFormatHelper.cs b/Plugins/ZString/PreparedFormatHelper.cs deleted file mode 100644 index 18d808da..00000000 --- a/Plugins/ZString/PreparedFormatHelper.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text -{ - internal static class PreparedFormatHelper - { - internal static Utf16FormatSegment[] Utf16Parse(string format) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var list = new List(); - - int i = 0; - int len = format.Length; - - var copyFrom = 0; - var formatSpan = format.AsSpan(); - - while (true) - { - while (i < len) - { - var parserScanResult = FormatParser.ScanFormatString(formatSpan, ref i); - - if (ParserScanResult.NormalChar == parserScanResult && i < len) - { - // skip normal char - continue; - } - - var size = i - copyFrom; - if (ParserScanResult.EscapedChar == parserScanResult) - { - size--; - } - - if (size != 0) - { - list.Add(new Utf16FormatSegment(copyFrom, size, Utf16FormatSegment.NotFormatIndex, 0)); - } - - copyFrom = i; - - if (ParserScanResult.BraceOpen == parserScanResult) - { - break; - } - } - - if (i >= len) - { - break; - } - - // Here it is before `{`. - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; // continue after '}' - i = indexParse.LastIndex; - - list.Add(new Utf16FormatSegment(indexParse.LastIndex - indexParse.FormatString.Length - 1, indexParse.FormatString.Length, indexParse.Index, indexParse.Alignment)); - } - - return list.ToArray(); - } - - internal static Utf8FormatSegment[] Utf8Parse(string format, out byte[] utf8buffer) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var list = new List(); - utf8buffer = new byte[Encoding.UTF8.GetMaxByteCount(format.Length)]; - var bufOffset = 0; - - int i = 0; - int len = format.Length; - - var copyFrom = 0; - var formatSpan = format.AsSpan(); - - while (true) - { - while (i < len) - { - var parserScanResult = FormatParser.ScanFormatString(formatSpan, ref i); - - if (ParserScanResult.NormalChar == parserScanResult && i < len) - { - // skip normal char - continue; - } - - var size = i - copyFrom; - if (ParserScanResult.EscapedChar == parserScanResult) - { - size--; - } - - if (size != 0) - { - var utf8size = Encoding.UTF8.GetBytes(format, copyFrom, size, utf8buffer, bufOffset); - list.Add(new Utf8FormatSegment(bufOffset, utf8size, Utf8FormatSegment.NotFormatIndex, default, 0)); - bufOffset += utf8size; - } - - copyFrom = i; - - if (ParserScanResult.BraceOpen == parserScanResult) - { - break; - } - } - - if (i >= len) - { - break; - } - - // Here it is before `{`. - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; // continue after '}' - i = indexParse.LastIndex; - list.Add(new Utf8FormatSegment(0, 0, indexParse.Index, StandardFormat.Parse(indexParse.FormatString), indexParse.Alignment)); - } - - return list.ToArray(); - } - } - - internal readonly struct Utf8FormatSegment - { - public const int NotFormatIndex = -1; - - public readonly int Offset; - public readonly int Count; - public readonly int FormatIndex; - public readonly StandardFormat StandardFormat; - public readonly int Alignment; - - public bool IsFormatArgument => FormatIndex != NotFormatIndex; - - public Utf8FormatSegment(int offset, int count, int formatIndex, StandardFormat format, int alignment) - { - Offset = offset; - Count = count; - FormatIndex = formatIndex; - StandardFormat = format; - Alignment = alignment; - } - } - - internal readonly struct Utf16FormatSegment - { - public const int NotFormatIndex = -1; - - public readonly int Offset; - public readonly int Count; - public readonly int FormatIndex; - public readonly int Alignment; - - public bool IsFormatArgument => FormatIndex != NotFormatIndex; - - public Utf16FormatSegment(int offset, int count, int formatIndex, int alignment) - { - Offset = offset; - Count = count; - FormatIndex = formatIndex; - Alignment = alignment; - } - } -} diff --git a/Plugins/ZString/PreparedFormatHelper.cs.meta b/Plugins/ZString/PreparedFormatHelper.cs.meta deleted file mode 100644 index ecf22f56..00000000 --- a/Plugins/ZString/PreparedFormatHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 97f2a4c405b87a245ac38c1755f74a3b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ReadOnlyListAdaptor.cs b/Plugins/ZString/ReadOnlyListAdaptor.cs deleted file mode 100644 index bc8dbd55..00000000 --- a/Plugins/ZString/ReadOnlyListAdaptor.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace Cysharp.Text -{ - /// - /// Most IList interface-implementing classes implement the IReadOnlyList interface. - /// This is for the rare class that does not implement the IList interface. - /// - /// - internal readonly struct ReadOnlyListAdaptor : IReadOnlyList - { - readonly IList _list; - - public ReadOnlyListAdaptor(IList list) => _list = list; - - public T this[int index] => _list[index]; - - public int Count => _list.Count; - - public IEnumerator GetEnumerator() => _list.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } -} diff --git a/Plugins/ZString/ReadOnlyListAdaptor.cs.meta b/Plugins/ZString/ReadOnlyListAdaptor.cs.meta deleted file mode 100644 index e7027a48..00000000 --- a/Plugins/ZString/ReadOnlyListAdaptor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6bac71655584ae549bb144276ee22eed -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Shims.cs b/Plugins/ZString/Shims.cs deleted file mode 100644 index 6dd01f74..00000000 --- a/Plugins/ZString/Shims.cs +++ /dev/null @@ -1,244 +0,0 @@ -#if !NETSTANDARD2_1 - -using System; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Text; - -namespace Cysharp.Text -{ - internal static class Int32 - { - /// 0 ~ 9 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsNumber(char c) - { - return '0' <= c && c <= '9'; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Parse(ReadOnlySpan s) - { - var value = 0L; - var sign = 1; - - if (s[0] == '-') - { - sign = -1; - } - - for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) - { - if (!IsNumber(s[i])) - { - goto END; - } - - // long.MinValue causes overflow so use unchecked. - value = unchecked(value * 10 + ((byte)s[i] - '0')); - } - - END: - return checked((int)(unchecked(value * sign))); - } - } - - internal static class ShimsExtensions - { - public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) - { - if (span.Length == 0) return 0; - fixed (char* src = span) - fixed (byte* dest = bytes) - { - return encoding.GetBytes(src, span.Length, dest, bytes.Length); - } - } - - public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return Unsafe.As(ref value).TryFormat(destination, out charsWritten, format); - } - - public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return Number.TryFormatDecimal(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - - public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return Number.TryFormatSingle(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - - public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return Number.TryFormatDouble(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - - public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); - } - else - { - if (value < 0 && format.Length > 0 && (format[0] == 'X' || format[0] == 'x')) - { - uint temp = (uint)(value & 0x000000FF); - return Number.TryFormatUInt32(temp, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - } - - public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); - } - else - { - if (value < 0 && format.Length > 0 && (format[0] == 'X' || format[0] == 'x')) - { - uint temp = (uint)(value & 0x0000FFFF); - return Number.TryFormatUInt32(temp, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - } - - public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); - } - else - { - return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - } - - public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); - } - else - { - return Number.TryFormatInt64(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - } - - public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); - } - else - { - return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - } - - public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); - } - else - { - return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - } - - public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); - } - else - { - return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - } - - public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - if (format.Length == 0) - { - return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); - } - else - { - return Number.TryFormatUInt64(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); - } - } - - static string GetFormat(ReadOnlySpan format) - { - if (format.Length == 0) - { - return null; - } - - return format.ToString(); - } - } -} - -#endif \ No newline at end of file diff --git a/Plugins/ZString/Shims.cs.meta b/Plugins/ZString/Shims.cs.meta deleted file mode 100644 index ae689b2f..00000000 --- a/Plugins/ZString/Shims.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f69d4234282aeb44c988b029e96aaee1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/StringBuilder.AppendJoin.cs b/Plugins/ZString/StringBuilder.AppendJoin.cs deleted file mode 100644 index 19f5e3e1..00000000 --- a/Plugins/ZString/StringBuilder.AppendJoin.cs +++ /dev/null @@ -1,414 +0,0 @@ -using System; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { - /// - /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. - /// - /// - /// - /// - public void AppendJoin(char separator, params T[] values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values.AsSpan()); - } - - public void AppendJoin(char separator, List values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, (IReadOnlyList)values); - } - - public void AppendJoin(char separator, ReadOnlySpan values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values); - } - - /// - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - /// - /// - /// - /// - public void AppendJoin(char separator, IEnumerable values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values); - } - - public void AppendJoin(char separator, ICollection values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values.AsEnumerable()); - } - - public void AppendJoin(char separator, IList values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values); - } - - public void AppendJoin(char separator, IReadOnlyList values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values); - } - - public void AppendJoin(char separator, IReadOnlyCollection values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values.AsEnumerable()); - } - - /// - /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. - /// - /// - /// - /// - public void AppendJoin(string separator, params T[] values) - { - AppendJoinInternal(separator.AsSpan(), values.AsSpan()); - } - - public void AppendJoin(string separator, List values) - { - AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); - } - - public void AppendJoin(string separator, ReadOnlySpan values) - { - AppendJoinInternal(separator.AsSpan(), values); - } - - /// - /// Concatenates and appends the members of a collection, using the specified separator between each member. - /// - /// - /// - /// - public void AppendJoin(string separator, IEnumerable values) - { - AppendJoinInternal(separator.AsSpan(), values); - } - - public void AppendJoin(string separator, ICollection values) - { - AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); - } - - public void AppendJoin(string separator, IList values) - { - AppendJoinInternal(separator.AsSpan(), values); - } - - public void AppendJoin(string separator, IReadOnlyList values) - { - AppendJoinInternal(separator.AsSpan(), values); - } - - public void AppendJoin(string separator, IReadOnlyCollection values) - { - AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); - } - - internal void AppendJoinInternal(ReadOnlySpan separator, IList values) - { - var readOnlyList = values as IReadOnlyList; - // Boxing will occur, but JIT will be de-virtualized. - readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); - AppendJoinInternal(separator, readOnlyList); - } - - internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) - { - var count = values.Count; - for (int i = 0; i < count; i++) - { - if (i != 0) - { - Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - Append(s); - } - } - else - { - Append(item); - } - } - } - - internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - Append(s); - } - } - else - { - Append(item); - } - } - } - - internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) - { - var isFirst = true; - foreach (var item in values) - { - if (!isFirst) - { - Append(separator); - } - else - { - isFirst = false; - } - - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - Append(s); - } - } - else - { - Append(item); - } - } - } - } - public partial struct Utf8ValueStringBuilder - { - /// - /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. - /// - /// - /// - /// - public void AppendJoin(char separator, params T[] values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values.AsSpan()); - } - - public void AppendJoin(char separator, List values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, (IReadOnlyList)values); - } - - public void AppendJoin(char separator, ReadOnlySpan values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values); - } - - /// - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - /// - /// - /// - /// - public void AppendJoin(char separator, IEnumerable values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values); - } - - public void AppendJoin(char separator, ICollection values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values.AsEnumerable()); - } - - public void AppendJoin(char separator, IList values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values); - } - - public void AppendJoin(char separator, IReadOnlyList values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values); - } - - public void AppendJoin(char separator, IReadOnlyCollection values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - AppendJoinInternal(s, values.AsEnumerable()); - } - - /// - /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. - /// - /// - /// - /// - public void AppendJoin(string separator, params T[] values) - { - AppendJoinInternal(separator.AsSpan(), values.AsSpan()); - } - - public void AppendJoin(string separator, List values) - { - AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); - } - - public void AppendJoin(string separator, ReadOnlySpan values) - { - AppendJoinInternal(separator.AsSpan(), values); - } - - /// - /// Concatenates and appends the members of a collection, using the specified separator between each member. - /// - /// - /// - /// - public void AppendJoin(string separator, IEnumerable values) - { - AppendJoinInternal(separator.AsSpan(), values); - } - - public void AppendJoin(string separator, ICollection values) - { - AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); - } - - public void AppendJoin(string separator, IList values) - { - AppendJoinInternal(separator.AsSpan(), values); - } - - public void AppendJoin(string separator, IReadOnlyList values) - { - AppendJoinInternal(separator.AsSpan(), values); - } - - public void AppendJoin(string separator, IReadOnlyCollection values) - { - AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); - } - - internal void AppendJoinInternal(ReadOnlySpan separator, IList values) - { - var readOnlyList = values as IReadOnlyList; - // Boxing will occur, but JIT will be de-virtualized. - readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); - AppendJoinInternal(separator, readOnlyList); - } - - internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) - { - var count = values.Count; - for (int i = 0; i < count; i++) - { - if (i != 0) - { - Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - Append(s); - } - } - else - { - Append(item); - } - } - } - - internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - Append(s); - } - } - else - { - Append(item); - } - } - } - - internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) - { - var isFirst = true; - foreach (var item in values) - { - if (!isFirst) - { - Append(separator); - } - else - { - isFirst = false; - } - - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - Append(s); - } - } - else - { - Append(item); - } - } - } - } -} diff --git a/Plugins/ZString/StringBuilder.AppendJoin.cs.meta b/Plugins/ZString/StringBuilder.AppendJoin.cs.meta deleted file mode 100644 index 2f2bcc14..00000000 --- a/Plugins/ZString/StringBuilder.AppendJoin.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9e8eda83a35921f4ca67df72e7e5f3e9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Unity.meta b/Plugins/ZString/Unity.meta deleted file mode 100644 index d13e7e4d..00000000 --- a/Plugins/ZString/Unity.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4b4e692ce9cda6845bb75886923f3803 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs b/Plugins/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs deleted file mode 100644 index 47b425e1..00000000 --- a/Plugins/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using TMPro; - -namespace Cysharp.Text -{ - public static partial class TextMeshProExtensions - { - public static void SetText(this TMP_Text text, Utf16ValueStringBuilder stringBuilder) - { - var array = stringBuilder.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } -} diff --git a/Plugins/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs.meta b/Plugins/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs.meta deleted file mode 100644 index 59aadc5b..00000000 --- a/Plugins/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 26ef652c2e8c2cc488e0b2e063a179ce -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Unity/TextMeshProExtensions.cs b/Plugins/ZString/Unity/TextMeshProExtensions.cs deleted file mode 100644 index fffb4e48..00000000 --- a/Plugins/ZString/Unity/TextMeshProExtensions.cs +++ /dev/null @@ -1,195 +0,0 @@ -using System; -using TMPro; - -namespace Cysharp.Text -{ - public static partial class TextMeshProExtensions - { - public static void SetText(this TMP_Text text, T arg0) - { - using ( var sb = new Cysharp.Text.Utf16ValueStringBuilder( true ) ) - { - sb.Append(arg0); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) - { - - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - var array = sb.AsArraySegment(); - text.SetCharArray(array.Array, array.Offset, array.Count); - } - } - - } -} diff --git a/Plugins/ZString/Unity/TextMeshProExtensions.cs.meta b/Plugins/ZString/Unity/TextMeshProExtensions.cs.meta deleted file mode 100644 index 78de3725..00000000 --- a/Plugins/ZString/Unity/TextMeshProExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3e8ff697dcb687d47a24aeebcfb46817 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf16.meta b/Plugins/ZString/Utf16.meta deleted file mode 100644 index 79ab3ca1..00000000 --- a/Plugins/ZString/Utf16.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a43df9eeb16cffb429a0134e0bdfaa43 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/Plugins/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs deleted file mode 100644 index 717464b7..00000000 --- a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ /dev/null @@ -1,1552 +0,0 @@ -using System; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); - continue; - case 12: - AppendFormatInternal(arg13, indexParse.Alignment, indexParse.FormatString, nameof(arg13)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); - continue; - case 12: - AppendFormatInternal(arg13, indexParse.Alignment, indexParse.FormatString, nameof(arg13)); - continue; - case 13: - AppendFormatInternal(arg14, indexParse.Alignment, indexParse.FormatString, nameof(arg14)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); - continue; - case 12: - AppendFormatInternal(arg13, indexParse.Alignment, indexParse.FormatString, nameof(arg13)); - continue; - case 13: - AppendFormatInternal(arg14, indexParse.Alignment, indexParse.FormatString, nameof(arg14)); - continue; - case 14: - AppendFormatInternal(arg15, indexParse.Alignment, indexParse.FormatString, nameof(arg15)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); - continue; - case 12: - AppendFormatInternal(arg13, indexParse.Alignment, indexParse.FormatString, nameof(arg13)); - continue; - case 13: - AppendFormatInternal(arg14, indexParse.Alignment, indexParse.FormatString, nameof(arg14)); - continue; - case 14: - AppendFormatInternal(arg15, indexParse.Alignment, indexParse.FormatString, nameof(arg15)); - continue; - case 15: - AppendFormatInternal(arg16, indexParse.Alignment, indexParse.FormatString, nameof(arg16)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - } -} diff --git a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta b/Plugins/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta deleted file mode 100644 index fcbb76f0..00000000 --- a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2c686f65ca8d42c4aa85d157c378f10e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/Plugins/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs deleted file mode 100644 index 9039f7b6..00000000 --- a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { - static object CreateFormatter(Type type) - { - if (type == typeof(System.SByte)) - { - return new TryFormat((System.SByte x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Int16)) - { - return new TryFormat((System.Int16 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Int32)) - { - return new TryFormat((System.Int32 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Int64)) - { - return new TryFormat((System.Int64 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Byte)) - { - return new TryFormat((System.Byte x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.UInt16)) - { - return new TryFormat((System.UInt16 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.UInt32)) - { - return new TryFormat((System.UInt32 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.UInt64)) - { - return new TryFormat((System.UInt64 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Single)) - { - return new TryFormat((System.Single x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Double)) - { - return new TryFormat((System.Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.TimeSpan)) - { - return new TryFormat((System.TimeSpan x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.DateTime)) - { - return new TryFormat((System.DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.DateTimeOffset)) - { - return new TryFormat((System.DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Decimal)) - { - return new TryFormat((System.Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Guid)) - { - return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.Byte?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.DateTime?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.DateTimeOffset?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Decimal?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Double?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Int16?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Int32?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Int64?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.SByte?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Single?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.TimeSpan?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.UInt16?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.UInt32?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.UInt64?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Guid?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Boolean?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.IntPtr)) - { - // ignore format - return new TryFormat((System.IntPtr x, Span dest, out int written, ReadOnlySpan _) => System.IntPtr.Size == 4 - ? x.ToInt32().TryFormat(dest, out written, default) - : x.ToInt64().TryFormat(dest, out written, default)); - } - if (type == typeof(System.UIntPtr)) - { - // ignore format - return new TryFormat((System.UIntPtr x, Span dest, out int written, ReadOnlySpan _) => System.UIntPtr.Size == 4 - ? x.ToUInt32().TryFormat(dest, out written, default) - : x.ToUInt64().TryFormat(dest, out written, default)); - } - return null; - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta b/Plugins/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta deleted file mode 100644 index 8ab90678..00000000 --- a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d81568aff3a79df41881112bb037c194 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/Plugins/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs deleted file mode 100644 index 39009e31..00000000 --- a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ /dev/null @@ -1,684 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Byte value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Byte value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Byte value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Byte value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTime value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTime value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.DateTime value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.DateTime value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTimeOffset value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTimeOffset value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.DateTimeOffset value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.DateTimeOffset value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Decimal value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Decimal value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Decimal value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Decimal value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Double value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Double value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Double value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Double value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int16 value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int16 value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int16 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int16 value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int32 value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int32 value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int32 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int32 value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int64 value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int64 value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int64 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int64 value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.SByte value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.SByte value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.SByte value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.SByte value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Single value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Single value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Single value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Single value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.TimeSpan value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.TimeSpan value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.TimeSpan value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.TimeSpan value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt16 value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt16 value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt16 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt16 value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt32 value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt32 value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt32 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt32 value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt64 value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt64 value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt64 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt64 value, string format) - { - Append(value, format); - AppendLine(); - } - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Guid value) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Guid value, string format) - { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) - { - Grow(written); - if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Guid value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Guid value, string format) - { - Append(value, format); - AppendLine(); - } - } -} diff --git a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta b/Plugins/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta deleted file mode 100644 index 5ae630ba..00000000 --- a/Plugins/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0143a9022d2d364409298fa82d0bbc01 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf16ValueStringBuilder.cs b/Plugins/ZString/Utf16ValueStringBuilder.cs deleted file mode 100644 index b1d4419e..00000000 --- a/Plugins/ZString/Utf16ValueStringBuilder.cs +++ /dev/null @@ -1,751 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder : IDisposable, IBufferWriter, IResettableBufferWriter - { - public delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); - - const int ThreadStaticBufferSize = 31111; - const int DefaultBufferSize = 32768; // use 32K default buffer. - - static char newLine1; - static char newLine2; - static bool crlf; - - static Utf16ValueStringBuilder() - { - var newLine = Environment.NewLine.ToCharArray(); - if (newLine.Length == 1) - { - // cr or lf - newLine1 = newLine[0]; - crlf = false; - } - else - { - // crlf(windows) - newLine1 = newLine[0]; - newLine2 = newLine[1]; - crlf = true; - } - } - - [ThreadStatic] - static char[] scratchBuffer; - - [ThreadStatic] - internal static bool scratchBufferUsed; - - char[] buffer; - int index; - bool disposeImmediately; - - /// Length of written buffer. - public int Length => index; - /// Get the written buffer data. - public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); - /// Get the written buffer data. - public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); - /// Get the written buffer data. - public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); - - /// - /// Initializes a new instance - /// - /// - /// If true uses thread-static buffer that is faster but must return immediately. - /// - /// - /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateStringBuilder(notNested: true) is nested. - /// See the README.md - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Utf16ValueStringBuilder(bool disposeImmediately) - { - if (disposeImmediately && scratchBufferUsed) - { - ThrowNestedException(); - } - - char[] buf; - if (disposeImmediately) - { - buf = scratchBuffer; - if (buf == null) - { - buf = scratchBuffer = new char[ThreadStaticBufferSize]; - } - scratchBufferUsed = true; - } - else - { - buf = ArrayPool.Shared.Rent(DefaultBufferSize); - } - - buffer = buf; - index = 0; - this.disposeImmediately = disposeImmediately; - } - - /// - /// Return the inner buffer to pool. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() - { - if (buffer != null) - { - if (buffer.Length != ThreadStaticBufferSize) - { - ArrayPool.Shared.Return(buffer); - } - buffer = null; - index = 0; - if (disposeImmediately) - { - scratchBufferUsed = false; - } - } - } - - public void Clear() - { - index = 0; - } - - public void TryGrow(int sizeHint) - { - - if (buffer.Length < index + sizeHint) - { - Grow(sizeHint); - } - } - - public void Grow(int sizeHint) - { - var nextSize = buffer.Length * 2; - if (sizeHint != 0) - { - nextSize = Math.Max(nextSize, index + sizeHint); - } - - var newBuffer = ArrayPool.Shared.Rent(nextSize); - - buffer.CopyTo(newBuffer, 0); - if (buffer.Length != ThreadStaticBufferSize) - { - ArrayPool.Shared.Return(buffer); - } - - buffer = newBuffer; - } - - /// Appends the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine() - { - if (crlf) - { - if (buffer.Length - index < 2) Grow(2); - buffer[index] = newLine1; - buffer[index + 1] = newLine2; - index += 2; - } - else - { - if (buffer.Length - index < 1) Grow(1); - buffer[index] = newLine1; - index += 1; - } - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(char value) - { - if (buffer.Length - index < 1) - { - Grow(1); - } - - buffer[index++] = value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(char value, int repeatCount) - { - if (repeatCount < 0) - { - throw new ArgumentOutOfRangeException(nameof(repeatCount)); - } - - GetSpan(repeatCount).Fill(value); - Advance(repeatCount); - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(char value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(string value) - { -#if UNITY_2018_3_OR_NEWER - if (buffer.Length - index < value.Length) - { - Grow(value.Length); - } - value.CopyTo(0, buffer, index, value.Length); - index += value.Length; -#else - Append(value.AsSpan()); -#endif - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(string value) - { - Append(value); - AppendLine(); - } - - /// Appends a contiguous region of arbitrary memory to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(ReadOnlySpan value) - { - if (buffer.Length - index < value.Length) - { - Grow(value.Length); - } - - value.CopyTo(buffer.AsSpan(index)); - index += value.Length; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(ReadOnlySpan value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - public void Append(T value) - { - if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - public void AppendLine(T value) - { - Append(value); - AppendLine(); - } - - static class ExceptionUtil - { - public static void ThrowArgumentOutOfRangeException(string paramName) - { - throw new ArgumentOutOfRangeException(paramName); - } - } - - /// - /// Inserts a string 0 or more times into this builder at the specified position. - /// - /// The index to insert in this builder. - /// The string to insert. - /// The number of times to insert the string. - public void Insert(int index, string value, int count) - { - Insert(index, value.AsSpan(), count); - } - - public void Insert(int index, string value) - { - Insert(index, value.AsSpan(), 1); - } - - public void Insert(int index, ReadOnlySpan value, int count) - { - if (count < 0) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); - } - - int currentLength = Length; - if ((uint)index > (uint)currentLength) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(index)); - } - - if (value.Length == 0 || count == 0) - { - return; - } - - var newSize = index + value.Length * count; - var newBuffer = ArrayPool.Shared.Rent(Math.Max(DefaultBufferSize, newSize)); - - buffer.AsSpan(0, index).CopyTo(newBuffer); - int newBufferIndex = index; - - for (int i = 0; i < count; i++) - { - value.CopyTo(newBuffer.AsSpan(newBufferIndex)); - newBufferIndex += value.Length; - } - - int remainLnegth = this.index - index; - buffer.AsSpan(index, remainLnegth).CopyTo(newBuffer.AsSpan(newBufferIndex)); - - if (buffer.Length != ThreadStaticBufferSize) - { - if (buffer != null) - { - ArrayPool.Shared.Return(buffer); - } - } - - buffer = newBuffer; - this.index = newBufferIndex + remainLnegth; - } - - /// - /// Replaces all instances of one character with another in this builder. - /// - /// The character to replace. - /// The character to replace with. - public void Replace(char oldChar, char newChar) => Replace(oldChar, newChar, 0, Length); - - /// - /// Replaces all instances of one character with another in this builder. - /// - /// The character to replace. - /// The character to replace with. - /// The index to start in this builder. - /// The number of characters to read in this builder. - public void Replace(char oldChar, char newChar, int startIndex, int count) - { - int currentLength = Length; - if ((uint)startIndex > (uint)currentLength) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); - } - - if (count < 0 || startIndex > currentLength - count) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); - } - - int endIndex = startIndex + count; - - for (int i = startIndex; i < endIndex; i++) - { - if (buffer[i] == oldChar) - { - buffer[i] = newChar; - } - } - } - - /// - /// Replaces all instances of one string with another in this builder. - /// - /// The string to replace. - /// The string to replace with. - /// - /// If is null, instances of - /// are removed from this builder. - /// - public void Replace(string oldValue, string newValue) => Replace(oldValue, newValue, 0, Length); - - public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue) => Replace(oldValue, newValue, 0, Length); - - /// - /// Replaces all instances of one string with another in part of this builder. - /// - /// The string to replace. - /// The string to replace with. - /// The index to start in this builder. - /// The number of characters to read in this builder. - /// - /// If is null, instances of - /// are removed from this builder. - /// - public void Replace(string oldValue, string newValue, int startIndex, int count) - { - if (oldValue == null) - { - throw new ArgumentNullException(nameof(oldValue)); - } - - Replace(oldValue.AsSpan(), newValue.AsSpan(), startIndex, count); - } - - public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue, int startIndex, int count) - { - int currentLength = Length; - - if ((uint)startIndex > (uint)currentLength) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); - } - - if (count < 0 || startIndex > currentLength - count) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); - } - - if (oldValue.Length == 0) - { - throw new ArgumentException("oldValue.Length is 0", nameof(oldValue)); - } - - var readOnlySpan = AsSpan(); - int endIndex = startIndex + count; - int matchCount = 0; - - for (int i = startIndex; i < endIndex; i += oldValue.Length) - { - var span = readOnlySpan.Slice(i, endIndex - i); - var pos = span.IndexOf(oldValue, StringComparison.Ordinal); - if (pos == -1) - { - break; - } - i += pos; - matchCount++; - } - - if (matchCount == 0) - return; - - var newBuffer = ArrayPool.Shared.Rent(Math.Max(DefaultBufferSize, Length + (newValue.Length - oldValue.Length) * matchCount)); - - buffer.AsSpan(0, startIndex).CopyTo(newBuffer); - int newBufferIndex = startIndex; - - for (int i = startIndex; i < endIndex; i += oldValue.Length) - { - var span = readOnlySpan.Slice(i, endIndex - i); - var pos = span.IndexOf(oldValue, StringComparison.Ordinal); - if (pos == -1) - { - var remain = readOnlySpan.Slice(i); - remain.CopyTo(newBuffer.AsSpan(newBufferIndex)); - newBufferIndex += remain.Length; - break; - } - readOnlySpan.Slice(i, pos).CopyTo(newBuffer.AsSpan(newBufferIndex)); - newValue.CopyTo(newBuffer.AsSpan(newBufferIndex + pos)); - newBufferIndex += pos + newValue.Length; - i += pos; - } - - if (buffer.Length != ThreadStaticBufferSize) - { - ArrayPool.Shared.Return(buffer); - } - buffer = newBuffer; - index = newBufferIndex; - } - - /// - /// Removes a range of characters from this builder. - /// - /// - /// This method does not reduce the capacity of this builder. - /// - public void Remove(int startIndex, int length) - { - if (length < 0) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(length)); - } - - if (startIndex < 0) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); - } - - if (length > Length - startIndex) - { - ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(length)); - } - - if (Length == length && startIndex == 0) - { - index = 0; - return; - } - - if (length == 0) - { - return; - } - - int remain = startIndex + length; - buffer.AsSpan(remain, Length - remain).CopyTo(buffer.AsSpan(startIndex)); - index -= length; - } - - - // Output - - /// Copy inner buffer to the destination span. - public bool TryCopyTo(Span destination, out int charsWritten) - { - if (destination.Length < index) - { - charsWritten = 0; - return false; - } - - charsWritten = index; - buffer.AsSpan(0, index).CopyTo(destination); - return true; - } - - /// Converts the value of this instance to a System.String. - public override string ToString() - { - if (index == 0) - return string.Empty; - - return new string(buffer, 0, index); - } - - // IBufferWriter - - /// IBufferWriter.GetMemory. - public Memory GetMemory(int sizeHint) - { - if ((buffer.Length - index) < sizeHint) - { - Grow(sizeHint); - } - - return buffer.AsMemory(index); - } - - /// IBufferWriter.GetSpan. - public Span GetSpan(int sizeHint) - { - if ((buffer.Length - index) < sizeHint) - { - Grow(sizeHint); - } - - return buffer.AsSpan(index); - } - - /// IBufferWriter.Advance. - public void Advance(int count) - { - index += count; - } - - void IResettableBufferWriter.Reset() - { - index = 0; - } - - void ThrowArgumentException(string paramName) - { - throw new ArgumentException("Can't format argument.", paramName); - } - static void ThrowFormatException() - { - throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); - } - private static void FormatError() - { - throw new FormatException("Input string was not in a correct format."); - } - - void AppendFormatInternal(T arg, int width, ReadOnlySpan format, string argName) - { - if (width <= 0) // leftJustify - { - width *= -1; - - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format)) - { - Grow(charsWritten); - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format)) - { - ThrowArgumentException(argName); - } - } - - index += charsWritten; - - int padding = width - charsWritten; - if (width > 0 && padding > 0) - { - Append(' ', padding); // TODO Fill Method is too slow. - } - } - else // rightJustify - { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - Append(' ', padding); // TODO Fill Method is too slow. - } - - Append(s); - } - else - { - Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - - if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc char[s.Length * 2]; - if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ThrowArgumentException(argName); - } - } - - int padding = width - charsWritten; - if (padding > 0) - { - Append(' ', padding); // TODO Fill Method is too slow. - } - - Append(s.Slice(0, charsWritten)); - } - } - } - - static void ThrowNestedException() - { - throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); - } - - void AppendFormatInternal(T arg1, ReadOnlySpan format, string argName) - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(argName); - } - } - index += written; - } - - /// - /// Register custom formatter - /// - public static void RegisterTryFormat(TryFormat formatMethod) - { - FormatterCache.TryFormatDelegate = formatMethod; - } - - static TryFormat CreateNullableFormatter() where T : struct - { - return new TryFormat((T? x, Span dest, out int written, ReadOnlySpan format) => - { - if (x == null) - { - written = 0; - return true; - } - return FormatterCache.TryFormatDelegate(x.Value, dest, out written, format); - }); - } - - /// - /// Supports the Nullable type for a given struct type. - /// - public static void EnableNullableFormat() where T : struct - { - RegisterTryFormat(CreateNullableFormatter()); - } - - public static class FormatterCache - { - public static TryFormat TryFormatDelegate; - static FormatterCache() - { - var formatter = (TryFormat)CreateFormatter(typeof(T)); - if (formatter == null) - { - if (typeof(T).IsEnum) - { - formatter = new TryFormat(EnumUtil.TryFormatUtf16); - } - else if (typeof(T) == typeof(string)) - { - formatter = new TryFormat(TryFormatString); - } - else - { - formatter = new TryFormat(TryFormatDefault); - } - } - - TryFormatDelegate = formatter; - } - - static bool TryFormatString(T value, Span dest, out int written, ReadOnlySpan format) - { - var s = value as string; - - if (s == null) - { - written = 0; - return true; - } - - // also use this length when result is false. - written = s.Length; - return s.AsSpan().TryCopyTo(dest); - } - - static bool TryFormatDefault(T value, Span dest, out int written, ReadOnlySpan format) - { - if (value == null) - { - written = 0; - return true; - } - - var s = (value is IFormattable formattable && format.Length != 0) ? - formattable.ToString(format.ToString(), null) : - value.ToString(); - - // also use this length when result is false. - written = s.Length; - return s.AsSpan().TryCopyTo(dest); - } - } - } -} diff --git a/Plugins/ZString/Utf16ValueStringBuilder.cs.meta b/Plugins/ZString/Utf16ValueStringBuilder.cs.meta deleted file mode 100644 index 5c5c1bb6..00000000 --- a/Plugins/ZString/Utf16ValueStringBuilder.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a63cdeec02e3c54438967c859226bb32 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf8.meta b/Plugins/ZString/Utf8.meta deleted file mode 100644 index f4561e35..00000000 --- a/Plugins/ZString/Utf8.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 575710f478ce5e0449d3953fd6ccf1b8 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/Plugins/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs deleted file mode 100644 index 4f0b1ad7..00000000 --- a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ /dev/null @@ -1,1601 +0,0 @@ -using System; -using System.Buffers; - -namespace Cysharp.Text -{ - public partial struct Utf8ValueStringBuilder - { - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - case 12: - AppendFormatInternal(arg13, indexParse.Alignment, writeFormat, nameof(arg13)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - case 12: - AppendFormatInternal(arg13, indexParse.Alignment, writeFormat, nameof(arg13)); - continue; - case 13: - AppendFormatInternal(arg14, indexParse.Alignment, writeFormat, nameof(arg14)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - case 12: - AppendFormatInternal(arg13, indexParse.Alignment, writeFormat, nameof(arg13)); - continue; - case 13: - AppendFormatInternal(arg14, indexParse.Alignment, writeFormat, nameof(arg14)); - continue; - case 14: - AppendFormatInternal(arg15, indexParse.Alignment, writeFormat, nameof(arg15)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - case 12: - AppendFormatInternal(arg13, indexParse.Alignment, writeFormat, nameof(arg13)); - continue; - case 13: - AppendFormatInternal(arg14, indexParse.Alignment, writeFormat, nameof(arg14)); - continue; - case 14: - AppendFormatInternal(arg15, indexParse.Alignment, writeFormat, nameof(arg15)); - continue; - case 15: - AppendFormatInternal(arg16, indexParse.Alignment, writeFormat, nameof(arg16)); - continue; - default: - ThrowFormatException(); - break; - } - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ThrowFormatException(); - } - } - - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - Append(format.AsSpan(copyFrom, copyLength)); - } - } - } - - } -} diff --git a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta b/Plugins/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta deleted file mode 100644 index 3243019b..00000000 --- a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5d7ee057fcee1904f9ac7f3bf532a09e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/Plugins/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs deleted file mode 100644 index dd58fce1..00000000 --- a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Buffers; -using System.Buffers.Text; - -namespace Cysharp.Text -{ - public partial struct Utf8ValueStringBuilder - { - static object CreateFormatter(Type type) - { - if (type == typeof(System.Byte)) - { - return new TryFormat((System.Byte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.DateTime)) - { - return new TryFormat((System.DateTime x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.DateTimeOffset)) - { - return new TryFormat((System.DateTimeOffset x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Decimal)) - { - return new TryFormat((System.Decimal x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Double)) - { - return new TryFormat((System.Double x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Int16)) - { - return new TryFormat((System.Int16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Int32)) - { - return new TryFormat((System.Int32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Int64)) - { - return new TryFormat((System.Int64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.SByte)) - { - return new TryFormat((System.SByte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Single)) - { - return new TryFormat((System.Single x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.TimeSpan)) - { - return new TryFormat((System.TimeSpan x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.UInt16)) - { - return new TryFormat((System.UInt16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.UInt32)) - { - return new TryFormat((System.UInt32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.UInt64)) - { - return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Guid)) - { - return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Boolean)) - { - return new TryFormat((System.Boolean x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } - if (type == typeof(System.Byte?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.DateTime?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.DateTimeOffset?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Decimal?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Double?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Int16?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Int32?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Int64?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.SByte?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Single?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.TimeSpan?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.UInt16?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.UInt32?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.UInt64?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Guid?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.Boolean?)) - { - return CreateNullableFormatter(); - } - if (type == typeof(System.IntPtr)) - { - // ignore format - return new TryFormat((System.IntPtr x, Span dest, out int written, StandardFormat _) => System.IntPtr.Size == 4 - ? Utf8Formatter.TryFormat(x.ToInt32(), dest, out written, default) - : Utf8Formatter.TryFormat(x.ToInt64(), dest, out written, default)); - } - if (type == typeof(System.UIntPtr)) - { - // ignore format - return new TryFormat((System.UIntPtr x, Span dest, out int written, StandardFormat _) => System.UIntPtr.Size == 4 - ? Utf8Formatter.TryFormat(x.ToUInt32(), dest, out written, default) - : Utf8Formatter.TryFormat(x.ToUInt64(), dest, out written, default)); - } - - return null; - } - } -} \ No newline at end of file diff --git a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta b/Plugins/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta deleted file mode 100644 index 221d361c..00000000 --- a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 35e4f4117a41a70438f0ff051e65e239 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/Plugins/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs deleted file mode 100644 index 5321ecbf..00000000 --- a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ /dev/null @@ -1,747 +0,0 @@ -using System; -using System.Buffers; -using System.Buffers.Text; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public partial struct Utf8ValueStringBuilder - { - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Byte value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Byte value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Byte value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Byte value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTime value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTime value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.DateTime value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.DateTime value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTimeOffset value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTimeOffset value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.DateTimeOffset value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.DateTimeOffset value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Decimal value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Decimal value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Decimal value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Decimal value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Double value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Double value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Double value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Double value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int16 value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int16 value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int16 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int16 value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int32 value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int32 value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int32 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int32 value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int64 value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int64 value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int64 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Int64 value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.SByte value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.SByte value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.SByte value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.SByte value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Single value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Single value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Single value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Single value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.TimeSpan value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.TimeSpan value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.TimeSpan value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.TimeSpan value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt16 value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt16 value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt16 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt16 value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt32 value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt32 value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt32 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt32 value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt64 value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt64 value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt64 value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.UInt64 value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Guid value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Guid value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Guid value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Guid value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Boolean value) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value to this instance with numeric format strings. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Boolean value, StandardFormat format) - { - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Boolean value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(System.Boolean value, StandardFormat format) - { - Append(value, format); - AppendLine(); - } - - } -} diff --git a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta b/Plugins/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta deleted file mode 100644 index 257e3abd..00000000 --- a/Plugins/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d3c9ebcd92d8b6842821732af2a75fba -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/Utf8ValueStringBuilder.cs b/Plugins/ZString/Utf8ValueStringBuilder.cs deleted file mode 100644 index 0c66add1..00000000 --- a/Plugins/ZString/Utf8ValueStringBuilder.cs +++ /dev/null @@ -1,517 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace Cysharp.Text -{ - public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter, IResettableBufferWriter - { - public delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); - - const int ThreadStaticBufferSize = 64444; - const int DefaultBufferSize = 65536; // use 64K default buffer. - static Encoding UTF8NoBom = new UTF8Encoding(false); - - static byte newLine1; - static byte newLine2; - static bool crlf; - - static Utf8ValueStringBuilder() - { - var newLine = UTF8NoBom.GetBytes(Environment.NewLine); - if (newLine.Length == 1) - { - // cr or lf - newLine1 = newLine[0]; - crlf = false; - } - else - { - // crlf(windows) - newLine1 = newLine[0]; - newLine2 = newLine[1]; - crlf = true; - } - } - - [ThreadStatic] - static byte[] scratchBuffer; - - [ThreadStatic] - internal static bool scratchBufferUsed; - - byte[] buffer; - int index; - bool disposeImmediately; - - /// Length of written buffer. - public int Length => index; - - /// Get the written buffer data. - public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); - - /// Get the written buffer data. - public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); - - /// Get the written buffer data. - public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); - - /// - /// Initializes a new instance - /// - /// - /// If true uses thread-static buffer that is faster but must return immediately. - /// - /// - /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. - /// See the README.md - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Utf8ValueStringBuilder(bool disposeImmediately) - { - if (disposeImmediately && scratchBufferUsed) - { - ThrowNestedException(); - } - - byte[] buf; - if (disposeImmediately) - { - buf = scratchBuffer; - if (buf == null) - { - buf = scratchBuffer = new byte[ThreadStaticBufferSize]; - } - scratchBufferUsed = true; - } - else - { - buf = ArrayPool.Shared.Rent(DefaultBufferSize); - } - - buffer = buf; - index = 0; - this.disposeImmediately = disposeImmediately; - } - - /// - /// Return the inner buffer to pool. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() - { - if (buffer != null) - { - if (buffer.Length != ThreadStaticBufferSize) - { - ArrayPool.Shared.Return(buffer); - } - buffer = null; - index = 0; - if (disposeImmediately) - { - scratchBufferUsed = false; - } - } - } - - public void Clear() - { - index = 0; - } - - public void TryGrow(int sizeHint) - { - if (buffer.Length < index + sizeHint) - { - Grow(sizeHint); - } - } - - public void Grow(int sizeHint) - { - var nextSize = buffer.Length * 2; - if (sizeHint != 0) - { - nextSize = Math.Max(nextSize, index + sizeHint); - } - - var newBuffer = ArrayPool.Shared.Rent(nextSize); - - buffer.CopyTo(newBuffer, 0); - if (buffer.Length != ThreadStaticBufferSize) - { - ArrayPool.Shared.Return(buffer); - } - - buffer = newBuffer; - } - - /// Appends the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine() - { - if (crlf) - { - if (buffer.Length - index < 2) Grow(2); - buffer[index] = newLine1; - buffer[index + 1] = newLine2; - index += 2; - } - else - { - if (buffer.Length - index < 1) Grow(1); - buffer[index] = newLine1; - index += 1; - } - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Append(char value) - { - var maxLen = UTF8NoBom.GetMaxByteCount(1); - if (buffer.Length - index < maxLen) - { - Grow(maxLen); - } - - fixed (byte* bp = &buffer[index]) - { - index += UTF8NoBom.GetBytes(&value, 1, bp, maxLen); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(char value, int repeatCount) - { - if (repeatCount < 0) - { - throw new ArgumentOutOfRangeException(nameof(repeatCount)); - } - - if (value <= 0x7F) // ASCII - { - GetSpan(repeatCount).Fill((byte)value); - Advance(repeatCount); - } - else - { - var maxLen = UTF8NoBom.GetMaxByteCount(1); - Span utf8Bytes = stackalloc byte[maxLen]; - ReadOnlySpan chars = stackalloc char[1] { value }; - - int len = UTF8NoBom.GetBytes(chars, utf8Bytes); - - TryGrow(len * repeatCount); - - for (int i = 0; i < repeatCount; i++) - { - utf8Bytes.CopyTo(GetSpan(len)); - Advance(len); - } - } - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(char value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(string value) - { -#if UNITY_2018_3_OR_NEWER - var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); - if (buffer.Length - index < maxLen) - { - Grow(maxLen); - } - index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); -#else - Append(value.AsSpan()); -#endif - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(string value) - { - Append(value); - AppendLine(); - } - - /// Appends a contiguous region of arbitrary memory to this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(ReadOnlySpan value) - { - var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); - if (buffer.Length - index < maxLen) - { - Grow(maxLen); - } - - index += UTF8NoBom.GetBytes(value, buffer.AsSpan(index)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(ReadOnlySpan value) - { - Append(value); - AppendLine(); - } - - /// Appends the string representation of a specified value to this instance. - public void Append(T value) - { - if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(value)); - } - } - index += written; - } - - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. - public void AppendLine(T value) - { - Append(value); - AppendLine(); - } - - // Output - - /// Copy inner buffer to the bufferWriter. - public void CopyTo(IBufferWriter bufferWriter) - { - var destination = bufferWriter.GetSpan(index); - TryCopyTo(destination, out var written); - bufferWriter.Advance(written); - } - - /// Copy inner buffer to the destination span. - public bool TryCopyTo(Span destination, out int bytesWritten) - { - if (destination.Length < index) - { - bytesWritten = 0; - return false; - } - - bytesWritten = index; - buffer.AsSpan(0, index).CopyTo(destination); - return true; - } - - /// Write inner buffer to stream. - public Task WriteToAsync(Stream stream) - { - return stream.WriteAsync(buffer, 0, index); - } - - /// Encode the innner utf8 buffer to a System.String. - public override string ToString() - { - if (index == 0) - return string.Empty; - - return UTF8NoBom.GetString(buffer, 0, index); - } - - // IBufferWriter - - /// IBufferWriter.GetMemory. - public Memory GetMemory(int sizeHint) - { - if ((buffer.Length - index) < sizeHint) - { - Grow(sizeHint); - } - - return buffer.AsMemory(index); - } - - /// IBufferWriter.GetSpan. - public Span GetSpan(int sizeHint) - { - if ((buffer.Length - index) < sizeHint) - { - Grow(sizeHint); - } - - return buffer.AsSpan(index); - } - - /// IBufferWriter.Advance. - public void Advance(int count) - { - index += count; - } - - void IResettableBufferWriter.Reset() - { - index = 0; - } - - void ThrowArgumentException(string paramName) - { - throw new ArgumentException("Can't format argument.", paramName); - } - - void ThrowFormatException() - { - throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); - } - - static void ThrowNestedException() - { - throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); - } - - private void AppendFormatInternal(T arg, int width, StandardFormat format, string argName) - { - if (width <= 0) // leftJustify - { - width *= -1; - - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format)) - { - Grow(charsWritten); - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format)) - { - ThrowArgumentException(argName); - } - } - - index += charsWritten; - - int padding = width - charsWritten; - if (width > 0 && padding > 0) - { - Append(' ', padding); // TODO Fill Method is too slow. - } - } - else // rightJustify - { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - Append(' ', padding); // TODO Fill Method is too slow. - } - - Append(s); - } - else - { - Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - - if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc byte[s.Length * 2]; - if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ThrowArgumentException(argName); - } - } - - int padding = width - charsWritten; - if (padding > 0) - { - Append(' ', padding); // TODO Fill Method is too slow. - } - - s.CopyTo(GetSpan(charsWritten)); - Advance(charsWritten); - } - } - } - - /// - /// Register custom formatter - /// - public static void RegisterTryFormat(TryFormat formatMethod) - { - FormatterCache.TryFormatDelegate = formatMethod; - } - - static TryFormat CreateNullableFormatter() where T : struct - { - return new TryFormat((T? x, Span destination, out int written, StandardFormat format) => - { - if (x == null) - { - written = 0; - return true; - } - return FormatterCache.TryFormatDelegate(x.Value, destination, out written, format); - }); - } - - /// - /// Supports the Nullable type for a given struct type. - /// - public static void EnableNullableFormat() where T : struct - { - RegisterTryFormat(CreateNullableFormatter()); - } - - public static class FormatterCache - { - public static TryFormat TryFormatDelegate; - static FormatterCache() - { - var formatter = (TryFormat)CreateFormatter(typeof(T)); - if (formatter == null) - { - if (typeof(T).IsEnum) - { - formatter = new TryFormat(EnumUtil.TryFormatUtf8); - } - else - { - formatter = new TryFormat(TryFormatDefault); - } - } - - TryFormatDelegate = formatter; - } - - static bool TryFormatDefault(T value, Span dest, out int written, StandardFormat format) - { - if (value == null) - { - written = 0; - return true; - } - - var s = typeof(T) == typeof(string) ? Unsafe.As(value) : - (value is IFormattable formattable && format != default) ? formattable.ToString(format.ToString(), null) : - value.ToString(); - - // also use this length when result is false. - written = UTF8NoBom.GetMaxByteCount(s.Length); - if (dest.Length < written) - { - return false; - } - - written = UTF8NoBom.GetBytes(s.AsSpan(), dest); - return true; - - } - } - } -} diff --git a/Plugins/ZString/Utf8ValueStringBuilder.cs.meta b/Plugins/ZString/Utf8ValueStringBuilder.cs.meta deleted file mode 100644 index 86ac1b55..00000000 --- a/Plugins/ZString/Utf8ValueStringBuilder.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ea8889d2a42dc824697d997531ea0c14 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ZString.Concat.cs b/Plugins/ZString/ZString.Concat.cs deleted file mode 100644 index b97088b8..00000000 --- a/Plugins/ZString/ZString.Concat.cs +++ /dev/null @@ -1,2413 +0,0 @@ -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public static partial class ZString - { - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1) - { - if (typeof(T1) == typeof(string)) - { - return (arg1 != null) ? Unsafe.As(arg1) : string.Empty; - } - - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - if (typeof(T9) == typeof(string)) - { - if(arg9 != null) - { - sb.Append(Unsafe.As(ref arg9)); - } - } - else if (typeof(T9) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg9)); - } - else - { - sb.Append(arg9); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - if (typeof(T9) == typeof(string)) - { - if(arg9 != null) - { - sb.Append(Unsafe.As(ref arg9)); - } - } - else if (typeof(T9) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg9)); - } - else - { - sb.Append(arg9); - } - - if (typeof(T10) == typeof(string)) - { - if(arg10 != null) - { - sb.Append(Unsafe.As(ref arg10)); - } - } - else if (typeof(T10) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg10)); - } - else - { - sb.Append(arg10); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - if (typeof(T9) == typeof(string)) - { - if(arg9 != null) - { - sb.Append(Unsafe.As(ref arg9)); - } - } - else if (typeof(T9) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg9)); - } - else - { - sb.Append(arg9); - } - - if (typeof(T10) == typeof(string)) - { - if(arg10 != null) - { - sb.Append(Unsafe.As(ref arg10)); - } - } - else if (typeof(T10) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg10)); - } - else - { - sb.Append(arg10); - } - - if (typeof(T11) == typeof(string)) - { - if(arg11 != null) - { - sb.Append(Unsafe.As(ref arg11)); - } - } - else if (typeof(T11) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg11)); - } - else - { - sb.Append(arg11); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - if (typeof(T9) == typeof(string)) - { - if(arg9 != null) - { - sb.Append(Unsafe.As(ref arg9)); - } - } - else if (typeof(T9) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg9)); - } - else - { - sb.Append(arg9); - } - - if (typeof(T10) == typeof(string)) - { - if(arg10 != null) - { - sb.Append(Unsafe.As(ref arg10)); - } - } - else if (typeof(T10) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg10)); - } - else - { - sb.Append(arg10); - } - - if (typeof(T11) == typeof(string)) - { - if(arg11 != null) - { - sb.Append(Unsafe.As(ref arg11)); - } - } - else if (typeof(T11) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg11)); - } - else - { - sb.Append(arg11); - } - - if (typeof(T12) == typeof(string)) - { - if(arg12 != null) - { - sb.Append(Unsafe.As(ref arg12)); - } - } - else if (typeof(T12) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg12)); - } - else - { - sb.Append(arg12); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - if (typeof(T9) == typeof(string)) - { - if(arg9 != null) - { - sb.Append(Unsafe.As(ref arg9)); - } - } - else if (typeof(T9) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg9)); - } - else - { - sb.Append(arg9); - } - - if (typeof(T10) == typeof(string)) - { - if(arg10 != null) - { - sb.Append(Unsafe.As(ref arg10)); - } - } - else if (typeof(T10) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg10)); - } - else - { - sb.Append(arg10); - } - - if (typeof(T11) == typeof(string)) - { - if(arg11 != null) - { - sb.Append(Unsafe.As(ref arg11)); - } - } - else if (typeof(T11) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg11)); - } - else - { - sb.Append(arg11); - } - - if (typeof(T12) == typeof(string)) - { - if(arg12 != null) - { - sb.Append(Unsafe.As(ref arg12)); - } - } - else if (typeof(T12) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg12)); - } - else - { - sb.Append(arg12); - } - - if (typeof(T13) == typeof(string)) - { - if(arg13 != null) - { - sb.Append(Unsafe.As(ref arg13)); - } - } - else if (typeof(T13) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg13)); - } - else - { - sb.Append(arg13); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - if (typeof(T9) == typeof(string)) - { - if(arg9 != null) - { - sb.Append(Unsafe.As(ref arg9)); - } - } - else if (typeof(T9) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg9)); - } - else - { - sb.Append(arg9); - } - - if (typeof(T10) == typeof(string)) - { - if(arg10 != null) - { - sb.Append(Unsafe.As(ref arg10)); - } - } - else if (typeof(T10) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg10)); - } - else - { - sb.Append(arg10); - } - - if (typeof(T11) == typeof(string)) - { - if(arg11 != null) - { - sb.Append(Unsafe.As(ref arg11)); - } - } - else if (typeof(T11) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg11)); - } - else - { - sb.Append(arg11); - } - - if (typeof(T12) == typeof(string)) - { - if(arg12 != null) - { - sb.Append(Unsafe.As(ref arg12)); - } - } - else if (typeof(T12) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg12)); - } - else - { - sb.Append(arg12); - } - - if (typeof(T13) == typeof(string)) - { - if(arg13 != null) - { - sb.Append(Unsafe.As(ref arg13)); - } - } - else if (typeof(T13) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg13)); - } - else - { - sb.Append(arg13); - } - - if (typeof(T14) == typeof(string)) - { - if(arg14 != null) - { - sb.Append(Unsafe.As(ref arg14)); - } - } - else if (typeof(T14) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg14)); - } - else - { - sb.Append(arg14); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - if (typeof(T9) == typeof(string)) - { - if(arg9 != null) - { - sb.Append(Unsafe.As(ref arg9)); - } - } - else if (typeof(T9) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg9)); - } - else - { - sb.Append(arg9); - } - - if (typeof(T10) == typeof(string)) - { - if(arg10 != null) - { - sb.Append(Unsafe.As(ref arg10)); - } - } - else if (typeof(T10) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg10)); - } - else - { - sb.Append(arg10); - } - - if (typeof(T11) == typeof(string)) - { - if(arg11 != null) - { - sb.Append(Unsafe.As(ref arg11)); - } - } - else if (typeof(T11) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg11)); - } - else - { - sb.Append(arg11); - } - - if (typeof(T12) == typeof(string)) - { - if(arg12 != null) - { - sb.Append(Unsafe.As(ref arg12)); - } - } - else if (typeof(T12) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg12)); - } - else - { - sb.Append(arg12); - } - - if (typeof(T13) == typeof(string)) - { - if(arg13 != null) - { - sb.Append(Unsafe.As(ref arg13)); - } - } - else if (typeof(T13) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg13)); - } - else - { - sb.Append(arg13); - } - - if (typeof(T14) == typeof(string)) - { - if(arg14 != null) - { - sb.Append(Unsafe.As(ref arg14)); - } - } - else if (typeof(T14) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg14)); - } - else - { - sb.Append(arg14); - } - - if (typeof(T15) == typeof(string)) - { - if(arg15 != null) - { - sb.Append(Unsafe.As(ref arg15)); - } - } - else if (typeof(T15) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg15)); - } - else - { - sb.Append(arg15); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - if (typeof(T1) == typeof(string)) - { - if(arg1 != null) - { - sb.Append(Unsafe.As(ref arg1)); - } - } - else if (typeof(T1) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg1)); - } - else - { - sb.Append(arg1); - } - - if (typeof(T2) == typeof(string)) - { - if(arg2 != null) - { - sb.Append(Unsafe.As(ref arg2)); - } - } - else if (typeof(T2) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg2)); - } - else - { - sb.Append(arg2); - } - - if (typeof(T3) == typeof(string)) - { - if(arg3 != null) - { - sb.Append(Unsafe.As(ref arg3)); - } - } - else if (typeof(T3) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg3)); - } - else - { - sb.Append(arg3); - } - - if (typeof(T4) == typeof(string)) - { - if(arg4 != null) - { - sb.Append(Unsafe.As(ref arg4)); - } - } - else if (typeof(T4) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg4)); - } - else - { - sb.Append(arg4); - } - - if (typeof(T5) == typeof(string)) - { - if(arg5 != null) - { - sb.Append(Unsafe.As(ref arg5)); - } - } - else if (typeof(T5) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg5)); - } - else - { - sb.Append(arg5); - } - - if (typeof(T6) == typeof(string)) - { - if(arg6 != null) - { - sb.Append(Unsafe.As(ref arg6)); - } - } - else if (typeof(T6) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg6)); - } - else - { - sb.Append(arg6); - } - - if (typeof(T7) == typeof(string)) - { - if(arg7 != null) - { - sb.Append(Unsafe.As(ref arg7)); - } - } - else if (typeof(T7) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg7)); - } - else - { - sb.Append(arg7); - } - - if (typeof(T8) == typeof(string)) - { - if(arg8 != null) - { - sb.Append(Unsafe.As(ref arg8)); - } - } - else if (typeof(T8) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg8)); - } - else - { - sb.Append(arg8); - } - - if (typeof(T9) == typeof(string)) - { - if(arg9 != null) - { - sb.Append(Unsafe.As(ref arg9)); - } - } - else if (typeof(T9) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg9)); - } - else - { - sb.Append(arg9); - } - - if (typeof(T10) == typeof(string)) - { - if(arg10 != null) - { - sb.Append(Unsafe.As(ref arg10)); - } - } - else if (typeof(T10) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg10)); - } - else - { - sb.Append(arg10); - } - - if (typeof(T11) == typeof(string)) - { - if(arg11 != null) - { - sb.Append(Unsafe.As(ref arg11)); - } - } - else if (typeof(T11) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg11)); - } - else - { - sb.Append(arg11); - } - - if (typeof(T12) == typeof(string)) - { - if(arg12 != null) - { - sb.Append(Unsafe.As(ref arg12)); - } - } - else if (typeof(T12) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg12)); - } - else - { - sb.Append(arg12); - } - - if (typeof(T13) == typeof(string)) - { - if(arg13 != null) - { - sb.Append(Unsafe.As(ref arg13)); - } - } - else if (typeof(T13) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg13)); - } - else - { - sb.Append(arg13); - } - - if (typeof(T14) == typeof(string)) - { - if(arg14 != null) - { - sb.Append(Unsafe.As(ref arg14)); - } - } - else if (typeof(T14) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg14)); - } - else - { - sb.Append(arg14); - } - - if (typeof(T15) == typeof(string)) - { - if(arg15 != null) - { - sb.Append(Unsafe.As(ref arg15)); - } - } - else if (typeof(T15) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg15)); - } - else - { - sb.Append(arg15); - } - - if (typeof(T16) == typeof(string)) - { - if(arg16 != null) - { - sb.Append(Unsafe.As(ref arg16)); - } - } - else if (typeof(T16) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg16)); - } - else - { - sb.Append(arg16); - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - } -} \ No newline at end of file diff --git a/Plugins/ZString/ZString.Concat.cs.meta b/Plugins/ZString/ZString.Concat.cs.meta deleted file mode 100644 index 45f4df8e..00000000 --- a/Plugins/ZString/ZString.Concat.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3cc4c8c9a298173488ac495332e11009 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ZString.Format.cs b/Plugins/ZString/ZString.Format.cs deleted file mode 100644 index 294862ca..00000000 --- a/Plugins/ZString/ZString.Format.cs +++ /dev/null @@ -1,264 +0,0 @@ -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public static partial class ZString - { - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - /// Replaces one or more format items in a string with the string representation of some specified objects. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - } -} \ No newline at end of file diff --git a/Plugins/ZString/ZString.Format.cs.meta b/Plugins/ZString/ZString.Format.cs.meta deleted file mode 100644 index 54b423c2..00000000 --- a/Plugins/ZString/ZString.Format.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 46c1d83e619838446ba528f658244b56 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ZString.Prepare.cs b/Plugins/ZString/ZString.Prepare.cs deleted file mode 100644 index 90a309aa..00000000 --- a/Plugins/ZString/ZString.Prepare.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public static partial class ZString - { - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf16PreparedFormat PrepareUtf16(string format) - { - return new Utf16PreparedFormat(format); - } - - /// Prepare string format to avoid parse template in each operation. - public static Utf8PreparedFormat PrepareUtf8(string format) - { - return new Utf8PreparedFormat(format); - } - - } -} \ No newline at end of file diff --git a/Plugins/ZString/ZString.Prepare.cs.meta b/Plugins/ZString/ZString.Prepare.cs.meta deleted file mode 100644 index cc2e36c5..00000000 --- a/Plugins/ZString/ZString.Prepare.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fca154d819b770049860ac2c8c621141 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ZString.Utf8Format.cs b/Plugins/ZString/ZString.Utf8Format.cs deleted file mode 100644 index ce267b90..00000000 --- a/Plugins/ZString/ZString.Utf8Format.cs +++ /dev/null @@ -1,1732 +0,0 @@ -using System; -using System.Buffers; -using System.Runtime.CompilerServices; - -using static Cysharp.Text.Utf8ValueStringBuilder; - -namespace Cysharp.Text -{ - public static partial class ZString - { - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - case 12: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - case 12: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); - continue; - case 13: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - case 12: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); - continue; - case 13: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); - continue; - case 14: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg15, indexParse.Alignment, writeFormat, nameof(arg15)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - /// Replaces one or more format items in a string with the string representation of some specified values. - public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) - { - if (format == null) - { - throw new ArgumentNullException(nameof(format)); - } - - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) - { - var c = format[i]; - if (c == '{') - { - // escape. - if (i == format.Length - 1) - { - throw new FormatException("invalid format"); - } - - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - } - - // try to find range - var indexParse = FormatParser.Parse(format, i); - copyFrom = indexParse.LastIndex; - i = indexParse.LastIndex - 1; - var writeFormat = StandardFormat.Parse(indexParse.FormatString); - switch (indexParse.Index) - { - case 0: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); - continue; - case 1: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); - continue; - case 2: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); - continue; - case 3: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); - continue; - case 4: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); - continue; - case 5: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); - continue; - case 6: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); - continue; - case 7: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); - continue; - case 8: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); - continue; - case 9: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); - continue; - case 10: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); - continue; - case 11: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); - continue; - case 12: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); - continue; - case 13: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); - continue; - case 14: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg15, indexParse.Alignment, writeFormat, nameof(arg15)); - continue; - case 15: - Utf8FormatHelper.FormatTo(ref bufferWriter, arg16, indexParse.Alignment, writeFormat, nameof(arg16)); - continue; - default: - ExceptionUtil.ThrowFormatException(); - break; - } - - ExceptionUtil.ThrowFormatException(); - } - else if (c == '}') - { - if (i + 1 < format.Length && format[i + 1] == '}') - { - var size = i - copyFrom; - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); - bufferWriter.Advance(written); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; - } - else - { - ExceptionUtil.ThrowFormatException(); - } - } - } - - { - // copy final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) - { - var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); - var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); - bufferWriter.Advance(written); - } - } - } - } -} diff --git a/Plugins/ZString/ZString.Utf8Format.cs.meta b/Plugins/ZString/ZString.Utf8Format.cs.meta deleted file mode 100644 index 48600d47..00000000 --- a/Plugins/ZString/ZString.Utf8Format.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bdd4edf33de6a6c4b9911c8f3515cb8d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ZString.asmdef b/Plugins/ZString/ZString.asmdef deleted file mode 100644 index 8e7cc980..00000000 --- a/Plugins/ZString/ZString.asmdef +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "ZString", - "references": [ - "Unity.TextMeshPro" - ], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": true, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [] -} \ No newline at end of file diff --git a/Plugins/ZString/ZString.asmdef.meta b/Plugins/ZString/ZString.asmdef.meta deleted file mode 100644 index de79288a..00000000 --- a/Plugins/ZString/ZString.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 33661e06c33d31b4c9223810bf503247 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ZString.cs b/Plugins/ZString/ZString.cs deleted file mode 100644 index aa4cb110..00000000 --- a/Plugins/ZString/ZString.cs +++ /dev/null @@ -1,273 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; - -namespace Cysharp.Text -{ - public static partial class ZString - { - static Encoding UTF8NoBom = new UTF8Encoding(false); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void AppendChars(ref TBufferWriter sb, ReadOnlySpan chars) - where TBufferWriter : System.Buffers.IBufferWriter - { - var span = sb.GetSpan(UTF8NoBom.GetMaxByteCount(chars.Length)); - sb.Advance(UTF8NoBom.GetBytes(chars, span)); - } - - /// Create the Utf16 string StringBuilder. - public static Utf16ValueStringBuilder CreateStringBuilder() - { - return new Utf16ValueStringBuilder(false); - } - - /// Create the Utf16 string StringBuilder, when true uses thread-static buffer that is faster but must return immediately. - public static Utf8ValueStringBuilder CreateUtf8StringBuilder() - { - return new Utf8ValueStringBuilder(false); - } - - /// Create the Utf8(`Span[byte]`) StringBuilder. - /// - /// If true uses thread-static buffer that is faster but must return immediately. - /// - /// - /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. - /// See the README.md - /// - public static Utf16ValueStringBuilder CreateStringBuilder(bool notNested) - { - return new Utf16ValueStringBuilder(notNested); - } - - /// Create the Utf8(`Span[byte]`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. - /// - /// If true uses thread-static buffer that is faster but must return immediately. - /// - /// - /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. - /// See the README.md - /// - public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) - { - return new Utf8ValueStringBuilder(notNested); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(char separator, params T[] values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - return JoinInternal(s, values.AsSpan()); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(char separator, List values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - return JoinInternal(s, (IReadOnlyList)values); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(char separator, ReadOnlySpan values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - return JoinInternal(s, values); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(char separator, IEnumerable values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - return JoinInternal(s, values); - } - - public static string Join(char separator, ICollection values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - return JoinInternal(s, values.AsEnumerable()); - } - - public static string Join(char separator, IList values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - return JoinInternal(s, values); - } - - public static string Join(char separator, IReadOnlyList values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - return JoinInternal(s, values); - } - - public static string Join(char separator, IReadOnlyCollection values) - { - ReadOnlySpan s = stackalloc char[1] { separator }; - return JoinInternal(s, values.AsEnumerable()); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(string separator, params T[] values) - { - return JoinInternal(separator.AsSpan(), values.AsSpan()); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(string separator, List values) - { - return JoinInternal(separator.AsSpan(), (IReadOnlyList)values); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(string separator, ReadOnlySpan values) - { - return JoinInternal(separator.AsSpan(), values); - } - - public static string Join(string separator, ICollection values) - { - return JoinInternal(separator.AsSpan(), values.AsEnumerable()); - } - - public static string Join(string separator, IList values) - { - return JoinInternal(separator.AsSpan(), values); - } - - public static string Join(string separator, IReadOnlyList values) - { - return JoinInternal(separator.AsSpan(), values); - } - - public static string Join(string separator, IReadOnlyCollection values) - { - return JoinInternal(separator.AsSpan(), values.AsEnumerable()); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(string separator, IEnumerable values) - { - return JoinInternal(separator.AsSpan(), values); - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(params T[] values) - { - return JoinInternal(default, values.AsSpan()); - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(List values) - { - return JoinInternal(default, (IReadOnlyList)values); - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(ReadOnlySpan values) - { - return JoinInternal(default, values); - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(ICollection values) - { - return JoinInternal(default, values.AsEnumerable()); - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(IList values) - { - return JoinInternal(default, values); - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(IReadOnlyList values) - { - return JoinInternal(default, values); - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(IReadOnlyCollection values) - { - return JoinInternal(default, values.AsEnumerable()); - } - - /// Concatenates the string representation of some specified objects. - public static string Concat(IEnumerable values) - { - return JoinInternal(default, values); - } - - static string JoinInternal(ReadOnlySpan separator, IList values) - { - var readOnlyList = values as IReadOnlyList; - // Boxing will occur, but JIT will be de-virtualized. - readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); - return JoinInternal(separator, readOnlyList); - } - - static string JoinInternal(ReadOnlySpan separator, IReadOnlyList values) - { - var count = values.Count; - if (count == 0) - { - return string.Empty; - } - else if (typeof(T) == typeof(string) && count == 1) - { - return Unsafe.As(values[0]); - } - - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendJoinInternal(separator, values); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) - { - if (values.Length == 0) - { - return string.Empty; - } - else if (typeof(T) == typeof(string) && values.Length == 1) - { - return Unsafe.As(values[0]); - } - - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendJoinInternal(separator, values); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - static string JoinInternal(ReadOnlySpan separator, IEnumerable values) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - sb.AppendJoinInternal(separator, values); - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - } -} diff --git a/Plugins/ZString/ZString.cs.meta b/Plugins/ZString/ZString.cs.meta deleted file mode 100644 index 3c0d7174..00000000 --- a/Plugins/ZString/ZString.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a82083d5baadea245b3adc1ffd14da2c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/ZString/ZStringWriter.cs b/Plugins/ZString/ZStringWriter.cs deleted file mode 100644 index 70580645..00000000 --- a/Plugins/ZString/ZStringWriter.cs +++ /dev/null @@ -1,209 +0,0 @@ -using System; -using System.Globalization; -using System.IO; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Cysharp.Text -{ - /// - /// A implementation that is backed with . - /// - /// - /// It's important to make sure the writer is always properly disposed. - /// - public sealed class ZStringWriter : TextWriter - { - private Utf16ValueStringBuilder sb; - private bool isOpen; - private UnicodeEncoding encoding; - - /// - /// Creates a new instance using as format provider. - /// - public ZStringWriter() : this(CultureInfo.CurrentCulture) - { - } - - /// - /// Creates a new instance with given format provider. - /// - public ZStringWriter(IFormatProvider formatProvider) : base(formatProvider) - { - sb = ZString.CreateStringBuilder(); - isOpen = true; - } - - /// - /// Disposes this instance, operations are no longer allowed. - /// - public override void Close() - { - Dispose(true); - } - - protected override void Dispose(bool disposing) - { - sb.Dispose(); - isOpen = false; - base.Dispose(disposing); - } - - public override Encoding Encoding => encoding = encoding ?? new UnicodeEncoding(false, false); - - public override void Write(char value) - { - AssertNotDisposed(); - - sb.Append(value); - } - - public override void Write(char[] buffer, int index, int count) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - if (index < 0) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - if (buffer.Length - index < count) - { - throw new ArgumentException(); - } - AssertNotDisposed(); - - sb.Append(buffer.AsSpan(index, count)); - } - - public override void Write(string value) - { - AssertNotDisposed(); - - if (value != null) - { - sb.Append(value); - } - } - - public override Task WriteAsync(char value) - { - Write(value); - return Task.CompletedTask; - } - - public override Task WriteAsync(string value) - { - Write(value); - return Task.CompletedTask; - } - - public override Task WriteAsync(char[] buffer, int index, int count) - { - Write(buffer, index, count); - return Task.CompletedTask; - } - - public override Task WriteLineAsync(char value) - { - WriteLine(value); - return Task.CompletedTask; - } - - public override Task WriteLineAsync(string value) - { - WriteLine(value); - return Task.CompletedTask; - } - - public override Task WriteLineAsync(char[] buffer, int index, int count) - { - WriteLine(buffer, index, count); - return Task.CompletedTask; - } - - public override void Write(bool value) - { - AssertNotDisposed(); - sb.Append(value); - } - - public override void Write(decimal value) - { - AssertNotDisposed(); - sb.Append(value); - } - - /// - /// No-op. - /// - public override Task FlushAsync() - { - return Task.CompletedTask; - } - - /// - /// Materializes the current state from underlying string builder. - /// - public override string ToString() - { - return sb.ToString(); - } - -#if !NETSTANDARD2_0 -#if !UNITY_2018_3_OR_NEWER - - public override void Write(ReadOnlySpan buffer) - { - AssertNotDisposed(); - - sb.Append(buffer); - } - - public override void WriteLine(ReadOnlySpan buffer) - { - AssertNotDisposed(); - - sb.Append(buffer); - WriteLine(); - } - - public override Task WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - - Write(buffer.Span); - return Task.CompletedTask; - } - - public override Task WriteLineAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - - WriteLine(buffer.Span); - return Task.CompletedTask; - } -#endif -#endif - - private void AssertNotDisposed() - { - if (!isOpen) - { - throw new ObjectDisposedException(nameof(sb)); - } - } - } -} diff --git a/Plugins/ZString/ZStringWriter.cs.meta b/Plugins/ZString/ZStringWriter.cs.meta deleted file mode 100644 index 947e4fbd..00000000 --- a/Plugins/ZString/ZStringWriter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eb2ec9ac9521172449dbeac815854188 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From e8ba4fa64e1f7d1fc5105406e9c4ab1683a05c2c Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:19:42 +0700 Subject: [PATCH 02/58] feat: delete codes for Unity (Editor) --- Editor/LiteNetLibManagerEditor.asmdef | 16 ------ Editor/LiteNetLibManagerEditor.asmdef.meta | 7 --- Editor/ReadOnlyDrawer.cs | 21 -------- Editor/ReadOnlyDrawer.cs.meta | 13 ----- Editor/SceneFieldPropertyDrawer.cs | 60 ---------------------- Editor/SceneFieldPropertyDrawer.cs.meta | 13 ----- 6 files changed, 130 deletions(-) delete mode 100644 Editor/LiteNetLibManagerEditor.asmdef delete mode 100644 Editor/LiteNetLibManagerEditor.asmdef.meta delete mode 100644 Editor/ReadOnlyDrawer.cs delete mode 100644 Editor/ReadOnlyDrawer.cs.meta delete mode 100644 Editor/SceneFieldPropertyDrawer.cs delete mode 100644 Editor/SceneFieldPropertyDrawer.cs.meta diff --git a/Editor/LiteNetLibManagerEditor.asmdef b/Editor/LiteNetLibManagerEditor.asmdef deleted file mode 100644 index 73f3b2eb..00000000 --- a/Editor/LiteNetLibManagerEditor.asmdef +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "LiteNetLibManagerEditor", - "references": [ - "LiteNetLibManager" - ], - "optionalUnityReferences": [], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [] -} \ No newline at end of file diff --git a/Editor/LiteNetLibManagerEditor.asmdef.meta b/Editor/LiteNetLibManagerEditor.asmdef.meta deleted file mode 100644 index 9d63c78a..00000000 --- a/Editor/LiteNetLibManagerEditor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 8cb4ad36c844a104ca703a5950bbf5f1 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/ReadOnlyDrawer.cs b/Editor/ReadOnlyDrawer.cs deleted file mode 100644 index 773651f2..00000000 --- a/Editor/ReadOnlyDrawer.cs +++ /dev/null @@ -1,21 +0,0 @@ -using UnityEditor; -using UnityEngine; - -namespace LiteNetLibManager -{ - [CustomPropertyDrawer(typeof(ReadOnlyAttribute))] - public class ReadOnlyDrawer : PropertyDrawer - { - public override float GetPropertyHeight(SerializedProperty property, GUIContent label) - { - return EditorGUI.GetPropertyHeight(property, label, true); - } - - public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) - { - GUI.enabled = false; - EditorGUI.PropertyField(position, property, label, true); - GUI.enabled = true; - } - } -} diff --git a/Editor/ReadOnlyDrawer.cs.meta b/Editor/ReadOnlyDrawer.cs.meta deleted file mode 100644 index e491d1a7..00000000 --- a/Editor/ReadOnlyDrawer.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 32e976f08206cac40ba1f110caca18ec -timeCreated: 1508756854 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/SceneFieldPropertyDrawer.cs b/Editor/SceneFieldPropertyDrawer.cs deleted file mode 100644 index 85af6610..00000000 --- a/Editor/SceneFieldPropertyDrawer.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.IO; -using UnityEditor; -using UnityEngine; - -namespace LiteNetLibManager -{ - [CustomPropertyDrawer(typeof(SceneField))] - public class SceneFieldPropertyDrawer : PropertyDrawer - { - public override void OnGUI(Rect _position, SerializedProperty _property, GUIContent _label) - { - EditorGUI.BeginProperty(_position, GUIContent.none, _property); - SerializedProperty sceneAsset = _property.FindPropertyRelative("sceneAsset"); - SerializedProperty sceneName = _property.FindPropertyRelative("sceneName"); - _position = EditorGUI.PrefixLabel(_position, GUIUtility.GetControlID(FocusType.Passive), _label); - if (sceneAsset != null) - { - EditorGUI.BeginChangeCheck(); - - Object value = EditorGUI.ObjectField(_position, sceneAsset.objectReferenceValue, typeof(SceneAsset), false); - if (EditorGUI.EndChangeCheck()) - { - sceneAsset.objectReferenceValue = value; - if (sceneAsset.objectReferenceValue != null) - { - var _sceneName = (sceneAsset.objectReferenceValue as SceneAsset).name; - sceneName.stringValue = _sceneName; - var sceneObj = GetSceneObject(_sceneName); - if (sceneObj == null) - { - // Just warning, do not change value to null - Debug.LogWarning("The scene [" + _sceneName + "] cannot be used. To use this scene add it to the build settings for the project"); - } - } - else - sceneName.stringValue = null; - } - } - EditorGUI.EndProperty(); - } - - protected SceneAsset GetSceneObject(string sceneObjectName) - { - if (string.IsNullOrEmpty(sceneObjectName)) - { - return null; - } - - foreach (var editorScene in EditorBuildSettings.scenes) - { - var sceneNameWithoutExtension = Path.GetFileNameWithoutExtension(editorScene.path); - if (sceneNameWithoutExtension == sceneObjectName) - { - return AssetDatabase.LoadAssetAtPath(editorScene.path, typeof(SceneAsset)) as SceneAsset; - } - } - return null; - } - } -} diff --git a/Editor/SceneFieldPropertyDrawer.cs.meta b/Editor/SceneFieldPropertyDrawer.cs.meta deleted file mode 100644 index a303a99f..00000000 --- a/Editor/SceneFieldPropertyDrawer.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: b4ae4a5349aff3646b55ddd075e4d688 -timeCreated: 1525034239 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 9b958b97855057804b814d335c2edc18a8e573df Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:19:56 +0700 Subject: [PATCH 03/58] feat: delete codes for Unity (Attributes) --- Scripts/PropertyAttributes/ReadOnlyAttribute.cs | 6 ------ Scripts/PropertyAttributes/ReadOnlyAttribute.cs.meta | 11 ----------- 2 files changed, 17 deletions(-) delete mode 100644 Scripts/PropertyAttributes/ReadOnlyAttribute.cs delete mode 100644 Scripts/PropertyAttributes/ReadOnlyAttribute.cs.meta diff --git a/Scripts/PropertyAttributes/ReadOnlyAttribute.cs b/Scripts/PropertyAttributes/ReadOnlyAttribute.cs deleted file mode 100644 index b70491be..00000000 --- a/Scripts/PropertyAttributes/ReadOnlyAttribute.cs +++ /dev/null @@ -1,6 +0,0 @@ -using UnityEngine; - -namespace LiteNetLibManager -{ - public class ReadOnlyAttribute : PropertyAttribute { } -} diff --git a/Scripts/PropertyAttributes/ReadOnlyAttribute.cs.meta b/Scripts/PropertyAttributes/ReadOnlyAttribute.cs.meta deleted file mode 100644 index f134a3a5..00000000 --- a/Scripts/PropertyAttributes/ReadOnlyAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 942ee07808513a34f96ae46a107563be -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 02bb81e8438a4c388eb7f95736a8a1d7ffba8935 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:20:23 +0700 Subject: [PATCH 04/58] feat: delete codes for Unity (Transports) --- Scripts/Transports/MixTransport.meta | 8 - .../Transports/MixTransport/MixTransport.cs | 342 ------------------ .../MixTransport/MixTransport.cs.meta | 11 - .../MixTransport/MixTransportEventListener.cs | 105 ------ .../MixTransportEventListener.cs.meta | 11 - .../MixTransport/MixTransportFactory.cs | 34 -- .../MixTransport/MixTransportFactory.cs.meta | 11 - Scripts/Transports/WebSocket.meta | 8 - .../WebSocket/WebSocketTransport.cs | 234 ------------ .../WebSocket/WebSocketTransport.cs.meta | 11 - .../WebSocket/WebSocketTransportFactory.cs | 23 -- .../WebSocketTransportFactory.cs.meta | 11 - .../Transports/WebSocket/WsClientWrapper.cs | 227 ------------ .../WebSocket/WsClientWrapper.cs.meta | 11 - .../Transports/WebSocket/WsTransportClient.cs | 78 ---- .../WebSocket/WsTransportClient.cs.meta | 11 - .../Transports/WebSocket/WsTransportServer.cs | 52 --- .../WebSocket/WsTransportServer.cs.meta | 11 - .../WebSocket/WsTransportSession.cs | 76 ---- .../WebSocket/WsTransportSession.cs.meta | 11 - .../WebSocket/WssTransportClient.cs | 78 ---- .../WebSocket/WssTransportClient.cs.meta | 11 - .../WebSocket/WssTransportServer.cs | 52 --- .../WebSocket/WssTransportServer.cs.meta | 11 - .../WebSocket/WssTransportSession.cs | 76 ---- .../WebSocket/WssTransportSession.cs.meta | 11 - 26 files changed, 1525 deletions(-) delete mode 100644 Scripts/Transports/MixTransport.meta delete mode 100644 Scripts/Transports/MixTransport/MixTransport.cs delete mode 100644 Scripts/Transports/MixTransport/MixTransport.cs.meta delete mode 100644 Scripts/Transports/MixTransport/MixTransportEventListener.cs delete mode 100644 Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta delete mode 100644 Scripts/Transports/MixTransport/MixTransportFactory.cs delete mode 100644 Scripts/Transports/MixTransport/MixTransportFactory.cs.meta delete mode 100644 Scripts/Transports/WebSocket.meta delete mode 100644 Scripts/Transports/WebSocket/WebSocketTransport.cs delete mode 100644 Scripts/Transports/WebSocket/WebSocketTransport.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WebSocketTransportFactory.cs delete mode 100644 Scripts/Transports/WebSocket/WebSocketTransportFactory.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WsClientWrapper.cs delete mode 100644 Scripts/Transports/WebSocket/WsClientWrapper.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WsTransportClient.cs delete mode 100644 Scripts/Transports/WebSocket/WsTransportClient.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WsTransportServer.cs delete mode 100644 Scripts/Transports/WebSocket/WsTransportServer.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WsTransportSession.cs delete mode 100644 Scripts/Transports/WebSocket/WsTransportSession.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WssTransportClient.cs delete mode 100644 Scripts/Transports/WebSocket/WssTransportClient.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WssTransportServer.cs delete mode 100644 Scripts/Transports/WebSocket/WssTransportServer.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WssTransportSession.cs delete mode 100644 Scripts/Transports/WebSocket/WssTransportSession.cs.meta diff --git a/Scripts/Transports/MixTransport.meta b/Scripts/Transports/MixTransport.meta deleted file mode 100644 index 754a0b89..00000000 --- a/Scripts/Transports/MixTransport.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f6c248b4fca205743a0a14cb8bb4692e -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/MixTransport/MixTransport.cs b/Scripts/Transports/MixTransport/MixTransport.cs deleted file mode 100644 index a0861c33..00000000 --- a/Scripts/Transports/MixTransport/MixTransport.cs +++ /dev/null @@ -1,342 +0,0 @@ -using System.Collections.Generic; -using LiteNetLib; -using LiteNetLib.Utils; -using System.Collections.Concurrent; -using System.Net; -using System.Net.Security; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; -using System.Threading; -#if !UNITY_WEBGL || UNITY_EDITOR -using NetCoreServer; -#endif - -namespace LiteNetLibManager -{ - public sealed class MixTransport : ITransport, ITransportConnectionGenerator - { - private long _nextConnectionId = 1; - private bool _webSocketSecure; - private string _webSocketCertificateFilePath; - private string _webSocketCertificatePassword; - - // WebSocket data -#if UNITY_WEBGL - private WsClientWrapper _wsClient; -#endif -#if !UNITY_WEBGL || UNITY_EDITOR - private WsTransportServer _wsServer; - private WssTransportServer _wssServer; -#endif - - // LiteNetLib data - public NetManager Client { get; private set; } - public NetManager Server { get; private set; } - public string ConnectKey { get; private set; } - public int ServerPeersCount - { - get - { - int result = 0; - if (Server != null) - result += Server.ConnectedPeersCount; -#if !UNITY_WEBGL - if (!_webSocketSecure) - { - if (_wsServer != null) - result += _wsServer.PeersCount; - } - else - { - if (_wssServer != null) - result += _wssServer.PeersCount; - } -#endif - return result; - } - } - public int ServerMaxConnections { get; private set; } - public bool IsClientStarted - { - get - { -#if UNITY_WEBGL - return _wsClient.IsClientStarted; -#else - return Client != null && Client.FirstPeer != null && Client.FirstPeer.ConnectionState == ConnectionState.Connected; -#endif - } - } - public bool IsServerStarted - { - get - { -#if UNITY_WEBGL - // Don't integrate server networking to WebGL clients - return false; -#else - if (Server == null) - return false; - if (!_webSocketSecure) - return _wsServer != null && _wsServer.IsStarted; - else - return _wssServer != null && _wssServer.IsStarted; -#endif - } - } - - public bool HasImplementedPing - { - get - { -#if UNITY_WEBGL - return false; -#else - return true; -#endif - } - } - - private readonly Dictionary _serverPeers = new Dictionary(); - private readonly ConcurrentQueue _clientEventQueue = new ConcurrentQueue(); - private readonly ConcurrentQueue _serverEventQueue = new ConcurrentQueue(); - private readonly byte _clientDataChannelsCount; - private readonly byte _serverDataChannelsCount; - private readonly int _webSocketPortOffset; - - public MixTransport(string connectKey, int webSocketPortOffset, bool webSocketSecure, string webSocketCertificateFilePath, string webSocketCertificatePassword, byte clientDataChannelsCount, byte serverDataChannelsCount) - { - ConnectKey = connectKey; - _clientDataChannelsCount = clientDataChannelsCount; - _serverDataChannelsCount = serverDataChannelsCount; - _webSocketPortOffset = webSocketPortOffset; - _webSocketSecure = webSocketSecure; - _webSocketCertificateFilePath = webSocketCertificateFilePath; - _webSocketCertificatePassword = webSocketCertificatePassword; -#if UNITY_WEBGL - _wsClient = new WsClientWrapper(_clientEventQueue, webSocketSecure, SslProtocols.Tls12); -#endif - } - - public bool StartClient(string address, int port) - { - while (_clientEventQueue.TryDequeue(out _)) { } -#if UNITY_WEBGL - return _wsClient.StartClient(address, port); -#else - Client = new NetManager(new MixTransportEventListener(this, _clientEventQueue)); - Client.ChannelsCount = _clientDataChannelsCount; - return Client.Start() && Client.Connect(address, port, ConnectKey) != null; -#endif - } - - public void StopClient() - { -#if UNITY_WEBGL - _wsClient.StopClient(); -#else - if (Client != null) - Client.Stop(); - Client = null; -#endif - } - - public bool ClientReceive(out TransportEventData eventData) - { - eventData = default(TransportEventData); -#if UNITY_WEBGL - return _wsClient.ClientReceive(out eventData); -#else - if (Client == null) - return false; - Client.PollEvents(); - if (_clientEventQueue.Count == 0) - return false; - return _clientEventQueue.TryDequeue(out eventData); -#endif - } - - public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { -#if UNITY_WEBGL - return _wsClient.ClientSend(dataChannel, deliveryMethod, writer); -#else - if (IsClientStarted) - { - Client.FirstPeer.Send(writer, dataChannel, deliveryMethod); - return true; - } - return false; -#endif - } - - public bool StartServer(int port, int maxConnections) - { -#if UNITY_WEBGL - // Don't integrate server networking to WebGL clients - return false; -#else - if (IsServerStarted) - return false; - - ServerMaxConnections = maxConnections; - while (_serverEventQueue.TryDequeue(out _)) { } - - // Start WebSocket Server - if (!_webSocketSecure) - { - _wsServer = new WsTransportServer(this, IPAddress.Any, port + _webSocketPortOffset, maxConnections); - _wsServer.OptionDualMode = true; - _wsServer.OptionNoDelay = true; - if (!_wsServer.Start()) - return false; - } - else - { - SslContext context = new SslContext(SslProtocols.Tls12, new X509Certificate2(_webSocketCertificateFilePath, _webSocketCertificatePassword), CertValidationCallback); - _wssServer = new WssTransportServer(this, context, IPAddress.Any, port + _webSocketPortOffset, maxConnections); - _wssServer.OptionDualMode = true; - _wssServer.OptionNoDelay = true; - if (!_wssServer.Start()) - return false; - } - - // Start LiteNetLib Server - _serverPeers.Clear(); - Server = new NetManager(new MixTransportEventListener(this, _serverEventQueue, _serverPeers)); - Server.ChannelsCount = _serverDataChannelsCount; - return Server.Start(port); -#endif - } - - private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - return sslPolicyErrors == SslPolicyErrors.None; - } - - public bool ServerReceive(out TransportEventData eventData) - { - eventData = default(TransportEventData); -#if UNITY_WEBGL - // Don't integrate server networking to WebGL clients - return false; -#else - if (!IsServerStarted) - return false; - - if (!_webSocketSecure) - { - if (_wsServer.EventQueue.Count > 0) - return _wsServer.EventQueue.TryDequeue(out eventData); - } - else - { - if (_wssServer.EventQueue.Count > 0) - return _wssServer.EventQueue.TryDequeue(out eventData); - } - - Server.PollEvents(); - if (_serverEventQueue.Count > 0) - return _serverEventQueue.TryDequeue(out eventData); - - return false; -#endif - } - - public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { -#if !UNITY_WEBGL - // WebSocket Server Send - if (!_webSocketSecure) - { - if (_wsServer != null && _wsServer.SendAsync(connectionId, writer.Data)) - return true; - } - else - { - if (_wssServer != null && _wssServer.SendAsync(connectionId, writer.Data)) - return true; - } - - // LiteNetLib Server Send - if (IsServerStarted && _serverPeers.ContainsKey(connectionId) && _serverPeers[connectionId].ConnectionState == ConnectionState.Connected) - { - _serverPeers[connectionId].Send(writer, dataChannel, deliveryMethod); - return true; - } -#endif - return false; - } - - public bool ServerDisconnect(long connectionId) - { -#if !UNITY_WEBGL - // WebSocket Server Disconnect - if (!_webSocketSecure) - { - if (_wsServer != null && _wsServer.Disconnect(connectionId)) - return true; - } - else - { - if (_wssServer != null && _wssServer.Disconnect(connectionId)) - return true; - } - - // LiteNetLib Server Disconnect - if (IsServerStarted && _serverPeers.ContainsKey(connectionId)) - { - Server.DisconnectPeer(_serverPeers[connectionId]); - _serverPeers.Remove(connectionId); - return true; - } -#endif - return false; - } - - public void StopServer() - { -#if !UNITY_WEBGL - if (_wsServer != null) - _wsServer.Dispose(); - if (_wssServer != null) - _wssServer.Dispose(); - _wsServer = null; - _wssServer = null; - if (Server != null) - Server.Stop(); - Server = null; - _nextConnectionId = 1; -#endif - } - - public void Destroy() - { - StopClient(); - StopServer(); - } - - public long GetNewConnectionID() - { - return Interlocked.Increment(ref _nextConnectionId); - } - - public long GetClientRtt() - { -#if UNITY_WEBGL - return 0; -#else - return Client.FirstPeer.RoundTripTime; -#endif - } - - public long GetServerRtt(long connectionId) - { -#if UNITY_WEBGL - return 0; -#else - return _serverPeers[connectionId].RoundTripTime; -#endif - } - } -} diff --git a/Scripts/Transports/MixTransport/MixTransport.cs.meta b/Scripts/Transports/MixTransport/MixTransport.cs.meta deleted file mode 100644 index c2476fc4..00000000 --- a/Scripts/Transports/MixTransport/MixTransport.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 56e230e8b15094340bbaada6eb24a5bb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/MixTransport/MixTransportEventListener.cs b/Scripts/Transports/MixTransport/MixTransportEventListener.cs deleted file mode 100644 index e7308541..00000000 --- a/Scripts/Transports/MixTransport/MixTransportEventListener.cs +++ /dev/null @@ -1,105 +0,0 @@ -using LiteNetLib; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; - -namespace LiteNetLibManager -{ - public class MixTransportEventListener : INetEventListener - { - private MixTransport mixTransport; - private ConcurrentQueue eventQueue; - private Dictionary peersDict; - private Dictionary peerIdsDict; - - public MixTransportEventListener(MixTransport mixTransport, ConcurrentQueue eventQueue) - { - // This is constructor for client - this.mixTransport = mixTransport; - this.eventQueue = eventQueue; - } - - public MixTransportEventListener(MixTransport mixTransport, ConcurrentQueue eventQueue, Dictionary peersDict) : this(mixTransport, eventQueue) - { - // This is constructor for server - this.peersDict = peersDict; - peerIdsDict = new Dictionary(); - } - - public void OnConnectionRequest(ConnectionRequest request) - { - if (mixTransport.Server.ConnectedPeersCount < mixTransport.ServerMaxConnections) - request.AcceptIfKey(mixTransport.ConnectKey); - else - request.Reject(); - } - - public void OnNetworkError(IPEndPoint endPoint, SocketError socketError) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - endPoint = endPoint, - socketError = socketError, - }); - } - - public void OnNetworkLatencyUpdate(NetPeer peer, int latency) - { - } - - public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) - { - long tempConnectionId = 0; - if (peerIdsDict != null && peersDict != null) - tempConnectionId = peerIdsDict[peer.Id]; - - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DataEvent, - connectionId = tempConnectionId, - reader = reader, - }); - } - - public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) - { - } - - public void OnPeerConnected(NetPeer peer) - { - long tempConnectionId = 0; - if (peerIdsDict != null && peersDict != null) - { - tempConnectionId = mixTransport.GetNewConnectionID(); - peersDict[tempConnectionId] = peer; - peerIdsDict[peer.Id] = tempConnectionId; - } - - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ConnectEvent, - connectionId = tempConnectionId, - }); - } - - public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) - { - long tempConnectionId = 0; - if (peerIdsDict != null && peersDict != null) - { - tempConnectionId = peerIdsDict[peer.Id]; - peersDict.Remove(tempConnectionId); - peerIdsDict.Remove(peer.Id); - } - - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DisconnectEvent, - connectionId = tempConnectionId, - disconnectInfo = disconnectInfo, - }); - } - } -} diff --git a/Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta b/Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta deleted file mode 100644 index 5346cdfa..00000000 --- a/Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eab9350e2510f084599682f02cc2cd08 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/MixTransport/MixTransportFactory.cs b/Scripts/Transports/MixTransport/MixTransportFactory.cs deleted file mode 100644 index 24556288..00000000 --- a/Scripts/Transports/MixTransport/MixTransportFactory.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Security.Authentication; -using UnityEngine; - -namespace LiteNetLibManager -{ - public class MixTransportFactory : BaseTransportFactory, IWebSocketTransportFactory - { - [SerializeField] - private string connectKey = "SampleConnectKey"; - [SerializeField] - private int webSocketPortOffset = 100; - [SerializeField] - private bool webSocketSecure = false; - [SerializeField] - private string webSocketCertificateFilePath = string.Empty; - [SerializeField] - private string webSocketCertificatePassword = string.Empty; - [Range(1, 64)] - [SerializeField] - private byte clientDataChannelsCount = 16; - [Range(1, 64)] - [SerializeField] - private byte serverDataChannelsCount = 16; - public bool Secure { get { return webSocketSecure; } set { webSocketSecure = value; } } - public string CertificateFilePath { get { return webSocketCertificateFilePath; } set { webSocketCertificateFilePath = value; } } - public string CertificatePassword { get { return webSocketCertificatePassword; } set { webSocketCertificatePassword = value; } } - - - public override ITransport Build() - { - return new MixTransport(connectKey, webSocketPortOffset, webSocketSecure, webSocketCertificateFilePath, webSocketCertificatePassword, clientDataChannelsCount, serverDataChannelsCount); - } - } -} diff --git a/Scripts/Transports/MixTransport/MixTransportFactory.cs.meta b/Scripts/Transports/MixTransport/MixTransportFactory.cs.meta deleted file mode 100644 index 9e41db6f..00000000 --- a/Scripts/Transports/MixTransport/MixTransportFactory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1edd61c62fd42fc4ea55540e9ba136b5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket.meta b/Scripts/Transports/WebSocket.meta deleted file mode 100644 index 548ee264..00000000 --- a/Scripts/Transports/WebSocket.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8eadfb8d08f063342b86d0fb9024a345 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WebSocketTransport.cs b/Scripts/Transports/WebSocket/WebSocketTransport.cs deleted file mode 100644 index cadf2468..00000000 --- a/Scripts/Transports/WebSocket/WebSocketTransport.cs +++ /dev/null @@ -1,234 +0,0 @@ -using LiteNetLib; -using LiteNetLib.Utils; -using System.Collections.Concurrent; -using System.Net; -using System.Net.Security; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; -using System.Threading; -#if !UNITY_WEBGL || UNITY_EDITOR -using NetCoreServer; -#endif - -namespace LiteNetLibManager -{ - public class WebSocketTransport : ITransport, ITransportConnectionGenerator - { - private long _nextConnectionId = 1; - private bool _secure; - private string _certificateFilePath; - private string _certificatePassword; - private readonly ConcurrentQueue _clientEventQueue; - private WsClientWrapper _wsClient; -#if !UNITY_WEBGL || UNITY_EDITOR - private WsTransportServer _wsServer; - private WssTransportServer _wssServer; -#endif - - public bool IsClientStarted - { - get { return _wsClient.IsClientStarted; } - } - - public bool IsServerStarted - { - get - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - return _wsServer != null && _wsServer.IsStarted; - else - return _wssServer != null && _wssServer.IsStarted; -#else - return false; -#endif - } - } - - public int ServerPeersCount - { - get - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - { - if (_wsServer != null) - return _wsServer.PeersCount; - } - else - { - if (_wssServer != null) - return _wssServer.PeersCount; - } -#endif - return 0; - } - } - - public int ServerMaxConnections - { - get - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - { - if (_wsServer != null) - return _wsServer.MaxConnections; - } - else - { - if (_wssServer != null) - return _wssServer.MaxConnections; - } -#endif - return 0; - } - } - - public bool HasImplementedPing - { - get { return false; } - } - - public WebSocketTransport(bool secure, string certificateFilePath, string certificatePassword) - { - _secure = secure; - _certificateFilePath = certificateFilePath; - _certificatePassword = certificatePassword; - _clientEventQueue = new ConcurrentQueue(); - _wsClient = new WsClientWrapper(_clientEventQueue, secure, SslProtocols.Tls12); - } - - public bool StartClient(string address, int port) - { - while (_clientEventQueue.TryDequeue(out _)) { } - return _wsClient.StartClient(address, port); - } - - public void StopClient() - { - _wsClient.StopClient(); - } - - public bool ClientReceive(out TransportEventData eventData) - { - return _wsClient.ClientReceive(out eventData); - } - - public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - return _wsClient.ClientSend(dataChannel, deliveryMethod, writer); - } - - public bool StartServer(int port, int maxConnections) - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (IsServerStarted) - return false; - if (!_secure) - { - _wsServer = new WsTransportServer(this, IPAddress.Any, port, maxConnections); - _wsServer.OptionDualMode = true; - _wsServer.OptionNoDelay = true; - return _wsServer.Start(); - } - else - { - SslContext context = new SslContext(SslProtocols.Tls12, new X509Certificate2(_certificateFilePath, _certificatePassword), CertValidationCallback); - _wssServer = new WssTransportServer(this, context, IPAddress.Any, port, maxConnections); - _wssServer.OptionDualMode = true; - _wssServer.OptionNoDelay = true; - return _wssServer.Start(); - } -#else - return false; -#endif - } - - private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - return true; - } - - public bool ServerReceive(out TransportEventData eventData) - { - eventData = default(TransportEventData); -#if !UNITY_WEBGL || UNITY_EDITOR - if (!IsServerStarted) - return false; - if (!_secure) - { - if (_wsServer.EventQueue.Count == 0) - return false; - return _wsServer.EventQueue.TryDequeue(out eventData); - } - else - { - if (_wssServer.EventQueue.Count == 0) - return false; - return _wssServer.EventQueue.TryDequeue(out eventData); - } -#else - return false; -#endif - } - - public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - return _wsServer != null && _wsServer.SendAsync(connectionId, writer.Data); - else - return _wssServer != null && _wssServer.SendAsync(connectionId, writer.Data); -#else - return false; -#endif - } - - public bool ServerDisconnect(long connectionId) - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - return _wsServer != null && _wsServer.Disconnect(connectionId); - else - return _wssServer != null && _wssServer.Disconnect(connectionId); -#else - return false; -#endif - } - - public void StopServer() - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (_wsServer != null) - _wsServer.Dispose(); - if (_wssServer != null) - _wssServer.Dispose(); - _wsServer = null; - _wssServer = null; - _nextConnectionId = 1; -#endif - } - - public void Destroy() - { - StopClient(); - StopServer(); - } - - public long GetNewConnectionID() - { - return Interlocked.Increment(ref _nextConnectionId); - } - - public long GetClientRtt() - { - throw new System.NotImplementedException(); - } - - public long GetServerRtt(long connectionId) - { - throw new System.NotImplementedException(); - } - } -} diff --git a/Scripts/Transports/WebSocket/WebSocketTransport.cs.meta b/Scripts/Transports/WebSocket/WebSocketTransport.cs.meta deleted file mode 100644 index 03df1eb0..00000000 --- a/Scripts/Transports/WebSocket/WebSocketTransport.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3f09e5c02836e9f41921a402bfaadf1a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs deleted file mode 100644 index 4eee84d7..00000000 --- a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Security.Authentication; -using UnityEngine; - -namespace LiteNetLibManager -{ - public class WebSocketTransportFactory : BaseTransportFactory, IWebSocketTransportFactory - { - [SerializeField] - private bool secure = false; - [SerializeField] - private string certificateFilePath = string.Empty; - [SerializeField] - private string certificatePassword = string.Empty; - public bool Secure { get { return secure; } set { secure = value; } } - public string CertificateFilePath { get { return certificateFilePath; } set { certificateFilePath = value; } } - public string CertificatePassword { get { return certificatePassword; } set { certificatePassword = value; } } - - public override ITransport Build() - { - return new WebSocketTransport(secure, certificateFilePath, certificatePassword); - } - } -} diff --git a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs.meta b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs.meta deleted file mode 100644 index 26621c1a..00000000 --- a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 910acc198833e5443b3409d90e6afb4e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsClientWrapper.cs b/Scripts/Transports/WebSocket/WsClientWrapper.cs deleted file mode 100644 index cbe8fed0..00000000 --- a/Scripts/Transports/WebSocket/WsClientWrapper.cs +++ /dev/null @@ -1,227 +0,0 @@ -using LiteNetLib; -using System.Net.Security; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; -using System.Collections.Concurrent; -using LiteNetLib.Utils; -using System.Net; -using System.Net.Sockets; -using System; -using System.Runtime.InteropServices; -using System.Text; -#if !UNITY_WEBGL || UNITY_EDITOR -using NetCoreServer; -#endif - -namespace LiteNetLibManager -{ - public class WsClientWrapper - { -#if UNITY_WEBGL && !UNITY_EDITOR - [DllImport("__Internal")] - private static extern int SocketCreate_LnlM(string url); - [DllImport("__Internal")] - private static extern int GetSocketState_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern int GetSocketEventType_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern int GetSocketErrorCode_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern int GetSocketDataLength_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern void GetSocketData_LnlM(int wsNativeInstance, byte[] ptr, int length); - [DllImport("__Internal")] - private static extern void SocketEventDequeue_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern void SocketSend_LnlM(int wsNativeInstance, byte[] ptr, int length); - [DllImport("__Internal")] - private static extern void SocketClose_LnlM(int wsNativeInstance); - - private int wsNativeInstance = -1; - private byte[] tempBuffers; - private bool dirtyIsConnected = false; -#endif - -#if !UNITY_WEBGL || UNITY_EDITOR - private WsTransportClient wsClient; - private WssTransportClient wssClient; -#endif - private readonly ConcurrentQueue clientEventQueue; - private readonly bool secure; - private readonly SslProtocols sslProtocols; - - public bool IsClientStarted - { - get - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (secure) - return wssClient != null && wssClient.IsConnected; - else - return wsClient != null && wsClient.IsConnected; -#else - return GetSocketState_LnlM(wsNativeInstance) == 1; -#endif - } - } - - public WsClientWrapper(ConcurrentQueue clientEventQueue, bool secure, SslProtocols sslProtocols) - { - this.clientEventQueue = clientEventQueue; - this.secure = secure; - this.sslProtocols = sslProtocols; - } - - public bool StartClient(string address, int port) - { - if (IsClientStarted) - { - Logging.Log(nameof(WsClientWrapper), "Client started, so it can't be started again"); - return false; - } -#if !UNITY_WEBGL || UNITY_EDITOR - IPAddress[] ipAddresses = Dns.GetHostAddresses(address); - if (ipAddresses.Length == 0) - { - Logging.Log(nameof(WsClientWrapper), "Cannot find IP addresses from " + address); - return false; - } - - int indexOfAddress = -1; - for (int i = 0; i < ipAddresses.Length; ++i) - { - if (ipAddresses[i].AddressFamily == AddressFamily.InterNetwork) - { - indexOfAddress = i; - break; - } - } - - if (indexOfAddress < 0) - { - Logging.Log(nameof(WsClientWrapper), "Cannot find index of address from " + address); - return false; - } - - string url = (secure ? "wss://" : "ws://") + ipAddresses[indexOfAddress] + ":" + port; - Logging.Log(nameof(WsClientWrapper), $"Connecting to {url}"); - if (secure) - { - SslContext context = new SslContext(sslProtocols, new X509Certificate2(), CertValidationCallback); - wssClient = new WssTransportClient(clientEventQueue, context, ipAddresses[indexOfAddress], port); - wssClient.OptionDualMode = true; - wssClient.OptionNoDelay = true; - return wssClient.ConnectAsync(); - } - else - { - wsClient = new WsTransportClient(clientEventQueue, ipAddresses[indexOfAddress], port); - wsClient.OptionDualMode = true; - wsClient.OptionNoDelay = true; - return wsClient.ConnectAsync(); - } -#else - string url = (secure ? "wss://" : "ws://") + address + ":" + port; - Logging.Log(nameof(WsClientWrapper), $"Connecting to {url}"); - wsNativeInstance = SocketCreate_LnlM(url.ToString()); - return true; -#endif - } - - public void StopClient() - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (wssClient != null) - wssClient.Dispose(); - wssClient = null; - if (wsClient != null) - wsClient.Dispose(); - wsClient = null; -#else - SocketClose_LnlM(wsNativeInstance); -#endif - } - - private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - return true; - } - - public bool ClientReceive(out TransportEventData eventData) - { - eventData = default(TransportEventData); -#if !UNITY_WEBGL || UNITY_EDITOR - if (clientEventQueue.Count == 0) - return false; - return clientEventQueue.TryDequeue(out eventData); -#else - int eventType = GetSocketEventType_LnlM(wsNativeInstance); - if (eventType < 0) - return false; - switch ((ENetworkEvent)eventType) - { - case ENetworkEvent.DataEvent: - eventData.type = ENetworkEvent.DataEvent; - eventData.reader = new NetDataReader(GetSocketData()); - break; - case ENetworkEvent.ConnectEvent: - eventData.type = ENetworkEvent.ConnectEvent; - break; - case ENetworkEvent.DisconnectEvent: - eventData.type = ENetworkEvent.DisconnectEvent; - eventData.disconnectInfo = GetDisconnectInfo(GetSocketErrorCode_LnlM(wsNativeInstance)); - break; - case ENetworkEvent.ErrorEvent: - eventData.type = ENetworkEvent.ErrorEvent; - eventData.errorMessage = GetErrorMessage(GetSocketErrorCode_LnlM(wsNativeInstance)); - break; - } - SocketEventDequeue_LnlM(wsNativeInstance); - return true; -#endif - } - -#if UNITY_WEBGL && !UNITY_EDITOR - private byte[] GetSocketData() - { - int length = GetSocketDataLength_LnlM(wsNativeInstance); - if (length == 0) - return null; - byte[] buffer = new byte[length]; - GetSocketData_LnlM(wsNativeInstance, buffer, length); - return buffer; - } -#endif - -#if UNITY_WEBGL && !UNITY_EDITOR - public string GetErrorMessage(int errorCode) - { - // TODO: Implement this - return string.Empty; - } -#endif - -#if UNITY_WEBGL && !UNITY_EDITOR - public DisconnectInfo GetDisconnectInfo(int errorCode) - { - // TODO: Implement this - return default; - } -#endif - - public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsClientStarted) - return false; -#if !UNITY_WEBGL || UNITY_EDITOR - if (secure) - return wssClient.SendBinaryAsync(writer.Data, 0, writer.Data.Length); - else - return wsClient.SendBinaryAsync(writer.Data, 0, writer.Data.Length); -#else - SocketSend_LnlM(wsNativeInstance, writer.Data, writer.Data.Length); - return true; -#endif - } - } -} diff --git a/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta b/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta deleted file mode 100644 index c3a2e414..00000000 --- a/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9e3299f36c6c27e47935f2cf0616dfde -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsTransportClient.cs b/Scripts/Transports/WebSocket/WsTransportClient.cs deleted file mode 100644 index 9513d289..00000000 --- a/Scripts/Transports/WebSocket/WsTransportClient.cs +++ /dev/null @@ -1,78 +0,0 @@ -using LiteNetLib.Utils; -using NetCoreServer; -using System; -using System.Collections.Concurrent; -using System.Net; -using System.Net.Sockets; - -namespace LiteNetLibManager -{ - public class WsTransportClient : WsClient - { - private readonly ConcurrentQueue eventQueue; - - public WsTransportClient(ConcurrentQueue eventQueue, IPAddress address, int port) : base(address, port) - { - this.eventQueue = eventQueue; - } - - public override void OnWsConnecting(HttpRequest request) - { - Uri uri = new Uri($"wss://{Endpoint.Address}:{Endpoint.Port}"); - request.SetBegin("GET", uri.PathAndQuery); - request.SetHeader("Host", Endpoint.Port == 80 ? uri.DnsSafeHost : uri.Authority); - request.SetHeader("Upgrade", "websocket"); - request.SetHeader("Connection", "Upgrade"); - request.SetHeader("Sec-WebSocket-Key", Convert.ToBase64String(WsNonce)); - request.SetHeader("Sec-WebSocket-Version", "13"); - request.Cache.Append("\r\n"); - } - - public override void OnWsConnected(HttpResponse response) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ConnectEvent, - }); - } - - protected override void OnDisconnected() - { - base.OnDisconnected(); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DisconnectEvent, - }); - } - - public override void OnWsError(string error) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - errorMessage = error, - }); - } - - protected override void OnError(SocketError error) - { - base.OnError(error); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - socketError = error, - }); - } - - public override void OnWsReceived(byte[] buffer, long offset, long size) - { - byte[] coppiedBuffer = new byte[size]; - Array.Copy(buffer, offset, coppiedBuffer, 0, size); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(coppiedBuffer), - }); - } - } -} diff --git a/Scripts/Transports/WebSocket/WsTransportClient.cs.meta b/Scripts/Transports/WebSocket/WsTransportClient.cs.meta deleted file mode 100644 index f9adf82a..00000000 --- a/Scripts/Transports/WebSocket/WsTransportClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ced6efcdfe0e93142ac54704ee49777c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsTransportServer.cs b/Scripts/Transports/WebSocket/WsTransportServer.cs deleted file mode 100644 index 26544374..00000000 --- a/Scripts/Transports/WebSocket/WsTransportServer.cs +++ /dev/null @@ -1,52 +0,0 @@ -using NetCoreServer; -using System.Collections.Concurrent; -using System.Net; - -namespace LiteNetLibManager -{ - public class WsTransportServer : WsServer - { - public ConcurrentDictionary AcceptedClients { get; private set; } - public ConcurrentQueue EventQueue { get; private set; } - public int PeersCount { get { return AcceptedClients.Count; } } - public int MaxConnections { get; private set; } - - private ITransportConnectionGenerator connectionGenerator; - - public WsTransportServer(ITransportConnectionGenerator connectionGenerator, IPAddress address, int port, int maxConnections) : base(address, port) - { - this.connectionGenerator = connectionGenerator; - AcceptedClients = new ConcurrentDictionary(); - EventQueue = new ConcurrentQueue(); - MaxConnections = maxConnections; - } - - protected override TcpSession CreateSession() - { - WsTransportSession newSession = new WsTransportSession(connectionGenerator.GetNewConnectionID(), this); - if (PeersCount >= MaxConnections) - { - newSession.Disconnect(); - return null; - } - AcceptedClients.TryAdd(newSession.ConnectionId, newSession); - return newSession; - } - - internal bool SendAsync(long connectionId, byte[] buffer) - { - return AcceptedClients.ContainsKey(connectionId) && AcceptedClients[connectionId].SendBinaryAsync(buffer, 0, buffer.Length); - } - - internal bool Disconnect(long connectionId) - { - WsTransportSession session; - if (AcceptedClients.TryRemove(connectionId, out session)) - { - session.Dispose(); - return true; - } - return false; - } - } -} diff --git a/Scripts/Transports/WebSocket/WsTransportServer.cs.meta b/Scripts/Transports/WebSocket/WsTransportServer.cs.meta deleted file mode 100644 index 56bf51f1..00000000 --- a/Scripts/Transports/WebSocket/WsTransportServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d125cf39ccfa55e429fe21497e2f7cb9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsTransportSession.cs b/Scripts/Transports/WebSocket/WsTransportSession.cs deleted file mode 100644 index 7be9f3a1..00000000 --- a/Scripts/Transports/WebSocket/WsTransportSession.cs +++ /dev/null @@ -1,76 +0,0 @@ -using LiteNetLib.Utils; -using NetCoreServer; -using System; -using System.Net.Sockets; - -namespace LiteNetLibManager -{ - public class WsTransportSession : WsSession - { - public long ConnectionId { get; private set; } - - private readonly WsTransportServer _server; - - public WsTransportSession(long connectionId, WsTransportServer server) : base(server) - { - ConnectionId = connectionId; - _server = server; - } - - public override void OnWsConnected(HttpRequest request) - { - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ConnectEvent, - }); - } - - protected override void OnDisconnected() - { - base.OnDisconnected(); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.DisconnectEvent, - disconnectInfo = new LiteNetLib.DisconnectInfo() - { - Reason = LiteNetLib.DisconnectReason.RemoteConnectionClose, - }, - }); - } - - public override void OnWsError(string error) - { - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ErrorEvent, - errorMessage = error, - }); - } - - protected override void OnError(SocketError error) - { - base.OnError(error); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ErrorEvent, - socketError = error, - }); - } - - public override void OnWsReceived(byte[] buffer, long offset, long size) - { - byte[] coppiedBuffer = new byte[size]; - Array.Copy(buffer, offset, coppiedBuffer, 0, size); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(coppiedBuffer), - }); - } - } -} diff --git a/Scripts/Transports/WebSocket/WsTransportSession.cs.meta b/Scripts/Transports/WebSocket/WsTransportSession.cs.meta deleted file mode 100644 index 1577484e..00000000 --- a/Scripts/Transports/WebSocket/WsTransportSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 28d95ae7bbc891b48b174d9bb18d7297 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportClient.cs b/Scripts/Transports/WebSocket/WssTransportClient.cs deleted file mode 100644 index 9de033a3..00000000 --- a/Scripts/Transports/WebSocket/WssTransportClient.cs +++ /dev/null @@ -1,78 +0,0 @@ -using LiteNetLib.Utils; -using NetCoreServer; -using System; -using System.Collections.Concurrent; -using System.Net; -using System.Net.Sockets; - -namespace LiteNetLibManager -{ - public class WssTransportClient : WssClient - { - private readonly ConcurrentQueue eventQueue; - - public WssTransportClient(ConcurrentQueue eventQueue, SslContext context, IPAddress address, int port) : base(context, address, port) - { - this.eventQueue = eventQueue; - } - - public override void OnWsConnecting(HttpRequest request) - { - Uri uri = new Uri($"wss://{Endpoint.Address}:{Endpoint.Port}"); - request.SetBegin("GET", uri.PathAndQuery); - request.SetHeader("Host", Endpoint.Port == 443 ? uri.DnsSafeHost : uri.Authority); - request.SetHeader("Upgrade", "websocket"); - request.SetHeader("Connection", "Upgrade"); - request.SetHeader("Sec-WebSocket-Key", Convert.ToBase64String(WsNonce)); - request.SetHeader("Sec-WebSocket-Version", "13"); - request.Cache.Append("\r\n"); - } - - public override void OnWsConnected(HttpResponse response) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ConnectEvent, - }); - } - - protected override void OnDisconnected() - { - base.OnDisconnected(); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DisconnectEvent, - }); - } - - public override void OnWsError(string error) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - errorMessage = error, - }); - } - - protected override void OnError(SocketError error) - { - base.OnError(error); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - socketError = error, - }); - } - - public override void OnWsReceived(byte[] buffer, long offset, long size) - { - byte[] coppiedBuffer = new byte[size]; - Array.Copy(buffer, offset, coppiedBuffer, 0, size); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(coppiedBuffer), - }); - } - } -} diff --git a/Scripts/Transports/WebSocket/WssTransportClient.cs.meta b/Scripts/Transports/WebSocket/WssTransportClient.cs.meta deleted file mode 100644 index cc6432f7..00000000 --- a/Scripts/Transports/WebSocket/WssTransportClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 411ce407868cabf48b577e10208c7de6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportServer.cs b/Scripts/Transports/WebSocket/WssTransportServer.cs deleted file mode 100644 index 7d103cbc..00000000 --- a/Scripts/Transports/WebSocket/WssTransportServer.cs +++ /dev/null @@ -1,52 +0,0 @@ -using NetCoreServer; -using System.Collections.Concurrent; -using System.Net; - -namespace LiteNetLibManager -{ - public class WssTransportServer : WssServer - { - public ConcurrentDictionary AcceptedClients { get; private set; } - public ConcurrentQueue EventQueue { get; private set; } - public int PeersCount { get { return AcceptedClients.Count; } } - public int MaxConnections { get; private set; } - - private ITransportConnectionGenerator connectionGenerator; - - public WssTransportServer(ITransportConnectionGenerator connectionGenerator, SslContext context, IPAddress address, int port, int maxConnections) : base(context, address, port) - { - this.connectionGenerator = connectionGenerator; - AcceptedClients = new ConcurrentDictionary(); - EventQueue = new ConcurrentQueue(); - MaxConnections = maxConnections; - } - - protected override SslSession CreateSession() - { - WssTransportSession newSession = new WssTransportSession(connectionGenerator.GetNewConnectionID(), this); - if (PeersCount >= MaxConnections) - { - newSession.Disconnect(); - return null; - } - AcceptedClients.TryAdd(newSession.ConnectionId, newSession); - return newSession; - } - - internal bool SendAsync(long connectionId, byte[] buffer) - { - return AcceptedClients.ContainsKey(connectionId) && AcceptedClients[connectionId].SendBinaryAsync(buffer, 0, buffer.Length); - } - - internal bool Disconnect(long connectionId) - { - WssTransportSession session; - if (AcceptedClients.TryRemove(connectionId, out session)) - { - session.Dispose(); - return true; - } - return false; - } - } -} diff --git a/Scripts/Transports/WebSocket/WssTransportServer.cs.meta b/Scripts/Transports/WebSocket/WssTransportServer.cs.meta deleted file mode 100644 index bd3ef160..00000000 --- a/Scripts/Transports/WebSocket/WssTransportServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 84aec65ce7a649e4b8f3cc4fb192f821 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportSession.cs b/Scripts/Transports/WebSocket/WssTransportSession.cs deleted file mode 100644 index adab7f4e..00000000 --- a/Scripts/Transports/WebSocket/WssTransportSession.cs +++ /dev/null @@ -1,76 +0,0 @@ -using LiteNetLib.Utils; -using NetCoreServer; -using System; -using System.Net.Sockets; - -namespace LiteNetLibManager -{ - public class WssTransportSession : WssSession - { - public long ConnectionId { get; private set; } - - private readonly WssTransportServer _server; - - public WssTransportSession(long connectionId, WssTransportServer server) : base(server) - { - ConnectionId = connectionId; - _server = server; - } - - public override void OnWsConnected(HttpRequest request) - { - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ConnectEvent, - }); - } - - protected override void OnDisconnected() - { - base.OnDisconnected(); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.DisconnectEvent, - disconnectInfo = new LiteNetLib.DisconnectInfo() - { - Reason = LiteNetLib.DisconnectReason.RemoteConnectionClose, - }, - }); - } - - public override void OnWsError(string error) - { - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ErrorEvent, - errorMessage = error, - }); - } - - protected override void OnError(SocketError error) - { - base.OnError(error); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ErrorEvent, - socketError = error, - }); - } - - public override void OnWsReceived(byte[] buffer, long offset, long size) - { - byte[] coppiedBuffer = new byte[size]; - Array.Copy(buffer, offset, coppiedBuffer, 0, size); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(coppiedBuffer), - }); - } - } -} diff --git a/Scripts/Transports/WebSocket/WssTransportSession.cs.meta b/Scripts/Transports/WebSocket/WssTransportSession.cs.meta deleted file mode 100644 index cc6a5263..00000000 --- a/Scripts/Transports/WebSocket/WssTransportSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 102c4270c7677314898bb6da06d9f7a3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From e964fdde578af97a0555ed4cce30184a9608566b Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:22:05 +0700 Subject: [PATCH 05/58] feat: delete codes for Unity (PackedVariables) --- Scripts/PackedVariables/DirectionVector2.cs | 31 ----------------- .../PackedVariables/DirectionVector2.cs.meta | 11 ------- Scripts/PackedVariables/DirectionVector3.cs | 33 ------------------- .../PackedVariables/DirectionVector3.cs.meta | 11 ------- 4 files changed, 86 deletions(-) delete mode 100644 Scripts/PackedVariables/DirectionVector2.cs delete mode 100644 Scripts/PackedVariables/DirectionVector2.cs.meta delete mode 100644 Scripts/PackedVariables/DirectionVector3.cs delete mode 100644 Scripts/PackedVariables/DirectionVector3.cs.meta diff --git a/Scripts/PackedVariables/DirectionVector2.cs b/Scripts/PackedVariables/DirectionVector2.cs deleted file mode 100644 index 502f3e4a..00000000 --- a/Scripts/PackedVariables/DirectionVector2.cs +++ /dev/null @@ -1,31 +0,0 @@ -using UnityEngine; -using LiteNetLib.Utils; - -public struct DirectionVector2 : INetSerializable -{ - public static implicit operator DirectionVector2(Vector2 value) { return new DirectionVector2(value); } - public static implicit operator DirectionVector2(Vector3 value) { return new DirectionVector2(value); } - public static implicit operator Vector2(DirectionVector2 value) { return new Vector2((float)value.x / 100f, (float)value.y / 100f); } - public static implicit operator Vector3(DirectionVector2 value) { return new Vector2((float)value.x / 100f, (float)value.y / 100f); } - - public sbyte x; - public sbyte y; - - public DirectionVector2(Vector2 vector2) - { - x = (sbyte)(vector2.x * 100); - y = (sbyte)(vector2.y * 100); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(x); - writer.Put(y); - } - - public void Deserialize(NetDataReader reader) - { - x = reader.GetSByte(); - y = reader.GetSByte(); - } -} diff --git a/Scripts/PackedVariables/DirectionVector2.cs.meta b/Scripts/PackedVariables/DirectionVector2.cs.meta deleted file mode 100644 index 65cf13fe..00000000 --- a/Scripts/PackedVariables/DirectionVector2.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 614856a984a532b41af2b7d04e5daac7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/PackedVariables/DirectionVector3.cs b/Scripts/PackedVariables/DirectionVector3.cs deleted file mode 100644 index 1c481bf5..00000000 --- a/Scripts/PackedVariables/DirectionVector3.cs +++ /dev/null @@ -1,33 +0,0 @@ -using UnityEngine; -using LiteNetLib.Utils; - -public struct DirectionVector3 : INetSerializable -{ - public static implicit operator DirectionVector3(Vector3 value) { return new DirectionVector3(value); } - public static implicit operator Vector3(DirectionVector3 value) { return new Vector3((float)value.x / 100f, (float)value.y / 100f, (float)value.z / 100f); } - - public sbyte x; - public sbyte y; - public sbyte z; - - public DirectionVector3(Vector3 vector3) - { - x = (sbyte)(vector3.x * 100); - y = (sbyte)(vector3.y * 100); - z = (sbyte)(vector3.z * 100); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(x); - writer.Put(y); - writer.Put(z); - } - - public void Deserialize(NetDataReader reader) - { - x = reader.GetSByte(); - y = reader.GetSByte(); - z = reader.GetSByte(); - } -} diff --git a/Scripts/PackedVariables/DirectionVector3.cs.meta b/Scripts/PackedVariables/DirectionVector3.cs.meta deleted file mode 100644 index 69f23628..00000000 --- a/Scripts/PackedVariables/DirectionVector3.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 708f62165f063f04caf500f67a4a3311 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 3ac55ce3edff8e544da6ce01293b25f76bd50b1e Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:22:23 +0700 Subject: [PATCH 06/58] feat: delete codes for Unity (GameApi) --- Scripts/GameApi/Attributes.meta | 8 - Scripts/GameApi/Attributes/AllRpcAttribute.cs | 9 - .../Attributes/AllRpcAttribute.cs.meta | 11 - .../GameApi/Attributes/ElasticRpcAttribute.cs | 9 - .../Attributes/ElasticRpcAttribute.cs.meta | 11 - .../Attributes/NetFunctionAttribute.cs | 9 - .../Attributes/NetFunctionAttribute.cs.meta | 11 - Scripts/GameApi/Attributes/RpcAttribute.cs | 13 - .../GameApi/Attributes/RpcAttribute.cs.meta | 11 - .../GameApi/Attributes/ServerRpcAttribute.cs | 9 - .../Attributes/ServerRpcAttribute.cs.meta | 11 - .../GameApi/Attributes/SyncFieldAttribute.cs | 46 - .../Attributes/SyncFieldAttribute.cs.meta | 11 - .../GameApi/Attributes/TargetRpcAttribute.cs | 9 - .../Attributes/TargetRpcAttribute.cs.meta | 11 - Scripts/GameApi/BaseInterestManager.cs | 74 - Scripts/GameApi/BaseInterestManager.cs.meta | 11 - .../GameApi/BaseLiteNetLibVisibleChecker.cs | 11 - .../BaseLiteNetLibVisibleChecker.cs.meta | 11 - Scripts/GameApi/DefaultInterestManager.cs | 47 - .../GameApi/DefaultInterestManager.cs.meta | 11 - Scripts/GameApi/DestroyObjectReasons.cs | 9 - Scripts/GameApi/DestroyObjectReasons.cs.meta | 11 - Scripts/GameApi/Events.meta | 10 - .../GameApi/Events/LiteNetLibIdentityEvent.cs | 9 - .../Events/LiteNetLibIdentityEvent.cs.meta | 11 - .../Events/LiteNetLibLoadSceneEvent.cs | 9 - .../Events/LiteNetLibLoadSceneEvent.cs.meta | 13 - Scripts/GameApi/GameMsgTypes.cs | 24 - Scripts/GameApi/GameMsgTypes.cs.meta | 11 - Scripts/GameApi/GameReqTypes.cs | 9 - Scripts/GameApi/GameReqTypes.cs.meta | 11 - Scripts/GameApi/LiteNetLibAssets.cs | 515 ----- Scripts/GameApi/LiteNetLibAssets.cs.meta | 13 - Scripts/GameApi/LiteNetLibBehaviour.cs | 1755 ----------------- Scripts/GameApi/LiteNetLibBehaviour.cs.meta | 13 - Scripts/GameApi/LiteNetLibElement.cs | 105 - Scripts/GameApi/LiteNetLibElement.cs.meta | 13 - Scripts/GameApi/LiteNetLibFunction.cs | 471 ----- Scripts/GameApi/LiteNetLibFunction.cs.meta | 13 - Scripts/GameApi/LiteNetLibGameManager.cs | 1049 ---------- Scripts/GameApi/LiteNetLibGameManager.cs.meta | 13 - Scripts/GameApi/LiteNetLibIdentity.cs | 843 -------- Scripts/GameApi/LiteNetLibIdentity.cs.meta | 13 - Scripts/GameApi/LiteNetLibPlayer.cs | 122 -- Scripts/GameApi/LiteNetLibPlayer.cs.meta | 13 - Scripts/GameApi/LiteNetLibSpawnPoint.cs | 43 - Scripts/GameApi/LiteNetLibSpawnPoint.cs.meta | 13 - Scripts/GameApi/LiteNetLibSyncField.cs | 693 ------- Scripts/GameApi/LiteNetLibSyncField.cs.meta | 13 - Scripts/GameApi/LiteNetLibSyncList.cs | 609 ------ Scripts/GameApi/LiteNetLibSyncList.cs.meta | 13 - Scripts/GameApi/LiteNetLibTransform.cs | 521 ----- Scripts/GameApi/LiteNetLibTransform.cs.meta | 13 - Scripts/GameApi/LiteNetLibVisibleChecker.cs | 7 - .../GameApi/LiteNetLibVisibleChecker.cs.meta | 13 - .../Messages/EnterGameRequestMessage.cs | 19 - .../Messages/EnterGameRequestMessage.cs.meta | 11 - .../Messages/EnterGameResponseMessage.cs | 22 - .../Messages/EnterGameResponseMessage.cs.meta | 11 - .../GameApi/Messages/GenericValueMessage.cs | 188 -- .../Messages/GenericValueMessage.cs.meta | 11 - Scripts/GameApi/Messages/PingMessage.cs | 19 - Scripts/GameApi/Messages/PingMessage.cs.meta | 11 - Scripts/GameApi/Messages/PongMessage.cs | 22 - Scripts/GameApi/Messages/PongMessage.cs.meta | 11 - .../Messages/ServerDestroyObjectMessage.cs | 22 - .../ServerDestroyObjectMessage.cs.meta | 13 - .../GameApi/Messages/ServerErrorMessage.cs | 22 - .../Messages/ServerErrorMessage.cs.meta | 13 - .../Messages/ServerSceneChangeMessage.cs | 19 - .../Messages/ServerSceneChangeMessage.cs.meta | 13 - .../GameApi/Messages/ServerSetObjectOwner.cs | 22 - .../Messages/ServerSetObjectOwner.cs.meta | 11 - .../Messages/ServerSpawnObjectMessage.cs | 36 - .../Messages/ServerSpawnObjectMessage.cs.meta | 13 - .../Messages/ServerSpawnSceneObjectMessage.cs | 33 - .../ServerSpawnSceneObjectMessage.cs.meta | 13 - 78 files changed, 7925 deletions(-) delete mode 100644 Scripts/GameApi/Attributes.meta delete mode 100644 Scripts/GameApi/Attributes/AllRpcAttribute.cs delete mode 100644 Scripts/GameApi/Attributes/AllRpcAttribute.cs.meta delete mode 100644 Scripts/GameApi/Attributes/ElasticRpcAttribute.cs delete mode 100644 Scripts/GameApi/Attributes/ElasticRpcAttribute.cs.meta delete mode 100644 Scripts/GameApi/Attributes/NetFunctionAttribute.cs delete mode 100644 Scripts/GameApi/Attributes/NetFunctionAttribute.cs.meta delete mode 100644 Scripts/GameApi/Attributes/RpcAttribute.cs delete mode 100644 Scripts/GameApi/Attributes/RpcAttribute.cs.meta delete mode 100644 Scripts/GameApi/Attributes/ServerRpcAttribute.cs delete mode 100644 Scripts/GameApi/Attributes/ServerRpcAttribute.cs.meta delete mode 100644 Scripts/GameApi/Attributes/SyncFieldAttribute.cs delete mode 100644 Scripts/GameApi/Attributes/SyncFieldAttribute.cs.meta delete mode 100644 Scripts/GameApi/Attributes/TargetRpcAttribute.cs delete mode 100644 Scripts/GameApi/Attributes/TargetRpcAttribute.cs.meta delete mode 100644 Scripts/GameApi/BaseInterestManager.cs delete mode 100644 Scripts/GameApi/BaseInterestManager.cs.meta delete mode 100644 Scripts/GameApi/BaseLiteNetLibVisibleChecker.cs delete mode 100644 Scripts/GameApi/BaseLiteNetLibVisibleChecker.cs.meta delete mode 100644 Scripts/GameApi/DefaultInterestManager.cs delete mode 100644 Scripts/GameApi/DefaultInterestManager.cs.meta delete mode 100644 Scripts/GameApi/DestroyObjectReasons.cs delete mode 100644 Scripts/GameApi/DestroyObjectReasons.cs.meta delete mode 100644 Scripts/GameApi/Events.meta delete mode 100644 Scripts/GameApi/Events/LiteNetLibIdentityEvent.cs delete mode 100644 Scripts/GameApi/Events/LiteNetLibIdentityEvent.cs.meta delete mode 100644 Scripts/GameApi/Events/LiteNetLibLoadSceneEvent.cs delete mode 100644 Scripts/GameApi/Events/LiteNetLibLoadSceneEvent.cs.meta delete mode 100644 Scripts/GameApi/GameMsgTypes.cs delete mode 100644 Scripts/GameApi/GameMsgTypes.cs.meta delete mode 100644 Scripts/GameApi/GameReqTypes.cs delete mode 100644 Scripts/GameApi/GameReqTypes.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibAssets.cs delete mode 100644 Scripts/GameApi/LiteNetLibAssets.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibBehaviour.cs delete mode 100644 Scripts/GameApi/LiteNetLibBehaviour.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibElement.cs delete mode 100644 Scripts/GameApi/LiteNetLibElement.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibFunction.cs delete mode 100644 Scripts/GameApi/LiteNetLibFunction.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibGameManager.cs delete mode 100644 Scripts/GameApi/LiteNetLibGameManager.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibIdentity.cs delete mode 100644 Scripts/GameApi/LiteNetLibIdentity.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibPlayer.cs delete mode 100644 Scripts/GameApi/LiteNetLibPlayer.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibSpawnPoint.cs delete mode 100644 Scripts/GameApi/LiteNetLibSpawnPoint.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibSyncField.cs delete mode 100644 Scripts/GameApi/LiteNetLibSyncField.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibSyncList.cs delete mode 100644 Scripts/GameApi/LiteNetLibSyncList.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibTransform.cs delete mode 100644 Scripts/GameApi/LiteNetLibTransform.cs.meta delete mode 100644 Scripts/GameApi/LiteNetLibVisibleChecker.cs delete mode 100644 Scripts/GameApi/LiteNetLibVisibleChecker.cs.meta delete mode 100644 Scripts/GameApi/Messages/EnterGameRequestMessage.cs delete mode 100644 Scripts/GameApi/Messages/EnterGameRequestMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/EnterGameResponseMessage.cs delete mode 100644 Scripts/GameApi/Messages/EnterGameResponseMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/GenericValueMessage.cs delete mode 100644 Scripts/GameApi/Messages/GenericValueMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/PingMessage.cs delete mode 100644 Scripts/GameApi/Messages/PingMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/PongMessage.cs delete mode 100644 Scripts/GameApi/Messages/PongMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/ServerDestroyObjectMessage.cs delete mode 100644 Scripts/GameApi/Messages/ServerDestroyObjectMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/ServerErrorMessage.cs delete mode 100644 Scripts/GameApi/Messages/ServerErrorMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/ServerSceneChangeMessage.cs delete mode 100644 Scripts/GameApi/Messages/ServerSceneChangeMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/ServerSetObjectOwner.cs delete mode 100644 Scripts/GameApi/Messages/ServerSetObjectOwner.cs.meta delete mode 100644 Scripts/GameApi/Messages/ServerSpawnObjectMessage.cs delete mode 100644 Scripts/GameApi/Messages/ServerSpawnObjectMessage.cs.meta delete mode 100644 Scripts/GameApi/Messages/ServerSpawnSceneObjectMessage.cs delete mode 100644 Scripts/GameApi/Messages/ServerSpawnSceneObjectMessage.cs.meta diff --git a/Scripts/GameApi/Attributes.meta b/Scripts/GameApi/Attributes.meta deleted file mode 100644 index c359d2c1..00000000 --- a/Scripts/GameApi/Attributes.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2e2c381232fb17f4ba5116c6644d357b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Attributes/AllRpcAttribute.cs b/Scripts/GameApi/Attributes/AllRpcAttribute.cs deleted file mode 100644 index f9ca9338..00000000 --- a/Scripts/GameApi/Attributes/AllRpcAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class AllRpcAttribute : RpcAttribute - { - } -} diff --git a/Scripts/GameApi/Attributes/AllRpcAttribute.cs.meta b/Scripts/GameApi/Attributes/AllRpcAttribute.cs.meta deleted file mode 100644 index eb5113b7..00000000 --- a/Scripts/GameApi/Attributes/AllRpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 24f4ce169ace902478a464b82f69e284 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Attributes/ElasticRpcAttribute.cs b/Scripts/GameApi/Attributes/ElasticRpcAttribute.cs deleted file mode 100644 index 6aa0b852..00000000 --- a/Scripts/GameApi/Attributes/ElasticRpcAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class ElasticRpcAttribute : RpcAttribute - { - } -} diff --git a/Scripts/GameApi/Attributes/ElasticRpcAttribute.cs.meta b/Scripts/GameApi/Attributes/ElasticRpcAttribute.cs.meta deleted file mode 100644 index 155d55e0..00000000 --- a/Scripts/GameApi/Attributes/ElasticRpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5654a2358c8bcb844ad984f229c15fed -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Attributes/NetFunctionAttribute.cs b/Scripts/GameApi/Attributes/NetFunctionAttribute.cs deleted file mode 100644 index 859fb9d3..00000000 --- a/Scripts/GameApi/Attributes/NetFunctionAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class NetFunctionAttribute : ElasticRpcAttribute - { - } -} diff --git a/Scripts/GameApi/Attributes/NetFunctionAttribute.cs.meta b/Scripts/GameApi/Attributes/NetFunctionAttribute.cs.meta deleted file mode 100644 index e5b721ab..00000000 --- a/Scripts/GameApi/Attributes/NetFunctionAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0fe7e812fc00d644f971c72e4195d10a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Attributes/RpcAttribute.cs b/Scripts/GameApi/Attributes/RpcAttribute.cs deleted file mode 100644 index 7d23263c..00000000 --- a/Scripts/GameApi/Attributes/RpcAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public abstract class RpcAttribute : Attribute - { - /// - /// If is true non-owner client can call the object's net function - /// - public bool canCallByEveryone = false; - } -} diff --git a/Scripts/GameApi/Attributes/RpcAttribute.cs.meta b/Scripts/GameApi/Attributes/RpcAttribute.cs.meta deleted file mode 100644 index 05e33df7..00000000 --- a/Scripts/GameApi/Attributes/RpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 922389d8923e4dc40a79bfb30ec4cb95 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Attributes/ServerRpcAttribute.cs b/Scripts/GameApi/Attributes/ServerRpcAttribute.cs deleted file mode 100644 index 6de847ac..00000000 --- a/Scripts/GameApi/Attributes/ServerRpcAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class ServerRpcAttribute : RpcAttribute - { - } -} diff --git a/Scripts/GameApi/Attributes/ServerRpcAttribute.cs.meta b/Scripts/GameApi/Attributes/ServerRpcAttribute.cs.meta deleted file mode 100644 index eeffefbe..00000000 --- a/Scripts/GameApi/Attributes/ServerRpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 36c1b5b0980dabf4dba82bc55fbc25c6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Attributes/SyncFieldAttribute.cs b/Scripts/GameApi/Attributes/SyncFieldAttribute.cs deleted file mode 100644 index 8ca37aea..00000000 --- a/Scripts/GameApi/Attributes/SyncFieldAttribute.cs +++ /dev/null @@ -1,46 +0,0 @@ -using LiteNetLib; -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)] - public class SyncFieldAttribute : Attribute - { - /// - /// Sending data channel from server to clients - /// - public byte dataChannel = 0; - /// - /// Sending method type from server to clients - /// - public DeliveryMethod deliveryMethod = DeliveryMethod.ReliableOrdered; - /// - /// Sending data channel from clients to server (while `syncMode` is `ClientMulticast` only) - /// - public byte clientDataChannel = 0; - /// - /// Sending method type from clients to server (while `syncMode` is `ClientMulticast` only) - /// - public DeliveryMethod clientDeliveryMethod = DeliveryMethod.ReliableOrdered; - /// - /// Interval to send network data - /// - public float sendInterval = 0.1f; - /// - /// How it will sync data. If always sync, it will sync data although it has no changes. If don't sync initial data immediately, it will not sync initial data immdediately with networked object spawning message, it will sync later after spanwed. If don't sync update, it will not sync when data has changes. - /// - public LiteNetLibSyncField.SyncBehaviour syncBehaviour = LiteNetLibSyncField.SyncBehaviour.Default; - /// - /// Who can sync data and sync to whom - /// - public LiteNetLibSyncField.SyncMode syncMode = LiteNetLibSyncField.SyncMode.ServerToClients; - /// - /// Method name which will be invoked when data changed - /// - public string onChangeMethodName = string.Empty; - /// - /// Method name which will be invoked when data sent - /// - public string onUpdateMethodName = string.Empty; - } -} diff --git a/Scripts/GameApi/Attributes/SyncFieldAttribute.cs.meta b/Scripts/GameApi/Attributes/SyncFieldAttribute.cs.meta deleted file mode 100644 index f3119616..00000000 --- a/Scripts/GameApi/Attributes/SyncFieldAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 87ccb352ef1e4234cba4a002c09dd7c0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Attributes/TargetRpcAttribute.cs b/Scripts/GameApi/Attributes/TargetRpcAttribute.cs deleted file mode 100644 index 19bf4b98..00000000 --- a/Scripts/GameApi/Attributes/TargetRpcAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class TargetRpcAttribute : RpcAttribute - { - } -} diff --git a/Scripts/GameApi/Attributes/TargetRpcAttribute.cs.meta b/Scripts/GameApi/Attributes/TargetRpcAttribute.cs.meta deleted file mode 100644 index 00616fb3..00000000 --- a/Scripts/GameApi/Attributes/TargetRpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1f4dc3f2443322941bd8c9593ac1836c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/BaseInterestManager.cs b/Scripts/GameApi/BaseInterestManager.cs deleted file mode 100644 index 286eed90..00000000 --- a/Scripts/GameApi/BaseInterestManager.cs +++ /dev/null @@ -1,74 +0,0 @@ -using UnityEngine; - -namespace LiteNetLibManager -{ - [DisallowMultipleComponent] - public abstract class BaseInterestManager : MonoBehaviour - { - [Tooltip("Default visible range will be used when Identity's visible range is <= 0f")] - public float defaultVisibleRange = 80f; - public LiteNetLibGameManager Manager { get; protected set; } - public bool IsServer { get { return Manager.IsServer; } } - - protected virtual void Awake() - { - Manager = GetComponent(); - } - - public void NotifyNewObject(LiteNetLibIdentity newObject) - { - if (!IsServer) - { - // Notifies by server only - return; - } - // Subscribe old objects, if it should - if (newObject.ConnectionId >= 0 && newObject.Player.IsReady) - { - foreach (LiteNetLibIdentity target in Manager.Assets.GetSpawnedObjects()) - { - // Subscribe, it may subscribe or may not, up to how subscribe function implemented - Subscribe(newObject, target); - } - } - // Notify to other players - foreach (LiteNetLibPlayer player in Manager.GetPlayers()) - { - if (!player.IsReady || player.ConnectionId == newObject.ConnectionId) - { - // Don't subscribe if player not ready or the object is owned by the player - continue; - } - foreach (LiteNetLibIdentity subscriber in player.GetSpawnedObjects()) - { - // Subscribe, it may subscribe or may not, up to how subscribe function implemented - Subscribe(subscriber, newObject); - } - } - } - - public float GetVisibleRange(LiteNetLibIdentity identity) - { - return identity.VisibleRange > 0f ? identity.VisibleRange : defaultVisibleRange; - } - - public virtual bool ShouldSubscribe(LiteNetLibIdentity subscriber, LiteNetLibIdentity target, bool checkRange = true) - { - if (subscriber == null || target == null || subscriber.ConnectionId < 0) - return false; - if (subscriber.ConnectionId == target.ConnectionId) - return true; - return !target.IsHideFrom(subscriber) && (!checkRange || target.AlwaysVisible || Vector3.Distance(subscriber.transform.position, target.transform.position) <= GetVisibleRange(target)); - } - - public virtual bool Subscribe(LiteNetLibIdentity subscriber, LiteNetLibIdentity target) - { - if (ShouldSubscribe(subscriber, target)) - { - subscriber.AddSubscribing(target.ObjectId); - return true; - } - return false; - } - } -} diff --git a/Scripts/GameApi/BaseInterestManager.cs.meta b/Scripts/GameApi/BaseInterestManager.cs.meta deleted file mode 100644 index 988825ce..00000000 --- a/Scripts/GameApi/BaseInterestManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 14432c40583017d4e8beb2be9b8ec43e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/BaseLiteNetLibVisibleChecker.cs b/Scripts/GameApi/BaseLiteNetLibVisibleChecker.cs deleted file mode 100644 index 0de0940c..00000000 --- a/Scripts/GameApi/BaseLiteNetLibVisibleChecker.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace LiteNetLibManager -{ - [DisallowMultipleComponent] - [System.Obsolete("This component is deprecated because interest management system is changed")] - public abstract class BaseLiteNetLibVisibleChecker : MonoBehaviour - { - } -} diff --git a/Scripts/GameApi/BaseLiteNetLibVisibleChecker.cs.meta b/Scripts/GameApi/BaseLiteNetLibVisibleChecker.cs.meta deleted file mode 100644 index 8c948435..00000000 --- a/Scripts/GameApi/BaseLiteNetLibVisibleChecker.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a7058a555827f9a478fea05cbc44cb0e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/DefaultInterestManager.cs b/Scripts/GameApi/DefaultInterestManager.cs deleted file mode 100644 index 100e2364..00000000 --- a/Scripts/GameApi/DefaultInterestManager.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace LiteNetLibManager -{ - public class DefaultInterestManager : BaseInterestManager - { - [Tooltip("Update every ? seconds")] - public float updateInterval = 1f; - - private float updateCountDown = 0f; - - private void Update() - { - if (!IsServer) - { - // Update at server only - return; - } - updateCountDown -= Time.unscaledDeltaTime; - if (updateCountDown <= 0f) - { - updateCountDown = updateInterval; - HashSet subscribings = new HashSet(); - foreach (LiteNetLibPlayer player in Manager.GetPlayers()) - { - if (!player.IsReady) - { - // Don't subscribe if player not ready - continue; - } - foreach (LiteNetLibIdentity playerObject in player.GetSpawnedObjects()) - { - // Update subscribing list, it will unsubscribe objects which is not in this list - subscribings.Clear(); - foreach (LiteNetLibIdentity spawnedObject in Manager.Assets.GetSpawnedObjects()) - { - if (ShouldSubscribe(playerObject, spawnedObject)) - subscribings.Add(spawnedObject.ObjectId); - } - playerObject.UpdateSubscribings(subscribings); - } - } - } - } - } -} diff --git a/Scripts/GameApi/DefaultInterestManager.cs.meta b/Scripts/GameApi/DefaultInterestManager.cs.meta deleted file mode 100644 index 72c83b7b..00000000 --- a/Scripts/GameApi/DefaultInterestManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a1ccd9ce8d0d28d4fb1d2e56e08bc6ef -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/DestroyObjectReasons.cs b/Scripts/GameApi/DestroyObjectReasons.cs deleted file mode 100644 index b036566f..00000000 --- a/Scripts/GameApi/DestroyObjectReasons.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace LiteNetLibManager -{ - public static partial class DestroyObjectReasons - { - public const byte RequestedToDestroy = 0; - public const byte RemovedFromSubscribing = 1; - public const byte Highest = 1; - } -} diff --git a/Scripts/GameApi/DestroyObjectReasons.cs.meta b/Scripts/GameApi/DestroyObjectReasons.cs.meta deleted file mode 100644 index a6a846ee..00000000 --- a/Scripts/GameApi/DestroyObjectReasons.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bf5e4e67b2edd55469fac12498be27a6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Events.meta b/Scripts/GameApi/Events.meta deleted file mode 100644 index 464631d8..00000000 --- a/Scripts/GameApi/Events.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 202557d6bd6392b4a8e26f3e1cbfbcdf -folderAsset: yes -timeCreated: 1525035216 -licenseType: Free -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Events/LiteNetLibIdentityEvent.cs b/Scripts/GameApi/Events/LiteNetLibIdentityEvent.cs deleted file mode 100644 index 452886c2..00000000 --- a/Scripts/GameApi/Events/LiteNetLibIdentityEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEngine.Events; - -namespace LiteNetLibManager -{ - [System.Serializable] - public class LiteNetLibIdentityEvent : UnityEvent - { - } -} diff --git a/Scripts/GameApi/Events/LiteNetLibIdentityEvent.cs.meta b/Scripts/GameApi/Events/LiteNetLibIdentityEvent.cs.meta deleted file mode 100644 index 5783ffb2..00000000 --- a/Scripts/GameApi/Events/LiteNetLibIdentityEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 74e03bd06ca73434590bb4486608c477 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Events/LiteNetLibLoadSceneEvent.cs b/Scripts/GameApi/Events/LiteNetLibLoadSceneEvent.cs deleted file mode 100644 index 05100d27..00000000 --- a/Scripts/GameApi/Events/LiteNetLibLoadSceneEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEngine.Events; - -namespace LiteNetLibManager -{ - [System.Serializable] - public class LiteNetLibLoadSceneEvent : UnityEvent - { - } -} diff --git a/Scripts/GameApi/Events/LiteNetLibLoadSceneEvent.cs.meta b/Scripts/GameApi/Events/LiteNetLibLoadSceneEvent.cs.meta deleted file mode 100644 index a573e4b7..00000000 --- a/Scripts/GameApi/Events/LiteNetLibLoadSceneEvent.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 9ad5883371559724ca569b77258ec07b -timeCreated: 1525035242 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/GameMsgTypes.cs b/Scripts/GameApi/GameMsgTypes.cs deleted file mode 100644 index 95c0f35c..00000000 --- a/Scripts/GameApi/GameMsgTypes.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace LiteNetLibManager -{ - public static partial class GameMsgTypes - { - public const ushort Request = 0; - public const ushort Response = 1; - public const ushort CallFunction = 3; - public const ushort ServerSpawnSceneObject = 4; - public const ushort ServerSpawnObject = 5; - public const ushort ServerDestroyObject = 6; - public const ushort UpdateSyncField = 7; - public const ushort InitialSyncField = 8; - public const ushort OperateSyncList = 9; - public const ushort ServerSyncBehaviour = 11; - public const ushort ServerError = 12; - public const ushort ServerSceneChange = 13; - public const ushort ClientSendTransform = 14; - public const ushort ServerSetObjectOwner = 15; - public const ushort Ping = 16; - public const ushort Pong = 17; - public const ushort Disconnect = 18; - public const ushort Highest = 18; - } -} diff --git a/Scripts/GameApi/GameMsgTypes.cs.meta b/Scripts/GameApi/GameMsgTypes.cs.meta deleted file mode 100644 index 3eac67e5..00000000 --- a/Scripts/GameApi/GameMsgTypes.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3a03ecc48c1a8a54eb4abe116d9bb35b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/GameReqTypes.cs b/Scripts/GameApi/GameReqTypes.cs deleted file mode 100644 index 4905f8f8..00000000 --- a/Scripts/GameApi/GameReqTypes.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace LiteNetLibManager -{ - public static partial class GameReqTypes - { - public const ushort EnterGame = 0; - public const ushort ClientReady = 1; - public const ushort ClientNotReady = 2; - } -} diff --git a/Scripts/GameApi/GameReqTypes.cs.meta b/Scripts/GameApi/GameReqTypes.cs.meta deleted file mode 100644 index 63f1c5bb..00000000 --- a/Scripts/GameApi/GameReqTypes.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b8a4fd8828789514c891003b9e990dbb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibAssets.cs b/Scripts/GameApi/LiteNetLibAssets.cs deleted file mode 100644 index b6c96a0a..00000000 --- a/Scripts/GameApi/LiteNetLibAssets.cs +++ /dev/null @@ -1,515 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Events; - -namespace LiteNetLibManager -{ - public class LiteNetLibAssets : MonoBehaviour - { - private static int spawnPositionCounter = 0; - public bool playerSpawnRandomly; - public LiteNetLibIdentity playerPrefab; - public LiteNetLibIdentity[] spawnablePrefabs; - public LiteNetLibIdentity PlayerPrefab { get; protected set; } - public SceneField offlineScene; - public SceneField onlineScene; - public UnityEvent onInitialize; - public LiteNetLibLoadSceneEvent onLoadSceneStart; - public LiteNetLibLoadSceneEvent onLoadSceneProgress; - public LiteNetLibLoadSceneEvent onLoadSceneFinish; - public LiteNetLibIdentityEvent onObjectSpawn; - public LiteNetLibIdentityEvent onObjectDestroy; - - internal readonly List CacheSpawnPoints = new List(); - internal readonly Dictionary GuidToPrefabs = new Dictionary(); - internal readonly Dictionary SceneObjects = new Dictionary(); - internal readonly Dictionary SpawnedObjects = new Dictionary(); - internal readonly Dictionary> PooledObjects = new Dictionary>(); - - public LiteNetLibGameManager Manager { get; private set; } - private string logTag; - public string LogTag - { - get - { - if (string.IsNullOrEmpty(logTag)) - logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; - return logTag; - } - } - - private void Awake() - { - Manager = GetComponent(); - } - - public void Initialize() - { - if (onInitialize != null) - onInitialize.Invoke(); - RegisterPrefabs(); - RegisterSpawnPoints(); - RegisterSceneObjects(); - } - - public void Clear(bool doNotResetObjectId = false) - { - ClearSpawnedObjects(); - ClearPooledObjects(); - CacheSpawnPoints.Clear(); - SceneObjects.Clear(); - ResetSpawnPositionCounter(); - if (!doNotResetObjectId) - LiteNetLibIdentity.ResetObjectId(); - } - - public void RegisterSpawnPoints() - { - CacheSpawnPoints.Clear(); - CacheSpawnPoints.AddRange(FindObjectsOfType()); - } - - public void RegisterPrefabs() - { - for (int i = 0; i < spawnablePrefabs.Length; ++i) - { - LiteNetLibIdentity registeringPrefab = spawnablePrefabs[i]; - RegisterPrefab(registeringPrefab); - } - if (playerPrefab != null) - { - PlayerPrefab = playerPrefab; - RegisterPrefab(playerPrefab); - } - } - - public void RegisterPrefab(LiteNetLibIdentity prefab) - { - if (prefab == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "RegisterPrefab - prefab is null."); - return; - } - if (Manager.LogDev) Logging.Log(LogTag, $"RegisterPrefab [{prefab.HashAssetId}] name [{prefab.name}]"); - GuidToPrefabs[prefab.HashAssetId] = prefab; - } - - public bool UnregisterPrefab(LiteNetLibIdentity prefab) - { - if (prefab == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "UnregisterPrefab - prefab is null."); - return false; - } - if (Manager.LogDev) Logging.Log(LogTag, $"UnregisterPrefab [{prefab.HashAssetId}] name [{prefab.name}]"); - return GuidToPrefabs.Remove(prefab.HashAssetId); - } - - public void ClearSpawnedObjects() - { - List objectIds = new List(SpawnedObjects.Keys); - for (int i = objectIds.Count - 1; i >= 0; --i) - { - uint objectId = objectIds[i]; - LiteNetLibIdentity spawnedObject; - if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) - { - // Destroy only non scene object - if (!SceneObjects.ContainsKey(objectId) && spawnedObject != null) - Destroy(spawnedObject.gameObject); - // Remove from asset spawned objects dictionary - SpawnedObjects.Remove(objectId); - } - } - SpawnedObjects.Clear(); - } - - public void ClearPooledObjects() - { - foreach (Queue queue in PooledObjects.Values) - { - while (queue.Count > 0) - { - LiteNetLibIdentity instance = queue.Dequeue(); - try - { - // I tried to avoid null exception but it still ocurring - if (instance != null) - Destroy(instance.gameObject); - } - catch { } - } - } - PooledObjects.Clear(); - } - - public void InitPoolingObjects() - { - foreach (int hashAssetId in GuidToPrefabs.Keys) - { - InitPoolingObject(hashAssetId); - } - } - - public void InitPoolingObject(int hashAssetId) - { - if (!GuidToPrefabs.ContainsKey(hashAssetId)) - { - Debug.LogWarning($"Cannot init prefab: {hashAssetId}, can't find the registered prefab."); - return; - } - - // Already init pool for the prefab - if (PooledObjects.ContainsKey(hashAssetId)) - return; - - LiteNetLibIdentity prefab = GuidToPrefabs[hashAssetId]; - // Don't create an instance for this prefab, if pooling size < 0 - if (prefab.PoolingSize <= 0) - return; - - Queue queue = new Queue(); - LiteNetLibIdentity tempInstance; - for (int i = 0; i < prefab.PoolingSize; ++i) - { - tempInstance = Instantiate(prefab); - tempInstance.IsPooledInstance = true; - tempInstance.gameObject.SetActive(false); - queue.Enqueue(tempInstance); - } - - PooledObjects[hashAssetId] = queue; - } - - public LiteNetLibIdentity GetObjectInstance(int hashAssetId) - { - return GetObjectInstance(hashAssetId, Vector3.zero, Quaternion.identity); - } - - public LiteNetLibIdentity GetObjectInstance(int hashAssetId, Vector3 position, Quaternion rotation) - { - if (PooledObjects.ContainsKey(hashAssetId) && PooledObjects[hashAssetId].Count > 0) - { - // Get pooled instance - LiteNetLibIdentity instance = PooledObjects[hashAssetId].Dequeue(); - instance.OnGetInstance(); - instance.transform.position = position; - instance.transform.rotation = rotation; - return instance; - } - - if (GuidToPrefabs.ContainsKey(hashAssetId)) - { - // Create a new instance - LiteNetLibIdentity instance = Instantiate(GuidToPrefabs[hashAssetId], position, rotation); - instance.gameObject.SetActive(false); - return instance; - } - - return null; - } - - public void PushInstanceBack(LiteNetLibIdentity instance) - { - if (instance == null) - { - Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance's is empty."); - return; - } - if (!instance.IsPooledInstance) - { - Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance is not pooled instance."); - return; - } - Queue queue; - if (!PooledObjects.TryGetValue(instance.HashAssetId, out queue)) - { - Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance's prefab does not initailized yet."); - return; - } - if (queue.Count >= instance.PoolingSize) - { - Destroy(instance.gameObject); - } - else - { - instance.gameObject.SetActive(false); - queue.Enqueue(instance); - } - } - - public void RegisterSceneObjects() - { - SceneObjects.Clear(); - LiteNetLibIdentity[] sceneObjects = FindObjectsOfType(); - for (int i = 0; i < sceneObjects.Length; ++i) - { - LiteNetLibIdentity sceneObject = sceneObjects[i]; - if (sceneObject.ObjectId > 0) - { - sceneObject.gameObject.SetActive(false); - SceneObjects[sceneObject.ObjectId] = sceneObject; - LiteNetLibIdentity.UpdateHighestObjectId(sceneObject.ObjectId); - } - } - } - - /// - /// This function will be called on start server and when network scene loaded to spawn scene objects - /// So each scene objects connection id will = -1 (No owning client) - /// - public void SpawnSceneObjects() - { - List sceneObjects = new List(SceneObjects.Values); - for (int i = 0; i < sceneObjects.Count; ++i) - { - LiteNetLibIdentity sceneObject = sceneObjects[i]; - NetworkSpawnScene(sceneObject.ObjectId, sceneObject.transform.position, sceneObject.transform.rotation); - } - } - - public LiteNetLibIdentity NetworkSpawnScene(uint objectId, Vector3 position, Quaternion rotation, long connectionId = -1) - { - if (!Manager.IsNetworkActive) - { - Logging.LogWarning(LogTag, "NetworkSpawnScene - Network is not active cannot spawn"); - return null; - } - - LiteNetLibIdentity identity; - if (!SceneObjects.TryGetValue(objectId, out identity)) - { - Logging.LogWarning(LogTag, $"NetworkSpawnScene - Object Id: {objectId} is not registered."); - return null; - } - - identity.gameObject.SetActive(true); - identity.Initial(Manager, true, objectId, connectionId); - identity.InitTransform(position, rotation); - identity.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); - if (Manager.IsServer) - identity.OnStartServer(); - if (Manager.IsClient) - identity.OnStartClient(); - if (connectionId >= 0 && connectionId == Manager.ClientConnectionId) - identity.OnStartOwnerClient(); - if (onObjectSpawn != null) - onObjectSpawn.Invoke(identity); - - return identity; - } - - public LiteNetLibIdentity NetworkSpawn(GameObject gameObject, uint objectId = 0, long connectionId = -1) - { - if (gameObject == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - gameObject is null."); - return null; - } - return NetworkSpawn(gameObject.GetComponent(), objectId, connectionId); - } - - public LiteNetLibIdentity NetworkSpawn(LiteNetLibIdentity identity, uint objectId = 0, long connectionId = -1) - { - if (identity == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - identity is null."); - return null; - } - - identity.gameObject.SetActive(true); - identity.Initial(Manager, false, objectId, connectionId); - identity.InitTransform(identity.transform.position, identity.transform.rotation); - identity.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); - if (Manager.IsServer) - identity.OnStartServer(); - if (Manager.IsClient) - identity.OnStartClient(); - if (connectionId >= 0 && connectionId == Manager.ClientConnectionId) - identity.OnStartOwnerClient(); - if (onObjectSpawn != null) - onObjectSpawn.Invoke(identity); - - return identity; - } - - public LiteNetLibIdentity NetworkSpawn(int hashAssetId, Vector3 position, Quaternion rotation, uint objectId = 0, long connectionId = -1) - { - if (!GuidToPrefabs.ContainsKey(hashAssetId)) - { - if (Manager.LogWarn) - Logging.LogWarning(LogTag, $"NetworkSpawn - Asset Id: {hashAssetId} is not registered."); - return null; - } - return NetworkSpawn(GetObjectInstance(hashAssetId, position, rotation), objectId, connectionId); - } - - public bool NetworkDestroy(GameObject gameObject, byte reasons) - { - if (gameObject == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkDestroy - gameObject is null."); - return false; - } - LiteNetLibIdentity identity = gameObject.GetComponent(); - if (identity == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - identity is null."); - return false; - } - return NetworkDestroy(identity.ObjectId, reasons); - } - - public bool NetworkDestroy(uint objectId, byte reasons) - { - if (!Manager.IsNetworkActive) - { - Logging.LogWarning(LogTag, "NetworkDestroy - Network is not active cannot destroy"); - return false; - } - - LiteNetLibIdentity spawnedObject; - if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) - { - // Call this function to tell behaviour that the identity is being destroyed - spawnedObject.OnNetworkDestroy(reasons); - if (onObjectDestroy != null) - onObjectDestroy.Invoke(spawnedObject); - // If the object is scene object, don't destroy just hide it, else destroy - if (SceneObjects.ContainsKey(objectId)) - { - spawnedObject.gameObject.SetActive(false); - } - else - { - if (spawnedObject.IsPooledInstance) - PushInstanceBack(spawnedObject); - else - Destroy(spawnedObject.gameObject); - } - return true; - } - else if (Manager.LogWarn) - { - Logging.LogWarning(LogTag, $"NetworkDestroy - Object Id: {objectId} is not spawned."); - } - return false; - } - - public bool SetObjectOwner(uint objectId, long connectionId) - { - if (!Manager.IsNetworkActive) - { - Logging.LogWarning(LogTag, "SetObjectOwner - Network is not active cannot set object owner"); - return false; - } - LiteNetLibIdentity spawnedObject; - if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) - { - if (spawnedObject.ConnectionId == connectionId) - return false; - - // If this is server, send message to clients to set object owner - if (Manager.IsServer) - { - foreach (long subscriber in spawnedObject.Subscribers) - { - if (subscriber == connectionId) - continue; - Manager.SendServerSetObjectOwner(subscriber, objectId, connectionId); - } - Manager.SendServerSetObjectOwner(connectionId, objectId, connectionId); - } - // Remove from player spawned objects dictionary and add to target connection id - LiteNetLibPlayer playerA; - LiteNetLibPlayer playerB; - if (Manager.TryGetPlayer(spawnedObject.ConnectionId, out playerA)) - playerA.SpawnedObjects.Remove(objectId); - if (Manager.TryGetPlayer(connectionId, out playerB)) - playerB.SpawnedObjects[spawnedObject.ObjectId] = spawnedObject; - // Set connection id - spawnedObject.ConnectionId = connectionId; - // Call set owner client event - spawnedObject.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); - return true; - } - else if (Manager.LogWarn) - Logging.LogWarning(LogTag, $"SetObjectOwner - Object Id: {objectId} is not spawned."); - - return false; - } - - public Vector3 GetPlayerSpawnPosition() - { - if (CacheSpawnPoints.Count == 0) - return Vector3.zero; - if (playerSpawnRandomly) - return CacheSpawnPoints[Random.Range(0, CacheSpawnPoints.Count)].GetRandomPosition(); - else - { - if (spawnPositionCounter >= CacheSpawnPoints.Count) - spawnPositionCounter = 0; - return CacheSpawnPoints[spawnPositionCounter++].GetRandomPosition(); - } - } - - public bool ContainsSceneObject(uint objectId) - { - return SceneObjects.ContainsKey(objectId); - } - - public bool TryGetSceneObject(uint objectId, out LiteNetLibIdentity identity) - { - return SceneObjects.TryGetValue(objectId, out identity); - } - - public bool TryGetSceneObject(uint objectId, out T result) where T : LiteNetLibBehaviour - { - result = null; - LiteNetLibIdentity identity; - if (SceneObjects.TryGetValue(objectId, out identity)) - { - result = identity.GetComponent(); - return result != null; - } - return false; - } - - public IEnumerable GetSceneObjects() - { - return SceneObjects.Values; - } - - public bool ContainsSpawnedObject(uint objectId) - { - return SpawnedObjects.ContainsKey(objectId); - } - - public bool TryGetSpawnedObject(uint objectId, out LiteNetLibIdentity identity) - { - return SpawnedObjects.TryGetValue(objectId, out identity); - } - - public bool TryGetSpawnedObject(uint objectId, out T result) where T : LiteNetLibBehaviour - { - result = null; - LiteNetLibIdentity identity; - if (SpawnedObjects.TryGetValue(objectId, out identity)) - { - result = identity.GetComponent(); - return result != null; - } - return false; - } - - public IEnumerable GetSpawnedObjects() - { - return SpawnedObjects.Values; - } - - public static void ResetSpawnPositionCounter() - { - spawnPositionCounter = 0; - } - } -} diff --git a/Scripts/GameApi/LiteNetLibAssets.cs.meta b/Scripts/GameApi/LiteNetLibAssets.cs.meta deleted file mode 100644 index 2eb5fa7e..00000000 --- a/Scripts/GameApi/LiteNetLibAssets.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 4884384bff23a9c439e7ce9681ea5724 -timeCreated: 1508751282 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibBehaviour.cs b/Scripts/GameApi/LiteNetLibBehaviour.cs deleted file mode 100644 index 015a6bee..00000000 --- a/Scripts/GameApi/LiteNetLibBehaviour.cs +++ /dev/null @@ -1,1755 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Linq; -using UnityEngine; -using LiteNetLib; -using LiteNetLib.Utils; -using UnityEngine.Profiling; -using System.Text; - -namespace LiteNetLibManager -{ - public partial class LiteNetLibBehaviour : MonoBehaviour, INetSerializable - { - private struct CacheFields - { - public List syncFields; - public List syncLists; - public List syncFieldsWithAttribute; - } - - private struct CacheFunctions - { - public List functions; - public List functionsCanCallByEveryone; - } - - [ReadOnly, SerializeField] - private byte behaviourIndex; - public byte BehaviourIndex - { - get { return behaviourIndex; } - } - - [Header("Behaviour Sync Options")] - public byte dataChannel; - public DeliveryMethod sendOptions; - [Tooltip("Interval to send network data")] - [Range(0.01f, 2f)] - public float sendInterval = 0.1f; - /// - /// How many times per second it will sync behaviour - /// - public float SendRate - { - get { return 1f / sendInterval; } - } - - private float sendCountDown; - - private static readonly Dictionary CacheSyncElements = new Dictionary(); - private static readonly Dictionary CacheElasticRpcs = new Dictionary(); - private static readonly Dictionary CacheTargetRpcs = new Dictionary(); - private static readonly Dictionary CacheAllRpcs = new Dictionary(); - private static readonly Dictionary CacheServerRpcs = new Dictionary(); - private static readonly Dictionary CacheOnChangeFunctions = new Dictionary(); - private static readonly Dictionary CacheOnUpdateFunctions = new Dictionary(); - private static readonly Dictionary CacheDyncnamicFunctionTypes = new Dictionary(); - - private readonly Dictionary targetRpcIds = new Dictionary(); - private readonly Dictionary allRpcIds = new Dictionary(); - private readonly Dictionary serverRpcIds = new Dictionary(); - - // Optimize garbage collector - private Type tempLookupType; - private HashSet tempLookupNames = new HashSet(); - private FieldInfo[] tempLookupFields; - private MethodInfo[] tempLookupMethods; - - private Type classType; - /// - /// This will be used when setup sync fields and sync lists - /// - public Type ClassType - { - get - { - if (classType == null) - classType = GetType(); - return classType; - } - } - - /// - /// This will be used when setup sync fields and sync lists as key for cached fields - /// - public string TypeName - { - get { return ClassType.FullName; } - } - - private bool isFoundIdentity; - private LiteNetLibIdentity identity; - public LiteNetLibIdentity Identity - { - get - { - if (!isFoundIdentity) - { - identity = GetComponent(); - if (identity == null) - identity = GetComponentInParent(); - isFoundIdentity = identity != null; - } - return identity; - } - } - - public long ConnectionId - { - get { return Identity.ConnectionId; } - } - - public uint ObjectId - { - get { return Identity.ObjectId; } - } - - public LiteNetLibGameManager Manager - { - get { return Identity.Manager; } - } - - public LiteNetLibPlayer Player - { - get { return Identity.Player; } - } - - public bool IsServer - { - get { return Identity.IsServer; } - } - - public bool IsClient - { - get { return Identity.IsClient; } - } - - public bool IsOwnerClient - { - get { return Identity.IsOwnerClient; } - } - - public bool IsHost - { - get { return IsServer && IsOwnerClient; } - } - - public bool IsOwnedByServer - { - get { return Identity.IsOwnedByServer; } - } - - public bool IsOwnerClientOrOwnedByServer - { - get { return Identity.IsOwnerClientOrOwnedByServer; } - } - - public bool IsSceneObject - { - get { return Identity.IsSceneObject; } - } - - private string logTag; - public virtual string LogTag - { - get - { - if (string.IsNullOrEmpty(logTag)) - logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; - return logTag; - } - } - - internal void NetworkUpdate(float deltaTime) - { - // Sync behaviour - if (!IsServer || !CanSyncBehaviour()) - return; - - // It's time to send update? - sendCountDown -= deltaTime; - if (sendCountDown > 0) - return; - - // Set count down - sendCountDown = sendInterval; - - Profiler.BeginSample("LiteNetLibBehaviour - Update Sync Behaviour"); - if (ShouldSyncBehaviour()) - { - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - TransportHandler.WritePacket(server.Writer, GameMsgTypes.ServerSyncBehaviour); - Serialize(server.Writer); - foreach (long connectionId in manager.GetConnectionIds()) - { - if (Identity.HasSubscriberOrIsOwning(connectionId)) - server.SendMessage(connectionId, dataChannel, sendOptions, server.Writer); - } - } - Profiler.EndSample(); - } - - public void Setup(byte behaviourIndex) - { - this.behaviourIndex = behaviourIndex; - OnSetup(); - CacheElements(); - CacheRpcs(serverRpcIds, CacheElasticRpcs); - CacheRpcs(allRpcIds, CacheElasticRpcs); - CacheRpcs(targetRpcIds, CacheElasticRpcs); - CacheRpcs(serverRpcIds, CacheServerRpcs); - CacheRpcs(allRpcIds, CacheAllRpcs); - CacheRpcs(targetRpcIds, CacheTargetRpcs); - } - - private void CacheElements() - { - CacheFields tempCacheFields; - if (!CacheSyncElements.TryGetValue(TypeName, out tempCacheFields)) - { - tempCacheFields = new CacheFields() - { - syncFields = new List(), - syncLists = new List(), - syncFieldsWithAttribute = new List() - }; - tempLookupNames.Clear(); - tempLookupType = ClassType; - SyncFieldAttribute tempAttribute = null; - // Find for sync field and sync list from the class - while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) - { - tempLookupFields = tempLookupType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - foreach (FieldInfo lookupField in tempLookupFields) - { - // Avoid duplicate fields - if (tempLookupNames.Contains(lookupField.Name)) - continue; - - if (lookupField.FieldType.IsSubclassOf(typeof(LiteNetLibSyncField))) - { - tempCacheFields.syncFields.Add(lookupField); - } - else if (lookupField.FieldType.IsSubclassOf(typeof(LiteNetLibSyncList))) - { - tempCacheFields.syncLists.Add(lookupField); - } - else - { - // Must have [SyncField] attribute - tempAttribute = lookupField.GetCustomAttribute(); - if (tempAttribute != null) - tempCacheFields.syncFieldsWithAttribute.Add(lookupField); - } - - tempLookupNames.Add(lookupField.Name); - } - tempLookupType = tempLookupType.BaseType; - } - // Sort name to make sure the fields will be sync correctly by its index - tempCacheFields.syncFields.Sort((a, b) => a.Name.ToLower().CompareTo(b.Name.ToLower())); - tempCacheFields.syncLists.Sort((a, b) => a.Name.ToLower().CompareTo(b.Name.ToLower())); - CacheSyncElements.Add(TypeName, tempCacheFields); - } - SetupSyncElements(tempCacheFields.syncFields, Identity.SyncFields); - SetupSyncElements(tempCacheFields.syncLists, Identity.SyncLists); - SetupSyncFieldsWithAttribute(tempCacheFields.syncFieldsWithAttribute); - } - - private void SetupSyncElements(List fields, List elementList) where T : LiteNetLibElement - { - if (fields == null || fields.Count == 0) - return; - - foreach (FieldInfo field in fields) - { - try - { - RegisterSyncElement((T)field.GetValue(this), elementList); - } - catch (Exception ex) - { - if (Manager.LogFatal) - Logging.LogException(LogTag, ex); - } - } - } - - private void SetupSyncFieldsWithAttribute(List fieldInfos) - { - if (fieldInfos == null || fieldInfos.Count == 0) - return; - - StringBuilder stringBuilder = new StringBuilder(); - SyncFieldAttribute tempAttribute; - LiteNetLibSyncField tempSyncField; - MethodInfo tempOnChangeMethod; - MethodInfo tempOnUpdateMethod; - foreach (FieldInfo fieldInfo in fieldInfos) - { - try - { - tempAttribute = fieldInfo.GetCustomAttribute(); - // Find on change method - tempOnChangeMethod = null; - if (!string.IsNullOrEmpty(tempAttribute.onChangeMethodName)) - { - tempOnChangeMethod = FindAndCacheMethods(stringBuilder, tempAttribute.onChangeMethodName, fieldInfo, CacheOnChangeFunctions, (tempMethodParams) => - { - return tempMethodParams != null && tempMethodParams.Length == 1 && tempMethodParams[0].ParameterType == fieldInfo.FieldType; - }); - if (tempOnChangeMethod == null) - { - if (Manager.LogError) - Logging.LogError(LogTag, "Cannot find `on change` method named [" + tempAttribute.onChangeMethodName + "] from [" + TypeName + "], FYI the function must has 1 parameter with the same type with the field."); - } - } - // Find on update method - tempOnUpdateMethod = null; - if (!string.IsNullOrEmpty(tempAttribute.onUpdateMethodName)) - { - tempOnUpdateMethod = FindAndCacheMethods(stringBuilder, tempAttribute.onUpdateMethodName, fieldInfo, CacheOnUpdateFunctions, (tempMethodParams) => - { - return tempMethodParams == null || tempMethodParams.Length == 0; - }); - if (tempOnUpdateMethod == null) - { - if (Manager.LogError) - Logging.LogError(LogTag, "Cannot find `on update` method named [" + tempAttribute.onUpdateMethodName + "] from [" + TypeName + "], FYI the function must has 0 parameter."); - } - } - // Create new sync field container - tempSyncField = new LiteNetLibSyncFieldContainer(fieldInfo, this, tempOnChangeMethod, tempOnUpdateMethod); - tempSyncField.dataChannel = tempAttribute.dataChannel; - tempSyncField.deliveryMethod = tempAttribute.deliveryMethod; - tempSyncField.clientDataChannel = tempAttribute.clientDataChannel; - tempSyncField.clientDeliveryMethod = tempAttribute.clientDeliveryMethod; - tempSyncField.sendInterval = tempAttribute.sendInterval; - tempSyncField.syncBehaviour = tempAttribute.syncBehaviour; - tempSyncField.syncMode = tempAttribute.syncMode; - RegisterSyncElement(tempSyncField, Identity.SyncFields); - } - catch (Exception ex) - { - if (Manager.LogFatal) - Logging.LogException(LogTag, ex); - } - } - } - - private MethodInfo FindAndCacheMethods(StringBuilder stringBuilder, string methodName, FieldInfo fieldInfo, Dictionary dictionary, Func parameterValidator) - { - MethodInfo tempMethod; - string key = stringBuilder.Clear().Append(TypeName).Append('.').Append(methodName).ToString(); - if (!dictionary.TryGetValue(key, out tempMethod)) - { - // Not found hook function in cache dictionary, try find the function - tempLookupType = ClassType; - while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) - { - tempLookupMethods = tempLookupType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); - foreach (MethodInfo lookupMethod in tempLookupMethods) - { - // Return type must be `void` - if (lookupMethod.ReturnType != typeof(void)) - continue; - - // Not the function it's looking for - if (!lookupMethod.Name.Equals(methodName)) - continue; - - // Parameter not match - if (!parameterValidator.Invoke(lookupMethod.GetParameters())) - continue; - - // Found the function - tempMethod = lookupMethod; - break; - } - - // Found the function so exit the loop, don't find the function in base class - if (tempMethod != null) - break; - - tempLookupType = tempLookupType.BaseType; - } - // Add to cache dictionary althrough it's empty to avoid it try to lookup next time - dictionary.Add(key, tempMethod); - } - return tempMethod; - } - - private void CacheRpcs(Dictionary ids, Dictionary cacheDict) - where RpcType : RpcAttribute - { - CacheFunctions tempCacheFunctions; - if (!cacheDict.TryGetValue(TypeName, out tempCacheFunctions)) - { - tempCacheFunctions = new CacheFunctions() - { - functions = new List(), - functionsCanCallByEveryone = new List() - }; - tempLookupNames.Clear(); - tempLookupType = ClassType; - RpcType tempAttribute; - // Find for function with [Rpc] attribute to register as RPC - while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) - { - tempLookupMethods = tempLookupType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); - foreach (MethodInfo lookupMethod in tempLookupMethods) - { - // Avoid duplicate functions - if (tempLookupNames.Contains(lookupMethod.Name)) - continue; - - // Must have [Rpc] attribute - tempAttribute = lookupMethod.GetCustomAttribute(); - if (tempAttribute == null) - continue; - - // Return type must be `void` - if (lookupMethod.ReturnType != typeof(void)) - { - if (Manager.LogError) - Logging.LogError(LogTag, "Cannot register rpc [" + lookupMethod.Name + "] return type must be void"); - continue; - } - - if (!tempAttribute.canCallByEveryone) - tempCacheFunctions.functions.Add(lookupMethod); - else - tempCacheFunctions.functionsCanCallByEveryone.Add(lookupMethod); - tempLookupNames.Add(lookupMethod.Name); - } - tempLookupType = tempLookupType.BaseType; - } - cacheDict.Add(TypeName, tempCacheFunctions); - } - SetupRpcs(ids, tempCacheFunctions.functions, false); - SetupRpcs(ids, tempCacheFunctions.functionsCanCallByEveryone, true); - } - - private void SetupRpcs(Dictionary ids, List methodInfos, bool canCallByEveryone) - { - if (methodInfos == null || methodInfos.Count == 0) - return; - - string tempFunctionId; - Type[] tempParamTypes; - foreach (MethodInfo methodInfo in methodInfos) - { - tempFunctionId = MakeNetFunctionId(methodInfo); - if (!CacheDyncnamicFunctionTypes.TryGetValue(tempFunctionId, out tempParamTypes)) - { - tempParamTypes = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray(); - CacheDyncnamicFunctionTypes[tempFunctionId] = tempParamTypes; - } - RegisterRPC(ids, tempFunctionId, new LiteNetLibFunctionDynamic(tempParamTypes, this, methodInfo), canCallByEveryone); - } - } - - #region Sync Elements Registration - private void RegisterSyncElement(T element, List elementList) where T : LiteNetLibElement - { - int elementId = elementList.Count; - element.Setup(this, elementId); - elementList.Add(element); - } - - public void RegisterSyncField(T syncField) where T : LiteNetLibSyncField - { - RegisterSyncElement(syncField, Identity.SyncFields); - } - - public void RegisterSyncList(T syncList) where T : LiteNetLibSyncList - { - RegisterSyncElement(syncList, Identity.SyncLists); - } - #endregion - - #region RPCs Registration - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - #endregion - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, string id, LiteNetLibFunction netFunction, bool canCallByEveryone) - { - if (dict.ContainsKey(id)) - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot register rpc with existed id [" + id + "]."); - return; - } - if (Identity.NetFunctions.Count >= int.MaxValue) - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot register rpc it's exceeds limit."); - return; - } - int elementId = Identity.NetFunctions.Count; - netFunction.Setup(this, elementId); - netFunction.CanCallByEveryone = canCallByEveryone; - Identity.NetFunctions.Add(netFunction); - dict[id] = elementId; - } - - #region Elastic RPC with receivers and parameters - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers) - { - RPC(func, receivers); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1) - { - RPC(func, receivers, param1); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2) - { - RPC(func, receivers, param1, param2); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) - { - RPC(func, receivers, param1, param2, param3); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func, receivers, param1, param2, param3, param4); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func, receivers, param1, param2, param3, param4, param5); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - #region Elastic RPC with delivery method, receivers and parameters - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers) - { - RPC(func, dataChannel, deliveryMethod, receivers); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - #region All RPC or Server RPC with parameters - public void RPC(NetFunctionDelegate func) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered); - } - - public void RPC(NetFunctionDelegate func, T1 param1) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - #region All RPC or Server RPC with delivery method and parameters - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod) - { - RPC(func.Method.Name, dataChannel, deliveryMethod); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - #region Target RPC with connectionId and parameters - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId) - { - RPC(func, connectionId); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1) - { - RPC(func, connectionId, param1); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2) - { - RPC(func, connectionId, param1, param2); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3) - { - RPC(func, connectionId, param1, param2, param3); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func, connectionId, param1, param2, param3, param4); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func, connectionId, param1, param2, param3, param4, param5); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - - public void RPC(NetFunctionDelegate func, long connectionId) - { - RPC(func.Method.Name, connectionId); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1) - { - RPC(func.Method.Name, connectionId, param1); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2) - { - RPC(func.Method.Name, connectionId, param1, param2); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, connectionId, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - /// - /// This is another synonym of `RPC` which contains `receivers` and `parameters` - /// - public void CallNetFunction(string methodName, FunctionReceivers receivers, params object[] parameters) - { - RPC(methodName, receivers, parameters); - } - - /// - /// Call elastic RPC, it can be `All RPC` or `Server RPC` up to how you define `receivers` - /// - /// - /// - /// - public void RPC(string methodName, FunctionReceivers receivers, params object[] parameters) - { - RPC(methodName, 0, DeliveryMethod.ReliableOrdered, receivers, parameters); - } - - /// - /// This is another synonym of `RPC` which contains `dataChannel`, `deliveryMethod`, `receivers` and `parameters` - /// - public void CallNetFunction(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameters) - { - RPC(methodName, dataChannel, deliveryMethod, receivers, parameters); - } - - /// - /// Call elastic RPC, it can be `All RPC` or `Server RPC` up to how you define `receivers` - /// - /// - /// - /// - /// - /// - public void RPC(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameters) - { - int elementId; - switch (receivers) - { - case FunctionReceivers.All: - if (allRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, receivers, parameters); - } - else - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, any rpc [" + methodName + "] not found."); - } - break; - case FunctionReceivers.Server: - if (serverRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, receivers, parameters); - } - else - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, any rpc [" + methodName + "] not found."); - } - break; - default: - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, rpc [" + methodName + "] receives must be `All` or `Server`."); - break; - } - } - - /// - /// Call `All RPC` or `Server RPC`, if it's elastic RPC, it will call `All RPC` - /// - /// - /// - public void RPC(string methodName, params object[] parameters) - { - RPC(methodName, 0, DeliveryMethod.ReliableOrdered, parameters); - } - - /// - /// Call `All RPC` or `Server RPC`, if it's elastic RPC, it will call `All RPC` - /// - /// - /// - /// - /// - public void RPC(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, params object[] parameters) - { - int elementId; - if (allRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, FunctionReceivers.All, parameters); - } - else if (serverRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, FunctionReceivers.Server, parameters); - } - else - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, client or server rpc [" + methodName + "] not found."); - } - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` and `parameters` - /// - public void CallNetFunction(string methodName, long connectionId, params object[] parameters) - { - RPC(methodName, connectionId, parameters); - } - - /// - /// Call function at target client by connection id - /// - /// - /// - /// - public void RPC(string methodName, long connectionId, params object[] parameters) - { - int elementId; - if (targetRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(0, DeliveryMethod.ReliableOrdered, connectionId, parameters); - } - else - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, target rpc [" + methodName + "] not found."); - } - } - - private string MakeNetFunctionId(MethodInfo methodInfo) - { - return MakeNetFunctionId(methodInfo.Name); - } - - private string MakeNetFunctionId(string methodName) - { - return new StringBuilder(TypeName).Append('+').Append(methodName).ToString(); - } - - public void Serialize(NetDataWriter writer) - { - if (!IsServer) - return; - - writer.PutPackedUInt(Identity.ObjectId); - writer.Put(BehaviourIndex); - OnSerialize(writer); - } - - public void Deserialize(NetDataReader reader) - { - OnDeserialize(reader); - } - - public void SetOwnerClient(long connectionId) - { - Identity.SetOwnerClient(connectionId); - } - - public void NetworkDestroy() - { - Identity.NetworkDestroy(); - } - - public void NetworkDestroy(float delay) - { - Identity.NetworkDestroy(delay); - } - - public void ClientSendMessage(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsClient) - return; - Manager.ClientSendMessage(dataChannel, deliveryMethod, writer); - } - - public void ClientSendPacket(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) - { - if (!IsClient) - return; - Manager.ClientSendPacket(dataChannel, deliveryMethod, msgType, serializerDelegate); - } - - public void ServerSendMessage(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsServer) - return; - Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, writer); - } - - public void ServerSendPacket(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) - { - if (!IsServer) - return; - Manager.ServerSendPacket(connectionId, dataChannel, deliveryMethod, msgType, serializerDelegate); - } - - public void ServerSendMessageToAllConnections(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsServer) - return; - Manager.ServerSendMessageToAllConnections(dataChannel, deliveryMethod, writer); - } - - public void ServerSendPacketToAllConnections(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) - { - if (!IsServer) - return; - Manager.ServerSendPacketToAllConnections(dataChannel, deliveryMethod, msgType, serializerDelegate); - } - - public void ServerSendMessageToSubscribers(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsServer) - return; - foreach (long connectionId in Manager.GetConnectionIds()) - { - if (Identity.HasSubscriber(connectionId)) - Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, writer); - } - } - - public void ServerSendPacketToSubscribers(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) - { - if (!IsServer) - return; - TransportHandler.WritePacket(Manager.Server.Writer, msgType, serializerDelegate); - foreach (long connectionId in Manager.GetConnectionIds()) - { - if (Identity.HasSubscriber(connectionId)) - Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, Manager.Server.Writer); - } - } - - /// - /// This function will be called when this behaviour spawned at server - /// - public virtual void OnStartServer() { } - - /// - /// This function will be called when this behaviour spawned at client (all client types `non-owner and owner`) - /// - public virtual void OnStartClient() { } - - /// - /// This function will be called when this behaviour spawned at owner-client - /// - public virtual void OnStartOwnerClient() { } - - /// - /// This function will be called when this client has been verified as owner client - /// - public virtual void OnSetOwnerClient(bool isOwnerClient) { } - - /// - /// This function will be called when this client receive spawn object message with position and rotation - /// - /// - /// - public virtual void InitTransform(Vector3 position, Quaternion rotation) { } - - /// - /// This function will be called when object destroy from server - /// - /// - public virtual void OnNetworkDestroy(byte reasons) { } - - /// - /// This function will be called when this behaviour have been setup by identity - /// You may do some initialize things within this function - /// - public virtual void OnSetup() { } - - /// - /// Override this function to define condition to sync behaviour data to client or not - /// - /// - public virtual bool CanSyncBehaviour() - { - return false; - } - - /// - /// Override this function to define condition to sync behaviour data to client when it should - /// - /// - public virtual bool ShouldSyncBehaviour() - { - return false; - } - - /// - /// Override this function to write custom data to send from server to client - /// - public virtual void OnSerialize(NetDataWriter writer) { } - - /// - /// Override this function to read data from server at client - /// - public virtual void OnDeserialize(NetDataReader reader) { } - - /// - /// Override this function to change object visibility when this added to player as subcribing - /// - public virtual void OnServerSubscribingAdded() { } - - /// - /// Override this function to change object visibility when this removed from player as subcribing - /// - public virtual void OnServerSubscribingRemoved() { } - } -} diff --git a/Scripts/GameApi/LiteNetLibBehaviour.cs.meta b/Scripts/GameApi/LiteNetLibBehaviour.cs.meta deleted file mode 100644 index 8f77957a..00000000 --- a/Scripts/GameApi/LiteNetLibBehaviour.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 1e3668c0fbd3f354489edb3a96824749 -timeCreated: 1508753155 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibElement.cs b/Scripts/GameApi/LiteNetLibElement.cs deleted file mode 100644 index 91d847d5..00000000 --- a/Scripts/GameApi/LiteNetLibElement.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct LiteNetLibElementInfo - { - public uint objectId; - public int elementId; - public LiteNetLibElementInfo(uint objectId, int elementId) - { - this.objectId = objectId; - this.elementId = elementId; - } - - public static void SerializeInfo(LiteNetLibElementInfo info, NetDataWriter writer) - { - writer.PutPackedUInt(info.objectId); - writer.PutPackedUInt((uint)info.elementId); - } - - public static LiteNetLibElementInfo DeserializeInfo(NetDataReader reader) - { - return new LiteNetLibElementInfo(reader.GetPackedUInt(), (int)reader.GetPackedUInt()); - } - } - - public abstract class LiteNetLibElement - { - [ReadOnly, SerializeField] - protected LiteNetLibBehaviour behaviour; - public LiteNetLibBehaviour Behaviour - { - get { return behaviour; } - } - - public LiteNetLibIdentity Identity - { - get { return Behaviour.Identity; } - } - - public long ConnectionId - { - get { return !IsSetup ? -1 : Behaviour.ConnectionId; } - } - - public uint ObjectId - { - get { return !IsSetup ? 0 : Behaviour.ObjectId; } - } - - public LiteNetLibGameManager Manager - { - get { return Behaviour.Manager; } - } - - public virtual string LogTag - { - get { return (!IsSetup ? "(No Behaviour)" : Behaviour.LogTag) + "->" + ToString(); } - } - - public bool IsServer - { - get { return IsSetup && Behaviour.IsServer; } - } - - public bool IsClient - { - get { return IsSetup && Behaviour.IsClient; } - } - - public bool IsOwnerClient - { - get { return IsSetup && Behaviour.IsOwnerClient; } - } - - public bool IsSetup { get; private set; } - - [ReadOnly, SerializeField] - protected int elementId; - public int ElementId - { - get { return elementId; } - } - - public LiteNetLibElementInfo GetInfo() - { - return new LiteNetLibElementInfo(Behaviour.ObjectId, ElementId); - } - - internal virtual void Setup(LiteNetLibBehaviour behaviour, int elementId) - { - this.behaviour = behaviour; - this.elementId = elementId; - IsSetup = true; - } - - protected virtual bool CanSync() - { - return IsSetup; - } - } -} diff --git a/Scripts/GameApi/LiteNetLibElement.cs.meta b/Scripts/GameApi/LiteNetLibElement.cs.meta deleted file mode 100644 index 92395850..00000000 --- a/Scripts/GameApi/LiteNetLibElement.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 6ef4e992e48d90a45ae6c3958a7df40d -timeCreated: 1511719678 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibFunction.cs b/Scripts/GameApi/LiteNetLibFunction.cs deleted file mode 100644 index 4c86bd51..00000000 --- a/Scripts/GameApi/LiteNetLibFunction.cs +++ /dev/null @@ -1,471 +0,0 @@ -using System; -using System.Reflection; -using LiteNetLib; -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public enum FunctionReceivers : byte - { - Target, - All, - Server, - } - - public class LiteNetLibFunction : LiteNetLibElement - { - protected readonly static NetDataWriter ServerWriter = new NetDataWriter(); - protected readonly static NetDataWriter ClientWriter = new NetDataWriter(); - - public readonly Type[] ParameterTypes; - public readonly object[] Parameters; - public bool CanCallByEveryone { get; set; } - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : this(0) - { - } - - protected LiteNetLibFunction(int parameterCount) - { - Parameters = new object[parameterCount]; - ParameterTypes = new Type[parameterCount]; - } - - protected LiteNetLibFunction(Type[] parameterTypes) - { - Parameters = new object[parameterTypes.Length]; - ParameterTypes = parameterTypes; - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - protected override bool CanSync() - { - return Behaviour != null && (IsServer || IsOwnerClient || CanCallByEveryone); - } - - internal virtual void HookCallback() - { - callback.Invoke(); - } - - protected void SendCall(byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, long targetConnectionId) - { - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - LiteNetLibClient client = manager.Client; - if (manager.IsServer) - { - switch (receivers) - { - case FunctionReceivers.Target: - if (Identity.HasSubscriberOrIsOwning(targetConnectionId) && manager.ContainsConnectionId(targetConnectionId)) - { - // Prepare packet - TransportHandler.WritePacket(ServerWriter, GameMsgTypes.CallFunction); - SerializeForSend(ServerWriter); - // Send function call message from server to target client by target connection Id - server.SendMessage(targetConnectionId, dataChannel, deliveryMethod, ServerWriter); - } - break; - case FunctionReceivers.All: - // Send to all connections - foreach (long connectionId in manager.GetConnectionIds()) - { - if (manager.ClientConnectionId == connectionId) - { - // This is host's networking oject, so hook callback immediately - // Don't have to send message to the client, because it is currently run as both server and client - HookCallback(); - } - else if (Identity.HasSubscriberOrIsOwning(connectionId)) - { - // Prepare packet - TransportHandler.WritePacket(ServerWriter, GameMsgTypes.CallFunction); - SerializeForSend(ServerWriter); - // Send message to subscribing clients - server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); - } - } - if (!manager.IsClientConnected) - { - // It's not a host(client+host), it's just a server - // So hook callback immediately to do the function at server - HookCallback(); - } - break; - case FunctionReceivers.Server: - // Call server function at server - // So hook callback immediately to do the function at server - HookCallback(); - break; - } - } - else if (manager.IsClientConnected) - { - // Prepare packet - TransportHandler.WritePacket(ClientWriter, GameMsgTypes.CallFunction); - SerializeForClientSend(ClientWriter, receivers, targetConnectionId); - // Client send net function call to server - // Then the server will hook callback or forward message to other clients - client.SendMessage(dataChannel, deliveryMethod, ClientWriter); - } - } - - internal void SetParameters(params object[] parameterValues) - { - for (int i = 0; i < Parameters.Length; ++i) - { - if (i >= parameterValues.Length) - break; - Parameters[i] = parameterValues[i]; - } - } - - internal void Call(byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameterValues) - { - if (!CanSync()) - return; - - SetParameters(parameterValues); - SendCall(dataChannel, deliveryMethod, receivers, ConnectionId); - } - - internal void Call(byte dataChannel, DeliveryMethod deliveryMethod, long connectionId, params object[] parameterValues) - { - if (!CanSync()) - return; - - SetParameters(parameterValues); - SendCall(dataChannel, deliveryMethod, FunctionReceivers.Target, connectionId); - } - - internal void CallWithoutParametersSet(FunctionReceivers receivers) - { - if (!CanSync()) - return; - - SendCall(0, DeliveryMethod.ReliableOrdered, receivers, ConnectionId); - } - - internal void CallWithoutParametersSet(long connectionId) - { - if (!CanSync()) - return; - - SendCall(0, DeliveryMethod.ReliableOrdered, FunctionReceivers.Target, connectionId); - } - - private void SerializeForClientSend(NetDataWriter writer, FunctionReceivers receivers, long connectionId) - { - writer.Put((byte)receivers); - if (receivers == FunctionReceivers.Target) - writer.PutPackedLong(connectionId); - SerializeForSend(writer); - } - - private void SerializeForSend(NetDataWriter writer) - { - LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); - SerializeParameters(writer); - } - - public void DeserializeParameters(NetDataReader reader) - { - if (Parameters == null || Parameters.Length == 0) - return; - for (int i = 0; i < Parameters.Length; ++i) - { - if (ParameterTypes[i].IsArray) - Parameters[i] = reader.GetArray(ParameterTypes[i].GetElementType()); - else - Parameters[i] = reader.GetValue(ParameterTypes[i]); - } - } - - public void SerializeParameters(NetDataWriter writer) - { - if (Parameters == null || Parameters.Length == 0) - return; - for (int i = 0; i < Parameters.Length; ++i) - { - if (ParameterTypes[i].IsArray) - writer.PutArray(ParameterTypes[i].GetElementType(), Parameters[i]); - else - writer.PutValue(ParameterTypes[i], Parameters[i]); - } - } - } - - #region Implement for multiple parameter usages - public class LiteNetLibFunctionDynamic : LiteNetLibFunction - { - /// - /// The class which contain the function - /// - private object instance; - - private MethodInfo callback; - - public LiteNetLibFunctionDynamic(Type[] parameterTypes, object instance, MethodInfo callback) : base(parameterTypes) - { - this.instance = instance; - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback.Invoke(instance, Parameters); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(1) - { - ParameterTypes[0] = typeof(T1); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(2) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(3) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(4) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(5) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(6) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(7) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - ParameterTypes[6] = typeof(T7); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(8) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - ParameterTypes[6] = typeof(T7); - ParameterTypes[7] = typeof(T8); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(9) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - ParameterTypes[6] = typeof(T7); - ParameterTypes[7] = typeof(T8); - ParameterTypes[8] = typeof(T9); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7], (T9)Parameters[8]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(10) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - ParameterTypes[6] = typeof(T7); - ParameterTypes[7] = typeof(T8); - ParameterTypes[8] = typeof(T9); - ParameterTypes[9] = typeof(T10); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7], (T9)Parameters[8], (T10)Parameters[9]); - } - } - #endregion -} diff --git a/Scripts/GameApi/LiteNetLibFunction.cs.meta b/Scripts/GameApi/LiteNetLibFunction.cs.meta deleted file mode 100644 index d95ea24a..00000000 --- a/Scripts/GameApi/LiteNetLibFunction.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 2fd014728a1d38448952ac768473cb6e -timeCreated: 1509024653 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibGameManager.cs b/Scripts/GameApi/LiteNetLibGameManager.cs deleted file mode 100644 index 887e27cc..00000000 --- a/Scripts/GameApi/LiteNetLibGameManager.cs +++ /dev/null @@ -1,1049 +0,0 @@ -using UnityEngine; -using UnityEngine.SceneManagement; -using LiteNetLib; -using LiteNetLib.Utils; -using Cysharp.Threading.Tasks; -using System.Collections.Generic; -using System.Net.Sockets; - -namespace LiteNetLibManager -{ - [RequireComponent(typeof(LiteNetLibAssets))] - public class LiteNetLibGameManager : LiteNetLibManager - { - [Header("Game manager configs")] - public uint packetVersion = 1; - public float pingDuration = 1f; - public bool doNotEnterGameOnConnect; - public bool doNotDestroyOnSceneChanges; - - protected readonly Dictionary Players = new Dictionary(); - - private float _clientSendPingCountDown; - private float _serverSendPingCountDown; - private AsyncOperation _loadSceneAsyncOperation; - - public long ClientConnectionId { get; protected set; } - private long _rtt; - public long Rtt - { - get - { - if (IsServer) - return 0; - return _rtt; - } - } - private long _lastPingTime; - private long _totalRtt; - private int _rttCount; - public long Timestamp { get { return System.DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } } - /// - /// Unix timestamp (milliseconds) offsets from server - /// - public long ServerTimestampOffsets { get; protected set; } - /// - /// Server unix timestamp (milliseconds) - /// - public long ServerTimestamp - { - get - { - if (IsServer) - return Timestamp; - return Timestamp + ServerTimestampOffsets; - } - } - public string ServerSceneName { get; protected set; } - public LiteNetLibAssets Assets { get; protected set; } - public BaseInterestManager InterestManager { get; protected set; } - - protected virtual void Awake() - { - Assets = GetComponent(); - InterestManager = GetComponent(); - if (InterestManager == null) - InterestManager = gameObject.AddComponent(); - ServerSceneName = string.Empty; - if (doNotDestroyOnSceneChanges) - DontDestroyOnLoad(gameObject); - } - - protected override void FixedUpdate() - { - if (_loadSceneAsyncOperation == null) - { - if (IsClientConnected) - { - // Send ping from client - _clientSendPingCountDown -= Time.fixedDeltaTime; - if (_clientSendPingCountDown <= 0f) - { - SendClientPing(); - _clientSendPingCountDown = pingDuration; - } - } - if (IsServer) - { - // Send ping from server - _serverSendPingCountDown -= Time.fixedDeltaTime; - if (_serverSendPingCountDown <= 0f) - { - SendServerPing(); - _serverSendPingCountDown = pingDuration; - } - } - } - base.FixedUpdate(); - } - - public virtual uint PacketVersion() - { - return packetVersion; - } - - public bool TryGetPlayer(long connectionId, out LiteNetLibPlayer player) - { - return Players.TryGetValue(connectionId, out player); - } - - public bool ContainsPlayer(long connectionId) - { - return Players.ContainsKey(connectionId); - } - - public LiteNetLibPlayer GetPlayer(long connectionId) - { - return Players[connectionId]; - } - - public IEnumerable GetPlayers() - { - return Players.Values; - } - - public int PlayersCount - { - get { return Players.Count; } - } - - /// - /// Call this function to change gameplay scene at server, then the server will tell clients to change scene - /// - /// - public virtual void ServerSceneChange(string sceneName) - { - if (!IsServer) - return; - LoadSceneRoutine(sceneName, true).Forget(); - } - - /// - /// This function will be called to load scene async - /// - /// - /// - /// - private async UniTaskVoid LoadSceneRoutine(string sceneName, bool online) - { - if (_loadSceneAsyncOperation == null) - { - // If doNotDestroyOnSceneChanges not TRUE still not destroy this game object - // But it will be destroyed after scene loaded, if scene is offline scene - if (!doNotDestroyOnSceneChanges) - DontDestroyOnLoad(gameObject); - - if (online) - { - foreach (LiteNetLibPlayer player in Players.Values) - { - player.IsReady = false; - player.Subscribings.Clear(); - player.SpawnedObjects.Clear(); - } - Assets.Clear(true); - } - - if (LogDev) Logging.Log(LogTag, "Loading Scene: " + sceneName + " is online: " + online); - if (Assets.onLoadSceneStart != null) - Assets.onLoadSceneStart.Invoke(sceneName, online, 0f); - - _loadSceneAsyncOperation = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single); - while (_loadSceneAsyncOperation != null && !_loadSceneAsyncOperation.isDone) - { - if (Assets.onLoadSceneProgress != null) - Assets.onLoadSceneProgress.Invoke(sceneName, online, _loadSceneAsyncOperation.progress); - await UniTask.Yield(); - } - _loadSceneAsyncOperation = null; - - if (online) - { - Assets.Initialize(); - Assets.InitPoolingObjects(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> Assets.Initialize()"); - if (IsClient) - { - // If it is host (both client and server) wait for client connection id before proceed server scene load - while (ClientConnectionId < 0) await UniTask.Yield(); - } - if (IsServer) - { - ServerSceneName = sceneName; - Assets.SpawnSceneObjects(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> Assets.SpawnSceneObjects()"); - OnServerOnlineSceneLoaded(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> OnServerOnlineSceneLoaded()"); - SendServerSceneChange(sceneName); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> SendServerSceneChange()"); - } - if (IsClient) - { - OnClientOnlineSceneLoaded(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> OnClientOnlineSceneLoaded()"); - SendClientReady(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> SendClientReady()"); - } - } - else if (!doNotDestroyOnSceneChanges) - { - // Destroy manager's game object if loaded scene is not online scene - Destroy(gameObject); - } - - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " is online: " + online); - if (Assets.onLoadSceneFinish != null) - Assets.onLoadSceneFinish.Invoke(sceneName, online, 1f); - } - } - - protected override void RegisterMessages() - { - EnableRequestResponse(GameMsgTypes.Request, GameMsgTypes.Response); - // Request to server (response to client) - RegisterRequestToServer(GameReqTypes.EnterGame, HandleEnterGameRequest, HandleEnterGameResponse); - RegisterRequestToServer(GameReqTypes.ClientReady, HandleClientReadyRequest, HandleClientReadyResponse); - RegisterRequestToServer(GameReqTypes.ClientNotReady, HandleClientNotReadyRequest, HandleClientNotReadyResponse); - // Server messages - RegisterServerMessage(GameMsgTypes.CallFunction, HandleClientCallFunction); - RegisterServerMessage(GameMsgTypes.UpdateSyncField, HandleClientUpdateSyncField); - RegisterServerMessage(GameMsgTypes.InitialSyncField, HandleClientInitialSyncField); - RegisterServerMessage(GameMsgTypes.ClientSendTransform, HandleClientSendTransform); - RegisterServerMessage(GameMsgTypes.Ping, HandleClientPing); - RegisterServerMessage(GameMsgTypes.Pong, HandleClientPong); - // Client messages - RegisterClientMessage(GameMsgTypes.ServerSpawnSceneObject, HandleServerSpawnSceneObject); - RegisterClientMessage(GameMsgTypes.ServerSpawnObject, HandleServerSpawnObject); - RegisterClientMessage(GameMsgTypes.ServerDestroyObject, HandleServerDestroyObject); - RegisterClientMessage(GameMsgTypes.CallFunction, HandleServerCallFunction); - RegisterClientMessage(GameMsgTypes.UpdateSyncField, HandleServerUpdateSyncField); - RegisterClientMessage(GameMsgTypes.InitialSyncField, HandleServerInitialSyncField); - RegisterClientMessage(GameMsgTypes.OperateSyncList, HandleServerUpdateSyncList); - RegisterClientMessage(GameMsgTypes.ServerSyncBehaviour, HandleServerSyncBehaviour); - RegisterClientMessage(GameMsgTypes.ServerError, HandleServerError); - RegisterClientMessage(GameMsgTypes.ServerSceneChange, HandleServerSceneChange); - RegisterClientMessage(GameMsgTypes.ServerSetObjectOwner, HandleServerSetObjectOwner); - RegisterClientMessage(GameMsgTypes.Ping, HandleServerPing); - RegisterClientMessage(GameMsgTypes.Pong, HandleServerPong); - RegisterClientMessage(GameMsgTypes.Disconnect, HandleServerDisconnect); - } - - public async void KickClient(long connectionId, byte[] data) - { - if (!IsServer) - return; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.Disconnect, (writer) => writer.PutBytesWithLength(data)); - await UniTask.Delay(500); - ServerTransport.ServerDisconnect(connectionId); - } - - public void ResetRtt() - { - _rtt = 0; - _totalRtt = 0; - _rttCount = 0; - } - - public override void OnPeerConnected(long connectionId) - { - base.OnPeerConnected(connectionId); - if (!Players.ContainsKey(connectionId)) - Players.Add(connectionId, new LiteNetLibPlayer(this, connectionId)); - } - - public override void OnPeerDisconnected(long connectionId, DisconnectReason reason, SocketError socketError) - { - base.OnPeerDisconnected(connectionId, reason, socketError); - if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player)) - return; - player.ClearSubscribing(false); - player.DestroyObjectsWhenDisconnect(); - Players.Remove(connectionId); - } - - public override void OnClientConnected() - { - base.OnClientConnected(); - // Reset client connection id, will be received from server later - ClientConnectionId = -1; - ResetRtt(); - if (!doNotEnterGameOnConnect) - SendClientEnterGame(); - } - - public override void OnStartServer() - { - base.OnStartServer(); - // Reset client connection id, will be received from server later - ClientConnectionId = -1; - ResetRtt(); - if (!Assets.onlineScene.IsSet() || Assets.onlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) - { - ServerSceneName = SceneManager.GetActiveScene().name; - Assets.Initialize(); - Assets.SpawnSceneObjects(); - Assets.InitPoolingObjects(); - OnServerOnlineSceneLoaded(); - } - else - { - ServerSceneName = Assets.onlineScene.SceneName; - LoadSceneRoutine(Assets.onlineScene.SceneName, true).Forget(); - } - } - - public override void OnStopServer() - { - base.OnStopServer(); - ServerSceneName = string.Empty; - Players.Clear(); - Assets.Clear(); - if (Assets.offlineScene.IsSet() && !Assets.offlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) - LoadSceneRoutine(Assets.offlineScene.SceneName, false).Forget(); - } - - public override void OnStopClient() - { - base.OnStopClient(); - if (!IsServer) - { - Players.Clear(); - Assets.Clear(); - if (Assets.offlineScene.IsSet() && !Assets.offlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) - LoadSceneRoutine(Assets.offlineScene.SceneName, false).Forget(); - } - } - - #region Send messages functions - public void SendClientEnterGame() - { - if (!IsClientConnected) - return; - ClientSendRequest(GameReqTypes.EnterGame, new EnterGameRequestMessage() - { - packetVersion = PacketVersion(), - }, extraRequestSerializer: SerializeEnterGameData); - } - - public void SendClientReady() - { - if (!IsClientConnected) - return; - ClientSendRequest(GameReqTypes.ClientReady, EmptyMessage.Value, extraRequestSerializer: SerializeClientReadyData); - } - - public void SendClientNotReady() - { - if (!IsClientConnected) - return; - ClientSendRequest(GameReqTypes.ClientNotReady, EmptyMessage.Value); - } - - public void SendClientPing() - { - if (!IsClientConnected) - return; - ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.Ping, new PingMessage() - { - pingTime = Timestamp, - }); - } - - public void SendServerPing() - { - if (!IsServer) - return; - ServerSendPacketToAllConnections(0, DeliveryMethod.Unreliable, GameMsgTypes.Ping, new PingMessage() - { - pingTime = Timestamp, - }); - } - - public bool SendServerSpawnSceneObject(long connectionId, LiteNetLibIdentity identity) - { - if (!IsServer) - return false; - LiteNetLibPlayer player; - if (!Players.TryGetValue(connectionId, out player) || !player.IsReady) - return false; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSpawnSceneObject, new ServerSpawnSceneObjectMessage() - { - objectId = identity.ObjectId, - connectionId = identity.ConnectionId, - position = identity.transform.position, - rotation = identity.transform.rotation, - }, identity.WriteInitSyncFields); - return true; - } - - public bool SendServerSpawnObject(long connectionId, LiteNetLibIdentity identity) - { - if (!IsServer) - return false; - LiteNetLibPlayer player; - if (!Players.TryGetValue(connectionId, out player) || !player.IsReady) - return false; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSpawnObject, new ServerSpawnObjectMessage() - { - hashAssetId = identity.HashAssetId, - objectId = identity.ObjectId, - connectionId = identity.ConnectionId, - position = identity.transform.position, - rotation = identity.transform.rotation, - }, identity.WriteInitSyncFields); - return true; - } - - public void SendServerSpawnObjectWithData(long connectionId, LiteNetLibIdentity identity) - { - if (identity == null) - return; - - bool spawnObjectSent; - if (Assets.ContainsSceneObject(identity.ObjectId)) - spawnObjectSent = SendServerSpawnSceneObject(connectionId, identity); - else - spawnObjectSent = SendServerSpawnObject(connectionId, identity); - if (spawnObjectSent) - { - identity.SendInitSyncFields(connectionId); - identity.SendInitSyncLists(connectionId); - } - } - - public bool SendServerDestroyObject(long connectionId, uint objectId, byte reasons) - { - if (!IsServer) - return false; - if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player) || !player.IsReady) - return false; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerDestroyObject, new ServerDestroyObjectMessage() - { - objectId = objectId, - reasons = reasons, - }); - return true; - } - - public void SendServerError(bool shouldDisconnect, string errorMessage) - { - if (!IsServer) - return; - foreach (long connectionId in Server.ConnectionIds) - { - SendServerError(connectionId, shouldDisconnect, errorMessage); - } - } - - public void SendServerError(long connectionId, bool shouldDisconnect, string errorMessage) - { - if (!IsServer) - return; - if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player) || !player.IsReady) - return; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerDestroyObject, new ServerErrorMessage() - { - shouldDisconnect = shouldDisconnect, - errorMessage = errorMessage, - }); - } - - public void SendServerSceneChange(string sceneName) - { - if (!IsServer) - return; - foreach (long connectionId in Server.ConnectionIds) - { - if (IsClientConnected && connectionId == ClientConnectionId) - continue; - SendServerSceneChange(connectionId, sceneName); - } - } - - public void SendServerSceneChange(long connectionId, string sceneName) - { - if (!IsServer) - return; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSceneChange, new ServerSceneChangeMessage() - { - serverSceneName = sceneName, - }); - } - - public void SendServerSetObjectOwner(long connectionId, uint objectId, long ownerConnectionId) - { - if (!IsServer) - return; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSetObjectOwner, new ServerSetObjectOwner() - { - objectId = objectId, - connectionId = ownerConnectionId, - }); - } - #endregion - - #region Message Handlers - - protected virtual async UniTaskVoid HandleEnterGameRequest( - RequestHandlerData requestHandler, - EnterGameRequestMessage request, - RequestProceedResultDelegate result) - { - AckResponseCode responseCode = AckResponseCode.Error; - EnterGameResponseMessage response = new EnterGameResponseMessage(); - if (request.packetVersion == PacketVersion() && - await DeserializeEnterGameData(requestHandler.ConnectionId, requestHandler.Reader)) - { - responseCode = AckResponseCode.Success; - response.connectionId = requestHandler.ConnectionId; - response.serverSceneName = ServerSceneName; - } - result.Invoke(responseCode, response); - } - - protected virtual void HandleEnterGameResponse( - ResponseHandlerData responseHandler, - AckResponseCode responseCode, - EnterGameResponseMessage response) - { - if (responseCode == AckResponseCode.Success) - { - ClientConnectionId = response.connectionId; - if (IsClientConnected) - HandleServerSceneChange(response.serverSceneName); - } - else - { - if (LogError) Logging.LogError(LogTag, "Enter game request was refused by server, disconnecting..."); - OnClientConnectionRefused(); - } - } - - protected virtual async UniTaskVoid HandleClientReadyRequest( - RequestHandlerData requestHandler, - EmptyMessage request, - RequestProceedResultDelegate result) - { - AckResponseCode responseCode = AckResponseCode.Error; - if (await SetPlayerReady(requestHandler.ConnectionId, requestHandler.Reader)) - { - responseCode = AckResponseCode.Success; - } - result.Invoke(responseCode, EmptyMessage.Value); - } - - protected virtual void HandleClientReadyResponse( - ResponseHandlerData responseHandler, - AckResponseCode responseCode, - EmptyMessage response) - { - // Override this function to do something by response code - } - - protected virtual UniTaskVoid HandleClientNotReadyRequest( - RequestHandlerData requestHandler, - EmptyMessage request, - RequestProceedResultDelegate result) - { - AckResponseCode responseCode = AckResponseCode.Error; - if (SetPlayerNotReady(requestHandler.ConnectionId, requestHandler.Reader)) - { - responseCode = AckResponseCode.Success; - } - result.Invoke(responseCode, EmptyMessage.Value); - return default; - } - - protected void HandleClientNotReadyResponse( - ResponseHandlerData responseHandler, - AckResponseCode responseCode, - EmptyMessage response) - { - // Override this function to do something by response code - } - - protected virtual void HandleClientInitialSyncField(MessageHandlerData messageHandler) - { - // Field updated at owner-client, if this is server then multicast message to other clients - if (!IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - { - LiteNetLibSyncField syncField = identity.GetSyncField(info); - // Sync field at server also have to be client multicast to allow it to multicast to other clients - if (syncField != null && syncField.syncMode == LiteNetLibSyncField.SyncMode.ClientMulticast) - { - // If this is server but it is not host, set data (deserialize) then pass to other clients - // If this is host don't set data because it's already did (in LiteNetLibSyncField class) - if (!identity.IsOwnerClient) - syncField.Deserialize(messageHandler.Reader, true); - // Send to other clients - foreach (long connectionId in Server.ConnectionIds) - { - // Don't send the update to owner client because it was updated before send update to server - if (connectionId == messageHandler.ConnectionId) - continue; - // Send update to clients except owner client - if (identity.HasSubscriberOrIsOwning(connectionId)) - syncField.SendUpdate(true, connectionId); - } - } - } - } - - protected virtual void HandleClientUpdateSyncField(MessageHandlerData messageHandler) - { - // Field updated at owner-client, if this is server then multicast message to other clients - if (!IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - { - LiteNetLibSyncField syncField = identity.GetSyncField(info); - // Sync field at server also have to be client multicast to allow it to multicast to other clients - if (syncField != null && syncField.syncMode == LiteNetLibSyncField.SyncMode.ClientMulticast) - { - // If this is server but it is not host, set data (deserialize) then pass to other clients - // If this is host don't set data because it's already did (in LiteNetLibSyncField class) - if (!identity.IsOwnerClient) - syncField.Deserialize(messageHandler.Reader, false); - // Send to other clients - foreach (long connectionId in Server.ConnectionIds) - { - // Don't send the update to owner client because it was updated before send update to server - if (connectionId == messageHandler.ConnectionId) - continue; - // Send update to clients except owner client - if (identity.HasSubscriberOrIsOwning(connectionId)) - syncField.SendUpdate(false, connectionId); - } - } - } - } - - protected virtual void HandleClientCallFunction(MessageHandlerData messageHandler) - { - FunctionReceivers receivers = (FunctionReceivers)messageHandler.Reader.GetByte(); - long connectionId = -1; - if (receivers == FunctionReceivers.Target) - connectionId = messageHandler.Reader.GetPackedLong(); - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - { - LiteNetLibFunction netFunction = identity.GetNetFunction(info); - if (netFunction == null) - { - // There is no net function that player try to call (player may try to hack) - return; - } - if (!netFunction.CanCallByEveryone && messageHandler.ConnectionId != identity.ConnectionId) - { - // The function not allowed anyone except owner client to call this net function - // And the client is also not the owner client - return; - } - if (receivers == FunctionReceivers.Server) - { - // Request from client to server, so hook callback at server immediately - identity.ProcessNetFunction(netFunction, messageHandler.Reader, true); - } - else - { - // Request from client to other clients, so hook callback later - identity.ProcessNetFunction(netFunction, messageHandler.Reader, false); - // Use call with out parameters set because parameters already set while process net function - if (receivers == FunctionReceivers.Target) - netFunction.CallWithoutParametersSet(connectionId); - else - netFunction.CallWithoutParametersSet(receivers); - } - } - } - - protected virtual void HandleClientSendTransform(MessageHandlerData messageHandler) - { - uint objectId = messageHandler.Reader.GetPackedUInt(); - byte behaviourIndex = messageHandler.Reader.GetByte(); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(objectId, out identity)) - { - LiteNetLibTransform netTransform; - if (identity.TryGetBehaviour(behaviourIndex, out netTransform)) - netTransform.HandleClientSendTransform(messageHandler.Reader); - } - } - - protected void HandleClientPing(MessageHandlerData messageHandler) - { - PingMessage message = messageHandler.ReadMessage(); - ServerSendPacket(messageHandler.ConnectionId, 0, DeliveryMethod.Unreliable, GameMsgTypes.Pong, new PongMessage() - { - pingTime = message.pingTime, - serverTime = Timestamp, - }); - } - - protected void HandleClientPong(MessageHandlerData messageHandler) - { - if (!Players.TryGetValue(messageHandler.ConnectionId, out LiteNetLibPlayer player)) - return; - PongMessage message = messageHandler.ReadMessage(); - if (player.LastPingTime < message.pingTime) - { - player.LastPingTime = message.pingTime; - long rtt = Timestamp - message.pingTime; - if (player.RttCount > 10) - { - player.TotalRtt = player.Rtt; - player.RttCount = 1; - } - player.TotalRtt += rtt; - player.RttCount++; - player.Rtt = player.TotalRtt / player.RttCount; - } - } - - protected virtual void HandleServerSpawnSceneObject(MessageHandlerData messageHandler) - { - ServerSpawnSceneObjectMessage message = messageHandler.ReadMessage(); - if (!IsServer) - Assets.NetworkSpawnScene(message.objectId, message.position, message.rotation, message.connectionId); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(message.objectId, out identity)) - { - // If it is not server, read its initial data - if (!IsServer) - { - identity.ResetSyncData(); - identity.ReadInitSyncFields(messageHandler.Reader); - } - // If it is host, it may hidden so show it - if (IsServer) - identity.OnServerSubscribingAdded(); - } - } - - protected virtual void HandleServerSpawnObject(MessageHandlerData messageHandler) - { - ServerSpawnObjectMessage message = messageHandler.ReadMessage(); - if (!IsServer) - Assets.NetworkSpawn(message.hashAssetId, message.position, message.rotation, message.objectId, message.connectionId); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(message.objectId, out identity)) - { - // If it is not server, read its initial data - if (!IsServer) - identity.ReadInitSyncFields(messageHandler.Reader); - // If it is host, it may hidden so show it - if (IsServer) - identity.OnServerSubscribingAdded(); - } - } - - protected virtual void HandleServerDestroyObject(MessageHandlerData messageHandler) - { - ServerDestroyObjectMessage message = messageHandler.ReadMessage(); - if (!IsServer) - { - Assets.NetworkDestroy(message.objectId, message.reasons); - } - else - { - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(message.objectId, out identity)) - identity.OnServerSubscribingRemoved(); - } - } - - protected virtual void HandleServerInitialSyncField(MessageHandlerData messageHandler) - { - // Field updated at server, if this is host (client and server) then skip it. - if (IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - identity.ProcessSyncField(info, messageHandler.Reader, true); - } - - protected virtual void HandleServerUpdateSyncField(MessageHandlerData messageHandler) - { - // Field updated at server, if this is host (client and server) then skip it. - if (IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - identity.ProcessSyncField(info, messageHandler.Reader, false); - } - - protected virtual void HandleServerCallFunction(MessageHandlerData messageHandler) - { - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - { - // All function from server will be processed (because it's always trust server) - identity.ProcessNetFunction(info, messageHandler.Reader, true); - } - } - - protected virtual void HandleServerUpdateSyncList(MessageHandlerData messageHandler) - { - // List updated at server, if this is host (client and server) then skip it. - if (IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - identity.ProcessSyncList(info, messageHandler.Reader); - } - - protected virtual void HandleServerSyncBehaviour(MessageHandlerData messageHandler) - { - // Behaviour sync from server, if this is host (client and server) then skip it. - if (IsServer) - return; - uint objectId = messageHandler.Reader.GetPackedUInt(); - byte behaviourIndex = messageHandler.Reader.GetByte(); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(objectId, out identity)) - identity.ProcessSyncBehaviour(behaviourIndex, messageHandler.Reader); - } - - protected virtual void HandleServerError(MessageHandlerData messageHandler) - { - // Error sent from server - ServerErrorMessage message = messageHandler.ReadMessage(); - OnServerError(message); - } - - protected virtual void HandleServerSceneChange(MessageHandlerData messageHandler) - { - // Received scene name from server - ServerSceneChangeMessage message = messageHandler.ReadMessage(); - HandleServerSceneChange(message.serverSceneName); - } - - protected void HandleServerSceneChange(string serverSceneName) - { - // Scene loaded at server, if this is host (client and server) then skip it. - if (IsServer) - return; - - if (string.IsNullOrEmpty(serverSceneName) || serverSceneName.Equals(SceneManager.GetActiveScene().name)) - { - Assets.Initialize(); - Assets.InitPoolingObjects(); - OnClientOnlineSceneLoaded(); - SendClientReady(); - } - else - { - // If scene is difference, load changing scene - LoadSceneRoutine(serverSceneName, true).Forget(); - } - } - - protected virtual void HandleServerSetObjectOwner(MessageHandlerData messageHandler) - { - // Object owner was set at server, if this is host (client and server) then skip it. - if (IsServer) - return; - ServerSetObjectOwner message = messageHandler.ReadMessage(); - Assets.SetObjectOwner(message.objectId, message.connectionId); - } - - protected void HandleServerPing(MessageHandlerData messageHandler) - { - PingMessage message = messageHandler.ReadMessage(); - // Send pong back to server (then server will calculates Rtt for this client later) - ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.Pong, new PongMessage() - { - pingTime = message.pingTime, - }); - } - - protected void HandleServerPong(MessageHandlerData messageHandler) - { - PongMessage message = messageHandler.ReadMessage(); - if (_lastPingTime < message.pingTime) - { - _lastPingTime = message.pingTime; - long rtt = Timestamp - message.pingTime; - if (_rttCount > 10) - { - _totalRtt = _rtt; - _rttCount = 1; - } - _totalRtt += rtt; - _rttCount++; - _rtt = _totalRtt / _rttCount; - // Calculate time offsets by device time offsets and RTT - ServerTimestampOffsets = (long)(message.serverTime - Timestamp + (Rtt * 0.5f)); - if (LogDev) Logging.Log(LogTag, "Rtt: " + Rtt + ", ServerTimestampOffsets: " + ServerTimestampOffsets); - } - } - - protected void HandleServerDisconnect(MessageHandlerData messageHandler) - { - Client.SetDisconnectData(messageHandler.Reader.GetBytesWithLength()); - } - #endregion - - /// - /// Overrride this function to send custom data when send enter game message - /// - /// - public virtual void SerializeEnterGameData(NetDataWriter writer) - { - - } - - /// - /// Override this function to read custom data that come with enter game message - /// - /// - /// - /// Return `true` if allow player to enter game. - public virtual async UniTask DeserializeEnterGameData(long connectionId, NetDataReader reader) - { - await UniTask.Yield(); - return true; - } - /// - /// Overrride this function to send custom data when send client ready message - /// - /// - public virtual void SerializeClientReadyData(NetDataWriter writer) - { - - } - - /// - /// Override this function to read custom data that come with client ready message - /// - /// - /// - /// - /// Return `true` if player is ready to play. - public virtual async UniTask DeserializeClientReadyData(LiteNetLibIdentity playerIdentity, long connectionId, NetDataReader reader) - { - await UniTask.Yield(); - return true; - } - - /// - /// Override this function to do anything after online scene loaded at server side - /// - public virtual void OnServerOnlineSceneLoaded() - { - - } - - /// - /// Override this function to do anything after online scene loaded at client side - /// - public virtual void OnClientOnlineSceneLoaded() - { - - } - - /// - /// Override this function to do anything after refused from server - /// - public virtual void OnClientConnectionRefused() - { - StopClient(); - } - - /// - /// Override this function to show error message / disconnect - /// - /// - public virtual void OnServerError(ServerErrorMessage message) - { - if (message.shouldDisconnect && !IsServer) - StopClient(); - } - - public virtual async UniTask SetPlayerReady(long connectionId, NetDataReader reader) - { - if (!IsServer) - return false; - - LiteNetLibPlayer player = Players[connectionId]; - if (player.IsReady) - return false; - player.IsReady = true; - if (!await DeserializeClientReadyData(SpawnPlayer(connectionId), connectionId, reader)) - { - player.IsReady = false; - return false; - } - - return true; - } - - public virtual bool SetPlayerNotReady(long connectionId, NetDataReader reader) - { - if (!IsServer) - return false; - - LiteNetLibPlayer player = Players[connectionId]; - if (!player.IsReady) - return false; - - player.IsReady = false; - player.ClearSubscribing(true); - player.DestroyObjectsWhenNotReady(); - return true; - } - - protected LiteNetLibIdentity SpawnPlayer(long connectionId) - { - if (Assets.PlayerPrefab == null) - return null; - return SpawnPlayer(connectionId, Assets.PlayerPrefab); - } - - protected LiteNetLibIdentity SpawnPlayer(long connectionId, LiteNetLibIdentity prefab) - { - if (prefab == null) - return null; - return SpawnPlayer(connectionId, prefab.HashAssetId); - } - - protected LiteNetLibIdentity SpawnPlayer(long connectionId, int hashAssetId) - { - LiteNetLibIdentity spawnedObject = Assets.NetworkSpawn(hashAssetId, Assets.GetPlayerSpawnPosition(), Quaternion.identity, 0, connectionId); - if (spawnedObject != null) - return spawnedObject; - return null; - } - } -} diff --git a/Scripts/GameApi/LiteNetLibGameManager.cs.meta b/Scripts/GameApi/LiteNetLibGameManager.cs.meta deleted file mode 100644 index 2c97d7d6..00000000 --- a/Scripts/GameApi/LiteNetLibGameManager.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: ea8c7de787d565341b570116d5fa455a -timeCreated: 1508925027 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibIdentity.cs b/Scripts/GameApi/LiteNetLibIdentity.cs deleted file mode 100644 index f7690f7e..00000000 --- a/Scripts/GameApi/LiteNetLibIdentity.cs +++ /dev/null @@ -1,843 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.SceneManagement; -#if UNITY_EDITOR -using UnityEditor; -using UnityEditor.SceneManagement; -#endif -using LiteNetLib.Utils; -using UnityEngine.Events; -using UnityEngine.Profiling; -using UnityEngine.Rendering; - -namespace LiteNetLibManager -{ - [DisallowMultipleComponent] - public sealed class LiteNetLibIdentity : MonoBehaviour - { - public static uint HighestObjectId { get; private set; } - [Tooltip("Asset ID will be hashed to uses as prefab instantiating reference, leave it empty to auto generate asset ID by asset path"), SerializeField] - private string assetId = string.Empty; - [ReadOnly, SerializeField] - private uint objectId = 0; - [Tooltip("If this is <= 0f, it will uses interest manager's `defaultVisibleRange` setting"), SerializeField] - private float visibleRange = 0f; - [Tooltip("If this is `TRUE` it will always visible no matter how far from player's objects"), SerializeField] - private bool alwaysVisible = false; - [Tooltip("If this is `TRUE` it will not destroy this network object when player disconnect the game"), SerializeField] - private bool doNotDestroyWhenDisconnect = false; - [Tooltip("If this is > 0, it will get instance from pooling system"), SerializeField] - private int poolingSize = 0; - - [Header("Events")] - public UnityEvent onGetInstance = new UnityEvent(); - - /// - /// This will be true when identity was spawned by manager - /// - public bool IsSpawned { get; private set; } - /// - /// This will be true when identity was requested to destroy - /// - public bool IsDestroyed { get; private set; } - /// - /// This will be true when identity setup - /// - public bool IsSetupBehaviours { get; private set; } - /// - /// Array of all behaviours - /// - public LiteNetLibBehaviour[] Behaviours { get; private set; } - /// - /// List of sync fields from all behaviours (include children behaviours) - /// - internal readonly List SyncFields = new List(); - /// - /// List of net functions from all behaviours (include children behaviours) - /// - internal readonly List NetFunctions = new List(); - /// - /// List of sync lists from all behaviours (include children behaviours) - /// - internal readonly List SyncLists = new List(); - /// - /// List of sync behaviours - /// - internal readonly List SyncBehaviours = new List(); - /// - /// List of networked objects which subscribed by this identity - /// - internal readonly HashSet Subscribings = new HashSet(); - /// - /// List of players which subscribe this identity - /// - internal readonly HashSet Subscribers = new HashSet(); - - public string AssetId { get { return assetId; } } - private int? hashAssetId; - public int HashAssetId - { - get - { - if (!hashAssetId.HasValue) - { - unchecked - { - int hash1 = 5381; - int hash2 = hash1; - - for (int i = 0; i < AssetId.Length && AssetId[i] != '\0'; i += 2) - { - hash1 = ((hash1 << 5) + hash1) ^ AssetId[i]; - if (i == AssetId.Length - 1 || AssetId[i + 1] == '\0') - break; - hash2 = ((hash2 << 5) + hash2) ^ AssetId[i + 1]; - } - - hashAssetId = hash1 + (hash2 * 1566083941); - } - } - return hashAssetId.Value; - } - } - public uint ObjectId { get { return objectId; } internal set { objectId = value; } } - public float VisibleRange { get { return visibleRange; } set { visibleRange = value; } } - public bool AlwaysVisible { get { return alwaysVisible; } set { alwaysVisible = value; } } - public bool DoNotDestroyWhenDisconnect { get { return doNotDestroyWhenDisconnect; } set { doNotDestroyWhenDisconnect = value; } } - public int PoolingSize { get { return poolingSize; } set { poolingSize = value; } } - public byte DataChannel { get; set; } = 0; - /// - /// If this is `TRUE` it will disallow other connections to subscribe this networked object - /// - public bool IsHide { get; set; } - /// - /// This will be used while `IsHide` is `TRUE` to allow some connections to subscribe this networked object - /// - public HashSet HideExceptions { get; } = new HashSet(); - public long ConnectionId { get; internal set; } = -1; - public bool IsPooledInstance { get; internal set; } = false; - public LiteNetLibGameManager Manager { get; internal set; } - - private string logTag; - public string LogTag - { - get - { - if (string.IsNullOrEmpty(logTag)) - logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; - return logTag; - } - } - - public LiteNetLibPlayer Player - { - get - { - LiteNetLibPlayer foundPlayer; - if (Manager == null || !Manager.TryGetPlayer(ConnectionId, out foundPlayer)) - return null; - return foundPlayer; - } - } - - public bool IsServer - { - get { return Manager != null && Manager.IsServer; } - } - - public bool IsClient - { - get { return Manager != null && Manager.IsClient; } - } - - public bool IsOwnerClient - { - get { return IsClient && Manager.ClientConnectionId >= 0 && ConnectionId >= 0 && Manager.ClientConnectionId == ConnectionId; } - } - - public bool IsHost - { - get { return IsServer && IsOwnerClient; } - } - - public bool IsOwnedByServer - { - get { return IsServer && ConnectionId < 0; } - } - - public bool IsOwnerClientOrOwnedByServer - { - get { return IsOwnerClient || IsOwnedByServer; } - } - - public bool IsSceneObject - { - get; private set; - } - - private float? destroyTime; - - private void FixedUpdate() - { - NetworkUpdate(Time.fixedDeltaTime); - } - - internal void NetworkUpdate(float deltaTime) - { - if (Manager == null || !IsSpawned) - return; - - if (destroyTime.HasValue && Time.fixedTime >= destroyTime.Value) - { - DestroyFromAssets(); - return; - } - - int loopCounter; - Profiler.BeginSample("LiteNetLibIdentity - SyncFields Update"); - for (loopCounter = 0; loopCounter < SyncFields.Count; ++loopCounter) - { - SyncFields[loopCounter].NetworkUpdate(deltaTime); - } - Profiler.EndSample(); - - Profiler.BeginSample("LiteNetLibIdentity - SyncLists Update"); - for (loopCounter = 0; loopCounter < SyncLists.Count; ++loopCounter) - { - SyncLists[loopCounter].SendOperations(); - } - Profiler.EndSample(); - - Profiler.BeginSample("LiteNetLibIdentity - SyncBehaviours Update"); - for (loopCounter = 0; loopCounter < SyncBehaviours.Count; ++loopCounter) - { - SyncBehaviours[loopCounter].NetworkUpdate(deltaTime); - } - Profiler.EndSample(); - } - - #region IDs generate in Editor -#if UNITY_EDITOR - private void OnValidate() - { - Event evt = Event.current; - if (evt != null && evt.commandName == "Duplicate") - { - // Reset asset ID to regenerate it - assetId = string.Empty; - } - SetupIDs(); - } - - [ContextMenu("Reorder Scene Object Id")] - public void ContextMenuReorderSceneObjectId() - { - ReorderSceneObjectId(); - } - - internal void AssignAssetID(GameObject prefab, bool clearAssetId = false) - { - if (clearAssetId) - assetId = string.Empty; - if (!string.IsNullOrEmpty(assetId)) - return; - assetId = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(prefab)); - } - - private bool ThisIsAPrefab() - { -#if UNITY_2018_3_OR_NEWER - return PrefabUtility.IsPartOfPrefabAsset(gameObject); -#else - PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject); - if (prefabType == PrefabType.Prefab) - return true; - return false; -#endif - } - - private bool ThisIsASceneObjectWithThatReferencesPrefabAsset(out GameObject prefab) - { - prefab = null; -#if UNITY_2018_3_OR_NEWER - if (!PrefabUtility.IsPartOfNonAssetPrefabInstance(gameObject)) - return false; -#else - PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject); - if (prefabType == PrefabType.None) - return false; -#endif -#if UNITY_2018_2_OR_NEWER - prefab = PrefabUtility.GetCorrespondingObjectFromSource(gameObject); -#else - prefab = (GameObject)PrefabUtility.GetPrefabParent(gameObject); -#endif - if (prefab == null) - { - Logging.LogError(LogTag, $"Failed to find prefab parent for scene object: {gameObject.name}."); - return false; - } - return true; - } - - internal void SetupIDs() - { - string oldAssetId = assetId; - uint oldObjectId = objectId; - GameObject prefab; - if (ThisIsAPrefab()) - { - // This is a prefab, can create prefab while playing so it will still assign asset ID and reset object ID - AssignAssetID(gameObject); - objectId = 0; - } - else if (ThisIsASceneObjectWithThatReferencesPrefabAsset(out prefab)) - { - if (!Application.isPlaying) - { - // This is a scene object with prefab link - AssignAssetID(prefab); - if (gameObject.scene == SceneManager.GetActiveScene()) - { - // Assign object id if it is in scene - AssignSceneObjectId(); - EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); - } - else - { - // Difference working scene?, clear object Id - objectId = 0; - } - } - } - else - { - if (!Application.isPlaying) - { - // This is a pure scene object (Not a prefab) - assetId = string.Empty; - if (gameObject.scene == SceneManager.GetActiveScene()) - { - // Assign object id if it is in scene - AssignSceneObjectId(); - EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); - } - else - { - // Difference working scene?, clear object Id - objectId = 0; - } - } - } - // Do not mark dirty while playing - if (!Application.isPlaying && (oldAssetId != assetId || oldObjectId != objectId)) - EditorUtility.SetDirty(this); - } -#endif - #endregion - - #region SyncField Functions - internal LiteNetLibSyncField ProcessSyncField(LiteNetLibElementInfo info, NetDataReader reader, bool isInitial) - { - return ProcessSyncField(GetSyncField(info), reader, isInitial); - } - - internal LiteNetLibSyncField ProcessSyncField(LiteNetLibSyncField syncField, NetDataReader reader, bool isInitial) - { - if (syncField == null) - return null; - syncField.Deserialize(reader, isInitial); - return syncField; - } - - internal LiteNetLibSyncField GetSyncField(LiteNetLibElementInfo info) - { - if (info.objectId != ObjectId) - return null; - if (info.elementId >= 0 && info.elementId < SyncFields.Count) - return SyncFields[info.elementId]; - if (Manager.LogError) - Logging.LogError(LogTag, $"Cannot find sync field: {info.elementId}."); - return null; - } - #endregion - - #region NetFunction Functions - internal LiteNetLibFunction ProcessNetFunction(LiteNetLibElementInfo info, NetDataReader reader, bool hookCallback) - { - return ProcessNetFunction(GetNetFunction(info), reader, hookCallback); - } - - internal LiteNetLibFunction ProcessNetFunction(LiteNetLibFunction netFunction, NetDataReader reader, bool hookCallback) - { - if (netFunction == null) - return null; - netFunction.DeserializeParameters(reader); - if (hookCallback) - netFunction.HookCallback(); - return netFunction; - } - - internal LiteNetLibFunction GetNetFunction(LiteNetLibElementInfo info) - { - if (info.objectId != ObjectId) - return null; - if (info.elementId >= 0 && info.elementId < NetFunctions.Count) - return NetFunctions[info.elementId]; - if (Manager.LogError) - Logging.LogError(LogTag, $"Cannot find net function: {info.elementId}."); - return null; - } - #endregion - - #region SyncList Functions - internal LiteNetLibSyncList ProcessSyncList(LiteNetLibElementInfo info, NetDataReader reader) - { - return ProcessSyncList(GetSyncList(info), reader); - } - - internal LiteNetLibSyncList ProcessSyncList(LiteNetLibSyncList syncList, NetDataReader reader) - { - if (syncList == null) - return null; - syncList.ProcessOperations(reader); - return syncList; - } - - internal LiteNetLibSyncList GetSyncList(LiteNetLibElementInfo info) - { - if (info.objectId != ObjectId) - return null; - if (info.elementId >= 0 && info.elementId < SyncLists.Count) - return SyncLists[info.elementId]; - if (Manager.LogError) - Logging.LogError(LogTag, $"Cannot find sync list: {info.elementId}."); - return null; - } - #endregion - - internal LiteNetLibBehaviour ProcessSyncBehaviour(byte behaviourIndex, NetDataReader reader) - { - if (behaviourIndex >= Behaviours.Length) - return null; - LiteNetLibBehaviour behaviour = Behaviours[behaviourIndex]; - behaviour.Deserialize(reader); - return behaviour; - } - - internal bool TryGetBehaviour(byte behaviourIndex, out T behaviour) - where T : LiteNetLibBehaviour - { - behaviour = null; - if (behaviourIndex >= Behaviours.Length) - return false; - behaviour = Behaviours[behaviourIndex] as T; - return behaviour != null; - } - - /// - /// This function will be called when send networked object spawning message, to write sync field data - /// - /// - internal void WriteInitSyncFields(NetDataWriter writer) - { - foreach (LiteNetLibSyncField field in SyncFields) - { - if (field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) - continue; - field.Serialize(writer); - } - } - - /// - /// This function will be called when receive networked object spawning message, to read sync field data - /// - /// - internal void ReadInitSyncFields(NetDataReader reader) - { - foreach (LiteNetLibSyncField field in SyncFields) - { - if (field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) - continue; - field.Deserialize(reader, true); - } - } - - /// - /// This function will be called after networked object spawning message was sent - /// - /// - internal void SendInitSyncFields(long connectionId) - { - foreach (LiteNetLibSyncField field in SyncFields) - { - if (!field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) - continue; - field.SendUpdate(true, connectionId); - } - } - - internal void SendInitSyncLists(long connectionId) - { - foreach (LiteNetLibSyncList list in SyncLists) - { - list.SendInitialList(connectionId); - } - } - - public bool IsSceneObjectExists(uint objectId) - { - if (Manager != null) - { - // If this is spawned while gameplay, find it by manager assets - return Manager.Assets.ContainsSceneObject(objectId); - } - // If this is now spawned while gameplay, find objects in scene - LiteNetLibIdentity[] netObjects = FindObjectsOfType(); - foreach (LiteNetLibIdentity netObject in netObjects) - { - if (netObject.objectId == objectId && netObject != this) - return true; - } - return false; - } - - /// - /// Initial Identity, will be called when spawned. If object id == 0, it will generate new object id - /// - /// - /// - /// - /// - internal void Initial(LiteNetLibGameManager manager, bool isSceneObject, uint objectId = 0, long connectionId = -1) - { - Manager = manager; - ObjectId = objectId; - ConnectionId = connectionId; - UpdateHighestObjectId(objectId); - IsDestroyed = false; - IsSpawned = true; - IsSceneObject = isSceneObject; - if (!IsSceneObject) - AssignSceneObjectId(); - - if (!IsSetupBehaviours) - { - // Setup behaviours index, we will use this as reference for network functions - // NOTE: Maximum network behaviour for a identity is 255 (included children) - Behaviours = GetComponentsInChildren(); - SyncBehaviours.Clear(); - byte loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].Setup(loopCounter); - if (Behaviours[loopCounter].CanSyncBehaviour()) - SyncBehaviours.Add(Behaviours[loopCounter]); - } - IsSetupBehaviours = true; - } - - // If this is host, hide it then will be showned when initialize subscribings - if (IsServer && IsClient) - OnServerSubscribingRemoved(); - - Manager.Assets.SpawnedObjects.Add(ObjectId, this); - if (IsServer && ConnectionId >= 0) - { - Player.SpawnedObjects.Add(ObjectId, this); - Player.Subscribe(ObjectId); - } - - Manager.InterestManager.NotifyNewObject(this); - } - - internal void OnSetOwnerClient(bool isOwnerClient) - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnSetOwnerClient(isOwnerClient); - } - } - - internal void InitTransform(Vector3 position, Quaternion rotation) - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].InitTransform(position, rotation); - } - } - - internal void OnStartServer() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnStartServer(); - } - } - - internal void OnStartClient() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnStartClient(); - } - } - - internal void OnStartOwnerClient() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnStartOwnerClient(); - } - } - - internal void AssignSceneObjectId() - { - if (objectId == 0 || IsSceneObjectExists(objectId)) - objectId = GetNewObjectId(); - } - - internal static void ResetObjectId() - { - HighestObjectId = 0; - } - - internal static uint GetNewObjectId() - { - if (HighestObjectId == 0) - { - uint result = HighestObjectId; - LiteNetLibIdentity[] netObjects = FindObjectsOfType(); - foreach (LiteNetLibIdentity netObject in netObjects) - { - if (netObject.objectId > result) - result = netObject.objectId; - } - HighestObjectId = result; - } - ++HighestObjectId; - return HighestObjectId; - } - - internal static void ReorderSceneObjectId() - { - ResetObjectId(); - LiteNetLibIdentity[] netObjects = FindObjectsOfType(); - foreach (LiteNetLibIdentity netObject in netObjects) - { - netObject.objectId = ++HighestObjectId; -#if UNITY_EDITOR - // Do not mark dirty while playing - if (!Application.isPlaying) - EditorUtility.SetDirty(netObject); -#endif - } -#if UNITY_EDITOR - // Do not mark dirty while playing - if (!Application.isPlaying) - EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); -#endif - } - - internal static void UpdateHighestObjectId(uint objectId) - { - if (objectId > HighestObjectId) - HighestObjectId = objectId; - } - - public bool AddSubscriber(long connectionId) - { - return Subscribers.Add(connectionId); - } - - public bool RemoveSubscriber(long connectionId) - { - return Subscribers.Remove(connectionId); - } - - public bool HasSubscriber(long connectionId) - { - return Subscribers.Contains(connectionId); - } - - public int CountSubscribers() - { - return Subscribers.Count; - } - - public bool HasSubscriberOrIsOwning(long connectionId) - { - return connectionId == ConnectionId || HasSubscriber(connectionId); - } - - public void AddSubscribing(uint subscribing) - { - Subscribings.Add(subscribing); - Player.Subscribe(subscribing); - } - - public void RemoveSubscribing(uint subscribing) - { - Subscribings.Remove(subscribing); - Player.Unsubscribe(subscribing); - } - - public void UpdateSubscribings(HashSet newSubscribings) - { - if (!IsServer || ConnectionId < 0 || !Player.IsReady) - { - // This is not player's networked object - return; - } - // Always add controlled network object to subscribe it - LiteNetLibIdentity tempIdentity; - newSubscribings.Add(ObjectId); - foreach (uint oldSubscribing in Subscribings) - { - if (oldSubscribing == ObjectId) - continue; - if (!newSubscribings.Contains(oldSubscribing)) - { - Player.Unsubscribe(oldSubscribing); - if (Manager.LogDebug) - Logging.Log(LogTag, $"Player: {ConnectionId} unsubscribe object ID: {oldSubscribing}."); - } - } - Subscribings.Clear(); - foreach (uint newSubscribing in newSubscribings) - { - if (!Manager.Assets.TryGetSpawnedObject(newSubscribing, out tempIdentity) || - tempIdentity.IsDestroyed) - continue; - Subscribings.Add(newSubscribing); - Player.Subscribe(newSubscribing); - if (Manager.LogDebug) - Logging.Log(LogTag, $"Player: {ConnectionId} subscribe object ID: {newSubscribing}."); - } - } - - public bool IsHideFrom(LiteNetLibIdentity identity) - { - if (identity == null) - return true; - return IsHide && !HideExceptions.Contains(ConnectionId) && ConnectionId != identity.ConnectionId; - } - - public void OnServerSubscribingAdded() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnServerSubscribingAdded(); - } - if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) - return; - Renderer[] renderers = GetComponentsInChildren(true); - for (int i = 0; i < renderers.Length; ++i) - { - renderers[i].forceRenderingOff = false; - } - } - - public void OnServerSubscribingRemoved() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnServerSubscribingRemoved(); - } - if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) - return; - Renderer[] renderers = GetComponentsInChildren(true); - for (int i = 0; i < renderers.Length; ++i) - { - renderers[i].forceRenderingOff = true; - } - } - - public void SetOwnerClient(long connectionId) - { - if (!IsServer) - return; - - Manager.Assets.SetObjectOwner(ObjectId, connectionId); - } - - public void NetworkDestroy() - { - if (!IsServer) - return; - - DestroyFromAssets(); - } - - public void NetworkDestroy(float delay) - { - if (!IsServer) - return; - destroyTime = Time.fixedTime + delay; - } - - private void DestroyFromAssets() - { - if (!IsDestroyed && Manager.Assets.NetworkDestroy(ObjectId, DestroyObjectReasons.RequestedToDestroy)) - IsDestroyed = true; - destroyTime = null; - } - - internal void OnNetworkDestroy(byte reasons) - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnNetworkDestroy(reasons); - } - if (Manager.IsServer) - { - // If this is server, send message to clients to destroy object - LiteNetLibPlayer player; - foreach (long subscriber in Subscribers) - { - if (Manager.TryGetPlayer(subscriber, out player)) - { - player.Subscribings.Remove(objectId); - Manager.SendServerDestroyObject(subscriber, objectId, reasons); - } - } - // Delete object from owner player's spawned objects collection - if (ConnectionId >= 0) - Player.SpawnedObjects.Remove(ObjectId); - } - // Delete object from assets component - Manager.Assets.SpawnedObjects.Remove(ObjectId); - // Clear data - Subscribings.Clear(); - Subscribers.Clear(); - IsSpawned = false; - } - - internal void OnGetInstance() - { - ResetSyncData(); - onGetInstance.Invoke(); - } - - internal void ResetSyncData() - { - // Clear/reset syncing data - foreach (LiteNetLibSyncField field in SyncFields) - { - field.Reset(); - } - foreach (LiteNetLibSyncList list in SyncLists) - { - list.Reset(); - } - } - } -} diff --git a/Scripts/GameApi/LiteNetLibIdentity.cs.meta b/Scripts/GameApi/LiteNetLibIdentity.cs.meta deleted file mode 100644 index 512f6d9c..00000000 --- a/Scripts/GameApi/LiteNetLibIdentity.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 56367cc2ed44f1e49835e9c247771fd9 -timeCreated: 1508750760 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibPlayer.cs b/Scripts/GameApi/LiteNetLibPlayer.cs deleted file mode 100644 index 400e7a43..00000000 --- a/Scripts/GameApi/LiteNetLibPlayer.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System.Collections.Generic; - -namespace LiteNetLibManager -{ - public class LiteNetLibPlayer - { - public LiteNetLibGameManager Manager { get; protected set; } - public long ConnectionId { get; protected set; } - public bool IsReady { get; set; } - public long Rtt { get; internal set; } - - internal long LastPingTime; - internal long TotalRtt; - internal int RttCount; - internal readonly HashSet Subscribings = new HashSet(); - internal readonly Dictionary SpawnedObjects = new Dictionary(); - - public LiteNetLibPlayer(LiteNetLibGameManager manager, long connectionId) - { - Manager = manager; - ConnectionId = connectionId; - } - - internal bool IsSubscribing(uint objectId) - { - return Subscribings.Contains(objectId); - } - - internal int CountSubscribing() - { - return Subscribings.Count; - } - - internal void Subscribe(uint objectId) - { - LiteNetLibIdentity identity; - if (Subscribings.Add(objectId) && Manager.Assets.TryGetSpawnedObject(objectId, out identity)) - { - identity.AddSubscriber(ConnectionId); - Manager.SendServerSpawnObjectWithData(ConnectionId, identity); - } - } - - internal void Unsubscribe(uint objectId) - { - LiteNetLibIdentity identity; - if (Subscribings.Remove(objectId) && Manager.Assets.TryGetSpawnedObject(objectId, out identity)) - { - identity.RemoveSubscriber(ConnectionId); - Manager.SendServerDestroyObject(ConnectionId, objectId, DestroyObjectReasons.RemovedFromSubscribing); - } - } - - internal void ClearSubscribing(bool destroyObjectsOnPeer) - { - // Remove player's subscribing and remove this player from subscribers - LiteNetLibIdentity identity; - foreach (uint objectId in Subscribings) - { - if (!Manager.Assets.TryGetSpawnedObject(objectId, out identity)) - continue; - identity.RemoveSubscriber(ConnectionId); - if (destroyObjectsOnPeer) - Manager.SendServerDestroyObject(ConnectionId, objectId, DestroyObjectReasons.RemovedFromSubscribing); - } - Subscribings.Clear(); - } - - internal void DestroyObjectsWhenNotReady() - { - List objectIds = new List(SpawnedObjects.Keys); - foreach (uint objectId in objectIds) - Manager.Assets.NetworkDestroy(objectId, DestroyObjectReasons.RequestedToDestroy); - SpawnedObjects.Clear(); - } - - internal void DestroyObjectsWhenDisconnect() - { - List objectIds = new List(SpawnedObjects.Keys); - foreach (uint objectId in objectIds) - { - if (SpawnedObjects[objectId].DoNotDestroyWhenDisconnect) - { - SpawnedObjects[objectId].ConnectionId = -1; - continue; - } - Manager.Assets.NetworkDestroy(objectId, DestroyObjectReasons.RequestedToDestroy); - } - SpawnedObjects.Clear(); - } - - public bool TryGetSpawnedObject(uint objectId, out LiteNetLibIdentity identity) - { - return SpawnedObjects.TryGetValue(objectId, out identity); - } - - public bool ContainsSpawnedObject(uint objectId) - { - return SpawnedObjects.ContainsKey(objectId); - } - - public LiteNetLibIdentity GetSpawnedObject(uint objectId) - { - return SpawnedObjects[objectId]; - } - - public IEnumerable GetSpawnedObjects() - { - return SpawnedObjects.Values; - } - - public IEnumerable GetSubscribingObjectIds() - { - return Subscribings; - } - - public int SpawnedObjectsCount - { - get { return SpawnedObjects.Count; } - } - } -} diff --git a/Scripts/GameApi/LiteNetLibPlayer.cs.meta b/Scripts/GameApi/LiteNetLibPlayer.cs.meta deleted file mode 100644 index 31a4ab3c..00000000 --- a/Scripts/GameApi/LiteNetLibPlayer.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: b905784494aa1194883589d0008336d2 -timeCreated: 1518872995 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibSpawnPoint.cs b/Scripts/GameApi/LiteNetLibSpawnPoint.cs deleted file mode 100644 index 9ba9554a..00000000 --- a/Scripts/GameApi/LiteNetLibSpawnPoint.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace LiteNetLibManager -{ - public class LiteNetLibSpawnPoint : MonoBehaviour - { - [SerializeField] - private float radius = 0f; - - public Transform CacheTransform { get; private set; } - - public Vector3 Position - { - get { return CacheTransform.position; } - } - - private void Awake() - { - CacheTransform = transform; - } - -#if UNITY_EDITOR - private void OnDrawGizmos() - { - Color color = Color.green; - Gizmos.color = color; - Gizmos.DrawWireSphere(transform.position, radius); - color.a = 0.5f; - Gizmos.color = color; - Gizmos.DrawSphere(transform.position, radius); - } -#endif - - public Vector3 GetRandomPosition() - { - Vector3 offsets = Random.insideUnitSphere * radius; - offsets.y = 0; - return Position + offsets; - } - } -} diff --git a/Scripts/GameApi/LiteNetLibSpawnPoint.cs.meta b/Scripts/GameApi/LiteNetLibSpawnPoint.cs.meta deleted file mode 100644 index d1d67a84..00000000 --- a/Scripts/GameApi/LiteNetLibSpawnPoint.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: f2a1f142556b957428162f23ccf49bfd -timeCreated: 1524424716 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibSyncField.cs b/Scripts/GameApi/LiteNetLibSyncField.cs deleted file mode 100644 index 8a615c55..00000000 --- a/Scripts/GameApi/LiteNetLibSyncField.cs +++ /dev/null @@ -1,693 +0,0 @@ -using System; -using UnityEngine; -using LiteNetLib; -using LiteNetLib.Utils; -using System.Reflection; - -namespace LiteNetLibManager -{ - public abstract class LiteNetLibSyncField : LiteNetLibElement - { - protected readonly static NetDataWriter ServerWriter = new NetDataWriter(); - protected readonly static NetDataWriter ClientWriter = new NetDataWriter(); - - public enum SyncMode : byte - { - /// - /// Changes handle by server - /// Will send to connected clients when changes occurs on server - /// - ServerToClients, - /// - /// Changes handle by server - /// Will send to owner-client when changes occurs on server - /// - ServerToOwnerClient, - /// - /// Changes handle by owner-client - /// Will send to server then server multicast to other clients when changes occurs on owner-client - /// - ClientMulticast - } - - [Flags] - public enum SyncBehaviour : byte - { - Default = 0, - AlwaysSync = 1 << 0, - DoNotSyncInitialDataImmediately = 1 << 1, - DoNotSyncUpdate = 1 << 2, - } - - [Header("Generic Settings")] - [Tooltip("How it will sync data. If always sync, it will sync data although it has no changes. If don't sync initial data immediately, it will not sync initial data immdediately with networked object spawning message, it will sync later after spanwed. If don't sync update, it will not sync when data has changes.")] - public SyncBehaviour syncBehaviour; - [Tooltip("Who can sync data and sync to whom")] - public SyncMode syncMode; - [Tooltip("Interval to send networking data")] - [Range(0.01f, 2f)] - public float sendInterval = 0.1f; - - [Header("Server Sync Settings")] - [Tooltip("Sending data channel from server to clients")] - public byte dataChannel = 0; - [Tooltip("Sending method type from server to clients, default is `Sequenced`")] - public DeliveryMethod deliveryMethod = DeliveryMethod.Sequenced; - - [Header("Client Sync Settings (`syncMode` is `ClientMulticast` only)")] - [Tooltip("Sending data channel from clients to server (`syncMode` is `ClientMulticast` only)")] - public byte clientDataChannel = 0; - [Tooltip("Sending method type from clients to server (`syncMode` is `ClientMulticast` only), default is `Sequenced`")] - public DeliveryMethod clientDeliveryMethod = DeliveryMethod.Sequenced; - - private float sendCountDown; - private bool onChangeCalled; - protected object defaultValue; - - public abstract Type GetFieldType(); - public abstract object GetValue(); - public abstract void SetValue(object value); - internal abstract void OnChange(bool initial); - internal abstract bool HasUpdate(); - internal abstract void Updated(); - - public bool HasSyncBehaviourFlag(SyncBehaviour flag) - { - return (syncBehaviour & flag) == flag; - } - - internal void Reset() - { - SetValue(defaultValue); - } - - internal override sealed void Setup(LiteNetLibBehaviour behaviour, int elementId) - { - base.Setup(behaviour, elementId); - defaultValue = GetValue(); - // Invoke on change function with initial state = true - switch (syncMode) - { - case SyncMode.ServerToClients: - case SyncMode.ServerToOwnerClient: - if (IsServer) - OnChange(true); - break; - case SyncMode.ClientMulticast: - if (IsOwnerClient) - OnChange(true); - break; - } - } - - internal void NetworkUpdate(float deltaTime) - { - if (!CanSync()) - return; - - // Won't update - if (HasSyncBehaviourFlag(SyncBehaviour.DoNotSyncUpdate)) - return; - - // No update - if (!HasSyncBehaviourFlag(SyncBehaviour.AlwaysSync) && !HasUpdate()) - return; - - // Call `OnChange` if it's not called yet. - if ((HasSyncBehaviourFlag(SyncBehaviour.AlwaysSync) || HasUpdate()) && !onChangeCalled) - { - // Invoke on change function with initial state = false - switch (syncMode) - { - case SyncMode.ServerToClients: - case SyncMode.ServerToOwnerClient: - if (IsServer) - OnChange(false); - break; - case SyncMode.ClientMulticast: - if (IsOwnerClient) - OnChange(false); - break; - } - onChangeCalled = true; - } - - // It's time to send update? - sendCountDown -= deltaTime; - if (sendCountDown > 0f) - return; - - // Set count down - sendCountDown = sendInterval; - - // Send the update - SendUpdate(false); - - // Update already sent - Updated(); - - // Reset on change called state to call `OnChange` later when has update - onChangeCalled = false; - } - - public void UpdateImmediately() - { - sendCountDown = 0f; - NetworkUpdate(0f); - } - - internal void Deserialize(NetDataReader reader, bool isInitial) - { - DeserializeValue(reader); - OnChange(isInitial); - } - - internal void Serialize(NetDataWriter writer) - { - SerializeValue(writer); - } - - internal virtual void DeserializeValue(NetDataReader reader) - { - SetValue(reader.GetValue(GetFieldType())); - } - - internal virtual void SerializeValue(NetDataWriter writer) - { - writer.PutValue(GetFieldType(), GetValue()); - } - - internal void SendUpdate(bool isInitial, long connectionId) - { - if (!CanSync() || !IsServer) - return; - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ServerWriter); - if (manager.ContainsConnectionId(connectionId)) - server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); - } - - internal void SendUpdate(bool isInitial) - { - if (!CanSync()) - { - Logging.LogError(LogTag, "Error while set value, behaviour is empty"); - return; - } - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - LiteNetLibClient client = manager.Client; - switch (syncMode) - { - case SyncMode.ServerToClients: - TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ServerWriter); - foreach (long connectionId in manager.GetConnectionIds()) - { - if (Identity.HasSubscriberOrIsOwning(connectionId)) - server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); - } - break; - case SyncMode.ServerToOwnerClient: - if (manager.ContainsConnectionId(ConnectionId)) - { - TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ServerWriter); - server.SendMessage(ConnectionId, dataChannel, deliveryMethod, ServerWriter); - } - break; - case SyncMode.ClientMulticast: - if (IsOwnerClient) - { - TransportHandler.WritePacket(ClientWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ClientWriter); - // Client send data to server, then server send to other clients, it should be reliable-ordered - client.SendMessage(clientDataChannel, clientDeliveryMethod, ClientWriter); - } - else if (IsServer) - { - TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ServerWriter); - foreach (long connectionId in manager.GetConnectionIds()) - { - if (Identity.HasSubscriberOrIsOwning(connectionId)) - server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); - } - } - break; - } - } - - private void SerializeForSend(NetDataWriter writer) - { - LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); - Serialize(writer); - } - - public override string ToString() - { - return GetValue().ToString(); - } - } - - public class LiteNetLibSyncFieldContainer : LiteNetLibSyncField - { - /// - /// The field which going to sync its value - /// - private FieldInfo field; - - /// - /// The class which contain the field - /// - private object instance; - - /// - /// Use this variable to tell that it has to update after value changed - /// - private bool hasUpdate; - - /// - /// This method will be invoked after value changed - /// - private MethodInfo onChangeMethod; - - /// - /// This method will be invoked after data sent - /// - private MethodInfo onUpdateMethod; - - /// - /// Use this value to check field's value changes - /// - private object value; - - public LiteNetLibSyncFieldContainer(FieldInfo field, object instance, MethodInfo onChangeMethod, MethodInfo onUpdateMethod) - { - this.field = field; - this.instance = instance; - this.onChangeMethod = onChangeMethod; - this.onUpdateMethod = onUpdateMethod; - value = field.GetValue(instance); - } - - public override sealed Type GetFieldType() - { - return field.FieldType; - } - - public override sealed object GetValue() - { - return field.GetValue(instance); - } - - public override sealed void SetValue(object value) - { - field.SetValue(instance, value); - } - - internal override sealed bool HasUpdate() - { - if (hasUpdate) - return true; - - if (value == null || !value.Equals(field.GetValue(instance))) - { - // Set value because it's going to sync later - value = field.GetValue(instance); - // Set `hasUpdate` to `TRUE` this value will turn to `FALSE` when `Updated()` called - hasUpdate = true; - } - - return hasUpdate; - } - - internal override void Updated() - { - if (onUpdateMethod != null) - onUpdateMethod.Invoke(instance, new object[0]); - hasUpdate = false; - } - - internal override sealed void OnChange(bool initial) - { - if (onChangeMethod != null) - onChangeMethod.Invoke(instance, new object[] { GetValue() }); - } - } - - public class LiteNetLibSyncField : LiteNetLibSyncField - { - public delegate void OnChangeDelegate(bool initial, TType value); - public delegate void OnUpdatedDelegate(); - /// - /// Action with initial state and value, this will be invoked after data changed - /// - public OnChangeDelegate onChange; - - /// - /// This will be invoked after data sent - /// - public OnUpdatedDelegate onUpdated; - - /// - /// Use this variable to tell that it has to update after value changed - /// - protected bool hasUpdate; - - [SerializeField] - protected TType value; - public TType Value - { - get { return value; } - set - { - if (IsValueChanged(value)) - { - this.value = value; - if (CanSync()) - hasUpdate = true; - } - } - } - - protected virtual bool IsValueChanged(TType newValue) - { - return value == null || !value.Equals(newValue); - } - - internal override bool HasUpdate() - { - return hasUpdate; - } - - internal override void Updated() - { - if (onUpdated != null) - onUpdated.Invoke(); - hasUpdate = false; - } - - public override sealed Type GetFieldType() - { - return typeof(TType); - } - - public override sealed object GetValue() - { - return Value; - } - - public override sealed void SetValue(object value) - { - Value = (TType)value; - } - - internal override sealed void OnChange(bool initial) - { - if (onChange != null) - onChange.Invoke(initial, Value); - } - - public static implicit operator TType(LiteNetLibSyncField field) - { - return field.Value; - } - } - - [Serializable] - public class SyncFieldArray : LiteNetLibSyncField - { - public TType this[int i] - { - get { return Value[i]; } - set - { - Value[i] = value; - hasUpdate = true; - } - } - - internal override void DeserializeValue(NetDataReader reader) - { - Value = reader.GetArray(); - } - - internal override void SerializeValue(NetDataWriter writer) - { - writer.PutArray(Value); - } - - public int Length { get { return Value.Length; } } - } - - #region Implement for general usages and serializable - [Serializable] - public class SyncFieldBool : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldBoolArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldByte : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldByteArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldChar : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldDouble : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldDoubleArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldFloat : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldFloatArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldInt : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldIntArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldLong : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldLongArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldSByte : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldShort : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldShortArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldString : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldUInt : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldUIntArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldULong : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldULongArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldUShort : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldUShortArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldColor : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldQuaternion : LiteNetLibSyncField - { - [Tooltip("If angle between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeAngle = 1f; - - protected override bool IsValueChanged(Quaternion newValue) - { - return Quaternion.Angle(value, newValue) >= valueChangeAngle; - } - } - - [Serializable] - public class SyncFieldVector2 : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector2 newValue) - { - return Vector2.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - public class SyncFieldVector2Int : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector2Int newValue) - { - return Vector2Int.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - public class SyncFieldVector3 : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector3 newValue) - { - return Vector3.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - public class SyncFieldVector3Int : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector3Int newValue) - { - return Vector3Int.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - public class SyncFieldVector4 : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector4 newValue) - { - return Vector4.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedUShort : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedUInt : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedULong : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedShort : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedInt : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedLong : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldDirectionVector2 : LiteNetLibSyncField - { - protected override bool IsValueChanged(DirectionVector2 newValue) - { - return Value.x != newValue.x || Value.y != newValue.y; - } - } - - [Serializable] - public class SyncFieldDirectionVector3 : LiteNetLibSyncField - { - protected override bool IsValueChanged(DirectionVector3 newValue) - { - return Value.x != newValue.x || Value.y != newValue.y || Value.z != newValue.z; - } - } - #endregion -} diff --git a/Scripts/GameApi/LiteNetLibSyncField.cs.meta b/Scripts/GameApi/LiteNetLibSyncField.cs.meta deleted file mode 100644 index cd10b767..00000000 --- a/Scripts/GameApi/LiteNetLibSyncField.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: f13e8093d1ab8fd42ac6c519c60b1f30 -timeCreated: 1508947932 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibSyncList.cs b/Scripts/GameApi/LiteNetLibSyncList.cs deleted file mode 100644 index f5f163b9..00000000 --- a/Scripts/GameApi/LiteNetLibSyncList.cs +++ /dev/null @@ -1,609 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using LiteNetLib; -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public abstract partial class LiteNetLibSyncList : LiteNetLibElement - { - protected readonly static NetDataWriter Writer = new NetDataWriter(); - - public partial struct Operation - { - public const byte Add = 0; - public const byte Clear = 1; - public const byte Insert = 2; - public const byte RemoveAt = 3; - public const byte Set = 4; - public const byte Dirty = 5; - public const byte RemoveFirst = 6; - public const byte RemoveLast = 7; - public const byte AddInitial = 8; - - public Operation(byte value) - { - Value = value; - } - - public byte Value { get; private set; } - - public static implicit operator byte(Operation operation) - { - return operation.Value; - } - - public static implicit operator Operation(byte value) - { - return new Operation(value); - } - } - - public delegate void OnOperationDelegate(Operation op, int itemIndex); - - [Tooltip("Sending data channel")] - public byte dataChannel = 0; - [Tooltip("If this is `TRUE`, this will update to owner client only, default is `FALSE`")] - public bool forOwnerOnly = false; - public OnOperationDelegate onOperation; - - public abstract Type FieldType { get; } - public abstract int Count { get; } - internal abstract void Reset(); - internal abstract void SendInitialList(long connectionId); - internal abstract void SendOperations(); - internal abstract void ProcessOperations(NetDataReader reader); - - protected override bool CanSync() - { - return IsServer; - } - - internal override sealed void Setup(LiteNetLibBehaviour behaviour, int elementId) - { - base.Setup(behaviour, elementId); - if (Count > 0 && onOperation != null) - { - for (int i = 0; i < Count; ++i) - { - onOperation.Invoke(Operation.AddInitial, i); - } - } - } - } - - public class LiteNetLibSyncList : LiteNetLibSyncList, IList - { - protected struct OperationEntry - { - public Operation operation; - public int index; - public TType data; - public int count; - } - - protected readonly List list = new List(); - protected readonly List operationEntries = new List(); - - public TType this[int index] - { - get { return list[index]; } - set - { - if (IsSetup && !IsServer) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - list[index] = value; - PrepareOperation(Operation.Set, index); - } - } - - public override sealed Type FieldType - { - get { return typeof(TType); } - } - - public override sealed int Count - { - get { return list.Count; } - } - - public bool IsReadOnly - { - get { return false; } - } - - public TType Get(int index) - { - return this[index]; - } - - public void Set(int index, TType value) - { - this[index] = value; - } - - public void Add(TType item) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - int index = list.Count; - list.Add(item); - PrepareOperation(Operation.Add, index); - } - - public void AddRange(IEnumerable collection) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - foreach (TType item in collection) - { - Add(item); - } - } - - public void Insert(int index, TType item) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - list.Insert(index, item); - PrepareOperation(Operation.Insert, index); - } - - public bool Contains(TType item) - { - return list.Contains(item); - } - - public int IndexOf(TType item) - { - return list.IndexOf(item); - } - - public bool Remove(TType value) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return false; - } - int index = IndexOf(value); - if (index >= 0) - { - RemoveAt(index); - return true; - } - return false; - } - - public void RemoveAt(int index) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - if (index == 0) - { - list.RemoveAt(index); - PrepareOperation(Operation.RemoveFirst, 0); - } - else if (index == list.Count - 1) - { - list.RemoveAt(index); - PrepareOperation(Operation.RemoveLast, index); - } - else - { - list.RemoveAt(index); - PrepareOperation(Operation.RemoveAt, index); - } - } - - public void Clear() - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - list.Clear(); - PrepareOperation(Operation.Clear, -1); - } - - public void CopyTo(TType[] array, int arrayIndex) - { - list.CopyTo(array, arrayIndex); - } - - public IEnumerator GetEnumerator() - { - return list.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return list.GetEnumerator(); - } - - public void Dirty(int index) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - PrepareOperation(Operation.Dirty, index); - } - - internal override sealed void Reset() - { - list.Clear(); - operationEntries.Clear(); - } - - protected void PrepareOperation(Operation operation, int index) - { - OnOperation(operation, index); - PrepareOperation(operationEntries, operation, index); - } - - protected void PrepareOperation(List operationEntries, Operation operation, int index) - { - switch (operation) - { - case Operation.Clear: - operationEntries.Add(new OperationEntry() - { - operation = operation, - index = index, - count = 0, - }); - break; - case Operation.RemoveAt: - case Operation.RemoveFirst: - case Operation.RemoveLast: - operationEntries.Add(new OperationEntry() - { - operation = operation, - index = index, - count = 1, - }); - break; - default: - operationEntries.Add(new OperationEntry() - { - operation = operation, - index = index, - data = list[index], - count = 1, - }); - break; - } - } - - internal override sealed void SendInitialList(long connectionId) - { - if (!CanSync()) - return; - List addInitialOperationEntries = new List(); - for (int i = 0; i < Count; ++i) - { - if (!ContainsAddOperation(i)) - PrepareOperation(addInitialOperationEntries, Operation.AddInitial, i); - } - LiteNetLibServer server = Manager.Server; - TransportHandler.WritePacket(Writer, GameMsgTypes.OperateSyncList); - SerializeForSendOperations(Writer, addInitialOperationEntries); - server.SendMessage(connectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); - } - - private bool ContainsAddOperation(int index) - { - for (int i = 0; i < operationEntries.Count; ++i) - { - if (operationEntries[i].operation == Operation.Add && operationEntries[i].index == index) - return true; - } - return false; - } - - internal override sealed void SendOperations() - { - if (operationEntries.Count <= 0 || !CanSync()) - return; - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - TransportHandler.WritePacket(Writer, GameMsgTypes.OperateSyncList); - SerializeForSendOperations(Writer, operationEntries); - operationEntries.Clear(); - if (forOwnerOnly) - { - if (manager.ContainsConnectionId(ConnectionId)) - server.SendMessage(ConnectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); - } - else - { - foreach (long connectionId in manager.GetConnectionIds()) - { - if (Identity.HasSubscriberOrIsOwning(connectionId)) - server.SendMessage(connectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); - } - } - } - - internal override sealed void ProcessOperations(NetDataReader reader) - { - int operationCount = reader.GetPackedInt(); - for (int i = 0; i < operationCount; ++i) - { - DeserializeOperation(reader); - } - } - - protected void SerializeForSendOperations(NetDataWriter writer, List operationEntries) - { - LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); - writer.PutPackedInt(operationEntries.Count); - for (int i = 0; i < operationEntries.Count; ++i) - { - SerializeOperation(writer, operationEntries[i]); - } - } - - protected void DeserializeOperation(NetDataReader reader) - { - Operation operation = reader.GetByte(); - int index = -1; - TType item; - switch (operation) - { - case Operation.Add: - case Operation.AddInitial: - item = DeserializeValueForAddOrInsert(index, reader); - index = list.Count; - list.Add(item); - break; - case Operation.Insert: - index = reader.GetInt(); - item = DeserializeValueForAddOrInsert(index, reader); - list.Insert(index, item); - break; - case Operation.Set: - case Operation.Dirty: - index = reader.GetInt(); - item = DeserializeValueForSetOrDirty(index, reader); - list[index] = item; - break; - case Operation.RemoveAt: - index = reader.GetInt(); - list.RemoveAt(index); - break; - case Operation.RemoveFirst: - index = 0; - list.RemoveAt(index); - break; - case Operation.RemoveLast: - index = list.Count - 1; - list.RemoveAt(index); - break; - case Operation.Clear: - list.Clear(); - break; - default: - index = reader.GetInt(); - item = DeserializeValueForCustomDirty(index, operation, reader); - list[index] = item; - break; - } - OnOperation(operation, index); - } - - protected void SerializeOperation(NetDataWriter writer, OperationEntry entry) - { - writer.Put((byte)entry.operation); - switch (entry.operation) - { - case Operation.Add: - case Operation.AddInitial: - SerializeValueForAddOrInsert(entry.index, writer, entry.data); - break; - case Operation.Insert: - writer.Put(entry.index); - SerializeValueForAddOrInsert(entry.index, writer, entry.data); - break; - case Operation.Set: - case Operation.Dirty: - writer.Put(entry.index); - SerializeValueForSetOrDirty(entry.index, writer, entry.data); - break; - case Operation.RemoveAt: - writer.Put(entry.index); - break; - case Operation.RemoveFirst: - case Operation.RemoveLast: - case Operation.Clear: - break; - default: - writer.Put(entry.index); - SerializeValueForCustomDirty(entry.index, entry.operation, writer, entry.data); - break; - } - } - - protected virtual TType DeserializeValue(NetDataReader reader) - { - return reader.GetValue(); - } - - protected virtual void SerializeValue(NetDataWriter writer, TType value) - { - writer.PutValue(value); - } - - protected virtual TType DeserializeValueForAddOrInsert(int index, NetDataReader reader) - { - return DeserializeValue(reader); - } - - protected virtual void SerializeValueForAddOrInsert(int index, NetDataWriter writer, TType value) - { - SerializeValue(writer, value); - } - - protected virtual TType DeserializeValueForSetOrDirty(int index, NetDataReader reader) - { - return DeserializeValue(reader); - } - - protected virtual void SerializeValueForSetOrDirty(int index, NetDataWriter writer, TType value) - { - SerializeValue(writer, value); - } - - protected virtual void SerializeValueForCustomDirty(int index, byte customOperation, NetDataWriter writer, TType value) - { - SerializeValue(writer, value); - } - - protected virtual TType DeserializeValueForCustomDirty(int index, byte customOperation, NetDataReader reader) - { - return DeserializeValue(reader); - } - - protected void OnOperation(Operation operation, int index) - { - if (onOperation != null) - onOperation.Invoke(operation, index); - } - } - - #region Implement for general usages and serializable - // Generics - - [Serializable] - public class SyncListBool : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListByte : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListChar : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListDouble : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListFloat : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListInt : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListLong : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListSByte : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListShort : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListString : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListUInt : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListULong : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListUShort : LiteNetLibSyncList - { - } - - // Unity - - [Serializable] - public class SyncListColor : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListQuaternion : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector2 : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector2Int : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector3 : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector3Int : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector4 : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListDirectionVector2 : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListDirectionVector3 : LiteNetLibSyncList - { - } - #endregion -} diff --git a/Scripts/GameApi/LiteNetLibSyncList.cs.meta b/Scripts/GameApi/LiteNetLibSyncList.cs.meta deleted file mode 100644 index e9e0e82b..00000000 --- a/Scripts/GameApi/LiteNetLibSyncList.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: d5fb20391be68d949b2b768c055e3c15 -timeCreated: 1511713954 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibTransform.cs b/Scripts/GameApi/LiteNetLibTransform.cs deleted file mode 100644 index 52333f01..00000000 --- a/Scripts/GameApi/LiteNetLibTransform.cs +++ /dev/null @@ -1,521 +0,0 @@ -using LiteNetLib; -using LiteNetLib.Utils; -using UnityEngine; -using UnityEngine.AI; - -namespace LiteNetLibManager -{ - public class LiteNetLibTransform : LiteNetLibBehaviour - { - private struct TransformResult - { - public Vector3 position; - public Quaternion rotation; - public float timestamp; - } - - public enum SyncPositionOptions - { - Sync, - NotSync, - } - - public enum SyncRotationOptions - { - Sync, - NotSync, - CompressToUShort, - CompressToByte, - } - - public enum InterpolateMode - { - EstimatedSpeed, - FixedSpeed, - } - - public enum ExtrapolateMode - { - None, - EstimatedSpeed, - FixedSpeed, - } - - [Tooltip("Which transform you are going to sync, if it is empty it will use transform which this component attached to")] - public Transform syncingTransform; - [Tooltip("If this is TRUE, transform data will be sent from owner client to server to update to another clients")] - public bool ownerClientCanSendTransform; - [Tooltip("This will be used when `ownerClientCanSendTransform` is set to TRUE to send transform update from client to server")] - [Range(0.01f, 2f)] - public float ownerClientSendInterval = 0.1f; - public float snapThreshold = 5.0f; - public InterpolateMode interpolateMode = InterpolateMode.EstimatedSpeed; - public float fixedInterpolateSpeed; - public ExtrapolateMode extrapolateMode = ExtrapolateMode.None; - public float fixedExtrapolateSpeed; - [Header("Sync Position Settings")] - public SyncPositionOptions syncPositionX; - public SyncPositionOptions syncPositionY; - public SyncPositionOptions syncPositionZ; - [Header("Sync Rotation Settings")] - public SyncRotationOptions syncRotationX; - public SyncRotationOptions syncRotationY; - public SyncRotationOptions syncRotationZ; - - public System.Action onTeleport; - - #region Cache components - public NavMeshAgent CacheNavMeshAgent { get; private set; } - public Rigidbody CacheRigidbody3D { get; private set; } - public Rigidbody2D CacheRigidbody2D { get; private set; } - public CharacterController CacheCharacterController { get; private set; } - #endregion - - private bool syncingTransformIsIdentity; - // Interpolation related variables - private float ownerSendElapsed = 0f; - private float lastReceivedTime = 0f; - private float lastReceivedTimestamp = 0f; - private TransformResult currentInterpResult; - private TransformResult previousEndInterpResult; - private TransformResult endInterpResult; - - private void Awake() - { - if (syncingTransform == null) - syncingTransform = transform; - // Nav mesh agent is highest priority, then character controller - // Then Rigidbodies, that both 3d/2d are same priority - CacheNavMeshAgent = syncingTransform.GetComponent(); - if (CacheNavMeshAgent == null) - { - CacheCharacterController = syncingTransform.GetComponent(); - if (CacheCharacterController == null) - { - CacheRigidbody3D = syncingTransform.GetComponent(); - CacheRigidbody2D = syncingTransform.GetComponent(); - } - } - sendOptions = DeliveryMethod.Unreliable; - } - - private void OnValidate() - { - // Force set to `Unreliable` - sendOptions = DeliveryMethod.Unreliable; - } - - private void OnEnable() - { - InitInterpResults(syncingTransform.position, syncingTransform.rotation); - } - - public override void OnSetOwnerClient(bool isOwnerClient) - { - InitInterpResults(syncingTransform.position, syncingTransform.rotation); - } - - public override void InitTransform(Vector3 position, Quaternion rotation) - { - if (syncingTransformIsIdentity) - { - InitInterpResults(position, rotation); - Snap(position, rotation); - } - } - - private void InitInterpResults(Vector3 position, Quaternion rotation) - { - currentInterpResult = new TransformResult(); - currentInterpResult.position = position; - currentInterpResult.rotation = rotation; - currentInterpResult.timestamp = GetTimeStamp(); - previousEndInterpResult = currentInterpResult; - endInterpResult = currentInterpResult; - } - - public override void OnSetup() - { - base.OnSetup(); - RegisterNetFunction(NetFunction_Teleport); - if (syncingTransform == null) - syncingTransform = transform; - syncingTransformIsIdentity = syncingTransform == Identity.transform; - } - - private void NetFunction_Teleport(Vector3 position, Quaternion rotation) - { - InitInterpResults(position, rotation); - Snap(position, rotation); - if (onTeleport != null) - onTeleport.Invoke(position, rotation); - } - - /// - /// This function will be called at server after receive transform from clients - /// to interpolate and sync position to other clients - /// - /// - internal void HandleClientSendTransform(NetDataReader reader) - { - // Don't update transform follow client's request - // if not set "ownerClientCanSendTransform" to `TRUE` - // or it's this is owned by host - if (!ownerClientCanSendTransform || IsOwnerClient) - return; - TransformResult result = DeserializeResult(reader); - // Discard out of order results - if (result.timestamp <= lastReceivedTimestamp) - return; - lastReceivedTime = Time.fixedTime; - lastReceivedTimestamp = result.timestamp; - result.timestamp = GetTimeStamp(); - previousEndInterpResult = endInterpResult; - endInterpResult = result; - } - - /// - /// This function will be called at client to send transform - /// - /// - private void ClientSendTransform(TransformResult transformResult) - { - // Don't request to set transform if not set "canClientSendResult" to TRUE - if (!ownerClientCanSendTransform || !IsOwnerClient) - return; - Manager.ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.ClientSendTransform, (writer) => ClientSendTransformWriter(writer, transformResult)); - } - - private void ClientSendTransformWriter(NetDataWriter writer, TransformResult transformResult) - { - writer.PutPackedUInt(ObjectId); - writer.Put(BehaviourIndex); - SerializePositionAxis(writer, transformResult.position.x, syncPositionX); - SerializePositionAxis(writer, transformResult.position.y, syncPositionY); - SerializePositionAxis(writer, transformResult.position.z, syncPositionZ); - SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.x, syncRotationX); - SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.y, syncRotationY); - SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.z, syncRotationZ); - writer.Put(GetTimeStamp()); - } - - public void Teleport(Vector3 position, Quaternion rotation) - { - if (IsServer || (ownerClientCanSendTransform && IsOwnerClient)) - { - InitInterpResults(position, rotation); - Snap(position, rotation); - // This function can be called before networked object spawned - // to set initial object transform, so it won't be able to call net function yet. - // So have to avoid net function calling by check is behaviours already setup or not. - if (Identity.IsSetupBehaviours) - CallNetFunction(NetFunction_Teleport, FunctionReceivers.All, position, rotation); - } - } - - public override bool CanSyncBehaviour() - { - return true; - } - - public override bool ShouldSyncBehaviour() - { - return true; - } - - public override void OnSerialize(NetDataWriter writer) - { - SerializePositionAxis(writer, syncingTransform.position.x, syncPositionX); - SerializePositionAxis(writer, syncingTransform.position.y, syncPositionY); - SerializePositionAxis(writer, syncingTransform.position.z, syncPositionZ); - SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.x, syncRotationX); - SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.y, syncRotationY); - SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.z, syncRotationZ); - writer.Put(GetTimeStamp()); - } - - public override void OnDeserialize(NetDataReader reader) - { - // Update transform only non-owner client - if ((ownerClientCanSendTransform && IsOwnerClient) || IsServer) - return; - TransformResult result = DeserializeResult(reader); - // Discard out of order results - if (result.timestamp <= lastReceivedTimestamp) - return; - lastReceivedTime = Time.fixedTime; - lastReceivedTimestamp = result.timestamp; - result.timestamp = GetTimeStamp(); - previousEndInterpResult = endInterpResult; - endInterpResult = result; - } - - private TransformResult DeserializeResult(NetDataReader reader) - { - TransformResult result = new TransformResult(); - result.position = new Vector3( - DeserializePositionAxis(reader, syncPositionX, syncingTransform.position.x), - DeserializePositionAxis(reader, syncPositionY, syncingTransform.position.y), - DeserializePositionAxis(reader, syncPositionZ, syncingTransform.position.z)); - result.rotation = Quaternion.Euler( - DeserializeRotationAxis(reader, syncRotationX, syncingTransform.rotation.eulerAngles.x), - DeserializeRotationAxis(reader, syncRotationY, syncingTransform.rotation.eulerAngles.y), - DeserializeRotationAxis(reader, syncRotationZ, syncingTransform.rotation.eulerAngles.z)); - result.timestamp = reader.GetFloat(); - return result; - } - - private void SerializePositionAxis(NetDataWriter writer, float data, SyncPositionOptions syncOptions) - { - switch (syncOptions) - { - case SyncPositionOptions.Sync: - writer.Put(data); - break; - default: - case SyncPositionOptions.NotSync: - break; - } - } - - private void SerializeRotationAxis(NetDataWriter writer, float data, SyncRotationOptions syncOptions) - { - data = To360Angle(data); - switch (syncOptions) - { - case SyncRotationOptions.Sync: - writer.Put(data); - break; - case SyncRotationOptions.CompressToUShort: - writer.Put((ushort)(data * 100)); - break; - case SyncRotationOptions.CompressToByte: - writer.Put((byte)(data / 360f * 100)); - break; - default: - case SyncRotationOptions.NotSync: - break; - } - } - - private float DeserializePositionAxis(NetDataReader reader, SyncPositionOptions syncOptions, float defaultValue) - { - switch (syncOptions) - { - case SyncPositionOptions.Sync: - return reader.GetFloat(); - default: - case SyncPositionOptions.NotSync: - break; - } - return defaultValue; - } - - private float DeserializeRotationAxis(NetDataReader reader, SyncRotationOptions syncOptions, float defaultValue) - { - switch (syncOptions) - { - case SyncRotationOptions.Sync: - return reader.GetFloat(); - case SyncRotationOptions.CompressToUShort: - return (float)reader.GetUShort() * 0.01f; - case SyncRotationOptions.CompressToByte: - return (float)reader.GetByte() * 0.01f * 360f; - default: - case SyncRotationOptions.NotSync: - break; - } - return defaultValue; - } - - private void Update() - { - if (!IsServer && !IsClient) - return; - // Sending transform to all clients - if (IsServer) - { - // Interpolate transform that receives from clients - // So if this is no owning client (ConnectionId < 0), it won't interpolate - if (ownerClientCanSendTransform && !IsOwnerClient && ConnectionId >= 0) - UpdateTransform(Time.deltaTime); - } - // Interpolating results for non-owner client objects on clients - else if (!ownerClientCanSendTransform || !IsOwnerClient) - { - UpdateTransform(Time.deltaTime); - } - } - - private void FixedUpdate() - { - if (!IsServer && !IsClient) - return; - // Sending client transform result to server - // Don't send to server if it's server which already update transform result - // So only owner client can send transform result to server - if (ownerClientCanSendTransform && IsOwnerClient && !IsServer) - { - ownerSendElapsed += Time.fixedDeltaTime; - if (ownerSendElapsed >= ownerClientSendInterval) - { - // Send transform to server only when there are changes on transform - ClientSendTransform(new TransformResult() - { - position = syncingTransform.position, - rotation = syncingTransform.rotation, - timestamp = GetTimeStamp(), - }); - ownerSendElapsed = 0; - } - } - } - - private void UpdateTransform(float deltaTime) - { - if (ShouldSnap(endInterpResult.position)) - { - currentInterpResult.position = endInterpResult.position; - currentInterpResult.rotation = endInterpResult.rotation; - Snap(endInterpResult.position, endInterpResult.rotation); - } - else - { - if (IsOwnerClient && ownerClientCanSendTransform) - { - // If owner client can send transform, it won't interpolating transform at owner client - return; - } - // Calculate move speed by distance and time - float dist = Vector3.Distance(endInterpResult.position, previousEndInterpResult.position); - float timeDiff = endInterpResult.timestamp - previousEndInterpResult.timestamp; - float moveSpeed = 0f; - if (timeDiff > 0f) - moveSpeed = dist / timeDiff; - // Find extrapolated move by move direction, time passed (which calculated by current time and last received time) - // and calculate move speed or fixed extrapolate speed - Vector3 extrapolatedMove = Vector3.zero; - if (extrapolateMode != ExtrapolateMode.None) - { - float timePassed = Time.fixedTime - lastReceivedTime; - Vector3 moveDirection = (endInterpResult.position - previousEndInterpResult.position).normalized; - if (moveDirection.sqrMagnitude > 0f && timePassed > 0f) - { - switch (extrapolateMode) - { - case ExtrapolateMode.EstimatedSpeed: - extrapolatedMove = moveDirection * moveSpeed * timePassed; - break; - case ExtrapolateMode.FixedSpeed: - extrapolatedMove = moveDirection * fixedExtrapolateSpeed * timePassed; - break; - } - } - } - // Set interpolate move speed to fixed value if interpolate mode is fixed speed - if (interpolateMode == InterpolateMode.FixedSpeed) - moveSpeed = fixedInterpolateSpeed; - // Move it - currentInterpResult.position = Vector3.MoveTowards(currentInterpResult.position, endInterpResult.position + extrapolatedMove, moveSpeed * deltaTime); - currentInterpResult.rotation = Quaternion.Slerp(currentInterpResult.rotation, endInterpResult.rotation, (1f / timeDiff) * deltaTime); - Interpolate(currentInterpResult.position, currentInterpResult.rotation); - } - } - - private bool ShouldSnap(Vector3 targetPosition) - { - float dist; - if (CacheRigidbody2D != null) - dist = (CacheRigidbody2D.position - new Vector2(targetPosition.x, targetPosition.y)).sqrMagnitude; - else - dist = (syncingTransform.position - targetPosition).sqrMagnitude; - return dist > snapThreshold * snapThreshold; - } - - private void Snap(Vector3 position, Quaternion rotation) - { - if (CacheNavMeshAgent != null) - { - CacheNavMeshAgent.Warp(position); - syncingTransform.rotation = rotation; - } - else if (CacheRigidbody3D != null && !CacheRigidbody3D.isKinematic) - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - CacheRigidbody3D.position = position; - CacheRigidbody3D.rotation = rotation; - } - else if (CacheRigidbody2D != null && !CacheRigidbody2D.isKinematic) - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - CacheRigidbody2D.position = position; - CacheRigidbody2D.rotation = rotation.eulerAngles.z; - } - else - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - } - } - - private void Interpolate(Vector3 position, Quaternion rotation) - { - if (CacheNavMeshAgent != null) - { - CacheNavMeshAgent.Move(position - syncingTransform.position); - syncingTransform.rotation = rotation; - } - else if (CacheCharacterController != null) - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - } - else if (CacheRigidbody3D != null && !CacheRigidbody3D.isKinematic) - { - if (Vector3.Distance(position, CacheRigidbody3D.position) > 0f) - CacheRigidbody3D.MovePosition(position); - else - { - CacheRigidbody3D.velocity = Vector3.zero; - CacheRigidbody3D.MovePosition(position); - } - syncingTransform.rotation = rotation; - } - else if (CacheRigidbody2D != null && !CacheRigidbody2D.isKinematic) - { - if (Vector2.Distance(position, CacheRigidbody2D.position) > 0f) - CacheRigidbody2D.MovePosition(position); - else - { - CacheRigidbody2D.velocity = Vector2.zero; - CacheRigidbody2D.MovePosition(position); - } - syncingTransform.rotation = rotation; - } - else - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - } - } - - private float GetTimeStamp() - { - return Time.fixedTime; - } - - #region Math Utilities - public static float To360Angle(float angle) - { - float result = angle - Mathf.CeilToInt(angle / 360f) * 360f; - if (result < 0) - { - result += 360f; - } - return result; - } - #endregion - } -} diff --git a/Scripts/GameApi/LiteNetLibTransform.cs.meta b/Scripts/GameApi/LiteNetLibTransform.cs.meta deleted file mode 100644 index c00d84ac..00000000 --- a/Scripts/GameApi/LiteNetLibTransform.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 8631d361478af9d4895c657221a7b4b1 -timeCreated: 1518974961 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/LiteNetLibVisibleChecker.cs b/Scripts/GameApi/LiteNetLibVisibleChecker.cs deleted file mode 100644 index 127d365e..00000000 --- a/Scripts/GameApi/LiteNetLibVisibleChecker.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace LiteNetLibManager -{ - [System.Obsolete("This component is deprecated because interest management system is changed")] - public class LiteNetLibVisibleChecker : BaseLiteNetLibVisibleChecker - { - } -} diff --git a/Scripts/GameApi/LiteNetLibVisibleChecker.cs.meta b/Scripts/GameApi/LiteNetLibVisibleChecker.cs.meta deleted file mode 100644 index 71595f13..00000000 --- a/Scripts/GameApi/LiteNetLibVisibleChecker.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 01d64c7b615199243b727eaa75d79574 -timeCreated: 1519828611 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/EnterGameRequestMessage.cs b/Scripts/GameApi/Messages/EnterGameRequestMessage.cs deleted file mode 100644 index 54751ae5..00000000 --- a/Scripts/GameApi/Messages/EnterGameRequestMessage.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct EnterGameRequestMessage : INetSerializable - { - public uint packetVersion; - - public void Deserialize(NetDataReader reader) - { - packetVersion = reader.GetPackedUInt(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedUInt(packetVersion); - } - } -} diff --git a/Scripts/GameApi/Messages/EnterGameRequestMessage.cs.meta b/Scripts/GameApi/Messages/EnterGameRequestMessage.cs.meta deleted file mode 100644 index 867f8165..00000000 --- a/Scripts/GameApi/Messages/EnterGameRequestMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2d5f68ce278e65a49a39b690045b92f3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/EnterGameResponseMessage.cs b/Scripts/GameApi/Messages/EnterGameResponseMessage.cs deleted file mode 100644 index 9ba0b3c6..00000000 --- a/Scripts/GameApi/Messages/EnterGameResponseMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public class EnterGameResponseMessage : INetSerializable - { - public long connectionId; - public string serverSceneName; - - public void Deserialize(NetDataReader reader) - { - connectionId = reader.GetPackedLong(); - serverSceneName = reader.GetString(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedLong(connectionId); - writer.Put(serverSceneName); - } - } -} diff --git a/Scripts/GameApi/Messages/EnterGameResponseMessage.cs.meta b/Scripts/GameApi/Messages/EnterGameResponseMessage.cs.meta deleted file mode 100644 index 4048842a..00000000 --- a/Scripts/GameApi/Messages/EnterGameResponseMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 37fe05c61ea31694d888887a9a7f81c3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/GenericValueMessage.cs b/Scripts/GameApi/Messages/GenericValueMessage.cs deleted file mode 100644 index 53f415b0..00000000 --- a/Scripts/GameApi/Messages/GenericValueMessage.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System; -using UnityEngine; -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public class GenericValueMessage : INetSerializable - { - public TType value; - - public void Deserialize(NetDataReader reader) - { - value = reader.GetValue(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutValue(value); - } - } - - #region Implement for general usages and serializable - [Serializable] - public class BoolMessage : GenericValueMessage - { - } - - [Serializable] - public class BoolArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class ByteMessage : GenericValueMessage - { - } - - [Serializable] - public class ByteArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class CharMessage : GenericValueMessage - { - } - - [Serializable] - public class DoubleMessage : GenericValueMessage - { - } - - [Serializable] - public class DoubleArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class FloatMessage : GenericValueMessage - { - } - - [Serializable] - public class FloatArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class IntMessage : GenericValueMessage - { - } - - [Serializable] - public class IntArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class LongMessage : GenericValueMessage - { - } - - [Serializable] - public class LongArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class SByteMessage : GenericValueMessage - { - } - - [Serializable] - public class ShortMessage : GenericValueMessage - { - } - - [Serializable] - public class ShortArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class StringMessage : GenericValueMessage - { - } - - [Serializable] - public class UIntMessage : GenericValueMessage - { - } - - [Serializable] - public class UIntArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class ULongMessage : GenericValueMessage - { - } - - [Serializable] - public class ULongArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class UShortMessage : GenericValueMessage - { - } - - [Serializable] - public class UShortArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class ColorMessage : GenericValueMessage - { - } - - [Serializable] - public class QuaternionMessage : GenericValueMessage - { - } - - [Serializable] - public class Vector2Message : GenericValueMessage - { - } - - [Serializable] - public class Vector2IntMessage : GenericValueMessage - { - } - - [Serializable] - public class Vector3Message : GenericValueMessage - { - } - - [Serializable] - public class Vector3IntMessage : GenericValueMessage - { - } - - [Serializable] - public class Vector4Message : GenericValueMessage - { - } - - [Serializable] - public class PackedUShortMessage : GenericValueMessage - { - } - - [Serializable] - public class PackedUIntMessage : GenericValueMessage - { - } - - [Serializable] - public class PackedULongMessage : GenericValueMessage - { - } - #endregion -} diff --git a/Scripts/GameApi/Messages/GenericValueMessage.cs.meta b/Scripts/GameApi/Messages/GenericValueMessage.cs.meta deleted file mode 100644 index 7bbfa2c8..00000000 --- a/Scripts/GameApi/Messages/GenericValueMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 11ec5c0f0e06d5c45ba82e2bf6c1fb2d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/PingMessage.cs b/Scripts/GameApi/Messages/PingMessage.cs deleted file mode 100644 index ef09e496..00000000 --- a/Scripts/GameApi/Messages/PingMessage.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct PingMessage : INetSerializable - { - public long pingTime; - - public void Deserialize(NetDataReader reader) - { - pingTime = reader.GetPackedLong(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedLong(pingTime); - } - } -} diff --git a/Scripts/GameApi/Messages/PingMessage.cs.meta b/Scripts/GameApi/Messages/PingMessage.cs.meta deleted file mode 100644 index 803acc82..00000000 --- a/Scripts/GameApi/Messages/PingMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 88aad3795437e6645b550e242d147c13 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/PongMessage.cs b/Scripts/GameApi/Messages/PongMessage.cs deleted file mode 100644 index 45bce529..00000000 --- a/Scripts/GameApi/Messages/PongMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct PongMessage : INetSerializable - { - public long pingTime; - public long serverTime; - - public void Deserialize(NetDataReader reader) - { - pingTime = reader.GetPackedLong(); - serverTime = reader.GetPackedLong(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedLong(pingTime); - writer.PutPackedLong(serverTime); - } - } -} diff --git a/Scripts/GameApi/Messages/PongMessage.cs.meta b/Scripts/GameApi/Messages/PongMessage.cs.meta deleted file mode 100644 index 987a9c4b..00000000 --- a/Scripts/GameApi/Messages/PongMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0d3b5836388d4de4891673efc33eafd3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/ServerDestroyObjectMessage.cs b/Scripts/GameApi/Messages/ServerDestroyObjectMessage.cs deleted file mode 100644 index b52a00cc..00000000 --- a/Scripts/GameApi/Messages/ServerDestroyObjectMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct ServerDestroyObjectMessage : INetSerializable - { - public uint objectId; - public byte reasons; - - public void Deserialize(NetDataReader reader) - { - objectId = reader.GetPackedUInt(); - reasons = reader.GetByte(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedUInt(objectId); - writer.Put(reasons); - } - } -} diff --git a/Scripts/GameApi/Messages/ServerDestroyObjectMessage.cs.meta b/Scripts/GameApi/Messages/ServerDestroyObjectMessage.cs.meta deleted file mode 100644 index 724d0820..00000000 --- a/Scripts/GameApi/Messages/ServerDestroyObjectMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 58f4f8e22dbb4a94f874aceb5815dc44 -timeCreated: 1508932284 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/ServerErrorMessage.cs b/Scripts/GameApi/Messages/ServerErrorMessage.cs deleted file mode 100644 index 9f6ecd64..00000000 --- a/Scripts/GameApi/Messages/ServerErrorMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct ServerErrorMessage : INetSerializable - { - public bool shouldDisconnect; - public string errorMessage; - - public void Deserialize(NetDataReader reader) - { - shouldDisconnect = reader.GetBool(); - errorMessage = reader.GetString(); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(shouldDisconnect); - writer.Put(errorMessage); - } - } -} \ No newline at end of file diff --git a/Scripts/GameApi/Messages/ServerErrorMessage.cs.meta b/Scripts/GameApi/Messages/ServerErrorMessage.cs.meta deleted file mode 100644 index ee5136df..00000000 --- a/Scripts/GameApi/Messages/ServerErrorMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: b4d19b05d26f3854d83d967efef217e4 -timeCreated: 1519725292 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/ServerSceneChangeMessage.cs b/Scripts/GameApi/Messages/ServerSceneChangeMessage.cs deleted file mode 100644 index 90c6e62b..00000000 --- a/Scripts/GameApi/Messages/ServerSceneChangeMessage.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct ServerSceneChangeMessage : INetSerializable - { - public string serverSceneName; - - public void Deserialize(NetDataReader reader) - { - serverSceneName = reader.GetString(); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(serverSceneName); - } - } -} diff --git a/Scripts/GameApi/Messages/ServerSceneChangeMessage.cs.meta b/Scripts/GameApi/Messages/ServerSceneChangeMessage.cs.meta deleted file mode 100644 index b26fb39b..00000000 --- a/Scripts/GameApi/Messages/ServerSceneChangeMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: c69e59286bb7023469ad76ddcc7c4dad -timeCreated: 1525038105 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/ServerSetObjectOwner.cs b/Scripts/GameApi/Messages/ServerSetObjectOwner.cs deleted file mode 100644 index 358fb3d0..00000000 --- a/Scripts/GameApi/Messages/ServerSetObjectOwner.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct ServerSetObjectOwner : INetSerializable - { - public uint objectId; - public long connectionId; - - public void Deserialize(NetDataReader reader) - { - objectId = reader.GetPackedUInt(); - connectionId = reader.GetPackedLong(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedUInt(objectId); - writer.PutPackedLong(connectionId); - } - } -} diff --git a/Scripts/GameApi/Messages/ServerSetObjectOwner.cs.meta b/Scripts/GameApi/Messages/ServerSetObjectOwner.cs.meta deleted file mode 100644 index 0a5878c0..00000000 --- a/Scripts/GameApi/Messages/ServerSetObjectOwner.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d3015cf7812103846aa5fbb5cc484b38 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/ServerSpawnObjectMessage.cs b/Scripts/GameApi/Messages/ServerSpawnObjectMessage.cs deleted file mode 100644 index 39c29677..00000000 --- a/Scripts/GameApi/Messages/ServerSpawnObjectMessage.cs +++ /dev/null @@ -1,36 +0,0 @@ -using LiteNetLib.Utils; -using UnityEngine; - -namespace LiteNetLibManager -{ - public struct ServerSpawnObjectMessage : INetSerializable - { - public int hashAssetId; - public uint objectId; - public long connectionId; - public Vector3 position; - public Quaternion rotation; - - public void Deserialize(NetDataReader reader) - { - hashAssetId = reader.GetPackedInt(); - objectId = reader.GetPackedUInt(); - connectionId = reader.GetPackedLong(); - position = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - rotation = Quaternion.Euler(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedInt(hashAssetId); - writer.PutPackedUInt(objectId); - writer.PutPackedLong(connectionId); - writer.Put(position.x); - writer.Put(position.y); - writer.Put(position.z); - writer.Put(rotation.eulerAngles.x); - writer.Put(rotation.eulerAngles.y); - writer.Put(rotation.eulerAngles.z); - } - } -} diff --git a/Scripts/GameApi/Messages/ServerSpawnObjectMessage.cs.meta b/Scripts/GameApi/Messages/ServerSpawnObjectMessage.cs.meta deleted file mode 100644 index 5bd06b1f..00000000 --- a/Scripts/GameApi/Messages/ServerSpawnObjectMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 9823c3024abd0c348bb5e297226e819a -timeCreated: 1508932284 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameApi/Messages/ServerSpawnSceneObjectMessage.cs b/Scripts/GameApi/Messages/ServerSpawnSceneObjectMessage.cs deleted file mode 100644 index 95a63b48..00000000 --- a/Scripts/GameApi/Messages/ServerSpawnSceneObjectMessage.cs +++ /dev/null @@ -1,33 +0,0 @@ -using LiteNetLib.Utils; -using UnityEngine; - -namespace LiteNetLibManager -{ - public struct ServerSpawnSceneObjectMessage : INetSerializable - { - public uint objectId; - public long connectionId; - public Vector3 position; - public Quaternion rotation; - - public void Deserialize(NetDataReader reader) - { - objectId = reader.GetPackedUInt(); - connectionId = reader.GetPackedLong(); - position = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - rotation = Quaternion.Euler(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedUInt(objectId); - writer.PutPackedLong(connectionId); - writer.Put(position.x); - writer.Put(position.y); - writer.Put(position.z); - writer.Put(rotation.eulerAngles.x); - writer.Put(rotation.eulerAngles.y); - writer.Put(rotation.eulerAngles.z); - } - } -} diff --git a/Scripts/GameApi/Messages/ServerSpawnSceneObjectMessage.cs.meta b/Scripts/GameApi/Messages/ServerSpawnSceneObjectMessage.cs.meta deleted file mode 100644 index 65404916..00000000 --- a/Scripts/GameApi/Messages/ServerSpawnSceneObjectMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 3a57f78648eb8cd4d900d0097f0bd20c -timeCreated: 1511672224 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 57a3b5d1cfa705ae27b370bd99ff1165d9ce3107 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:22:49 +0700 Subject: [PATCH 07/58] feat: delete codes for Unity (Utils) --- Scripts/Utils/SceneField.cs | 34 -------------------------------- Scripts/Utils/SceneField.cs.meta | 11 ----------- 2 files changed, 45 deletions(-) delete mode 100644 Scripts/Utils/SceneField.cs delete mode 100644 Scripts/Utils/SceneField.cs.meta diff --git a/Scripts/Utils/SceneField.cs b/Scripts/Utils/SceneField.cs deleted file mode 100644 index 0f32206e..00000000 --- a/Scripts/Utils/SceneField.cs +++ /dev/null @@ -1,34 +0,0 @@ -using UnityEngine; - -namespace LiteNetLibManager -{ - [System.Serializable] - public struct SceneField - { - [SerializeField] - private Object sceneAsset; - [SerializeField] - private string sceneName; - - public Object SceneAsset - { - get { return sceneAsset; } - } - - public string SceneName - { - get { return sceneName; } - set { sceneName = value; } - } - - public static implicit operator string(SceneField unityScene) - { - return unityScene.SceneName; - } - - public bool IsSet() - { - return !string.IsNullOrEmpty(sceneName); - } - } -} diff --git a/Scripts/Utils/SceneField.cs.meta b/Scripts/Utils/SceneField.cs.meta deleted file mode 100644 index 221e6f28..00000000 --- a/Scripts/Utils/SceneField.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 03399e5071bb42646a695cca6189f3e4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 6c227f4c5e72f07383039711f7aa17a8efa885a5 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:23:07 +0700 Subject: [PATCH 08/58] feat: delete codes for Unity (Scripts) --- Scripts/LiteNetLibDiscovery.cs | 200 ---------------------------- Scripts/LiteNetLibDiscovery.cs.meta | 11 -- Scripts/LiteNetLibManagerUI.cs | 95 ------------- Scripts/LiteNetLibManagerUI.cs.meta | 13 -- Scripts/PropertyAttributes.meta | 10 -- 5 files changed, 329 deletions(-) delete mode 100644 Scripts/LiteNetLibDiscovery.cs delete mode 100644 Scripts/LiteNetLibDiscovery.cs.meta delete mode 100644 Scripts/LiteNetLibManagerUI.cs delete mode 100644 Scripts/LiteNetLibManagerUI.cs.meta delete mode 100644 Scripts/PropertyAttributes.meta diff --git a/Scripts/LiteNetLibDiscovery.cs b/Scripts/LiteNetLibDiscovery.cs deleted file mode 100644 index 9a5f309c..00000000 --- a/Scripts/LiteNetLibDiscovery.cs +++ /dev/null @@ -1,200 +0,0 @@ -using LiteNetLib; -using LiteNetLib.Utils; -using UnityEngine; - -namespace LiteNetLibManager -{ - public class LiteNetLibDiscovery : MonoBehaviour - { - public float broadcastDelay = 3f; - public int broadcastPort = 19050; - public ushort broadcastKey = 1; - [Tooltip("Will send this manager's address and port to discovery clients")] - public LiteNetLibManager manager; - [Tooltip("Data which will send from discovery server to clients")] - public string data; - - public bool IsServer { get { return _server != null; } } - public bool IsClient { get { return _client != null; } } - private EventBasedNetListener _serverListener; - private EventBasedNetListener _clientListener; - private NetManager _server; - private NetManager _client; - private NetDataWriter _serverWriter; - private NetDataWriter _clientWriter; - private float _broadcastElapsed; - - public delegate void ReceiveBroadcastDelegate(System.Net.IPEndPoint remoteEndPoint, string data); - public ReceiveBroadcastDelegate onReceivedBroadcast; - - private void Awake() - { - _serverWriter = new NetDataWriter(); - _clientWriter = new NetDataWriter(); - - _serverListener = new EventBasedNetListener(); - _serverListener.ConnectionRequestEvent += _serverListener_ConnectionRequestEvent; - _serverListener.NetworkErrorEvent += _serverListener_NetworkErrorEvent; - _serverListener.NetworkLatencyUpdateEvent += _serverListener_NetworkLatencyUpdateEvent; - _serverListener.NetworkReceiveEvent += _serverListener_NetworkReceiveEvent; - _serverListener.NetworkReceiveUnconnectedEvent += _serverListener_NetworkReceiveUnconnectedEvent; - _serverListener.PeerConnectedEvent += _serverListener_PeerConnectedEvent; - _serverListener.PeerDisconnectedEvent += _serverListener_PeerDisconnectedEvent; - - _clientListener = new EventBasedNetListener(); - _clientListener.ConnectionRequestEvent += _clientListener_ConnectionRequestEvent; - _clientListener.NetworkErrorEvent += _clientListener_NetworkErrorEvent; - _clientListener.NetworkLatencyUpdateEvent += _clientListener_NetworkLatencyUpdateEvent; - _clientListener.NetworkReceiveEvent += _clientListener_NetworkReceiveEvent; - _clientListener.NetworkReceiveUnconnectedEvent += _clientListener_NetworkReceiveUnconnectedEvent; - _clientListener.PeerConnectedEvent += _clientListener_PeerConnectedEvent; - _clientListener.PeerDisconnectedEvent += _clientListener_PeerDisconnectedEvent; - } - - public bool StartServer() - { - _server = new NetManager(_serverListener); - _server.BroadcastReceiveEnabled = true; - if (!_server.Start(broadcastPort)) - { - _server = null; - Logging.LogError("Cannot start discovery server"); - return false; - } - return true; - } - - public bool StartClient() - { - _client = new NetManager(_clientListener); - _client.UnconnectedMessagesEnabled = true; - if (!_client.Start()) - { - _client = null; - Logging.LogError("Cannot start discovery client"); - return false; - } - - return true; - } - - public void StopServer() - { - if (!IsServer) - return; - _server.Stop(); - _server = null; - } - - public void StopClient() - { - if (!IsClient) - return; - _client.Stop(); - _client = null; - } - - private void Update() - { - if (IsClient) - { - _client.PollEvents(); - _broadcastElapsed -= Time.deltaTime; - if (_broadcastElapsed <= 0f) - { - _clientWriter.Reset(); - _clientWriter.Put(broadcastKey); - _client.SendBroadcast(_clientWriter, broadcastPort); - _broadcastElapsed = broadcastDelay; - } - } - - if (IsServer) - { - _server.PollEvents(); - } - } - - private void _clientListener_PeerDisconnectedEvent(NetPeer peer, DisconnectInfo disconnectInfo) - { - - } - - private void _clientListener_PeerConnectedEvent(NetPeer peer) - { - - } - - private void _clientListener_NetworkReceiveUnconnectedEvent(System.Net.IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) - { - // Receive server data - if (reader.GetUShort() == broadcastKey) - { - if (onReceivedBroadcast != null) - onReceivedBroadcast.Invoke(remoteEndPoint, reader.GetString()); - } - } - - private void _clientListener_NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) - { - - } - - private void _clientListener_NetworkLatencyUpdateEvent(NetPeer peer, int latency) - { - - } - - private void _clientListener_NetworkErrorEvent(System.Net.IPEndPoint endPoint, System.Net.Sockets.SocketError socketError) - { - - } - - private void _clientListener_ConnectionRequestEvent(ConnectionRequest request) - { - - } - - private void _serverListener_PeerDisconnectedEvent(NetPeer peer, DisconnectInfo disconnectInfo) - { - - } - - private void _serverListener_PeerConnectedEvent(NetPeer peer) - { - - } - - private void _serverListener_NetworkReceiveUnconnectedEvent(System.Net.IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) - { - // Send back server data - if (reader.GetUShort() == broadcastKey) - { - _serverWriter.Reset(); - _serverWriter.Put(broadcastKey); - _serverWriter.Put(data); - _server.SendUnconnectedMessage(_serverWriter, remoteEndPoint); - } - } - - private void _serverListener_NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) - { - - } - - private void _serverListener_NetworkLatencyUpdateEvent(NetPeer peer, int latency) - { - - } - - private void _serverListener_NetworkErrorEvent(System.Net.IPEndPoint endPoint, System.Net.Sockets.SocketError socketError) - { - - } - - private void _serverListener_ConnectionRequestEvent(ConnectionRequest request) - { - - } - } -} diff --git a/Scripts/LiteNetLibDiscovery.cs.meta b/Scripts/LiteNetLibDiscovery.cs.meta deleted file mode 100644 index d70771e6..00000000 --- a/Scripts/LiteNetLibDiscovery.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 523b2882996900240b5b07e16fab2d02 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibManagerUI.cs b/Scripts/LiteNetLibManagerUI.cs deleted file mode 100644 index 731e7df7..00000000 --- a/Scripts/LiteNetLibManagerUI.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace LiteNetLibManager -{ - [RequireComponent(typeof(LiteNetLibManager))] - public class LiteNetLibManagerUI : MonoBehaviour - { - [SerializeField] - public bool showGUI = true; - [SerializeField] - public int offsetX; - [SerializeField] - public int offsetY; - - private LiteNetLibManager manager; - public LiteNetLibManager Manager - { - get - { - if (manager == null) - manager = GetComponent(); - return manager; - } - } - - void OnGUI() - { - if (!showGUI) - return; - - int xpos = 10 + offsetX; - int ypos = 10 + offsetY; - const int spacing = 24; - - if (!Manager.IsClientConnected && !Manager.IsServer) - { - if (!Manager.IsClient) - { - GUI.Label(new Rect(xpos, ypos, 100, 20), "Network Address"); - Manager.networkAddress = GUI.TextField(new Rect(xpos + 105, ypos, 95, 20), Manager.networkAddress); - ypos += spacing; - - GUI.Label(new Rect(xpos, ypos, 100, 20), "Network Port"); - Manager.networkPort = int.Parse(GUI.TextField(new Rect(xpos + 105, ypos, 95, 20), "" + Manager.networkPort)); - ypos += spacing; - - if (GUI.Button(new Rect(xpos, ypos, 200, 20), "Start Host")) - Manager.StartHost(); - ypos += spacing; - - if (GUI.Button(new Rect(xpos, ypos, 200, 20), "Start Client")) - Manager.StartClient(); - ypos += spacing; - - if (GUI.Button(new Rect(xpos, ypos, 200, 20), "Start Server")) - Manager.StartServer(); - ypos += spacing; - } - else - { - GUI.Label(new Rect(xpos, ypos, 200, 20), "Connecting to " + Manager.networkAddress + ":" + Manager.networkPort + ".."); - ypos += spacing; - - if (GUI.Button(new Rect(xpos, ypos, 200, 20), "Cancel Connection Attempt")) - { - Manager.StopClient(); - } - ypos += spacing; - } - } - else - { - if (Manager.IsServer) - { - GUI.Label(new Rect(xpos, ypos, 300, 20), "Server: port=" + Manager.networkPort); - ypos += spacing; - } - if (Manager.IsClient) - { - GUI.Label(new Rect(xpos, ypos, 300, 20), "Client: address=" + Manager.networkAddress + " port=" + Manager.networkPort); - ypos += spacing; - } - } - - if (Manager.IsServer || Manager.IsClient) - { - if (GUI.Button(new Rect(xpos, ypos, 200, 20), "Stop")) - Manager.StopHost(); - ypos += spacing; - } - } - } -} diff --git a/Scripts/LiteNetLibManagerUI.cs.meta b/Scripts/LiteNetLibManagerUI.cs.meta deleted file mode 100644 index 0abc55cd..00000000 --- a/Scripts/LiteNetLibManagerUI.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 3027f70f344fdf54a82f799f8bedfe35 -timeCreated: 1508758737 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/PropertyAttributes.meta b/Scripts/PropertyAttributes.meta deleted file mode 100644 index 7b3555dd..00000000 --- a/Scripts/PropertyAttributes.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 7d6fb2e6579971a4cb9a8155180cc550 -folderAsset: yes -timeCreated: 1508756708 -licenseType: Pro -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: From 4cbc224511f2c4ba0c662812f3eefff9f4a40ee8 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:23:32 +0700 Subject: [PATCH 09/58] feat: delete codes for Unity, changes some for NET7 --- Scripts/LiteNetLibManager.cs | 49 +--------- Scripts/LogManager.cs | 29 ++---- Scripts/Logging.cs | 43 -------- Scripts/NetDataReaderExtension.cs | 64 ------------ Scripts/NetDataWriterExtension.cs | 98 ------------------- Scripts/TransportHandler.cs | 2 +- Scripts/Transports/BaseTransportFactory.cs | 6 +- .../LiteNetLib/LiteNetLibTransportFactory.cs | 6 +- 8 files changed, 16 insertions(+), 281 deletions(-) diff --git a/Scripts/LiteNetLibManager.cs b/Scripts/LiteNetLibManager.cs index e5a6a143..d3b56e3b 100644 --- a/Scripts/LiteNetLibManager.cs +++ b/Scripts/LiteNetLibManager.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; using System.Net; using System.Net.Sockets; -using UnityEngine; using LiteNetLib; using LiteNetLib.Utils; using Cysharp.Threading.Tasks; namespace LiteNetLibManager { - public class LiteNetLibManager : MonoBehaviour + public class LiteNetLibManager { public LiteNetLibClient Client { get; protected set; } public LiteNetLibServer Server { get; protected set; } @@ -23,20 +22,10 @@ public class LiteNetLibManager : MonoBehaviour public bool LogError { get { return currentLogLevel.IsLogError(); } } public bool LogFatal { get { return currentLogLevel.IsLogFatal(); } } - [Header("Client & Server Settings")] public ELogLevel currentLogLevel = ELogLevel.Info; public string networkAddress = "localhost"; public int networkPort = 7770; - public bool useWebSocket = false; - public bool webSocketSecure = false; - public string webSocketCertificateFilePath = string.Empty; - public string webSocketCertificatePassword = string.Empty; - - [Header("Server Only Settings")] public int maxConnections = 4; - - [Header("Transport Layer Settings")] - [SerializeField] private BaseTransportFactory transportFactory; public BaseTransportFactory TransportFactory { @@ -64,48 +53,20 @@ public virtual string LogTag get { if (string.IsNullOrEmpty(logTag)) - logTag = $"{name}({GetType().Name})"; + logTag = $"{GetType().Name}"; return logTag; } } - protected virtual void Start() + public LiteNetLibManager() { InitTransportAndHandlers(); } protected void PrepareTransportFactory() { -#if UNITY_WEBGL && !UNITY_EDITOR - // Force to use websocket transport if it's running as webgl - if (transportFactory == null || !(transportFactory is IWebSocketTransportFactory)) - { - WebSocketTransportFactory webSocketTransportFactory = gameObject.AddComponent(); - webSocketTransportFactory.Secure = webSocketSecure; - webSocketTransportFactory.CertificateFilePath = webSocketCertificateFilePath; - webSocketTransportFactory.CertificatePassword = webSocketCertificatePassword; - transportFactory = webSocketTransportFactory; - } -#else - if (useWebSocket) - { - if (transportFactory == null || !(transportFactory is IWebSocketTransportFactory)) - { - WebSocketTransportFactory webSocketTransportFactory = gameObject.AddComponent(); - webSocketTransportFactory.Secure = webSocketSecure; - webSocketTransportFactory.CertificateFilePath = webSocketCertificateFilePath; - webSocketTransportFactory.CertificatePassword = webSocketCertificatePassword; - transportFactory = webSocketTransportFactory; - } - } - else - { - if (transportFactory == null) - transportFactory = GetComponent(); - if (transportFactory == null) - transportFactory = gameObject.AddComponent(); - } -#endif + if (transportFactory == null) + transportFactory = new LiteNetLibTransportFactory(); } public void PrepareClientTransport() diff --git a/Scripts/LogManager.cs b/Scripts/LogManager.cs index 21891dab..61e22cf0 100644 --- a/Scripts/LogManager.cs +++ b/Scripts/LogManager.cs @@ -28,15 +28,6 @@ public LoggerManager(ILoggerFactory loggerFactory) _loggerByTags.Clear(); _loggerFactory = loggerFactory; _defaultLogger = loggerFactory.CreateLogger("No Tag"); - - UnityEngine.Application.quitting += () => - { - // when quit, flush unfinished log entries. - if (_loggerFactory != null) - _loggerFactory.Dispose(); - _loggerFactory = null; - IsDisposed = true; - }; } public ILogger GetLogger() where T : class @@ -63,28 +54,22 @@ public static partial class LogManager public static LoggerManager WarningLoggerManager { get; set; } public static LoggerManager ErrorLoggerManager { get; set; } + static LogManager() + { + Initialize(); + } - [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.BeforeSceneLoad)] public static void Initialize() { // Standard LoggerFactory does not work on IL2CPP, // But you can use ZLogger's UnityLoggerFactory instead, // it works on IL2CPP, all platforms(includes mobile). - DefaultLoggerManager = new LoggerManager(UnityLoggerFactory.Create(builder => + DefaultLoggerManager = new LoggerManager(LoggerFactory.Create(builder => { // or more configuration, you can use builder.AddFilter + builder.ClearProviders(); builder.SetMinimumLevel(LogLevel.Trace); - - // AddZLoggerUnityDebug is only available for Unity, it send log to UnityEngine.Debug.Log. - // LogLevels are translate to - // * Trace/Debug/Information -> LogType.Log - // * Warning/Critical -> LogType.Warning - // * Error without Exception -> LogType.Error - // * Error with Exception -> LogException - builder.AddZLoggerUnityDebug(options => - { - options.PrefixFormatter = PrefixFormatterConfigure; - }); + builder.AddZLoggerConsole(); })); DefaultLoggerManager.Logger.LogInformation("===== Logger Initialized ====="); diff --git a/Scripts/Logging.cs b/Scripts/Logging.cs index ab387fa9..5d624fd8 100644 --- a/Scripts/Logging.cs +++ b/Scripts/Logging.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Logging; -using UnityEngine; namespace LiteNetLibManager { @@ -15,13 +14,7 @@ public static void Log(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsLoggerDisposed) - { - if (args.Length > 0) - Debug.Log(string.Format($"[{tag}] {message}", args)); - else - Debug.Log($"[{tag}] {message}"); return; - } LogManager.GetLogger(tag).LogInformation(message, args); } @@ -35,13 +28,7 @@ public static void LogError(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsErrorLoggerDisposed) - { - if (args.Length > 0) - Debug.LogError(string.Format($"[{tag}] {message}", args)); - else - Debug.LogError($"[{tag}] {message}"); return; - } LogManager.GetErrorLogger(tag).LogError(message, args); } @@ -55,13 +42,7 @@ public static void LogWarning(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsWarningLoggerDisposed) - { - if (args.Length > 0) - Debug.LogWarning(string.Format($"[{tag}] {message}", args)); - else - Debug.LogWarning($"[{tag}] {message}"); return; - } LogManager.GetWarningLogger(tag).LogWarning(message, args); } @@ -70,10 +51,7 @@ public static void LogException(string tag, System.Exception ex) if (ex == null) return; if (LogManager.IsErrorLoggerDisposed) - { - Debug.LogError($"[{tag}] {ex}"); return; - } LogManager.GetErrorLogger(tag).LogError(ex.ToString()); } @@ -87,13 +65,7 @@ public static void Log(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsLoggerDisposed) - { - if (args.Length > 0) - Debug.Log(string.Format($"{message}", args)); - else - Debug.Log($"{message}"); return; - } LogManager.Logger.LogInformation(message, args); } @@ -107,13 +79,7 @@ public static void LogError(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsErrorLoggerDisposed) - { - if (args.Length > 0) - Debug.LogError(string.Format($"{message}", args)); - else - Debug.LogError($"{message}"); return; - } LogManager.ErrorLogger.LogError(message, args); } @@ -127,13 +93,7 @@ public static void LogWarning(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsWarningLoggerDisposed) - { - if (args.Length > 0) - Debug.LogWarning(string.Format($"{message}", args)); - else - Debug.LogWarning($"{message}"); return; - } LogManager.WarningLogger.LogWarning(message, args); } @@ -142,10 +102,7 @@ public static void LogException(System.Exception ex) if (ex == null) return; if (LogManager.IsErrorLoggerDisposed) - { - Debug.LogError($"{ex}"); return; - } LogManager.ErrorLogger.LogError(ex.ToString()); } } diff --git a/Scripts/NetDataReaderExtension.cs b/Scripts/NetDataReaderExtension.cs index 12e308b2..1dc30ae7 100644 --- a/Scripts/NetDataReaderExtension.cs +++ b/Scripts/NetDataReaderExtension.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using UnityEngine; namespace LiteNetLib.Utils { @@ -57,29 +56,6 @@ public static object GetValue(this NetDataReader reader, Type type) return reader.GetPackedUShort(); #endregion - #region Unity Values - if (type == typeof(Color)) - return reader.GetColor(); - - if (type == typeof(Quaternion)) - return reader.GetQuaternion(); - - if (type == typeof(Vector2)) - return reader.GetVector2(); - - if (type == typeof(Vector2Int)) - return reader.GetVector2Int(); - - if (type == typeof(Vector3)) - return reader.GetVector3(); - - if (type == typeof(Vector3Int)) - return reader.GetVector3Int(); - - if (type == typeof(Vector4)) - return reader.GetVector4(); - #endregion - if (typeof(INetSerializable).IsAssignableFrom(type)) { object instance = Activator.CreateInstance(type); @@ -90,46 +66,6 @@ public static object GetValue(this NetDataReader reader, Type type) throw new ArgumentException("NetDataReader cannot read type " + type.Name); } - public static Color GetColor(this NetDataReader reader) - { - float r = reader.GetByte() * 0.01f; - float g = reader.GetByte() * 0.01f; - float b = reader.GetByte() * 0.01f; - float a = reader.GetByte() * 0.01f; - return new Color(r, g, b, a); - } - - public static Quaternion GetQuaternion(this NetDataReader reader) - { - Vector3 vector3 = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - return vector3.sqrMagnitude <= 0 ? Quaternion.identity : Quaternion.Euler(vector3); - } - - public static Vector2 GetVector2(this NetDataReader reader) - { - return new Vector2(reader.GetFloat(), reader.GetFloat()); - } - - public static Vector2Int GetVector2Int(this NetDataReader reader) - { - return new Vector2Int(reader.GetInt(), reader.GetInt()); - } - - public static Vector3 GetVector3(this NetDataReader reader) - { - return new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - } - - public static Vector3Int GetVector3Int(this NetDataReader reader) - { - return new Vector3Int(reader.GetInt(), reader.GetInt(), reader.GetInt()); - } - - public static Vector4 GetVector4(this NetDataReader reader) - { - return new Vector4(reader.GetFloat(), reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - } - public static TValue[] GetArray(this NetDataReader reader) { int count = reader.GetInt(); diff --git a/Scripts/NetDataWriterExtension.cs b/Scripts/NetDataWriterExtension.cs index e920eba5..87d5a394 100644 --- a/Scripts/NetDataWriterExtension.cs +++ b/Scripts/NetDataWriterExtension.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using UnityEngine; namespace LiteNetLib.Utils { @@ -96,50 +95,6 @@ public static void PutValue(this NetDataWriter writer, Type type, object value) } #endregion - #region Unity Values - if (type == typeof(Color)) - { - writer.PutColor((Color)value); - return; - } - - if (type == typeof(Quaternion)) - { - writer.PutQuaternion((Quaternion)value); - return; - } - - if (type == typeof(Vector2)) - { - writer.PutVector2((Vector2)value); - return; - } - - if (type == typeof(Vector2Int)) - { - writer.PutVector2Int((Vector2Int)value); - return; - } - - if (type == typeof(Vector3)) - { - writer.PutVector3((Vector3)value); - return; - } - - if (type == typeof(Vector3Int)) - { - writer.PutVector3Int((Vector3Int)value); - return; - } - - if (type == typeof(Vector4)) - { - writer.PutVector4((Vector4)value); - return; - } - #endregion - if (typeof(INetSerializable).IsAssignableFrom(type)) { (value as INetSerializable).Serialize(writer); @@ -149,59 +104,6 @@ public static void PutValue(this NetDataWriter writer, Type type, object value) throw new ArgumentException("NetDataWriter cannot write type " + value.GetType().Name); } - public static void PutColor(this NetDataWriter writer, Color value) - { - byte r = (byte)(value.r * 100f); - byte g = (byte)(value.g * 100f); - byte b = (byte)(value.b * 100f); - byte a = (byte)(value.a * 100f); - writer.Put(r); - writer.Put(g); - writer.Put(b); - writer.Put(a); - } - - public static void PutQuaternion(this NetDataWriter writer, Quaternion value) - { - writer.Put(value.eulerAngles.x); - writer.Put(value.eulerAngles.y); - writer.Put(value.eulerAngles.z); - } - - public static void PutVector2(this NetDataWriter writer, Vector2 value) - { - writer.Put(value.x); - writer.Put(value.y); - } - - public static void PutVector2Int(this NetDataWriter writer, Vector2Int value) - { - writer.Put(value.x); - writer.Put(value.y); - } - - public static void PutVector3(this NetDataWriter writer, Vector3 value) - { - writer.Put(value.x); - writer.Put(value.y); - writer.Put(value.z); - } - - public static void PutVector3Int(this NetDataWriter writer, Vector3Int value) - { - writer.Put(value.x); - writer.Put(value.y); - writer.Put(value.z); - } - - public static void PutVector4(this NetDataWriter writer, Vector4 value) - { - writer.Put(value.x); - writer.Put(value.y); - writer.Put(value.z); - writer.Put(value.w); - } - public static void PutArray(this NetDataWriter writer, TValue[] array) { if (array == null) diff --git a/Scripts/TransportHandler.cs b/Scripts/TransportHandler.cs index 2e6ed4a3..6a3ecab7 100644 --- a/Scripts/TransportHandler.cs +++ b/Scripts/TransportHandler.cs @@ -124,7 +124,7 @@ private async UniTaskVoid HandleRequestTimeout(uint requestId, int millisecondsT { if (millisecondsTimeout > 0) { - await UniTask.Delay(millisecondsTimeout); + await Task.Delay(millisecondsTimeout); LiteNetLibRequestCallback callback; if (requestCallbacks.TryRemove(requestId, out callback)) callback.ResponseTimeout(); diff --git a/Scripts/Transports/BaseTransportFactory.cs b/Scripts/Transports/BaseTransportFactory.cs index 90ace274..f1b79140 100644 --- a/Scripts/Transports/BaseTransportFactory.cs +++ b/Scripts/Transports/BaseTransportFactory.cs @@ -1,8 +1,6 @@ -using UnityEngine; - -namespace LiteNetLibManager +namespace LiteNetLibManager { - public abstract class BaseTransportFactory : MonoBehaviour + public abstract class BaseTransportFactory { public abstract ITransport Build(); } diff --git a/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs b/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs index 488756be..eed491d7 100644 --- a/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs +++ b/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs @@ -1,13 +1,9 @@ -using UnityEngine; - -namespace LiteNetLibManager +namespace LiteNetLibManager { public class LiteNetLibTransportFactory : BaseTransportFactory { public string connectKey = "SampleConnectKey"; - [Range(1, 64)] public byte clientDataChannelsCount = 16; - [Range(1, 64)] public byte serverDataChannelsCount = 16; public override ITransport Build() From 090f98455f24eb555cf69d5dc62647b182782826 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:24:55 +0700 Subject: [PATCH 10/58] feat: delete codes for Unity, changes some for NET7 --- Scripts/LiteNetLibManager.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Scripts/LiteNetLibManager.cs b/Scripts/LiteNetLibManager.cs index d3b56e3b..3f2a451c 100644 --- a/Scripts/LiteNetLibManager.cs +++ b/Scripts/LiteNetLibManager.cs @@ -110,17 +110,6 @@ protected virtual void OnDestroy() serverTransport.Destroy(); } - protected virtual void OnApplicationQuit() - { -#if UNITY_EDITOR - StopHost(); - if (clientTransport != null) - clientTransport.Destroy(); - if (serverTransport != null) - serverTransport.Destroy(); -#endif - } - /// /// Override this function to register messages /// From 9ec82f0f14530a67f22a0751da95fb6d63196bf0 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:26:54 +0700 Subject: [PATCH 11/58] Add dep list --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 64adfa0d..fe746bc4 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,10 @@ LiteNetLib Network Manager for Unity, this is required LiteNetLib (https://github.com/RevenantX/LiteNetLib) The document: https://insthync.github.io/LiteNetLibManager + + +## Dependencies +- LiteNetLib +- UniTask +- ZLogger +- ZString \ No newline at end of file From 5848c42b2bda67bc00888e57480f7a00bcf534cc Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:38:18 +0700 Subject: [PATCH 12/58] improve: change folder structure (RequestResponse) --- Scripts/RequestResponse.meta | 8 ++++++++ Scripts/{ => RequestResponse}/AckResponseCode.cs | 0 Scripts/{ => RequestResponse}/AckResponseCode.cs.meta | 0 Scripts/{ => RequestResponse}/AsyncResponseData.cs | 0 Scripts/{ => RequestResponse}/AsyncResponseData.cs.meta | 0 .../{ => RequestResponse}/LiteNetLibRequestCallback.cs | 0 .../LiteNetLibRequestCallback.cs.meta | 0 Scripts/{ => RequestResponse}/LiteNetLibRequestHandler.cs | 0 .../LiteNetLibRequestHandler.cs.meta | 0 .../{ => RequestResponse}/LiteNetLibResponseHandler.cs | 0 .../LiteNetLibResponseHandler.cs.meta | 0 Scripts/{ => RequestResponse}/RequestHandlerData.cs | 0 Scripts/{ => RequestResponse}/RequestHandlerData.cs.meta | 0 Scripts/{ => RequestResponse}/ResponseHandlerData.cs | 0 Scripts/{ => RequestResponse}/ResponseHandlerData.cs.meta | 0 15 files changed, 8 insertions(+) create mode 100644 Scripts/RequestResponse.meta rename Scripts/{ => RequestResponse}/AckResponseCode.cs (100%) rename Scripts/{ => RequestResponse}/AckResponseCode.cs.meta (100%) rename Scripts/{ => RequestResponse}/AsyncResponseData.cs (100%) rename Scripts/{ => RequestResponse}/AsyncResponseData.cs.meta (100%) rename Scripts/{ => RequestResponse}/LiteNetLibRequestCallback.cs (100%) rename Scripts/{ => RequestResponse}/LiteNetLibRequestCallback.cs.meta (100%) rename Scripts/{ => RequestResponse}/LiteNetLibRequestHandler.cs (100%) rename Scripts/{ => RequestResponse}/LiteNetLibRequestHandler.cs.meta (100%) rename Scripts/{ => RequestResponse}/LiteNetLibResponseHandler.cs (100%) rename Scripts/{ => RequestResponse}/LiteNetLibResponseHandler.cs.meta (100%) rename Scripts/{ => RequestResponse}/RequestHandlerData.cs (100%) rename Scripts/{ => RequestResponse}/RequestHandlerData.cs.meta (100%) rename Scripts/{ => RequestResponse}/ResponseHandlerData.cs (100%) rename Scripts/{ => RequestResponse}/ResponseHandlerData.cs.meta (100%) diff --git a/Scripts/RequestResponse.meta b/Scripts/RequestResponse.meta new file mode 100644 index 00000000..371695a4 --- /dev/null +++ b/Scripts/RequestResponse.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 44487af731033274392d0b7803976880 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/AckResponseCode.cs b/Scripts/RequestResponse/AckResponseCode.cs similarity index 100% rename from Scripts/AckResponseCode.cs rename to Scripts/RequestResponse/AckResponseCode.cs diff --git a/Scripts/AckResponseCode.cs.meta b/Scripts/RequestResponse/AckResponseCode.cs.meta similarity index 100% rename from Scripts/AckResponseCode.cs.meta rename to Scripts/RequestResponse/AckResponseCode.cs.meta diff --git a/Scripts/AsyncResponseData.cs b/Scripts/RequestResponse/AsyncResponseData.cs similarity index 100% rename from Scripts/AsyncResponseData.cs rename to Scripts/RequestResponse/AsyncResponseData.cs diff --git a/Scripts/AsyncResponseData.cs.meta b/Scripts/RequestResponse/AsyncResponseData.cs.meta similarity index 100% rename from Scripts/AsyncResponseData.cs.meta rename to Scripts/RequestResponse/AsyncResponseData.cs.meta diff --git a/Scripts/LiteNetLibRequestCallback.cs b/Scripts/RequestResponse/LiteNetLibRequestCallback.cs similarity index 100% rename from Scripts/LiteNetLibRequestCallback.cs rename to Scripts/RequestResponse/LiteNetLibRequestCallback.cs diff --git a/Scripts/LiteNetLibRequestCallback.cs.meta b/Scripts/RequestResponse/LiteNetLibRequestCallback.cs.meta similarity index 100% rename from Scripts/LiteNetLibRequestCallback.cs.meta rename to Scripts/RequestResponse/LiteNetLibRequestCallback.cs.meta diff --git a/Scripts/LiteNetLibRequestHandler.cs b/Scripts/RequestResponse/LiteNetLibRequestHandler.cs similarity index 100% rename from Scripts/LiteNetLibRequestHandler.cs rename to Scripts/RequestResponse/LiteNetLibRequestHandler.cs diff --git a/Scripts/LiteNetLibRequestHandler.cs.meta b/Scripts/RequestResponse/LiteNetLibRequestHandler.cs.meta similarity index 100% rename from Scripts/LiteNetLibRequestHandler.cs.meta rename to Scripts/RequestResponse/LiteNetLibRequestHandler.cs.meta diff --git a/Scripts/LiteNetLibResponseHandler.cs b/Scripts/RequestResponse/LiteNetLibResponseHandler.cs similarity index 100% rename from Scripts/LiteNetLibResponseHandler.cs rename to Scripts/RequestResponse/LiteNetLibResponseHandler.cs diff --git a/Scripts/LiteNetLibResponseHandler.cs.meta b/Scripts/RequestResponse/LiteNetLibResponseHandler.cs.meta similarity index 100% rename from Scripts/LiteNetLibResponseHandler.cs.meta rename to Scripts/RequestResponse/LiteNetLibResponseHandler.cs.meta diff --git a/Scripts/RequestHandlerData.cs b/Scripts/RequestResponse/RequestHandlerData.cs similarity index 100% rename from Scripts/RequestHandlerData.cs rename to Scripts/RequestResponse/RequestHandlerData.cs diff --git a/Scripts/RequestHandlerData.cs.meta b/Scripts/RequestResponse/RequestHandlerData.cs.meta similarity index 100% rename from Scripts/RequestHandlerData.cs.meta rename to Scripts/RequestResponse/RequestHandlerData.cs.meta diff --git a/Scripts/ResponseHandlerData.cs b/Scripts/RequestResponse/ResponseHandlerData.cs similarity index 100% rename from Scripts/ResponseHandlerData.cs rename to Scripts/RequestResponse/ResponseHandlerData.cs diff --git a/Scripts/ResponseHandlerData.cs.meta b/Scripts/RequestResponse/ResponseHandlerData.cs.meta similarity index 100% rename from Scripts/ResponseHandlerData.cs.meta rename to Scripts/RequestResponse/ResponseHandlerData.cs.meta From 014401091db631b5ba774808f25352e11152ea01 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:38:34 +0700 Subject: [PATCH 13/58] improve: change folder structure (Extensions) --- Scripts/Extensions.meta | 8 ++++++++ Scripts/{ => Extensions}/NetDataReaderExtension.cs | 0 Scripts/{ => Extensions}/NetDataReaderExtension.cs.meta | 0 Scripts/{ => Extensions}/NetDataWriterExtension.cs | 0 Scripts/{ => Extensions}/NetDataWriterExtension.cs.meta | 0 5 files changed, 8 insertions(+) create mode 100644 Scripts/Extensions.meta rename Scripts/{ => Extensions}/NetDataReaderExtension.cs (100%) rename Scripts/{ => Extensions}/NetDataReaderExtension.cs.meta (100%) rename Scripts/{ => Extensions}/NetDataWriterExtension.cs (100%) rename Scripts/{ => Extensions}/NetDataWriterExtension.cs.meta (100%) diff --git a/Scripts/Extensions.meta b/Scripts/Extensions.meta new file mode 100644 index 00000000..fb042adf --- /dev/null +++ b/Scripts/Extensions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9cf71a7213b6b7f408bcf479ef541e9b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/NetDataReaderExtension.cs b/Scripts/Extensions/NetDataReaderExtension.cs similarity index 100% rename from Scripts/NetDataReaderExtension.cs rename to Scripts/Extensions/NetDataReaderExtension.cs diff --git a/Scripts/NetDataReaderExtension.cs.meta b/Scripts/Extensions/NetDataReaderExtension.cs.meta similarity index 100% rename from Scripts/NetDataReaderExtension.cs.meta rename to Scripts/Extensions/NetDataReaderExtension.cs.meta diff --git a/Scripts/NetDataWriterExtension.cs b/Scripts/Extensions/NetDataWriterExtension.cs similarity index 100% rename from Scripts/NetDataWriterExtension.cs rename to Scripts/Extensions/NetDataWriterExtension.cs diff --git a/Scripts/NetDataWriterExtension.cs.meta b/Scripts/Extensions/NetDataWriterExtension.cs.meta similarity index 100% rename from Scripts/NetDataWriterExtension.cs.meta rename to Scripts/Extensions/NetDataWriterExtension.cs.meta From 09bd4440bdd85f7601b722daa8333e33ba8f1ed4 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:39:26 +0700 Subject: [PATCH 14/58] improve: change folder structure (Logging) --- Scripts/Logging.meta | 8 ++++++++ Scripts/{ => Logging}/ELogLevel.cs | 0 Scripts/{ => Logging}/ELogLevel.cs.meta | 0 Scripts/{ => Logging}/LogManager.cs | 0 Scripts/{ => Logging}/LogManager.cs.meta | 0 Scripts/{ => Logging}/Logging.cs | 0 Scripts/{ => Logging}/Logging.cs.meta | 0 7 files changed, 8 insertions(+) create mode 100644 Scripts/Logging.meta rename Scripts/{ => Logging}/ELogLevel.cs (100%) rename Scripts/{ => Logging}/ELogLevel.cs.meta (100%) rename Scripts/{ => Logging}/LogManager.cs (100%) rename Scripts/{ => Logging}/LogManager.cs.meta (100%) rename Scripts/{ => Logging}/Logging.cs (100%) rename Scripts/{ => Logging}/Logging.cs.meta (100%) diff --git a/Scripts/Logging.meta b/Scripts/Logging.meta new file mode 100644 index 00000000..b68d718e --- /dev/null +++ b/Scripts/Logging.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 93a6d604ae590004f9bad01ff8f87151 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/ELogLevel.cs b/Scripts/Logging/ELogLevel.cs similarity index 100% rename from Scripts/ELogLevel.cs rename to Scripts/Logging/ELogLevel.cs diff --git a/Scripts/ELogLevel.cs.meta b/Scripts/Logging/ELogLevel.cs.meta similarity index 100% rename from Scripts/ELogLevel.cs.meta rename to Scripts/Logging/ELogLevel.cs.meta diff --git a/Scripts/LogManager.cs b/Scripts/Logging/LogManager.cs similarity index 100% rename from Scripts/LogManager.cs rename to Scripts/Logging/LogManager.cs diff --git a/Scripts/LogManager.cs.meta b/Scripts/Logging/LogManager.cs.meta similarity index 100% rename from Scripts/LogManager.cs.meta rename to Scripts/Logging/LogManager.cs.meta diff --git a/Scripts/Logging.cs b/Scripts/Logging/Logging.cs similarity index 100% rename from Scripts/Logging.cs rename to Scripts/Logging/Logging.cs diff --git a/Scripts/Logging.cs.meta b/Scripts/Logging/Logging.cs.meta similarity index 100% rename from Scripts/Logging.cs.meta rename to Scripts/Logging/Logging.cs.meta From bab0924ac8badf3e0265855ef4067f2cea3f018c Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Wed, 26 Apr 2023 21:39:39 +0700 Subject: [PATCH 15/58] improve: change folder structure (Messages) --- Scripts/Messages.meta | 8 ++++++++ Scripts/{GameApi => }/Messages/EmptyMessage.cs | 0 Scripts/{GameApi => }/Messages/EmptyMessage.cs.meta | 0 Scripts/{ => Messages}/MessageHandlerData.cs | 0 Scripts/{ => Messages}/MessageHandlerData.cs.meta | 0 5 files changed, 8 insertions(+) create mode 100644 Scripts/Messages.meta rename Scripts/{GameApi => }/Messages/EmptyMessage.cs (100%) rename Scripts/{GameApi => }/Messages/EmptyMessage.cs.meta (100%) rename Scripts/{ => Messages}/MessageHandlerData.cs (100%) rename Scripts/{ => Messages}/MessageHandlerData.cs.meta (100%) diff --git a/Scripts/Messages.meta b/Scripts/Messages.meta new file mode 100644 index 00000000..2c58d2fa --- /dev/null +++ b/Scripts/Messages.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6aff29967eeb8f04a9f910a5e8a9fcf5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/GameApi/Messages/EmptyMessage.cs b/Scripts/Messages/EmptyMessage.cs similarity index 100% rename from Scripts/GameApi/Messages/EmptyMessage.cs rename to Scripts/Messages/EmptyMessage.cs diff --git a/Scripts/GameApi/Messages/EmptyMessage.cs.meta b/Scripts/Messages/EmptyMessage.cs.meta similarity index 100% rename from Scripts/GameApi/Messages/EmptyMessage.cs.meta rename to Scripts/Messages/EmptyMessage.cs.meta diff --git a/Scripts/MessageHandlerData.cs b/Scripts/Messages/MessageHandlerData.cs similarity index 100% rename from Scripts/MessageHandlerData.cs rename to Scripts/Messages/MessageHandlerData.cs diff --git a/Scripts/MessageHandlerData.cs.meta b/Scripts/Messages/MessageHandlerData.cs.meta similarity index 100% rename from Scripts/MessageHandlerData.cs.meta rename to Scripts/Messages/MessageHandlerData.cs.meta From d6854692b8ef7f5dc987f5a7ed8be36111aae5f7 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 00:45:20 +0700 Subject: [PATCH 16/58] Revert "feat: delete codes for Unity (PackedVariables)" This reverts commit e964fdde578af97a0555ed4cce30184a9608566b. --- Scripts/PackedVariables/DirectionVector2.cs | 31 +++++++++++++++++ .../PackedVariables/DirectionVector2.cs.meta | 11 +++++++ Scripts/PackedVariables/DirectionVector3.cs | 33 +++++++++++++++++++ .../PackedVariables/DirectionVector3.cs.meta | 11 +++++++ 4 files changed, 86 insertions(+) create mode 100644 Scripts/PackedVariables/DirectionVector2.cs create mode 100644 Scripts/PackedVariables/DirectionVector2.cs.meta create mode 100644 Scripts/PackedVariables/DirectionVector3.cs create mode 100644 Scripts/PackedVariables/DirectionVector3.cs.meta diff --git a/Scripts/PackedVariables/DirectionVector2.cs b/Scripts/PackedVariables/DirectionVector2.cs new file mode 100644 index 00000000..502f3e4a --- /dev/null +++ b/Scripts/PackedVariables/DirectionVector2.cs @@ -0,0 +1,31 @@ +using UnityEngine; +using LiteNetLib.Utils; + +public struct DirectionVector2 : INetSerializable +{ + public static implicit operator DirectionVector2(Vector2 value) { return new DirectionVector2(value); } + public static implicit operator DirectionVector2(Vector3 value) { return new DirectionVector2(value); } + public static implicit operator Vector2(DirectionVector2 value) { return new Vector2((float)value.x / 100f, (float)value.y / 100f); } + public static implicit operator Vector3(DirectionVector2 value) { return new Vector2((float)value.x / 100f, (float)value.y / 100f); } + + public sbyte x; + public sbyte y; + + public DirectionVector2(Vector2 vector2) + { + x = (sbyte)(vector2.x * 100); + y = (sbyte)(vector2.y * 100); + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(x); + writer.Put(y); + } + + public void Deserialize(NetDataReader reader) + { + x = reader.GetSByte(); + y = reader.GetSByte(); + } +} diff --git a/Scripts/PackedVariables/DirectionVector2.cs.meta b/Scripts/PackedVariables/DirectionVector2.cs.meta new file mode 100644 index 00000000..65cf13fe --- /dev/null +++ b/Scripts/PackedVariables/DirectionVector2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 614856a984a532b41af2b7d04e5daac7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/PackedVariables/DirectionVector3.cs b/Scripts/PackedVariables/DirectionVector3.cs new file mode 100644 index 00000000..1c481bf5 --- /dev/null +++ b/Scripts/PackedVariables/DirectionVector3.cs @@ -0,0 +1,33 @@ +using UnityEngine; +using LiteNetLib.Utils; + +public struct DirectionVector3 : INetSerializable +{ + public static implicit operator DirectionVector3(Vector3 value) { return new DirectionVector3(value); } + public static implicit operator Vector3(DirectionVector3 value) { return new Vector3((float)value.x / 100f, (float)value.y / 100f, (float)value.z / 100f); } + + public sbyte x; + public sbyte y; + public sbyte z; + + public DirectionVector3(Vector3 vector3) + { + x = (sbyte)(vector3.x * 100); + y = (sbyte)(vector3.y * 100); + z = (sbyte)(vector3.z * 100); + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(x); + writer.Put(y); + writer.Put(z); + } + + public void Deserialize(NetDataReader reader) + { + x = reader.GetSByte(); + y = reader.GetSByte(); + z = reader.GetSByte(); + } +} diff --git a/Scripts/PackedVariables/DirectionVector3.cs.meta b/Scripts/PackedVariables/DirectionVector3.cs.meta new file mode 100644 index 00000000..69f23628 --- /dev/null +++ b/Scripts/PackedVariables/DirectionVector3.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 708f62165f063f04caf500f67a4a3311 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From af72d6584cedc4f3bbdf1070fde16f7adeea9581 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 00:46:44 +0700 Subject: [PATCH 17/58] Revert "feat: delete codes for Unity, changes some for NET7" This reverts commit 4cbc224511f2c4ba0c662812f3eefff9f4a40ee8. --- Scripts/Extensions/NetDataReaderExtension.cs | 64 ++++++++++++ Scripts/Extensions/NetDataWriterExtension.cs | 98 +++++++++++++++++++ Scripts/LiteNetLibManager.cs | 49 +++++++++- Scripts/Logging/LogManager.cs | 29 ++++-- Scripts/Logging/Logging.cs | 43 ++++++++ Scripts/TransportHandler.cs | 2 +- Scripts/Transports/BaseTransportFactory.cs | 6 +- .../LiteNetLib/LiteNetLibTransportFactory.cs | 6 +- 8 files changed, 281 insertions(+), 16 deletions(-) diff --git a/Scripts/Extensions/NetDataReaderExtension.cs b/Scripts/Extensions/NetDataReaderExtension.cs index 1dc30ae7..12e308b2 100644 --- a/Scripts/Extensions/NetDataReaderExtension.cs +++ b/Scripts/Extensions/NetDataReaderExtension.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using UnityEngine; namespace LiteNetLib.Utils { @@ -56,6 +57,29 @@ public static object GetValue(this NetDataReader reader, Type type) return reader.GetPackedUShort(); #endregion + #region Unity Values + if (type == typeof(Color)) + return reader.GetColor(); + + if (type == typeof(Quaternion)) + return reader.GetQuaternion(); + + if (type == typeof(Vector2)) + return reader.GetVector2(); + + if (type == typeof(Vector2Int)) + return reader.GetVector2Int(); + + if (type == typeof(Vector3)) + return reader.GetVector3(); + + if (type == typeof(Vector3Int)) + return reader.GetVector3Int(); + + if (type == typeof(Vector4)) + return reader.GetVector4(); + #endregion + if (typeof(INetSerializable).IsAssignableFrom(type)) { object instance = Activator.CreateInstance(type); @@ -66,6 +90,46 @@ public static object GetValue(this NetDataReader reader, Type type) throw new ArgumentException("NetDataReader cannot read type " + type.Name); } + public static Color GetColor(this NetDataReader reader) + { + float r = reader.GetByte() * 0.01f; + float g = reader.GetByte() * 0.01f; + float b = reader.GetByte() * 0.01f; + float a = reader.GetByte() * 0.01f; + return new Color(r, g, b, a); + } + + public static Quaternion GetQuaternion(this NetDataReader reader) + { + Vector3 vector3 = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); + return vector3.sqrMagnitude <= 0 ? Quaternion.identity : Quaternion.Euler(vector3); + } + + public static Vector2 GetVector2(this NetDataReader reader) + { + return new Vector2(reader.GetFloat(), reader.GetFloat()); + } + + public static Vector2Int GetVector2Int(this NetDataReader reader) + { + return new Vector2Int(reader.GetInt(), reader.GetInt()); + } + + public static Vector3 GetVector3(this NetDataReader reader) + { + return new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); + } + + public static Vector3Int GetVector3Int(this NetDataReader reader) + { + return new Vector3Int(reader.GetInt(), reader.GetInt(), reader.GetInt()); + } + + public static Vector4 GetVector4(this NetDataReader reader) + { + return new Vector4(reader.GetFloat(), reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); + } + public static TValue[] GetArray(this NetDataReader reader) { int count = reader.GetInt(); diff --git a/Scripts/Extensions/NetDataWriterExtension.cs b/Scripts/Extensions/NetDataWriterExtension.cs index 87d5a394..e920eba5 100644 --- a/Scripts/Extensions/NetDataWriterExtension.cs +++ b/Scripts/Extensions/NetDataWriterExtension.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using UnityEngine; namespace LiteNetLib.Utils { @@ -95,6 +96,50 @@ public static void PutValue(this NetDataWriter writer, Type type, object value) } #endregion + #region Unity Values + if (type == typeof(Color)) + { + writer.PutColor((Color)value); + return; + } + + if (type == typeof(Quaternion)) + { + writer.PutQuaternion((Quaternion)value); + return; + } + + if (type == typeof(Vector2)) + { + writer.PutVector2((Vector2)value); + return; + } + + if (type == typeof(Vector2Int)) + { + writer.PutVector2Int((Vector2Int)value); + return; + } + + if (type == typeof(Vector3)) + { + writer.PutVector3((Vector3)value); + return; + } + + if (type == typeof(Vector3Int)) + { + writer.PutVector3Int((Vector3Int)value); + return; + } + + if (type == typeof(Vector4)) + { + writer.PutVector4((Vector4)value); + return; + } + #endregion + if (typeof(INetSerializable).IsAssignableFrom(type)) { (value as INetSerializable).Serialize(writer); @@ -104,6 +149,59 @@ public static void PutValue(this NetDataWriter writer, Type type, object value) throw new ArgumentException("NetDataWriter cannot write type " + value.GetType().Name); } + public static void PutColor(this NetDataWriter writer, Color value) + { + byte r = (byte)(value.r * 100f); + byte g = (byte)(value.g * 100f); + byte b = (byte)(value.b * 100f); + byte a = (byte)(value.a * 100f); + writer.Put(r); + writer.Put(g); + writer.Put(b); + writer.Put(a); + } + + public static void PutQuaternion(this NetDataWriter writer, Quaternion value) + { + writer.Put(value.eulerAngles.x); + writer.Put(value.eulerAngles.y); + writer.Put(value.eulerAngles.z); + } + + public static void PutVector2(this NetDataWriter writer, Vector2 value) + { + writer.Put(value.x); + writer.Put(value.y); + } + + public static void PutVector2Int(this NetDataWriter writer, Vector2Int value) + { + writer.Put(value.x); + writer.Put(value.y); + } + + public static void PutVector3(this NetDataWriter writer, Vector3 value) + { + writer.Put(value.x); + writer.Put(value.y); + writer.Put(value.z); + } + + public static void PutVector3Int(this NetDataWriter writer, Vector3Int value) + { + writer.Put(value.x); + writer.Put(value.y); + writer.Put(value.z); + } + + public static void PutVector4(this NetDataWriter writer, Vector4 value) + { + writer.Put(value.x); + writer.Put(value.y); + writer.Put(value.z); + writer.Put(value.w); + } + public static void PutArray(this NetDataWriter writer, TValue[] array) { if (array == null) diff --git a/Scripts/LiteNetLibManager.cs b/Scripts/LiteNetLibManager.cs index 3f2a451c..1f5e4e2f 100644 --- a/Scripts/LiteNetLibManager.cs +++ b/Scripts/LiteNetLibManager.cs @@ -1,13 +1,14 @@ using System.Collections.Generic; using System.Net; using System.Net.Sockets; +using UnityEngine; using LiteNetLib; using LiteNetLib.Utils; using Cysharp.Threading.Tasks; namespace LiteNetLibManager { - public class LiteNetLibManager + public class LiteNetLibManager : MonoBehaviour { public LiteNetLibClient Client { get; protected set; } public LiteNetLibServer Server { get; protected set; } @@ -22,10 +23,20 @@ public class LiteNetLibManager public bool LogError { get { return currentLogLevel.IsLogError(); } } public bool LogFatal { get { return currentLogLevel.IsLogFatal(); } } + [Header("Client & Server Settings")] public ELogLevel currentLogLevel = ELogLevel.Info; public string networkAddress = "localhost"; public int networkPort = 7770; + public bool useWebSocket = false; + public bool webSocketSecure = false; + public string webSocketCertificateFilePath = string.Empty; + public string webSocketCertificatePassword = string.Empty; + + [Header("Server Only Settings")] public int maxConnections = 4; + + [Header("Transport Layer Settings")] + [SerializeField] private BaseTransportFactory transportFactory; public BaseTransportFactory TransportFactory { @@ -53,20 +64,48 @@ public virtual string LogTag get { if (string.IsNullOrEmpty(logTag)) - logTag = $"{GetType().Name}"; + logTag = $"{name}({GetType().Name})"; return logTag; } } - public LiteNetLibManager() + protected virtual void Start() { InitTransportAndHandlers(); } protected void PrepareTransportFactory() { - if (transportFactory == null) - transportFactory = new LiteNetLibTransportFactory(); +#if UNITY_WEBGL && !UNITY_EDITOR + // Force to use websocket transport if it's running as webgl + if (transportFactory == null || !(transportFactory is IWebSocketTransportFactory)) + { + WebSocketTransportFactory webSocketTransportFactory = gameObject.AddComponent(); + webSocketTransportFactory.Secure = webSocketSecure; + webSocketTransportFactory.CertificateFilePath = webSocketCertificateFilePath; + webSocketTransportFactory.CertificatePassword = webSocketCertificatePassword; + transportFactory = webSocketTransportFactory; + } +#else + if (useWebSocket) + { + if (transportFactory == null || !(transportFactory is IWebSocketTransportFactory)) + { + WebSocketTransportFactory webSocketTransportFactory = gameObject.AddComponent(); + webSocketTransportFactory.Secure = webSocketSecure; + webSocketTransportFactory.CertificateFilePath = webSocketCertificateFilePath; + webSocketTransportFactory.CertificatePassword = webSocketCertificatePassword; + transportFactory = webSocketTransportFactory; + } + } + else + { + if (transportFactory == null) + transportFactory = GetComponent(); + if (transportFactory == null) + transportFactory = gameObject.AddComponent(); + } +#endif } public void PrepareClientTransport() diff --git a/Scripts/Logging/LogManager.cs b/Scripts/Logging/LogManager.cs index 61e22cf0..21891dab 100644 --- a/Scripts/Logging/LogManager.cs +++ b/Scripts/Logging/LogManager.cs @@ -28,6 +28,15 @@ public LoggerManager(ILoggerFactory loggerFactory) _loggerByTags.Clear(); _loggerFactory = loggerFactory; _defaultLogger = loggerFactory.CreateLogger("No Tag"); + + UnityEngine.Application.quitting += () => + { + // when quit, flush unfinished log entries. + if (_loggerFactory != null) + _loggerFactory.Dispose(); + _loggerFactory = null; + IsDisposed = true; + }; } public ILogger GetLogger() where T : class @@ -54,22 +63,28 @@ public static partial class LogManager public static LoggerManager WarningLoggerManager { get; set; } public static LoggerManager ErrorLoggerManager { get; set; } - static LogManager() - { - Initialize(); - } + [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.BeforeSceneLoad)] public static void Initialize() { // Standard LoggerFactory does not work on IL2CPP, // But you can use ZLogger's UnityLoggerFactory instead, // it works on IL2CPP, all platforms(includes mobile). - DefaultLoggerManager = new LoggerManager(LoggerFactory.Create(builder => + DefaultLoggerManager = new LoggerManager(UnityLoggerFactory.Create(builder => { // or more configuration, you can use builder.AddFilter - builder.ClearProviders(); builder.SetMinimumLevel(LogLevel.Trace); - builder.AddZLoggerConsole(); + + // AddZLoggerUnityDebug is only available for Unity, it send log to UnityEngine.Debug.Log. + // LogLevels are translate to + // * Trace/Debug/Information -> LogType.Log + // * Warning/Critical -> LogType.Warning + // * Error without Exception -> LogType.Error + // * Error with Exception -> LogException + builder.AddZLoggerUnityDebug(options => + { + options.PrefixFormatter = PrefixFormatterConfigure; + }); })); DefaultLoggerManager.Logger.LogInformation("===== Logger Initialized ====="); diff --git a/Scripts/Logging/Logging.cs b/Scripts/Logging/Logging.cs index 5d624fd8..ab387fa9 100644 --- a/Scripts/Logging/Logging.cs +++ b/Scripts/Logging/Logging.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Logging; +using UnityEngine; namespace LiteNetLibManager { @@ -14,7 +15,13 @@ public static void Log(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsLoggerDisposed) + { + if (args.Length > 0) + Debug.Log(string.Format($"[{tag}] {message}", args)); + else + Debug.Log($"[{tag}] {message}"); return; + } LogManager.GetLogger(tag).LogInformation(message, args); } @@ -28,7 +35,13 @@ public static void LogError(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsErrorLoggerDisposed) + { + if (args.Length > 0) + Debug.LogError(string.Format($"[{tag}] {message}", args)); + else + Debug.LogError($"[{tag}] {message}"); return; + } LogManager.GetErrorLogger(tag).LogError(message, args); } @@ -42,7 +55,13 @@ public static void LogWarning(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsWarningLoggerDisposed) + { + if (args.Length > 0) + Debug.LogWarning(string.Format($"[{tag}] {message}", args)); + else + Debug.LogWarning($"[{tag}] {message}"); return; + } LogManager.GetWarningLogger(tag).LogWarning(message, args); } @@ -51,7 +70,10 @@ public static void LogException(string tag, System.Exception ex) if (ex == null) return; if (LogManager.IsErrorLoggerDisposed) + { + Debug.LogError($"[{tag}] {ex}"); return; + } LogManager.GetErrorLogger(tag).LogError(ex.ToString()); } @@ -65,7 +87,13 @@ public static void Log(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsLoggerDisposed) + { + if (args.Length > 0) + Debug.Log(string.Format($"{message}", args)); + else + Debug.Log($"{message}"); return; + } LogManager.Logger.LogInformation(message, args); } @@ -79,7 +107,13 @@ public static void LogError(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsErrorLoggerDisposed) + { + if (args.Length > 0) + Debug.LogError(string.Format($"{message}", args)); + else + Debug.LogError($"{message}"); return; + } LogManager.ErrorLogger.LogError(message, args); } @@ -93,7 +127,13 @@ public static void LogWarning(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsWarningLoggerDisposed) + { + if (args.Length > 0) + Debug.LogWarning(string.Format($"{message}", args)); + else + Debug.LogWarning($"{message}"); return; + } LogManager.WarningLogger.LogWarning(message, args); } @@ -102,7 +142,10 @@ public static void LogException(System.Exception ex) if (ex == null) return; if (LogManager.IsErrorLoggerDisposed) + { + Debug.LogError($"{ex}"); return; + } LogManager.ErrorLogger.LogError(ex.ToString()); } } diff --git a/Scripts/TransportHandler.cs b/Scripts/TransportHandler.cs index 6a3ecab7..2e6ed4a3 100644 --- a/Scripts/TransportHandler.cs +++ b/Scripts/TransportHandler.cs @@ -124,7 +124,7 @@ private async UniTaskVoid HandleRequestTimeout(uint requestId, int millisecondsT { if (millisecondsTimeout > 0) { - await Task.Delay(millisecondsTimeout); + await UniTask.Delay(millisecondsTimeout); LiteNetLibRequestCallback callback; if (requestCallbacks.TryRemove(requestId, out callback)) callback.ResponseTimeout(); diff --git a/Scripts/Transports/BaseTransportFactory.cs b/Scripts/Transports/BaseTransportFactory.cs index f1b79140..90ace274 100644 --- a/Scripts/Transports/BaseTransportFactory.cs +++ b/Scripts/Transports/BaseTransportFactory.cs @@ -1,6 +1,8 @@ -namespace LiteNetLibManager +using UnityEngine; + +namespace LiteNetLibManager { - public abstract class BaseTransportFactory + public abstract class BaseTransportFactory : MonoBehaviour { public abstract ITransport Build(); } diff --git a/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs b/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs index eed491d7..488756be 100644 --- a/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs +++ b/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs @@ -1,9 +1,13 @@ -namespace LiteNetLibManager +using UnityEngine; + +namespace LiteNetLibManager { public class LiteNetLibTransportFactory : BaseTransportFactory { public string connectKey = "SampleConnectKey"; + [Range(1, 64)] public byte clientDataChannelsCount = 16; + [Range(1, 64)] public byte serverDataChannelsCount = 16; public override ITransport Build() From fc60b188176f730347fc24c0cd78c0f2d66804cc Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 00:58:16 +0700 Subject: [PATCH 18/58] feat: change quaternion serialization --- Scripts/Extensions/NetDataReaderExtension.cs | 3 +-- Scripts/Extensions/NetDataWriterExtension.cs | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Scripts/Extensions/NetDataReaderExtension.cs b/Scripts/Extensions/NetDataReaderExtension.cs index 12e308b2..3f241725 100644 --- a/Scripts/Extensions/NetDataReaderExtension.cs +++ b/Scripts/Extensions/NetDataReaderExtension.cs @@ -101,8 +101,7 @@ public static Color GetColor(this NetDataReader reader) public static Quaternion GetQuaternion(this NetDataReader reader) { - Vector3 vector3 = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - return vector3.sqrMagnitude <= 0 ? Quaternion.identity : Quaternion.Euler(vector3); + return new Quaternion(reader.GetFloat(), reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); } public static Vector2 GetVector2(this NetDataReader reader) diff --git a/Scripts/Extensions/NetDataWriterExtension.cs b/Scripts/Extensions/NetDataWriterExtension.cs index e920eba5..a5db112a 100644 --- a/Scripts/Extensions/NetDataWriterExtension.cs +++ b/Scripts/Extensions/NetDataWriterExtension.cs @@ -163,9 +163,10 @@ public static void PutColor(this NetDataWriter writer, Color value) public static void PutQuaternion(this NetDataWriter writer, Quaternion value) { - writer.Put(value.eulerAngles.x); - writer.Put(value.eulerAngles.y); - writer.Put(value.eulerAngles.z); + writer.Put(value.x); + writer.Put(value.y); + writer.Put(value.z); + writer.Put(value.w); } public static void PutVector2(this NetDataWriter writer, Vector2 value) From 3622746c4e08f5cbce0fd497a25f9ecc8e42de3e Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 00:58:33 +0700 Subject: [PATCH 19/58] feat: add Unity data types --- Scripts/EngineData/Unity/Color.cs | 18 ++++++++++++++++++ Scripts/EngineData/Unity/Quaternion.cs | 18 ++++++++++++++++++ Scripts/EngineData/Unity/Vector2.cs | 14 ++++++++++++++ Scripts/EngineData/Unity/Vector2Int.cs | 14 ++++++++++++++ Scripts/EngineData/Unity/Vector3.cs | 16 ++++++++++++++++ Scripts/EngineData/Unity/Vector3Int.cs | 16 ++++++++++++++++ Scripts/EngineData/Unity/Vector4.cs | 18 ++++++++++++++++++ 7 files changed, 114 insertions(+) create mode 100644 Scripts/EngineData/Unity/Color.cs create mode 100644 Scripts/EngineData/Unity/Quaternion.cs create mode 100644 Scripts/EngineData/Unity/Vector2.cs create mode 100644 Scripts/EngineData/Unity/Vector2Int.cs create mode 100644 Scripts/EngineData/Unity/Vector3.cs create mode 100644 Scripts/EngineData/Unity/Vector3Int.cs create mode 100644 Scripts/EngineData/Unity/Vector4.cs diff --git a/Scripts/EngineData/Unity/Color.cs b/Scripts/EngineData/Unity/Color.cs new file mode 100644 index 00000000..e22e7584 --- /dev/null +++ b/Scripts/EngineData/Unity/Color.cs @@ -0,0 +1,18 @@ +namespace UnityEngine +{ + public struct Color + { + public float r { get; set; } + public float g { get; set; } + public float b { get; set; } + public float a { get; set; } + + public Color(float r, float g, float b, float a) + { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + } +} diff --git a/Scripts/EngineData/Unity/Quaternion.cs b/Scripts/EngineData/Unity/Quaternion.cs new file mode 100644 index 00000000..41e078a8 --- /dev/null +++ b/Scripts/EngineData/Unity/Quaternion.cs @@ -0,0 +1,18 @@ +namespace UnityEngine +{ + public struct Quaternion + { + public float x { get; set; } + public float y { get; set; } + public float z { get; set; } + public float w { get; set; } + + public Quaternion(float x, float y, float z, float w) + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + } +} diff --git a/Scripts/EngineData/Unity/Vector2.cs b/Scripts/EngineData/Unity/Vector2.cs new file mode 100644 index 00000000..6e8d1ece --- /dev/null +++ b/Scripts/EngineData/Unity/Vector2.cs @@ -0,0 +1,14 @@ +namespace UnityEngine +{ + public struct Vector2 + { + public float x { get; set; } + public float y { get; set; } + + public Vector2(float x, float y) + { + this.x = x; + this.y = y; + } + } +} diff --git a/Scripts/EngineData/Unity/Vector2Int.cs b/Scripts/EngineData/Unity/Vector2Int.cs new file mode 100644 index 00000000..0ba37431 --- /dev/null +++ b/Scripts/EngineData/Unity/Vector2Int.cs @@ -0,0 +1,14 @@ +namespace UnityEngine +{ + public struct Vector2Int + { + public int x { get; set; } + public int y { get; set; } + + public Vector2Int(int x, int y) + { + this.x = x; + this.y = y; + } + } +} diff --git a/Scripts/EngineData/Unity/Vector3.cs b/Scripts/EngineData/Unity/Vector3.cs new file mode 100644 index 00000000..2e548b77 --- /dev/null +++ b/Scripts/EngineData/Unity/Vector3.cs @@ -0,0 +1,16 @@ +namespace UnityEngine +{ + public struct Vector3 + { + public float x { get; set; } + public float y { get; set; } + public float z { get; set; } + + public Vector3(float x, float y, float z) + { + this.x = x; + this.y = y; + this.z = z; + } + } +} diff --git a/Scripts/EngineData/Unity/Vector3Int.cs b/Scripts/EngineData/Unity/Vector3Int.cs new file mode 100644 index 00000000..4d5acad2 --- /dev/null +++ b/Scripts/EngineData/Unity/Vector3Int.cs @@ -0,0 +1,16 @@ +namespace UnityEngine +{ + public struct Vector3Int + { + public int x { get; set; } + public int y { get; set; } + public int z { get; set; } + + public Vector3Int(int x, int y, int z) + { + this.x = x; + this.y = y; + this.z = z; + } + } +} diff --git a/Scripts/EngineData/Unity/Vector4.cs b/Scripts/EngineData/Unity/Vector4.cs new file mode 100644 index 00000000..4b39da0e --- /dev/null +++ b/Scripts/EngineData/Unity/Vector4.cs @@ -0,0 +1,18 @@ +namespace UnityEngine +{ + public struct Vector4 + { + public float x { get; set; } + public float y { get; set; } + public float z { get; set; } + public float w { get; set; } + + public Vector4(float x, float y, float z, float w) + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + } +} From ab042179168efaed37cddaea19b1616443410888 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 00:58:46 +0700 Subject: [PATCH 20/58] Delete unused meta files --- Scripts/GameApi/Messages.meta | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 Scripts/GameApi/Messages.meta diff --git a/Scripts/GameApi/Messages.meta b/Scripts/GameApi/Messages.meta deleted file mode 100644 index 375cfe70..00000000 --- a/Scripts/GameApi/Messages.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 23d41bd091637764b80d267ef3099a9d -folderAsset: yes -timeCreated: 1509078803 -licenseType: Pro -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: From 37ee1fc8144bd3e67881be88bde3b2e733f7a2d3 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 00:58:58 +0700 Subject: [PATCH 21/58] feat: delete codes for Unity, changes some for NET7 --- Scripts/TransportHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/TransportHandler.cs b/Scripts/TransportHandler.cs index 2e6ed4a3..6a3ecab7 100644 --- a/Scripts/TransportHandler.cs +++ b/Scripts/TransportHandler.cs @@ -124,7 +124,7 @@ private async UniTaskVoid HandleRequestTimeout(uint requestId, int millisecondsT { if (millisecondsTimeout > 0) { - await UniTask.Delay(millisecondsTimeout); + await Task.Delay(millisecondsTimeout); LiteNetLibRequestCallback callback; if (requestCallbacks.TryRemove(requestId, out callback)) callback.ResponseTimeout(); From 87f53649de873a817481802355f4fab99ccf0401 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 01:02:24 +0700 Subject: [PATCH 22/58] feat: delete codes for Unity, changes some for NET7 (Logging) --- Scripts/Logging/LogManager.cs | 29 ++++++----------------- Scripts/Logging/Logging.cs | 43 ----------------------------------- 2 files changed, 7 insertions(+), 65 deletions(-) diff --git a/Scripts/Logging/LogManager.cs b/Scripts/Logging/LogManager.cs index 21891dab..61e22cf0 100644 --- a/Scripts/Logging/LogManager.cs +++ b/Scripts/Logging/LogManager.cs @@ -28,15 +28,6 @@ public LoggerManager(ILoggerFactory loggerFactory) _loggerByTags.Clear(); _loggerFactory = loggerFactory; _defaultLogger = loggerFactory.CreateLogger("No Tag"); - - UnityEngine.Application.quitting += () => - { - // when quit, flush unfinished log entries. - if (_loggerFactory != null) - _loggerFactory.Dispose(); - _loggerFactory = null; - IsDisposed = true; - }; } public ILogger GetLogger() where T : class @@ -63,28 +54,22 @@ public static partial class LogManager public static LoggerManager WarningLoggerManager { get; set; } public static LoggerManager ErrorLoggerManager { get; set; } + static LogManager() + { + Initialize(); + } - [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.BeforeSceneLoad)] public static void Initialize() { // Standard LoggerFactory does not work on IL2CPP, // But you can use ZLogger's UnityLoggerFactory instead, // it works on IL2CPP, all platforms(includes mobile). - DefaultLoggerManager = new LoggerManager(UnityLoggerFactory.Create(builder => + DefaultLoggerManager = new LoggerManager(LoggerFactory.Create(builder => { // or more configuration, you can use builder.AddFilter + builder.ClearProviders(); builder.SetMinimumLevel(LogLevel.Trace); - - // AddZLoggerUnityDebug is only available for Unity, it send log to UnityEngine.Debug.Log. - // LogLevels are translate to - // * Trace/Debug/Information -> LogType.Log - // * Warning/Critical -> LogType.Warning - // * Error without Exception -> LogType.Error - // * Error with Exception -> LogException - builder.AddZLoggerUnityDebug(options => - { - options.PrefixFormatter = PrefixFormatterConfigure; - }); + builder.AddZLoggerConsole(); })); DefaultLoggerManager.Logger.LogInformation("===== Logger Initialized ====="); diff --git a/Scripts/Logging/Logging.cs b/Scripts/Logging/Logging.cs index ab387fa9..5d624fd8 100644 --- a/Scripts/Logging/Logging.cs +++ b/Scripts/Logging/Logging.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Logging; -using UnityEngine; namespace LiteNetLibManager { @@ -15,13 +14,7 @@ public static void Log(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsLoggerDisposed) - { - if (args.Length > 0) - Debug.Log(string.Format($"[{tag}] {message}", args)); - else - Debug.Log($"[{tag}] {message}"); return; - } LogManager.GetLogger(tag).LogInformation(message, args); } @@ -35,13 +28,7 @@ public static void LogError(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsErrorLoggerDisposed) - { - if (args.Length > 0) - Debug.LogError(string.Format($"[{tag}] {message}", args)); - else - Debug.LogError($"[{tag}] {message}"); return; - } LogManager.GetErrorLogger(tag).LogError(message, args); } @@ -55,13 +42,7 @@ public static void LogWarning(string tag, string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsWarningLoggerDisposed) - { - if (args.Length > 0) - Debug.LogWarning(string.Format($"[{tag}] {message}", args)); - else - Debug.LogWarning($"[{tag}] {message}"); return; - } LogManager.GetWarningLogger(tag).LogWarning(message, args); } @@ -70,10 +51,7 @@ public static void LogException(string tag, System.Exception ex) if (ex == null) return; if (LogManager.IsErrorLoggerDisposed) - { - Debug.LogError($"[{tag}] {ex}"); return; - } LogManager.GetErrorLogger(tag).LogError(ex.ToString()); } @@ -87,13 +65,7 @@ public static void Log(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsLoggerDisposed) - { - if (args.Length > 0) - Debug.Log(string.Format($"{message}", args)); - else - Debug.Log($"{message}"); return; - } LogManager.Logger.LogInformation(message, args); } @@ -107,13 +79,7 @@ public static void LogError(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsErrorLoggerDisposed) - { - if (args.Length > 0) - Debug.LogError(string.Format($"{message}", args)); - else - Debug.LogError($"{message}"); return; - } LogManager.ErrorLogger.LogError(message, args); } @@ -127,13 +93,7 @@ public static void LogWarning(string message, params object[] args) if (string.IsNullOrEmpty(message)) return; if (LogManager.IsWarningLoggerDisposed) - { - if (args.Length > 0) - Debug.LogWarning(string.Format($"{message}", args)); - else - Debug.LogWarning($"{message}"); return; - } LogManager.WarningLogger.LogWarning(message, args); } @@ -142,10 +102,7 @@ public static void LogException(System.Exception ex) if (ex == null) return; if (LogManager.IsErrorLoggerDisposed) - { - Debug.LogError($"{ex}"); return; - } LogManager.ErrorLogger.LogError(ex.ToString()); } } From a9afa87276ece15abc49cf483afac6f43d9e2fee Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 01:02:40 +0700 Subject: [PATCH 23/58] feat: delete codes for Unity, changes some for NET7 (Transport) --- Scripts/Transports/BaseTransportFactory.cs | 6 ++---- Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Scripts/Transports/BaseTransportFactory.cs b/Scripts/Transports/BaseTransportFactory.cs index 90ace274..f1b79140 100644 --- a/Scripts/Transports/BaseTransportFactory.cs +++ b/Scripts/Transports/BaseTransportFactory.cs @@ -1,8 +1,6 @@ -using UnityEngine; - -namespace LiteNetLibManager +namespace LiteNetLibManager { - public abstract class BaseTransportFactory : MonoBehaviour + public abstract class BaseTransportFactory { public abstract ITransport Build(); } diff --git a/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs b/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs index 488756be..6d14c842 100644 --- a/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs +++ b/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs @@ -5,9 +5,7 @@ namespace LiteNetLibManager public class LiteNetLibTransportFactory : BaseTransportFactory { public string connectKey = "SampleConnectKey"; - [Range(1, 64)] public byte clientDataChannelsCount = 16; - [Range(1, 64)] public byte serverDataChannelsCount = 16; public override ITransport Build() From 9ed28d5088b08ca3a27a7c6420671e87a2484957 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 01:03:17 +0700 Subject: [PATCH 24/58] Revert "feat: delete codes for Unity (Transports)" This reverts commit 02bb81e8438a4c388eb7f95736a8a1d7ffba8935. --- Scripts/Transports/MixTransport.meta | 8 + .../Transports/MixTransport/MixTransport.cs | 342 ++++++++++++++++++ .../MixTransport/MixTransport.cs.meta | 11 + .../MixTransport/MixTransportEventListener.cs | 105 ++++++ .../MixTransportEventListener.cs.meta | 11 + .../MixTransport/MixTransportFactory.cs | 34 ++ .../MixTransport/MixTransportFactory.cs.meta | 11 + Scripts/Transports/WebSocket.meta | 8 + .../WebSocket/WebSocketTransport.cs | 234 ++++++++++++ .../WebSocket/WebSocketTransport.cs.meta | 11 + .../WebSocket/WebSocketTransportFactory.cs | 23 ++ .../WebSocketTransportFactory.cs.meta | 11 + .../Transports/WebSocket/WsClientWrapper.cs | 227 ++++++++++++ .../WebSocket/WsClientWrapper.cs.meta | 11 + .../Transports/WebSocket/WsTransportClient.cs | 78 ++++ .../WebSocket/WsTransportClient.cs.meta | 11 + .../Transports/WebSocket/WsTransportServer.cs | 52 +++ .../WebSocket/WsTransportServer.cs.meta | 11 + .../WebSocket/WsTransportSession.cs | 76 ++++ .../WebSocket/WsTransportSession.cs.meta | 11 + .../WebSocket/WssTransportClient.cs | 78 ++++ .../WebSocket/WssTransportClient.cs.meta | 11 + .../WebSocket/WssTransportServer.cs | 52 +++ .../WebSocket/WssTransportServer.cs.meta | 11 + .../WebSocket/WssTransportSession.cs | 76 ++++ .../WebSocket/WssTransportSession.cs.meta | 11 + 26 files changed, 1525 insertions(+) create mode 100644 Scripts/Transports/MixTransport.meta create mode 100644 Scripts/Transports/MixTransport/MixTransport.cs create mode 100644 Scripts/Transports/MixTransport/MixTransport.cs.meta create mode 100644 Scripts/Transports/MixTransport/MixTransportEventListener.cs create mode 100644 Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta create mode 100644 Scripts/Transports/MixTransport/MixTransportFactory.cs create mode 100644 Scripts/Transports/MixTransport/MixTransportFactory.cs.meta create mode 100644 Scripts/Transports/WebSocket.meta create mode 100644 Scripts/Transports/WebSocket/WebSocketTransport.cs create mode 100644 Scripts/Transports/WebSocket/WebSocketTransport.cs.meta create mode 100644 Scripts/Transports/WebSocket/WebSocketTransportFactory.cs create mode 100644 Scripts/Transports/WebSocket/WebSocketTransportFactory.cs.meta create mode 100644 Scripts/Transports/WebSocket/WsClientWrapper.cs create mode 100644 Scripts/Transports/WebSocket/WsClientWrapper.cs.meta create mode 100644 Scripts/Transports/WebSocket/WsTransportClient.cs create mode 100644 Scripts/Transports/WebSocket/WsTransportClient.cs.meta create mode 100644 Scripts/Transports/WebSocket/WsTransportServer.cs create mode 100644 Scripts/Transports/WebSocket/WsTransportServer.cs.meta create mode 100644 Scripts/Transports/WebSocket/WsTransportSession.cs create mode 100644 Scripts/Transports/WebSocket/WsTransportSession.cs.meta create mode 100644 Scripts/Transports/WebSocket/WssTransportClient.cs create mode 100644 Scripts/Transports/WebSocket/WssTransportClient.cs.meta create mode 100644 Scripts/Transports/WebSocket/WssTransportServer.cs create mode 100644 Scripts/Transports/WebSocket/WssTransportServer.cs.meta create mode 100644 Scripts/Transports/WebSocket/WssTransportSession.cs create mode 100644 Scripts/Transports/WebSocket/WssTransportSession.cs.meta diff --git a/Scripts/Transports/MixTransport.meta b/Scripts/Transports/MixTransport.meta new file mode 100644 index 00000000..754a0b89 --- /dev/null +++ b/Scripts/Transports/MixTransport.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f6c248b4fca205743a0a14cb8bb4692e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/MixTransport/MixTransport.cs b/Scripts/Transports/MixTransport/MixTransport.cs new file mode 100644 index 00000000..a0861c33 --- /dev/null +++ b/Scripts/Transports/MixTransport/MixTransport.cs @@ -0,0 +1,342 @@ +using System.Collections.Generic; +using LiteNetLib; +using LiteNetLib.Utils; +using System.Collections.Concurrent; +using System.Net; +using System.Net.Security; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +#if !UNITY_WEBGL || UNITY_EDITOR +using NetCoreServer; +#endif + +namespace LiteNetLibManager +{ + public sealed class MixTransport : ITransport, ITransportConnectionGenerator + { + private long _nextConnectionId = 1; + private bool _webSocketSecure; + private string _webSocketCertificateFilePath; + private string _webSocketCertificatePassword; + + // WebSocket data +#if UNITY_WEBGL + private WsClientWrapper _wsClient; +#endif +#if !UNITY_WEBGL || UNITY_EDITOR + private WsTransportServer _wsServer; + private WssTransportServer _wssServer; +#endif + + // LiteNetLib data + public NetManager Client { get; private set; } + public NetManager Server { get; private set; } + public string ConnectKey { get; private set; } + public int ServerPeersCount + { + get + { + int result = 0; + if (Server != null) + result += Server.ConnectedPeersCount; +#if !UNITY_WEBGL + if (!_webSocketSecure) + { + if (_wsServer != null) + result += _wsServer.PeersCount; + } + else + { + if (_wssServer != null) + result += _wssServer.PeersCount; + } +#endif + return result; + } + } + public int ServerMaxConnections { get; private set; } + public bool IsClientStarted + { + get + { +#if UNITY_WEBGL + return _wsClient.IsClientStarted; +#else + return Client != null && Client.FirstPeer != null && Client.FirstPeer.ConnectionState == ConnectionState.Connected; +#endif + } + } + public bool IsServerStarted + { + get + { +#if UNITY_WEBGL + // Don't integrate server networking to WebGL clients + return false; +#else + if (Server == null) + return false; + if (!_webSocketSecure) + return _wsServer != null && _wsServer.IsStarted; + else + return _wssServer != null && _wssServer.IsStarted; +#endif + } + } + + public bool HasImplementedPing + { + get + { +#if UNITY_WEBGL + return false; +#else + return true; +#endif + } + } + + private readonly Dictionary _serverPeers = new Dictionary(); + private readonly ConcurrentQueue _clientEventQueue = new ConcurrentQueue(); + private readonly ConcurrentQueue _serverEventQueue = new ConcurrentQueue(); + private readonly byte _clientDataChannelsCount; + private readonly byte _serverDataChannelsCount; + private readonly int _webSocketPortOffset; + + public MixTransport(string connectKey, int webSocketPortOffset, bool webSocketSecure, string webSocketCertificateFilePath, string webSocketCertificatePassword, byte clientDataChannelsCount, byte serverDataChannelsCount) + { + ConnectKey = connectKey; + _clientDataChannelsCount = clientDataChannelsCount; + _serverDataChannelsCount = serverDataChannelsCount; + _webSocketPortOffset = webSocketPortOffset; + _webSocketSecure = webSocketSecure; + _webSocketCertificateFilePath = webSocketCertificateFilePath; + _webSocketCertificatePassword = webSocketCertificatePassword; +#if UNITY_WEBGL + _wsClient = new WsClientWrapper(_clientEventQueue, webSocketSecure, SslProtocols.Tls12); +#endif + } + + public bool StartClient(string address, int port) + { + while (_clientEventQueue.TryDequeue(out _)) { } +#if UNITY_WEBGL + return _wsClient.StartClient(address, port); +#else + Client = new NetManager(new MixTransportEventListener(this, _clientEventQueue)); + Client.ChannelsCount = _clientDataChannelsCount; + return Client.Start() && Client.Connect(address, port, ConnectKey) != null; +#endif + } + + public void StopClient() + { +#if UNITY_WEBGL + _wsClient.StopClient(); +#else + if (Client != null) + Client.Stop(); + Client = null; +#endif + } + + public bool ClientReceive(out TransportEventData eventData) + { + eventData = default(TransportEventData); +#if UNITY_WEBGL + return _wsClient.ClientReceive(out eventData); +#else + if (Client == null) + return false; + Client.PollEvents(); + if (_clientEventQueue.Count == 0) + return false; + return _clientEventQueue.TryDequeue(out eventData); +#endif + } + + public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { +#if UNITY_WEBGL + return _wsClient.ClientSend(dataChannel, deliveryMethod, writer); +#else + if (IsClientStarted) + { + Client.FirstPeer.Send(writer, dataChannel, deliveryMethod); + return true; + } + return false; +#endif + } + + public bool StartServer(int port, int maxConnections) + { +#if UNITY_WEBGL + // Don't integrate server networking to WebGL clients + return false; +#else + if (IsServerStarted) + return false; + + ServerMaxConnections = maxConnections; + while (_serverEventQueue.TryDequeue(out _)) { } + + // Start WebSocket Server + if (!_webSocketSecure) + { + _wsServer = new WsTransportServer(this, IPAddress.Any, port + _webSocketPortOffset, maxConnections); + _wsServer.OptionDualMode = true; + _wsServer.OptionNoDelay = true; + if (!_wsServer.Start()) + return false; + } + else + { + SslContext context = new SslContext(SslProtocols.Tls12, new X509Certificate2(_webSocketCertificateFilePath, _webSocketCertificatePassword), CertValidationCallback); + _wssServer = new WssTransportServer(this, context, IPAddress.Any, port + _webSocketPortOffset, maxConnections); + _wssServer.OptionDualMode = true; + _wssServer.OptionNoDelay = true; + if (!_wssServer.Start()) + return false; + } + + // Start LiteNetLib Server + _serverPeers.Clear(); + Server = new NetManager(new MixTransportEventListener(this, _serverEventQueue, _serverPeers)); + Server.ChannelsCount = _serverDataChannelsCount; + return Server.Start(port); +#endif + } + + private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + return sslPolicyErrors == SslPolicyErrors.None; + } + + public bool ServerReceive(out TransportEventData eventData) + { + eventData = default(TransportEventData); +#if UNITY_WEBGL + // Don't integrate server networking to WebGL clients + return false; +#else + if (!IsServerStarted) + return false; + + if (!_webSocketSecure) + { + if (_wsServer.EventQueue.Count > 0) + return _wsServer.EventQueue.TryDequeue(out eventData); + } + else + { + if (_wssServer.EventQueue.Count > 0) + return _wssServer.EventQueue.TryDequeue(out eventData); + } + + Server.PollEvents(); + if (_serverEventQueue.Count > 0) + return _serverEventQueue.TryDequeue(out eventData); + + return false; +#endif + } + + public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { +#if !UNITY_WEBGL + // WebSocket Server Send + if (!_webSocketSecure) + { + if (_wsServer != null && _wsServer.SendAsync(connectionId, writer.Data)) + return true; + } + else + { + if (_wssServer != null && _wssServer.SendAsync(connectionId, writer.Data)) + return true; + } + + // LiteNetLib Server Send + if (IsServerStarted && _serverPeers.ContainsKey(connectionId) && _serverPeers[connectionId].ConnectionState == ConnectionState.Connected) + { + _serverPeers[connectionId].Send(writer, dataChannel, deliveryMethod); + return true; + } +#endif + return false; + } + + public bool ServerDisconnect(long connectionId) + { +#if !UNITY_WEBGL + // WebSocket Server Disconnect + if (!_webSocketSecure) + { + if (_wsServer != null && _wsServer.Disconnect(connectionId)) + return true; + } + else + { + if (_wssServer != null && _wssServer.Disconnect(connectionId)) + return true; + } + + // LiteNetLib Server Disconnect + if (IsServerStarted && _serverPeers.ContainsKey(connectionId)) + { + Server.DisconnectPeer(_serverPeers[connectionId]); + _serverPeers.Remove(connectionId); + return true; + } +#endif + return false; + } + + public void StopServer() + { +#if !UNITY_WEBGL + if (_wsServer != null) + _wsServer.Dispose(); + if (_wssServer != null) + _wssServer.Dispose(); + _wsServer = null; + _wssServer = null; + if (Server != null) + Server.Stop(); + Server = null; + _nextConnectionId = 1; +#endif + } + + public void Destroy() + { + StopClient(); + StopServer(); + } + + public long GetNewConnectionID() + { + return Interlocked.Increment(ref _nextConnectionId); + } + + public long GetClientRtt() + { +#if UNITY_WEBGL + return 0; +#else + return Client.FirstPeer.RoundTripTime; +#endif + } + + public long GetServerRtt(long connectionId) + { +#if UNITY_WEBGL + return 0; +#else + return _serverPeers[connectionId].RoundTripTime; +#endif + } + } +} diff --git a/Scripts/Transports/MixTransport/MixTransport.cs.meta b/Scripts/Transports/MixTransport/MixTransport.cs.meta new file mode 100644 index 00000000..c2476fc4 --- /dev/null +++ b/Scripts/Transports/MixTransport/MixTransport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56e230e8b15094340bbaada6eb24a5bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/MixTransport/MixTransportEventListener.cs b/Scripts/Transports/MixTransport/MixTransportEventListener.cs new file mode 100644 index 00000000..e7308541 --- /dev/null +++ b/Scripts/Transports/MixTransport/MixTransportEventListener.cs @@ -0,0 +1,105 @@ +using LiteNetLib; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; + +namespace LiteNetLibManager +{ + public class MixTransportEventListener : INetEventListener + { + private MixTransport mixTransport; + private ConcurrentQueue eventQueue; + private Dictionary peersDict; + private Dictionary peerIdsDict; + + public MixTransportEventListener(MixTransport mixTransport, ConcurrentQueue eventQueue) + { + // This is constructor for client + this.mixTransport = mixTransport; + this.eventQueue = eventQueue; + } + + public MixTransportEventListener(MixTransport mixTransport, ConcurrentQueue eventQueue, Dictionary peersDict) : this(mixTransport, eventQueue) + { + // This is constructor for server + this.peersDict = peersDict; + peerIdsDict = new Dictionary(); + } + + public void OnConnectionRequest(ConnectionRequest request) + { + if (mixTransport.Server.ConnectedPeersCount < mixTransport.ServerMaxConnections) + request.AcceptIfKey(mixTransport.ConnectKey); + else + request.Reject(); + } + + public void OnNetworkError(IPEndPoint endPoint, SocketError socketError) + { + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + endPoint = endPoint, + socketError = socketError, + }); + } + + public void OnNetworkLatencyUpdate(NetPeer peer, int latency) + { + } + + public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) + { + long tempConnectionId = 0; + if (peerIdsDict != null && peersDict != null) + tempConnectionId = peerIdsDict[peer.Id]; + + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DataEvent, + connectionId = tempConnectionId, + reader = reader, + }); + } + + public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) + { + } + + public void OnPeerConnected(NetPeer peer) + { + long tempConnectionId = 0; + if (peerIdsDict != null && peersDict != null) + { + tempConnectionId = mixTransport.GetNewConnectionID(); + peersDict[tempConnectionId] = peer; + peerIdsDict[peer.Id] = tempConnectionId; + } + + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ConnectEvent, + connectionId = tempConnectionId, + }); + } + + public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) + { + long tempConnectionId = 0; + if (peerIdsDict != null && peersDict != null) + { + tempConnectionId = peerIdsDict[peer.Id]; + peersDict.Remove(tempConnectionId); + peerIdsDict.Remove(peer.Id); + } + + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DisconnectEvent, + connectionId = tempConnectionId, + disconnectInfo = disconnectInfo, + }); + } + } +} diff --git a/Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta b/Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta new file mode 100644 index 00000000..5346cdfa --- /dev/null +++ b/Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eab9350e2510f084599682f02cc2cd08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/MixTransport/MixTransportFactory.cs b/Scripts/Transports/MixTransport/MixTransportFactory.cs new file mode 100644 index 00000000..24556288 --- /dev/null +++ b/Scripts/Transports/MixTransport/MixTransportFactory.cs @@ -0,0 +1,34 @@ +using System.Security.Authentication; +using UnityEngine; + +namespace LiteNetLibManager +{ + public class MixTransportFactory : BaseTransportFactory, IWebSocketTransportFactory + { + [SerializeField] + private string connectKey = "SampleConnectKey"; + [SerializeField] + private int webSocketPortOffset = 100; + [SerializeField] + private bool webSocketSecure = false; + [SerializeField] + private string webSocketCertificateFilePath = string.Empty; + [SerializeField] + private string webSocketCertificatePassword = string.Empty; + [Range(1, 64)] + [SerializeField] + private byte clientDataChannelsCount = 16; + [Range(1, 64)] + [SerializeField] + private byte serverDataChannelsCount = 16; + public bool Secure { get { return webSocketSecure; } set { webSocketSecure = value; } } + public string CertificateFilePath { get { return webSocketCertificateFilePath; } set { webSocketCertificateFilePath = value; } } + public string CertificatePassword { get { return webSocketCertificatePassword; } set { webSocketCertificatePassword = value; } } + + + public override ITransport Build() + { + return new MixTransport(connectKey, webSocketPortOffset, webSocketSecure, webSocketCertificateFilePath, webSocketCertificatePassword, clientDataChannelsCount, serverDataChannelsCount); + } + } +} diff --git a/Scripts/Transports/MixTransport/MixTransportFactory.cs.meta b/Scripts/Transports/MixTransport/MixTransportFactory.cs.meta new file mode 100644 index 00000000..9e41db6f --- /dev/null +++ b/Scripts/Transports/MixTransport/MixTransportFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1edd61c62fd42fc4ea55540e9ba136b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket.meta b/Scripts/Transports/WebSocket.meta new file mode 100644 index 00000000..548ee264 --- /dev/null +++ b/Scripts/Transports/WebSocket.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8eadfb8d08f063342b86d0fb9024a345 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WebSocketTransport.cs b/Scripts/Transports/WebSocket/WebSocketTransport.cs new file mode 100644 index 00000000..cadf2468 --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketTransport.cs @@ -0,0 +1,234 @@ +using LiteNetLib; +using LiteNetLib.Utils; +using System.Collections.Concurrent; +using System.Net; +using System.Net.Security; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +#if !UNITY_WEBGL || UNITY_EDITOR +using NetCoreServer; +#endif + +namespace LiteNetLibManager +{ + public class WebSocketTransport : ITransport, ITransportConnectionGenerator + { + private long _nextConnectionId = 1; + private bool _secure; + private string _certificateFilePath; + private string _certificatePassword; + private readonly ConcurrentQueue _clientEventQueue; + private WsClientWrapper _wsClient; +#if !UNITY_WEBGL || UNITY_EDITOR + private WsTransportServer _wsServer; + private WssTransportServer _wssServer; +#endif + + public bool IsClientStarted + { + get { return _wsClient.IsClientStarted; } + } + + public bool IsServerStarted + { + get + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (!_secure) + return _wsServer != null && _wsServer.IsStarted; + else + return _wssServer != null && _wssServer.IsStarted; +#else + return false; +#endif + } + } + + public int ServerPeersCount + { + get + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (!_secure) + { + if (_wsServer != null) + return _wsServer.PeersCount; + } + else + { + if (_wssServer != null) + return _wssServer.PeersCount; + } +#endif + return 0; + } + } + + public int ServerMaxConnections + { + get + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (!_secure) + { + if (_wsServer != null) + return _wsServer.MaxConnections; + } + else + { + if (_wssServer != null) + return _wssServer.MaxConnections; + } +#endif + return 0; + } + } + + public bool HasImplementedPing + { + get { return false; } + } + + public WebSocketTransport(bool secure, string certificateFilePath, string certificatePassword) + { + _secure = secure; + _certificateFilePath = certificateFilePath; + _certificatePassword = certificatePassword; + _clientEventQueue = new ConcurrentQueue(); + _wsClient = new WsClientWrapper(_clientEventQueue, secure, SslProtocols.Tls12); + } + + public bool StartClient(string address, int port) + { + while (_clientEventQueue.TryDequeue(out _)) { } + return _wsClient.StartClient(address, port); + } + + public void StopClient() + { + _wsClient.StopClient(); + } + + public bool ClientReceive(out TransportEventData eventData) + { + return _wsClient.ClientReceive(out eventData); + } + + public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { + return _wsClient.ClientSend(dataChannel, deliveryMethod, writer); + } + + public bool StartServer(int port, int maxConnections) + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (IsServerStarted) + return false; + if (!_secure) + { + _wsServer = new WsTransportServer(this, IPAddress.Any, port, maxConnections); + _wsServer.OptionDualMode = true; + _wsServer.OptionNoDelay = true; + return _wsServer.Start(); + } + else + { + SslContext context = new SslContext(SslProtocols.Tls12, new X509Certificate2(_certificateFilePath, _certificatePassword), CertValidationCallback); + _wssServer = new WssTransportServer(this, context, IPAddress.Any, port, maxConnections); + _wssServer.OptionDualMode = true; + _wssServer.OptionNoDelay = true; + return _wssServer.Start(); + } +#else + return false; +#endif + } + + private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + return true; + } + + public bool ServerReceive(out TransportEventData eventData) + { + eventData = default(TransportEventData); +#if !UNITY_WEBGL || UNITY_EDITOR + if (!IsServerStarted) + return false; + if (!_secure) + { + if (_wsServer.EventQueue.Count == 0) + return false; + return _wsServer.EventQueue.TryDequeue(out eventData); + } + else + { + if (_wssServer.EventQueue.Count == 0) + return false; + return _wssServer.EventQueue.TryDequeue(out eventData); + } +#else + return false; +#endif + } + + public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (!_secure) + return _wsServer != null && _wsServer.SendAsync(connectionId, writer.Data); + else + return _wssServer != null && _wssServer.SendAsync(connectionId, writer.Data); +#else + return false; +#endif + } + + public bool ServerDisconnect(long connectionId) + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (!_secure) + return _wsServer != null && _wsServer.Disconnect(connectionId); + else + return _wssServer != null && _wssServer.Disconnect(connectionId); +#else + return false; +#endif + } + + public void StopServer() + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (_wsServer != null) + _wsServer.Dispose(); + if (_wssServer != null) + _wssServer.Dispose(); + _wsServer = null; + _wssServer = null; + _nextConnectionId = 1; +#endif + } + + public void Destroy() + { + StopClient(); + StopServer(); + } + + public long GetNewConnectionID() + { + return Interlocked.Increment(ref _nextConnectionId); + } + + public long GetClientRtt() + { + throw new System.NotImplementedException(); + } + + public long GetServerRtt(long connectionId) + { + throw new System.NotImplementedException(); + } + } +} diff --git a/Scripts/Transports/WebSocket/WebSocketTransport.cs.meta b/Scripts/Transports/WebSocket/WebSocketTransport.cs.meta new file mode 100644 index 00000000..03df1eb0 --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketTransport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f09e5c02836e9f41921a402bfaadf1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs new file mode 100644 index 00000000..4eee84d7 --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs @@ -0,0 +1,23 @@ +using System.Security.Authentication; +using UnityEngine; + +namespace LiteNetLibManager +{ + public class WebSocketTransportFactory : BaseTransportFactory, IWebSocketTransportFactory + { + [SerializeField] + private bool secure = false; + [SerializeField] + private string certificateFilePath = string.Empty; + [SerializeField] + private string certificatePassword = string.Empty; + public bool Secure { get { return secure; } set { secure = value; } } + public string CertificateFilePath { get { return certificateFilePath; } set { certificateFilePath = value; } } + public string CertificatePassword { get { return certificatePassword; } set { certificatePassword = value; } } + + public override ITransport Build() + { + return new WebSocketTransport(secure, certificateFilePath, certificatePassword); + } + } +} diff --git a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs.meta b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs.meta new file mode 100644 index 00000000..26621c1a --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 910acc198833e5443b3409d90e6afb4e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsClientWrapper.cs b/Scripts/Transports/WebSocket/WsClientWrapper.cs new file mode 100644 index 00000000..cbe8fed0 --- /dev/null +++ b/Scripts/Transports/WebSocket/WsClientWrapper.cs @@ -0,0 +1,227 @@ +using LiteNetLib; +using System.Net.Security; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Collections.Concurrent; +using LiteNetLib.Utils; +using System.Net; +using System.Net.Sockets; +using System; +using System.Runtime.InteropServices; +using System.Text; +#if !UNITY_WEBGL || UNITY_EDITOR +using NetCoreServer; +#endif + +namespace LiteNetLibManager +{ + public class WsClientWrapper + { +#if UNITY_WEBGL && !UNITY_EDITOR + [DllImport("__Internal")] + private static extern int SocketCreate_LnlM(string url); + [DllImport("__Internal")] + private static extern int GetSocketState_LnlM(int wsNativeInstance); + [DllImport("__Internal")] + private static extern int GetSocketEventType_LnlM(int wsNativeInstance); + [DllImport("__Internal")] + private static extern int GetSocketErrorCode_LnlM(int wsNativeInstance); + [DllImport("__Internal")] + private static extern int GetSocketDataLength_LnlM(int wsNativeInstance); + [DllImport("__Internal")] + private static extern void GetSocketData_LnlM(int wsNativeInstance, byte[] ptr, int length); + [DllImport("__Internal")] + private static extern void SocketEventDequeue_LnlM(int wsNativeInstance); + [DllImport("__Internal")] + private static extern void SocketSend_LnlM(int wsNativeInstance, byte[] ptr, int length); + [DllImport("__Internal")] + private static extern void SocketClose_LnlM(int wsNativeInstance); + + private int wsNativeInstance = -1; + private byte[] tempBuffers; + private bool dirtyIsConnected = false; +#endif + +#if !UNITY_WEBGL || UNITY_EDITOR + private WsTransportClient wsClient; + private WssTransportClient wssClient; +#endif + private readonly ConcurrentQueue clientEventQueue; + private readonly bool secure; + private readonly SslProtocols sslProtocols; + + public bool IsClientStarted + { + get + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (secure) + return wssClient != null && wssClient.IsConnected; + else + return wsClient != null && wsClient.IsConnected; +#else + return GetSocketState_LnlM(wsNativeInstance) == 1; +#endif + } + } + + public WsClientWrapper(ConcurrentQueue clientEventQueue, bool secure, SslProtocols sslProtocols) + { + this.clientEventQueue = clientEventQueue; + this.secure = secure; + this.sslProtocols = sslProtocols; + } + + public bool StartClient(string address, int port) + { + if (IsClientStarted) + { + Logging.Log(nameof(WsClientWrapper), "Client started, so it can't be started again"); + return false; + } +#if !UNITY_WEBGL || UNITY_EDITOR + IPAddress[] ipAddresses = Dns.GetHostAddresses(address); + if (ipAddresses.Length == 0) + { + Logging.Log(nameof(WsClientWrapper), "Cannot find IP addresses from " + address); + return false; + } + + int indexOfAddress = -1; + for (int i = 0; i < ipAddresses.Length; ++i) + { + if (ipAddresses[i].AddressFamily == AddressFamily.InterNetwork) + { + indexOfAddress = i; + break; + } + } + + if (indexOfAddress < 0) + { + Logging.Log(nameof(WsClientWrapper), "Cannot find index of address from " + address); + return false; + } + + string url = (secure ? "wss://" : "ws://") + ipAddresses[indexOfAddress] + ":" + port; + Logging.Log(nameof(WsClientWrapper), $"Connecting to {url}"); + if (secure) + { + SslContext context = new SslContext(sslProtocols, new X509Certificate2(), CertValidationCallback); + wssClient = new WssTransportClient(clientEventQueue, context, ipAddresses[indexOfAddress], port); + wssClient.OptionDualMode = true; + wssClient.OptionNoDelay = true; + return wssClient.ConnectAsync(); + } + else + { + wsClient = new WsTransportClient(clientEventQueue, ipAddresses[indexOfAddress], port); + wsClient.OptionDualMode = true; + wsClient.OptionNoDelay = true; + return wsClient.ConnectAsync(); + } +#else + string url = (secure ? "wss://" : "ws://") + address + ":" + port; + Logging.Log(nameof(WsClientWrapper), $"Connecting to {url}"); + wsNativeInstance = SocketCreate_LnlM(url.ToString()); + return true; +#endif + } + + public void StopClient() + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (wssClient != null) + wssClient.Dispose(); + wssClient = null; + if (wsClient != null) + wsClient.Dispose(); + wsClient = null; +#else + SocketClose_LnlM(wsNativeInstance); +#endif + } + + private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + return true; + } + + public bool ClientReceive(out TransportEventData eventData) + { + eventData = default(TransportEventData); +#if !UNITY_WEBGL || UNITY_EDITOR + if (clientEventQueue.Count == 0) + return false; + return clientEventQueue.TryDequeue(out eventData); +#else + int eventType = GetSocketEventType_LnlM(wsNativeInstance); + if (eventType < 0) + return false; + switch ((ENetworkEvent)eventType) + { + case ENetworkEvent.DataEvent: + eventData.type = ENetworkEvent.DataEvent; + eventData.reader = new NetDataReader(GetSocketData()); + break; + case ENetworkEvent.ConnectEvent: + eventData.type = ENetworkEvent.ConnectEvent; + break; + case ENetworkEvent.DisconnectEvent: + eventData.type = ENetworkEvent.DisconnectEvent; + eventData.disconnectInfo = GetDisconnectInfo(GetSocketErrorCode_LnlM(wsNativeInstance)); + break; + case ENetworkEvent.ErrorEvent: + eventData.type = ENetworkEvent.ErrorEvent; + eventData.errorMessage = GetErrorMessage(GetSocketErrorCode_LnlM(wsNativeInstance)); + break; + } + SocketEventDequeue_LnlM(wsNativeInstance); + return true; +#endif + } + +#if UNITY_WEBGL && !UNITY_EDITOR + private byte[] GetSocketData() + { + int length = GetSocketDataLength_LnlM(wsNativeInstance); + if (length == 0) + return null; + byte[] buffer = new byte[length]; + GetSocketData_LnlM(wsNativeInstance, buffer, length); + return buffer; + } +#endif + +#if UNITY_WEBGL && !UNITY_EDITOR + public string GetErrorMessage(int errorCode) + { + // TODO: Implement this + return string.Empty; + } +#endif + +#if UNITY_WEBGL && !UNITY_EDITOR + public DisconnectInfo GetDisconnectInfo(int errorCode) + { + // TODO: Implement this + return default; + } +#endif + + public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { + if (!IsClientStarted) + return false; +#if !UNITY_WEBGL || UNITY_EDITOR + if (secure) + return wssClient.SendBinaryAsync(writer.Data, 0, writer.Data.Length); + else + return wsClient.SendBinaryAsync(writer.Data, 0, writer.Data.Length); +#else + SocketSend_LnlM(wsNativeInstance, writer.Data, writer.Data.Length); + return true; +#endif + } + } +} diff --git a/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta b/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta new file mode 100644 index 00000000..c3a2e414 --- /dev/null +++ b/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e3299f36c6c27e47935f2cf0616dfde +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsTransportClient.cs b/Scripts/Transports/WebSocket/WsTransportClient.cs new file mode 100644 index 00000000..9513d289 --- /dev/null +++ b/Scripts/Transports/WebSocket/WsTransportClient.cs @@ -0,0 +1,78 @@ +using LiteNetLib.Utils; +using NetCoreServer; +using System; +using System.Collections.Concurrent; +using System.Net; +using System.Net.Sockets; + +namespace LiteNetLibManager +{ + public class WsTransportClient : WsClient + { + private readonly ConcurrentQueue eventQueue; + + public WsTransportClient(ConcurrentQueue eventQueue, IPAddress address, int port) : base(address, port) + { + this.eventQueue = eventQueue; + } + + public override void OnWsConnecting(HttpRequest request) + { + Uri uri = new Uri($"wss://{Endpoint.Address}:{Endpoint.Port}"); + request.SetBegin("GET", uri.PathAndQuery); + request.SetHeader("Host", Endpoint.Port == 80 ? uri.DnsSafeHost : uri.Authority); + request.SetHeader("Upgrade", "websocket"); + request.SetHeader("Connection", "Upgrade"); + request.SetHeader("Sec-WebSocket-Key", Convert.ToBase64String(WsNonce)); + request.SetHeader("Sec-WebSocket-Version", "13"); + request.Cache.Append("\r\n"); + } + + public override void OnWsConnected(HttpResponse response) + { + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ConnectEvent, + }); + } + + protected override void OnDisconnected() + { + base.OnDisconnected(); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DisconnectEvent, + }); + } + + public override void OnWsError(string error) + { + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + errorMessage = error, + }); + } + + protected override void OnError(SocketError error) + { + base.OnError(error); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + socketError = error, + }); + } + + public override void OnWsReceived(byte[] buffer, long offset, long size) + { + byte[] coppiedBuffer = new byte[size]; + Array.Copy(buffer, offset, coppiedBuffer, 0, size); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DataEvent, + reader = new NetDataReader(coppiedBuffer), + }); + } + } +} diff --git a/Scripts/Transports/WebSocket/WsTransportClient.cs.meta b/Scripts/Transports/WebSocket/WsTransportClient.cs.meta new file mode 100644 index 00000000..f9adf82a --- /dev/null +++ b/Scripts/Transports/WebSocket/WsTransportClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ced6efcdfe0e93142ac54704ee49777c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsTransportServer.cs b/Scripts/Transports/WebSocket/WsTransportServer.cs new file mode 100644 index 00000000..26544374 --- /dev/null +++ b/Scripts/Transports/WebSocket/WsTransportServer.cs @@ -0,0 +1,52 @@ +using NetCoreServer; +using System.Collections.Concurrent; +using System.Net; + +namespace LiteNetLibManager +{ + public class WsTransportServer : WsServer + { + public ConcurrentDictionary AcceptedClients { get; private set; } + public ConcurrentQueue EventQueue { get; private set; } + public int PeersCount { get { return AcceptedClients.Count; } } + public int MaxConnections { get; private set; } + + private ITransportConnectionGenerator connectionGenerator; + + public WsTransportServer(ITransportConnectionGenerator connectionGenerator, IPAddress address, int port, int maxConnections) : base(address, port) + { + this.connectionGenerator = connectionGenerator; + AcceptedClients = new ConcurrentDictionary(); + EventQueue = new ConcurrentQueue(); + MaxConnections = maxConnections; + } + + protected override TcpSession CreateSession() + { + WsTransportSession newSession = new WsTransportSession(connectionGenerator.GetNewConnectionID(), this); + if (PeersCount >= MaxConnections) + { + newSession.Disconnect(); + return null; + } + AcceptedClients.TryAdd(newSession.ConnectionId, newSession); + return newSession; + } + + internal bool SendAsync(long connectionId, byte[] buffer) + { + return AcceptedClients.ContainsKey(connectionId) && AcceptedClients[connectionId].SendBinaryAsync(buffer, 0, buffer.Length); + } + + internal bool Disconnect(long connectionId) + { + WsTransportSession session; + if (AcceptedClients.TryRemove(connectionId, out session)) + { + session.Dispose(); + return true; + } + return false; + } + } +} diff --git a/Scripts/Transports/WebSocket/WsTransportServer.cs.meta b/Scripts/Transports/WebSocket/WsTransportServer.cs.meta new file mode 100644 index 00000000..56bf51f1 --- /dev/null +++ b/Scripts/Transports/WebSocket/WsTransportServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d125cf39ccfa55e429fe21497e2f7cb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsTransportSession.cs b/Scripts/Transports/WebSocket/WsTransportSession.cs new file mode 100644 index 00000000..7be9f3a1 --- /dev/null +++ b/Scripts/Transports/WebSocket/WsTransportSession.cs @@ -0,0 +1,76 @@ +using LiteNetLib.Utils; +using NetCoreServer; +using System; +using System.Net.Sockets; + +namespace LiteNetLibManager +{ + public class WsTransportSession : WsSession + { + public long ConnectionId { get; private set; } + + private readonly WsTransportServer _server; + + public WsTransportSession(long connectionId, WsTransportServer server) : base(server) + { + ConnectionId = connectionId; + _server = server; + } + + public override void OnWsConnected(HttpRequest request) + { + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.ConnectEvent, + }); + } + + protected override void OnDisconnected() + { + base.OnDisconnected(); + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.DisconnectEvent, + disconnectInfo = new LiteNetLib.DisconnectInfo() + { + Reason = LiteNetLib.DisconnectReason.RemoteConnectionClose, + }, + }); + } + + public override void OnWsError(string error) + { + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.ErrorEvent, + errorMessage = error, + }); + } + + protected override void OnError(SocketError error) + { + base.OnError(error); + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.ErrorEvent, + socketError = error, + }); + } + + public override void OnWsReceived(byte[] buffer, long offset, long size) + { + byte[] coppiedBuffer = new byte[size]; + Array.Copy(buffer, offset, coppiedBuffer, 0, size); + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.DataEvent, + reader = new NetDataReader(coppiedBuffer), + }); + } + } +} diff --git a/Scripts/Transports/WebSocket/WsTransportSession.cs.meta b/Scripts/Transports/WebSocket/WsTransportSession.cs.meta new file mode 100644 index 00000000..1577484e --- /dev/null +++ b/Scripts/Transports/WebSocket/WsTransportSession.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 28d95ae7bbc891b48b174d9bb18d7297 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportClient.cs b/Scripts/Transports/WebSocket/WssTransportClient.cs new file mode 100644 index 00000000..9de033a3 --- /dev/null +++ b/Scripts/Transports/WebSocket/WssTransportClient.cs @@ -0,0 +1,78 @@ +using LiteNetLib.Utils; +using NetCoreServer; +using System; +using System.Collections.Concurrent; +using System.Net; +using System.Net.Sockets; + +namespace LiteNetLibManager +{ + public class WssTransportClient : WssClient + { + private readonly ConcurrentQueue eventQueue; + + public WssTransportClient(ConcurrentQueue eventQueue, SslContext context, IPAddress address, int port) : base(context, address, port) + { + this.eventQueue = eventQueue; + } + + public override void OnWsConnecting(HttpRequest request) + { + Uri uri = new Uri($"wss://{Endpoint.Address}:{Endpoint.Port}"); + request.SetBegin("GET", uri.PathAndQuery); + request.SetHeader("Host", Endpoint.Port == 443 ? uri.DnsSafeHost : uri.Authority); + request.SetHeader("Upgrade", "websocket"); + request.SetHeader("Connection", "Upgrade"); + request.SetHeader("Sec-WebSocket-Key", Convert.ToBase64String(WsNonce)); + request.SetHeader("Sec-WebSocket-Version", "13"); + request.Cache.Append("\r\n"); + } + + public override void OnWsConnected(HttpResponse response) + { + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ConnectEvent, + }); + } + + protected override void OnDisconnected() + { + base.OnDisconnected(); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DisconnectEvent, + }); + } + + public override void OnWsError(string error) + { + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + errorMessage = error, + }); + } + + protected override void OnError(SocketError error) + { + base.OnError(error); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + socketError = error, + }); + } + + public override void OnWsReceived(byte[] buffer, long offset, long size) + { + byte[] coppiedBuffer = new byte[size]; + Array.Copy(buffer, offset, coppiedBuffer, 0, size); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DataEvent, + reader = new NetDataReader(coppiedBuffer), + }); + } + } +} diff --git a/Scripts/Transports/WebSocket/WssTransportClient.cs.meta b/Scripts/Transports/WebSocket/WssTransportClient.cs.meta new file mode 100644 index 00000000..cc6432f7 --- /dev/null +++ b/Scripts/Transports/WebSocket/WssTransportClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 411ce407868cabf48b577e10208c7de6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportServer.cs b/Scripts/Transports/WebSocket/WssTransportServer.cs new file mode 100644 index 00000000..7d103cbc --- /dev/null +++ b/Scripts/Transports/WebSocket/WssTransportServer.cs @@ -0,0 +1,52 @@ +using NetCoreServer; +using System.Collections.Concurrent; +using System.Net; + +namespace LiteNetLibManager +{ + public class WssTransportServer : WssServer + { + public ConcurrentDictionary AcceptedClients { get; private set; } + public ConcurrentQueue EventQueue { get; private set; } + public int PeersCount { get { return AcceptedClients.Count; } } + public int MaxConnections { get; private set; } + + private ITransportConnectionGenerator connectionGenerator; + + public WssTransportServer(ITransportConnectionGenerator connectionGenerator, SslContext context, IPAddress address, int port, int maxConnections) : base(context, address, port) + { + this.connectionGenerator = connectionGenerator; + AcceptedClients = new ConcurrentDictionary(); + EventQueue = new ConcurrentQueue(); + MaxConnections = maxConnections; + } + + protected override SslSession CreateSession() + { + WssTransportSession newSession = new WssTransportSession(connectionGenerator.GetNewConnectionID(), this); + if (PeersCount >= MaxConnections) + { + newSession.Disconnect(); + return null; + } + AcceptedClients.TryAdd(newSession.ConnectionId, newSession); + return newSession; + } + + internal bool SendAsync(long connectionId, byte[] buffer) + { + return AcceptedClients.ContainsKey(connectionId) && AcceptedClients[connectionId].SendBinaryAsync(buffer, 0, buffer.Length); + } + + internal bool Disconnect(long connectionId) + { + WssTransportSession session; + if (AcceptedClients.TryRemove(connectionId, out session)) + { + session.Dispose(); + return true; + } + return false; + } + } +} diff --git a/Scripts/Transports/WebSocket/WssTransportServer.cs.meta b/Scripts/Transports/WebSocket/WssTransportServer.cs.meta new file mode 100644 index 00000000..bd3ef160 --- /dev/null +++ b/Scripts/Transports/WebSocket/WssTransportServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84aec65ce7a649e4b8f3cc4fb192f821 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportSession.cs b/Scripts/Transports/WebSocket/WssTransportSession.cs new file mode 100644 index 00000000..adab7f4e --- /dev/null +++ b/Scripts/Transports/WebSocket/WssTransportSession.cs @@ -0,0 +1,76 @@ +using LiteNetLib.Utils; +using NetCoreServer; +using System; +using System.Net.Sockets; + +namespace LiteNetLibManager +{ + public class WssTransportSession : WssSession + { + public long ConnectionId { get; private set; } + + private readonly WssTransportServer _server; + + public WssTransportSession(long connectionId, WssTransportServer server) : base(server) + { + ConnectionId = connectionId; + _server = server; + } + + public override void OnWsConnected(HttpRequest request) + { + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.ConnectEvent, + }); + } + + protected override void OnDisconnected() + { + base.OnDisconnected(); + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.DisconnectEvent, + disconnectInfo = new LiteNetLib.DisconnectInfo() + { + Reason = LiteNetLib.DisconnectReason.RemoteConnectionClose, + }, + }); + } + + public override void OnWsError(string error) + { + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.ErrorEvent, + errorMessage = error, + }); + } + + protected override void OnError(SocketError error) + { + base.OnError(error); + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.ErrorEvent, + socketError = error, + }); + } + + public override void OnWsReceived(byte[] buffer, long offset, long size) + { + byte[] coppiedBuffer = new byte[size]; + Array.Copy(buffer, offset, coppiedBuffer, 0, size); + _server.EventQueue.Enqueue(new TransportEventData() + { + connectionId = ConnectionId, + type = ENetworkEvent.DataEvent, + reader = new NetDataReader(coppiedBuffer), + }); + } + } +} diff --git a/Scripts/Transports/WebSocket/WssTransportSession.cs.meta b/Scripts/Transports/WebSocket/WssTransportSession.cs.meta new file mode 100644 index 00000000..cc6a5263 --- /dev/null +++ b/Scripts/Transports/WebSocket/WssTransportSession.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 102c4270c7677314898bb6da06d9f7a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From ab4920da6527b0d950b501f1c32a3d09fdc2ec47 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 01:27:42 +0700 Subject: [PATCH 25/58] feat: delete codes for Unity, changes some for NET7 (Transport) --- .../LiteNetLib/LiteNetLibTransportFactory.cs | 12 +++---- .../MixTransport/MixTransportFactory.cs | 33 +++++-------------- .../WebSocket/WebSocketTransportFactory.cs | 19 +++-------- 3 files changed, 19 insertions(+), 45 deletions(-) diff --git a/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs b/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs index 6d14c842..e59122f3 100644 --- a/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs +++ b/Scripts/Transports/LiteNetLib/LiteNetLibTransportFactory.cs @@ -1,16 +1,14 @@ -using UnityEngine; - -namespace LiteNetLibManager +namespace LiteNetLibManager { public class LiteNetLibTransportFactory : BaseTransportFactory { - public string connectKey = "SampleConnectKey"; - public byte clientDataChannelsCount = 16; - public byte serverDataChannelsCount = 16; + public string ConnectKey { get; set; } = "SampleConnectKey"; + public byte ClientDataChannelsCount { get; set; } = 16; + public byte ServerDataChannelsCount { get; set; } = 16; public override ITransport Build() { - return new LiteNetLibTransport(connectKey, clientDataChannelsCount, serverDataChannelsCount); + return new LiteNetLibTransport(ConnectKey, ClientDataChannelsCount, ServerDataChannelsCount); } } } diff --git a/Scripts/Transports/MixTransport/MixTransportFactory.cs b/Scripts/Transports/MixTransport/MixTransportFactory.cs index 24556288..961f498f 100644 --- a/Scripts/Transports/MixTransport/MixTransportFactory.cs +++ b/Scripts/Transports/MixTransport/MixTransportFactory.cs @@ -1,34 +1,19 @@ -using System.Security.Authentication; -using UnityEngine; - -namespace LiteNetLibManager +namespace LiteNetLibManager { public class MixTransportFactory : BaseTransportFactory, IWebSocketTransportFactory { - [SerializeField] - private string connectKey = "SampleConnectKey"; - [SerializeField] - private int webSocketPortOffset = 100; - [SerializeField] - private bool webSocketSecure = false; - [SerializeField] - private string webSocketCertificateFilePath = string.Empty; - [SerializeField] - private string webSocketCertificatePassword = string.Empty; - [Range(1, 64)] - [SerializeField] - private byte clientDataChannelsCount = 16; - [Range(1, 64)] - [SerializeField] - private byte serverDataChannelsCount = 16; - public bool Secure { get { return webSocketSecure; } set { webSocketSecure = value; } } - public string CertificateFilePath { get { return webSocketCertificateFilePath; } set { webSocketCertificateFilePath = value; } } - public string CertificatePassword { get { return webSocketCertificatePassword; } set { webSocketCertificatePassword = value; } } + public string ConnectKey { get; set; } = "SampleConnectKey"; + public int WebSocketPortOffset { get; set; } = 100; + public byte ClientDataChannelsCount { get; set; } = 16; + public byte ServerDataChannelsCount { get; set; } = 16; + public bool Secure { get; set; } + public string CertificateFilePath { get; set; } = string.Empty; + public string CertificatePassword { get; set; } = string.Empty; public override ITransport Build() { - return new MixTransport(connectKey, webSocketPortOffset, webSocketSecure, webSocketCertificateFilePath, webSocketCertificatePassword, clientDataChannelsCount, serverDataChannelsCount); + return new MixTransport(ConnectKey, WebSocketPortOffset, Secure, CertificateFilePath, CertificatePassword, ClientDataChannelsCount, ServerDataChannelsCount); } } } diff --git a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs index 4eee84d7..8da7f92a 100644 --- a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs +++ b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs @@ -1,23 +1,14 @@ -using System.Security.Authentication; -using UnityEngine; - -namespace LiteNetLibManager +namespace LiteNetLibManager { public class WebSocketTransportFactory : BaseTransportFactory, IWebSocketTransportFactory { - [SerializeField] - private bool secure = false; - [SerializeField] - private string certificateFilePath = string.Empty; - [SerializeField] - private string certificatePassword = string.Empty; - public bool Secure { get { return secure; } set { secure = value; } } - public string CertificateFilePath { get { return certificateFilePath; } set { certificateFilePath = value; } } - public string CertificatePassword { get { return certificatePassword; } set { certificatePassword = value; } } + public bool Secure { get; set; } + public string CertificateFilePath { get; set; } = string.Empty; + public string CertificatePassword { get; set; } = string.Empty; public override ITransport Build() { - return new WebSocketTransport(secure, certificateFilePath, certificatePassword); + return new WebSocketTransport(Secure, CertificateFilePath, CertificatePassword); } } } From 9a2ad5541d395486e9c3c38d1bcb29a011416efd Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 01:27:48 +0700 Subject: [PATCH 26/58] feat: delete codes for Unity, changes some for NET7 (Manager) --- Scripts/LiteNetLibManager.cs | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/Scripts/LiteNetLibManager.cs b/Scripts/LiteNetLibManager.cs index 1f5e4e2f..648afefe 100644 --- a/Scripts/LiteNetLibManager.cs +++ b/Scripts/LiteNetLibManager.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; using System.Net; using System.Net.Sockets; -using UnityEngine; using LiteNetLib; using LiteNetLib.Utils; using Cysharp.Threading.Tasks; namespace LiteNetLibManager { - public class LiteNetLibManager : MonoBehaviour + public class LiteNetLibManager { public LiteNetLibClient Client { get; protected set; } public LiteNetLibServer Server { get; protected set; } @@ -23,7 +22,6 @@ public class LiteNetLibManager : MonoBehaviour public bool LogError { get { return currentLogLevel.IsLogError(); } } public bool LogFatal { get { return currentLogLevel.IsLogFatal(); } } - [Header("Client & Server Settings")] public ELogLevel currentLogLevel = ELogLevel.Info; public string networkAddress = "localhost"; public int networkPort = 7770; @@ -31,12 +29,7 @@ public class LiteNetLibManager : MonoBehaviour public bool webSocketSecure = false; public string webSocketCertificateFilePath = string.Empty; public string webSocketCertificatePassword = string.Empty; - - [Header("Server Only Settings")] public int maxConnections = 4; - - [Header("Transport Layer Settings")] - [SerializeField] private BaseTransportFactory transportFactory; public BaseTransportFactory TransportFactory { @@ -64,34 +57,23 @@ public virtual string LogTag get { if (string.IsNullOrEmpty(logTag)) - logTag = $"{name}({GetType().Name})"; + logTag = $"{GetType().Name}"; return logTag; } } - protected virtual void Start() + public LiteNetLibManager() { InitTransportAndHandlers(); } protected void PrepareTransportFactory() { -#if UNITY_WEBGL && !UNITY_EDITOR - // Force to use websocket transport if it's running as webgl - if (transportFactory == null || !(transportFactory is IWebSocketTransportFactory)) - { - WebSocketTransportFactory webSocketTransportFactory = gameObject.AddComponent(); - webSocketTransportFactory.Secure = webSocketSecure; - webSocketTransportFactory.CertificateFilePath = webSocketCertificateFilePath; - webSocketTransportFactory.CertificatePassword = webSocketCertificatePassword; - transportFactory = webSocketTransportFactory; - } -#else if (useWebSocket) { if (transportFactory == null || !(transportFactory is IWebSocketTransportFactory)) { - WebSocketTransportFactory webSocketTransportFactory = gameObject.AddComponent(); + WebSocketTransportFactory webSocketTransportFactory = new WebSocketTransportFactory(); webSocketTransportFactory.Secure = webSocketSecure; webSocketTransportFactory.CertificateFilePath = webSocketCertificateFilePath; webSocketTransportFactory.CertificatePassword = webSocketCertificatePassword; @@ -101,11 +83,8 @@ protected void PrepareTransportFactory() else { if (transportFactory == null) - transportFactory = GetComponent(); - if (transportFactory == null) - transportFactory = gameObject.AddComponent(); + transportFactory = new LiteNetLibTransportFactory(); } -#endif } public void PrepareClientTransport() From ca8a2f12556655ae9a0804a72cc471dfdb5db5fa Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 01:30:36 +0700 Subject: [PATCH 27/58] Revert "feat: delete codes for Unity (GameApi)" This reverts commit 3ac55ce3edff8e544da6ce01293b25f76bd50b1e. # Conflicts: # Scripts/Attributes.meta # Scripts/Attributes/AllRpcAttribute.cs # Scripts/Attributes/AllRpcAttribute.cs.meta # Scripts/Attributes/ElasticRpcAttribute.cs # Scripts/Attributes/ElasticRpcAttribute.cs.meta # Scripts/Attributes/NetFunctionAttribute.cs # Scripts/Attributes/NetFunctionAttribute.cs.meta # Scripts/Attributes/RpcAttribute.cs # Scripts/Attributes/RpcAttribute.cs.meta # Scripts/Attributes/ServerRpcAttribute.cs # Scripts/Attributes/ServerRpcAttribute.cs.meta # Scripts/Attributes/SyncFieldAttribute.cs # Scripts/Attributes/SyncFieldAttribute.cs.meta # Scripts/Attributes/TargetRpcAttribute.cs # Scripts/Attributes/TargetRpcAttribute.cs.meta # Scripts/BaseInterestManager.cs # Scripts/BaseInterestManager.cs.meta # Scripts/BaseLiteNetLibVisibleChecker.cs # Scripts/BaseLiteNetLibVisibleChecker.cs.meta # Scripts/DefaultInterestManager.cs # Scripts/DefaultInterestManager.cs.meta # Scripts/DestroyObjectReasons.cs # Scripts/DestroyObjectReasons.cs.meta # Scripts/Events.meta # Scripts/Events/LiteNetLibIdentityEvent.cs # Scripts/Events/LiteNetLibIdentityEvent.cs.meta # Scripts/Events/LiteNetLibLoadSceneEvent.cs # Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta # Scripts/GameMsgTypes.cs # Scripts/GameMsgTypes.cs.meta # Scripts/GameReqTypes.cs # Scripts/GameReqTypes.cs.meta # Scripts/LiteNetLibAssets.cs # Scripts/LiteNetLibAssets.cs.meta # Scripts/LiteNetLibBehaviour.cs # Scripts/LiteNetLibBehaviour.cs.meta # Scripts/LiteNetLibElement.cs # Scripts/LiteNetLibElement.cs.meta # Scripts/LiteNetLibFunction.cs # Scripts/LiteNetLibFunction.cs.meta # Scripts/LiteNetLibGameManager.cs # Scripts/LiteNetLibGameManager.cs.meta # Scripts/LiteNetLibIdentity.cs # Scripts/LiteNetLibIdentity.cs.meta # Scripts/LiteNetLibPlayer.cs # Scripts/LiteNetLibPlayer.cs.meta # Scripts/LiteNetLibSpawnPoint.cs # Scripts/LiteNetLibSpawnPoint.cs.meta # Scripts/LiteNetLibSyncField.cs # Scripts/LiteNetLibSyncField.cs.meta # Scripts/LiteNetLibSyncList.cs # Scripts/LiteNetLibSyncList.cs.meta # Scripts/LiteNetLibTransform.cs # Scripts/LiteNetLibTransform.cs.meta # Scripts/LiteNetLibVisibleChecker.cs # Scripts/LiteNetLibVisibleChecker.cs.meta # Scripts/Messages/EnterGameRequestMessage.cs # Scripts/Messages/EnterGameRequestMessage.cs.meta # Scripts/Messages/EnterGameResponseMessage.cs # Scripts/Messages/EnterGameResponseMessage.cs.meta # Scripts/Messages/GenericValueMessage.cs # Scripts/Messages/GenericValueMessage.cs.meta # Scripts/Messages/PingMessage.cs # Scripts/Messages/PingMessage.cs.meta # Scripts/Messages/PongMessage.cs # Scripts/Messages/PongMessage.cs.meta # Scripts/Messages/ServerDestroyObjectMessage.cs # Scripts/Messages/ServerDestroyObjectMessage.cs.meta # Scripts/Messages/ServerErrorMessage.cs # Scripts/Messages/ServerErrorMessage.cs.meta # Scripts/Messages/ServerSceneChangeMessage.cs # Scripts/Messages/ServerSceneChangeMessage.cs.meta # Scripts/Messages/ServerSetObjectOwner.cs # Scripts/Messages/ServerSetObjectOwner.cs.meta # Scripts/Messages/ServerSpawnObjectMessage.cs # Scripts/Messages/ServerSpawnObjectMessage.cs.meta # Scripts/Messages/ServerSpawnSceneObjectMessage.cs # Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta --- Scripts/Attributes.meta | 8 + Scripts/Attributes/AllRpcAttribute.cs | 9 + Scripts/Attributes/AllRpcAttribute.cs.meta | 11 + Scripts/Attributes/ElasticRpcAttribute.cs | 9 + .../Attributes/ElasticRpcAttribute.cs.meta | 11 + Scripts/Attributes/NetFunctionAttribute.cs | 9 + .../Attributes/NetFunctionAttribute.cs.meta | 11 + Scripts/Attributes/RpcAttribute.cs | 13 + Scripts/Attributes/RpcAttribute.cs.meta | 11 + Scripts/Attributes/ServerRpcAttribute.cs | 9 + Scripts/Attributes/ServerRpcAttribute.cs.meta | 11 + Scripts/Attributes/SyncFieldAttribute.cs | 46 + Scripts/Attributes/SyncFieldAttribute.cs.meta | 11 + Scripts/Attributes/TargetRpcAttribute.cs | 9 + Scripts/Attributes/TargetRpcAttribute.cs.meta | 11 + Scripts/BaseInterestManager.cs | 74 + Scripts/BaseInterestManager.cs.meta | 11 + Scripts/BaseLiteNetLibVisibleChecker.cs | 11 + Scripts/BaseLiteNetLibVisibleChecker.cs.meta | 11 + Scripts/DefaultInterestManager.cs | 47 + Scripts/DefaultInterestManager.cs.meta | 11 + Scripts/DestroyObjectReasons.cs | 9 + Scripts/DestroyObjectReasons.cs.meta | 11 + Scripts/Events.meta | 10 + Scripts/Events/LiteNetLibIdentityEvent.cs | 9 + .../Events/LiteNetLibIdentityEvent.cs.meta | 11 + Scripts/Events/LiteNetLibLoadSceneEvent.cs | 9 + .../Events/LiteNetLibLoadSceneEvent.cs.meta | 13 + Scripts/GameMsgTypes.cs | 24 + Scripts/GameMsgTypes.cs.meta | 11 + Scripts/GameReqTypes.cs | 9 + Scripts/GameReqTypes.cs.meta | 11 + Scripts/LiteNetLibAssets.cs | 515 +++++ Scripts/LiteNetLibAssets.cs.meta | 13 + Scripts/LiteNetLibBehaviour.cs | 1755 +++++++++++++++++ Scripts/LiteNetLibBehaviour.cs.meta | 13 + Scripts/LiteNetLibElement.cs | 105 + Scripts/LiteNetLibElement.cs.meta | 13 + Scripts/LiteNetLibFunction.cs | 471 +++++ Scripts/LiteNetLibFunction.cs.meta | 13 + Scripts/LiteNetLibGameManager.cs | 1049 ++++++++++ Scripts/LiteNetLibGameManager.cs.meta | 13 + Scripts/LiteNetLibIdentity.cs | 843 ++++++++ Scripts/LiteNetLibIdentity.cs.meta | 13 + Scripts/LiteNetLibPlayer.cs | 122 ++ Scripts/LiteNetLibPlayer.cs.meta | 13 + Scripts/LiteNetLibSpawnPoint.cs | 43 + Scripts/LiteNetLibSpawnPoint.cs.meta | 13 + Scripts/LiteNetLibSyncField.cs | 693 +++++++ Scripts/LiteNetLibSyncField.cs.meta | 13 + Scripts/LiteNetLibSyncList.cs | 609 ++++++ Scripts/LiteNetLibSyncList.cs.meta | 13 + Scripts/LiteNetLibTransform.cs | 521 +++++ Scripts/LiteNetLibTransform.cs.meta | 13 + Scripts/LiteNetLibVisibleChecker.cs | 7 + Scripts/LiteNetLibVisibleChecker.cs.meta | 13 + Scripts/Messages/EnterGameRequestMessage.cs | 19 + .../Messages/EnterGameRequestMessage.cs.meta | 11 + Scripts/Messages/EnterGameResponseMessage.cs | 22 + .../Messages/EnterGameResponseMessage.cs.meta | 11 + Scripts/Messages/GenericValueMessage.cs | 188 ++ Scripts/Messages/GenericValueMessage.cs.meta | 11 + Scripts/Messages/PingMessage.cs | 19 + Scripts/Messages/PingMessage.cs.meta | 11 + Scripts/Messages/PongMessage.cs | 22 + Scripts/Messages/PongMessage.cs.meta | 11 + .../Messages/ServerDestroyObjectMessage.cs | 22 + .../ServerDestroyObjectMessage.cs.meta | 13 + Scripts/Messages/ServerErrorMessage.cs | 22 + Scripts/Messages/ServerErrorMessage.cs.meta | 13 + Scripts/Messages/ServerSceneChangeMessage.cs | 19 + .../Messages/ServerSceneChangeMessage.cs.meta | 13 + Scripts/Messages/ServerSetObjectOwner.cs | 22 + Scripts/Messages/ServerSetObjectOwner.cs.meta | 11 + Scripts/Messages/ServerSpawnObjectMessage.cs | 36 + .../Messages/ServerSpawnObjectMessage.cs.meta | 13 + .../Messages/ServerSpawnSceneObjectMessage.cs | 33 + .../ServerSpawnSceneObjectMessage.cs.meta | 13 + 78 files changed, 7925 insertions(+) create mode 100644 Scripts/Attributes.meta create mode 100644 Scripts/Attributes/AllRpcAttribute.cs create mode 100644 Scripts/Attributes/AllRpcAttribute.cs.meta create mode 100644 Scripts/Attributes/ElasticRpcAttribute.cs create mode 100644 Scripts/Attributes/ElasticRpcAttribute.cs.meta create mode 100644 Scripts/Attributes/NetFunctionAttribute.cs create mode 100644 Scripts/Attributes/NetFunctionAttribute.cs.meta create mode 100644 Scripts/Attributes/RpcAttribute.cs create mode 100644 Scripts/Attributes/RpcAttribute.cs.meta create mode 100644 Scripts/Attributes/ServerRpcAttribute.cs create mode 100644 Scripts/Attributes/ServerRpcAttribute.cs.meta create mode 100644 Scripts/Attributes/SyncFieldAttribute.cs create mode 100644 Scripts/Attributes/SyncFieldAttribute.cs.meta create mode 100644 Scripts/Attributes/TargetRpcAttribute.cs create mode 100644 Scripts/Attributes/TargetRpcAttribute.cs.meta create mode 100644 Scripts/BaseInterestManager.cs create mode 100644 Scripts/BaseInterestManager.cs.meta create mode 100644 Scripts/BaseLiteNetLibVisibleChecker.cs create mode 100644 Scripts/BaseLiteNetLibVisibleChecker.cs.meta create mode 100644 Scripts/DefaultInterestManager.cs create mode 100644 Scripts/DefaultInterestManager.cs.meta create mode 100644 Scripts/DestroyObjectReasons.cs create mode 100644 Scripts/DestroyObjectReasons.cs.meta create mode 100644 Scripts/Events.meta create mode 100644 Scripts/Events/LiteNetLibIdentityEvent.cs create mode 100644 Scripts/Events/LiteNetLibIdentityEvent.cs.meta create mode 100644 Scripts/Events/LiteNetLibLoadSceneEvent.cs create mode 100644 Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta create mode 100644 Scripts/GameMsgTypes.cs create mode 100644 Scripts/GameMsgTypes.cs.meta create mode 100644 Scripts/GameReqTypes.cs create mode 100644 Scripts/GameReqTypes.cs.meta create mode 100644 Scripts/LiteNetLibAssets.cs create mode 100644 Scripts/LiteNetLibAssets.cs.meta create mode 100644 Scripts/LiteNetLibBehaviour.cs create mode 100644 Scripts/LiteNetLibBehaviour.cs.meta create mode 100644 Scripts/LiteNetLibElement.cs create mode 100644 Scripts/LiteNetLibElement.cs.meta create mode 100644 Scripts/LiteNetLibFunction.cs create mode 100644 Scripts/LiteNetLibFunction.cs.meta create mode 100644 Scripts/LiteNetLibGameManager.cs create mode 100644 Scripts/LiteNetLibGameManager.cs.meta create mode 100644 Scripts/LiteNetLibIdentity.cs create mode 100644 Scripts/LiteNetLibIdentity.cs.meta create mode 100644 Scripts/LiteNetLibPlayer.cs create mode 100644 Scripts/LiteNetLibPlayer.cs.meta create mode 100644 Scripts/LiteNetLibSpawnPoint.cs create mode 100644 Scripts/LiteNetLibSpawnPoint.cs.meta create mode 100644 Scripts/LiteNetLibSyncField.cs create mode 100644 Scripts/LiteNetLibSyncField.cs.meta create mode 100644 Scripts/LiteNetLibSyncList.cs create mode 100644 Scripts/LiteNetLibSyncList.cs.meta create mode 100644 Scripts/LiteNetLibTransform.cs create mode 100644 Scripts/LiteNetLibTransform.cs.meta create mode 100644 Scripts/LiteNetLibVisibleChecker.cs create mode 100644 Scripts/LiteNetLibVisibleChecker.cs.meta create mode 100644 Scripts/Messages/EnterGameRequestMessage.cs create mode 100644 Scripts/Messages/EnterGameRequestMessage.cs.meta create mode 100644 Scripts/Messages/EnterGameResponseMessage.cs create mode 100644 Scripts/Messages/EnterGameResponseMessage.cs.meta create mode 100644 Scripts/Messages/GenericValueMessage.cs create mode 100644 Scripts/Messages/GenericValueMessage.cs.meta create mode 100644 Scripts/Messages/PingMessage.cs create mode 100644 Scripts/Messages/PingMessage.cs.meta create mode 100644 Scripts/Messages/PongMessage.cs create mode 100644 Scripts/Messages/PongMessage.cs.meta create mode 100644 Scripts/Messages/ServerDestroyObjectMessage.cs create mode 100644 Scripts/Messages/ServerDestroyObjectMessage.cs.meta create mode 100644 Scripts/Messages/ServerErrorMessage.cs create mode 100644 Scripts/Messages/ServerErrorMessage.cs.meta create mode 100644 Scripts/Messages/ServerSceneChangeMessage.cs create mode 100644 Scripts/Messages/ServerSceneChangeMessage.cs.meta create mode 100644 Scripts/Messages/ServerSetObjectOwner.cs create mode 100644 Scripts/Messages/ServerSetObjectOwner.cs.meta create mode 100644 Scripts/Messages/ServerSpawnObjectMessage.cs create mode 100644 Scripts/Messages/ServerSpawnObjectMessage.cs.meta create mode 100644 Scripts/Messages/ServerSpawnSceneObjectMessage.cs create mode 100644 Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta diff --git a/Scripts/Attributes.meta b/Scripts/Attributes.meta new file mode 100644 index 00000000..c359d2c1 --- /dev/null +++ b/Scripts/Attributes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2e2c381232fb17f4ba5116c6644d357b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/AllRpcAttribute.cs b/Scripts/Attributes/AllRpcAttribute.cs new file mode 100644 index 00000000..f9ca9338 --- /dev/null +++ b/Scripts/Attributes/AllRpcAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace LiteNetLibManager +{ + [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public class AllRpcAttribute : RpcAttribute + { + } +} diff --git a/Scripts/Attributes/AllRpcAttribute.cs.meta b/Scripts/Attributes/AllRpcAttribute.cs.meta new file mode 100644 index 00000000..eb5113b7 --- /dev/null +++ b/Scripts/Attributes/AllRpcAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24f4ce169ace902478a464b82f69e284 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/ElasticRpcAttribute.cs b/Scripts/Attributes/ElasticRpcAttribute.cs new file mode 100644 index 00000000..6aa0b852 --- /dev/null +++ b/Scripts/Attributes/ElasticRpcAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace LiteNetLibManager +{ + [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public class ElasticRpcAttribute : RpcAttribute + { + } +} diff --git a/Scripts/Attributes/ElasticRpcAttribute.cs.meta b/Scripts/Attributes/ElasticRpcAttribute.cs.meta new file mode 100644 index 00000000..155d55e0 --- /dev/null +++ b/Scripts/Attributes/ElasticRpcAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5654a2358c8bcb844ad984f229c15fed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/NetFunctionAttribute.cs b/Scripts/Attributes/NetFunctionAttribute.cs new file mode 100644 index 00000000..859fb9d3 --- /dev/null +++ b/Scripts/Attributes/NetFunctionAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace LiteNetLibManager +{ + [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public class NetFunctionAttribute : ElasticRpcAttribute + { + } +} diff --git a/Scripts/Attributes/NetFunctionAttribute.cs.meta b/Scripts/Attributes/NetFunctionAttribute.cs.meta new file mode 100644 index 00000000..e5b721ab --- /dev/null +++ b/Scripts/Attributes/NetFunctionAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fe7e812fc00d644f971c72e4195d10a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/RpcAttribute.cs b/Scripts/Attributes/RpcAttribute.cs new file mode 100644 index 00000000..7d23263c --- /dev/null +++ b/Scripts/Attributes/RpcAttribute.cs @@ -0,0 +1,13 @@ +using System; + +namespace LiteNetLibManager +{ + [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public abstract class RpcAttribute : Attribute + { + /// + /// If is true non-owner client can call the object's net function + /// + public bool canCallByEveryone = false; + } +} diff --git a/Scripts/Attributes/RpcAttribute.cs.meta b/Scripts/Attributes/RpcAttribute.cs.meta new file mode 100644 index 00000000..05e33df7 --- /dev/null +++ b/Scripts/Attributes/RpcAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 922389d8923e4dc40a79bfb30ec4cb95 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/ServerRpcAttribute.cs b/Scripts/Attributes/ServerRpcAttribute.cs new file mode 100644 index 00000000..6de847ac --- /dev/null +++ b/Scripts/Attributes/ServerRpcAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace LiteNetLibManager +{ + [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public class ServerRpcAttribute : RpcAttribute + { + } +} diff --git a/Scripts/Attributes/ServerRpcAttribute.cs.meta b/Scripts/Attributes/ServerRpcAttribute.cs.meta new file mode 100644 index 00000000..eeffefbe --- /dev/null +++ b/Scripts/Attributes/ServerRpcAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36c1b5b0980dabf4dba82bc55fbc25c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/SyncFieldAttribute.cs b/Scripts/Attributes/SyncFieldAttribute.cs new file mode 100644 index 00000000..8ca37aea --- /dev/null +++ b/Scripts/Attributes/SyncFieldAttribute.cs @@ -0,0 +1,46 @@ +using LiteNetLib; +using System; + +namespace LiteNetLibManager +{ + [AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)] + public class SyncFieldAttribute : Attribute + { + /// + /// Sending data channel from server to clients + /// + public byte dataChannel = 0; + /// + /// Sending method type from server to clients + /// + public DeliveryMethod deliveryMethod = DeliveryMethod.ReliableOrdered; + /// + /// Sending data channel from clients to server (while `syncMode` is `ClientMulticast` only) + /// + public byte clientDataChannel = 0; + /// + /// Sending method type from clients to server (while `syncMode` is `ClientMulticast` only) + /// + public DeliveryMethod clientDeliveryMethod = DeliveryMethod.ReliableOrdered; + /// + /// Interval to send network data + /// + public float sendInterval = 0.1f; + /// + /// How it will sync data. If always sync, it will sync data although it has no changes. If don't sync initial data immediately, it will not sync initial data immdediately with networked object spawning message, it will sync later after spanwed. If don't sync update, it will not sync when data has changes. + /// + public LiteNetLibSyncField.SyncBehaviour syncBehaviour = LiteNetLibSyncField.SyncBehaviour.Default; + /// + /// Who can sync data and sync to whom + /// + public LiteNetLibSyncField.SyncMode syncMode = LiteNetLibSyncField.SyncMode.ServerToClients; + /// + /// Method name which will be invoked when data changed + /// + public string onChangeMethodName = string.Empty; + /// + /// Method name which will be invoked when data sent + /// + public string onUpdateMethodName = string.Empty; + } +} diff --git a/Scripts/Attributes/SyncFieldAttribute.cs.meta b/Scripts/Attributes/SyncFieldAttribute.cs.meta new file mode 100644 index 00000000..f3119616 --- /dev/null +++ b/Scripts/Attributes/SyncFieldAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87ccb352ef1e4234cba4a002c09dd7c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/TargetRpcAttribute.cs b/Scripts/Attributes/TargetRpcAttribute.cs new file mode 100644 index 00000000..19bf4b98 --- /dev/null +++ b/Scripts/Attributes/TargetRpcAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace LiteNetLibManager +{ + [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public class TargetRpcAttribute : RpcAttribute + { + } +} diff --git a/Scripts/Attributes/TargetRpcAttribute.cs.meta b/Scripts/Attributes/TargetRpcAttribute.cs.meta new file mode 100644 index 00000000..00616fb3 --- /dev/null +++ b/Scripts/Attributes/TargetRpcAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f4dc3f2443322941bd8c9593ac1836c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/BaseInterestManager.cs b/Scripts/BaseInterestManager.cs new file mode 100644 index 00000000..286eed90 --- /dev/null +++ b/Scripts/BaseInterestManager.cs @@ -0,0 +1,74 @@ +using UnityEngine; + +namespace LiteNetLibManager +{ + [DisallowMultipleComponent] + public abstract class BaseInterestManager : MonoBehaviour + { + [Tooltip("Default visible range will be used when Identity's visible range is <= 0f")] + public float defaultVisibleRange = 80f; + public LiteNetLibGameManager Manager { get; protected set; } + public bool IsServer { get { return Manager.IsServer; } } + + protected virtual void Awake() + { + Manager = GetComponent(); + } + + public void NotifyNewObject(LiteNetLibIdentity newObject) + { + if (!IsServer) + { + // Notifies by server only + return; + } + // Subscribe old objects, if it should + if (newObject.ConnectionId >= 0 && newObject.Player.IsReady) + { + foreach (LiteNetLibIdentity target in Manager.Assets.GetSpawnedObjects()) + { + // Subscribe, it may subscribe or may not, up to how subscribe function implemented + Subscribe(newObject, target); + } + } + // Notify to other players + foreach (LiteNetLibPlayer player in Manager.GetPlayers()) + { + if (!player.IsReady || player.ConnectionId == newObject.ConnectionId) + { + // Don't subscribe if player not ready or the object is owned by the player + continue; + } + foreach (LiteNetLibIdentity subscriber in player.GetSpawnedObjects()) + { + // Subscribe, it may subscribe or may not, up to how subscribe function implemented + Subscribe(subscriber, newObject); + } + } + } + + public float GetVisibleRange(LiteNetLibIdentity identity) + { + return identity.VisibleRange > 0f ? identity.VisibleRange : defaultVisibleRange; + } + + public virtual bool ShouldSubscribe(LiteNetLibIdentity subscriber, LiteNetLibIdentity target, bool checkRange = true) + { + if (subscriber == null || target == null || subscriber.ConnectionId < 0) + return false; + if (subscriber.ConnectionId == target.ConnectionId) + return true; + return !target.IsHideFrom(subscriber) && (!checkRange || target.AlwaysVisible || Vector3.Distance(subscriber.transform.position, target.transform.position) <= GetVisibleRange(target)); + } + + public virtual bool Subscribe(LiteNetLibIdentity subscriber, LiteNetLibIdentity target) + { + if (ShouldSubscribe(subscriber, target)) + { + subscriber.AddSubscribing(target.ObjectId); + return true; + } + return false; + } + } +} diff --git a/Scripts/BaseInterestManager.cs.meta b/Scripts/BaseInterestManager.cs.meta new file mode 100644 index 00000000..988825ce --- /dev/null +++ b/Scripts/BaseInterestManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14432c40583017d4e8beb2be9b8ec43e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/BaseLiteNetLibVisibleChecker.cs b/Scripts/BaseLiteNetLibVisibleChecker.cs new file mode 100644 index 00000000..0de0940c --- /dev/null +++ b/Scripts/BaseLiteNetLibVisibleChecker.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace LiteNetLibManager +{ + [DisallowMultipleComponent] + [System.Obsolete("This component is deprecated because interest management system is changed")] + public abstract class BaseLiteNetLibVisibleChecker : MonoBehaviour + { + } +} diff --git a/Scripts/BaseLiteNetLibVisibleChecker.cs.meta b/Scripts/BaseLiteNetLibVisibleChecker.cs.meta new file mode 100644 index 00000000..8c948435 --- /dev/null +++ b/Scripts/BaseLiteNetLibVisibleChecker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7058a555827f9a478fea05cbc44cb0e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/DefaultInterestManager.cs b/Scripts/DefaultInterestManager.cs new file mode 100644 index 00000000..100e2364 --- /dev/null +++ b/Scripts/DefaultInterestManager.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace LiteNetLibManager +{ + public class DefaultInterestManager : BaseInterestManager + { + [Tooltip("Update every ? seconds")] + public float updateInterval = 1f; + + private float updateCountDown = 0f; + + private void Update() + { + if (!IsServer) + { + // Update at server only + return; + } + updateCountDown -= Time.unscaledDeltaTime; + if (updateCountDown <= 0f) + { + updateCountDown = updateInterval; + HashSet subscribings = new HashSet(); + foreach (LiteNetLibPlayer player in Manager.GetPlayers()) + { + if (!player.IsReady) + { + // Don't subscribe if player not ready + continue; + } + foreach (LiteNetLibIdentity playerObject in player.GetSpawnedObjects()) + { + // Update subscribing list, it will unsubscribe objects which is not in this list + subscribings.Clear(); + foreach (LiteNetLibIdentity spawnedObject in Manager.Assets.GetSpawnedObjects()) + { + if (ShouldSubscribe(playerObject, spawnedObject)) + subscribings.Add(spawnedObject.ObjectId); + } + playerObject.UpdateSubscribings(subscribings); + } + } + } + } + } +} diff --git a/Scripts/DefaultInterestManager.cs.meta b/Scripts/DefaultInterestManager.cs.meta new file mode 100644 index 00000000..72c83b7b --- /dev/null +++ b/Scripts/DefaultInterestManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1ccd9ce8d0d28d4fb1d2e56e08bc6ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/DestroyObjectReasons.cs b/Scripts/DestroyObjectReasons.cs new file mode 100644 index 00000000..b036566f --- /dev/null +++ b/Scripts/DestroyObjectReasons.cs @@ -0,0 +1,9 @@ +namespace LiteNetLibManager +{ + public static partial class DestroyObjectReasons + { + public const byte RequestedToDestroy = 0; + public const byte RemovedFromSubscribing = 1; + public const byte Highest = 1; + } +} diff --git a/Scripts/DestroyObjectReasons.cs.meta b/Scripts/DestroyObjectReasons.cs.meta new file mode 100644 index 00000000..a6a846ee --- /dev/null +++ b/Scripts/DestroyObjectReasons.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf5e4e67b2edd55469fac12498be27a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Events.meta b/Scripts/Events.meta new file mode 100644 index 00000000..464631d8 --- /dev/null +++ b/Scripts/Events.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 202557d6bd6392b4a8e26f3e1cbfbcdf +folderAsset: yes +timeCreated: 1525035216 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Events/LiteNetLibIdentityEvent.cs b/Scripts/Events/LiteNetLibIdentityEvent.cs new file mode 100644 index 00000000..452886c2 --- /dev/null +++ b/Scripts/Events/LiteNetLibIdentityEvent.cs @@ -0,0 +1,9 @@ +using UnityEngine.Events; + +namespace LiteNetLibManager +{ + [System.Serializable] + public class LiteNetLibIdentityEvent : UnityEvent + { + } +} diff --git a/Scripts/Events/LiteNetLibIdentityEvent.cs.meta b/Scripts/Events/LiteNetLibIdentityEvent.cs.meta new file mode 100644 index 00000000..5783ffb2 --- /dev/null +++ b/Scripts/Events/LiteNetLibIdentityEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 74e03bd06ca73434590bb4486608c477 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Events/LiteNetLibLoadSceneEvent.cs b/Scripts/Events/LiteNetLibLoadSceneEvent.cs new file mode 100644 index 00000000..05100d27 --- /dev/null +++ b/Scripts/Events/LiteNetLibLoadSceneEvent.cs @@ -0,0 +1,9 @@ +using UnityEngine.Events; + +namespace LiteNetLibManager +{ + [System.Serializable] + public class LiteNetLibLoadSceneEvent : UnityEvent + { + } +} diff --git a/Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta b/Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta new file mode 100644 index 00000000..a573e4b7 --- /dev/null +++ b/Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 9ad5883371559724ca569b77258ec07b +timeCreated: 1525035242 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/GameMsgTypes.cs b/Scripts/GameMsgTypes.cs new file mode 100644 index 00000000..95c0f35c --- /dev/null +++ b/Scripts/GameMsgTypes.cs @@ -0,0 +1,24 @@ +namespace LiteNetLibManager +{ + public static partial class GameMsgTypes + { + public const ushort Request = 0; + public const ushort Response = 1; + public const ushort CallFunction = 3; + public const ushort ServerSpawnSceneObject = 4; + public const ushort ServerSpawnObject = 5; + public const ushort ServerDestroyObject = 6; + public const ushort UpdateSyncField = 7; + public const ushort InitialSyncField = 8; + public const ushort OperateSyncList = 9; + public const ushort ServerSyncBehaviour = 11; + public const ushort ServerError = 12; + public const ushort ServerSceneChange = 13; + public const ushort ClientSendTransform = 14; + public const ushort ServerSetObjectOwner = 15; + public const ushort Ping = 16; + public const ushort Pong = 17; + public const ushort Disconnect = 18; + public const ushort Highest = 18; + } +} diff --git a/Scripts/GameMsgTypes.cs.meta b/Scripts/GameMsgTypes.cs.meta new file mode 100644 index 00000000..3eac67e5 --- /dev/null +++ b/Scripts/GameMsgTypes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a03ecc48c1a8a54eb4abe116d9bb35b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/GameReqTypes.cs b/Scripts/GameReqTypes.cs new file mode 100644 index 00000000..4905f8f8 --- /dev/null +++ b/Scripts/GameReqTypes.cs @@ -0,0 +1,9 @@ +namespace LiteNetLibManager +{ + public static partial class GameReqTypes + { + public const ushort EnterGame = 0; + public const ushort ClientReady = 1; + public const ushort ClientNotReady = 2; + } +} diff --git a/Scripts/GameReqTypes.cs.meta b/Scripts/GameReqTypes.cs.meta new file mode 100644 index 00000000..63f1c5bb --- /dev/null +++ b/Scripts/GameReqTypes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8a4fd8828789514c891003b9e990dbb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibAssets.cs b/Scripts/LiteNetLibAssets.cs new file mode 100644 index 00000000..b6c96a0a --- /dev/null +++ b/Scripts/LiteNetLibAssets.cs @@ -0,0 +1,515 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Events; + +namespace LiteNetLibManager +{ + public class LiteNetLibAssets : MonoBehaviour + { + private static int spawnPositionCounter = 0; + public bool playerSpawnRandomly; + public LiteNetLibIdentity playerPrefab; + public LiteNetLibIdentity[] spawnablePrefabs; + public LiteNetLibIdentity PlayerPrefab { get; protected set; } + public SceneField offlineScene; + public SceneField onlineScene; + public UnityEvent onInitialize; + public LiteNetLibLoadSceneEvent onLoadSceneStart; + public LiteNetLibLoadSceneEvent onLoadSceneProgress; + public LiteNetLibLoadSceneEvent onLoadSceneFinish; + public LiteNetLibIdentityEvent onObjectSpawn; + public LiteNetLibIdentityEvent onObjectDestroy; + + internal readonly List CacheSpawnPoints = new List(); + internal readonly Dictionary GuidToPrefabs = new Dictionary(); + internal readonly Dictionary SceneObjects = new Dictionary(); + internal readonly Dictionary SpawnedObjects = new Dictionary(); + internal readonly Dictionary> PooledObjects = new Dictionary>(); + + public LiteNetLibGameManager Manager { get; private set; } + private string logTag; + public string LogTag + { + get + { + if (string.IsNullOrEmpty(logTag)) + logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; + return logTag; + } + } + + private void Awake() + { + Manager = GetComponent(); + } + + public void Initialize() + { + if (onInitialize != null) + onInitialize.Invoke(); + RegisterPrefabs(); + RegisterSpawnPoints(); + RegisterSceneObjects(); + } + + public void Clear(bool doNotResetObjectId = false) + { + ClearSpawnedObjects(); + ClearPooledObjects(); + CacheSpawnPoints.Clear(); + SceneObjects.Clear(); + ResetSpawnPositionCounter(); + if (!doNotResetObjectId) + LiteNetLibIdentity.ResetObjectId(); + } + + public void RegisterSpawnPoints() + { + CacheSpawnPoints.Clear(); + CacheSpawnPoints.AddRange(FindObjectsOfType()); + } + + public void RegisterPrefabs() + { + for (int i = 0; i < spawnablePrefabs.Length; ++i) + { + LiteNetLibIdentity registeringPrefab = spawnablePrefabs[i]; + RegisterPrefab(registeringPrefab); + } + if (playerPrefab != null) + { + PlayerPrefab = playerPrefab; + RegisterPrefab(playerPrefab); + } + } + + public void RegisterPrefab(LiteNetLibIdentity prefab) + { + if (prefab == null) + { + if (Manager.LogWarn) Logging.LogWarning(LogTag, "RegisterPrefab - prefab is null."); + return; + } + if (Manager.LogDev) Logging.Log(LogTag, $"RegisterPrefab [{prefab.HashAssetId}] name [{prefab.name}]"); + GuidToPrefabs[prefab.HashAssetId] = prefab; + } + + public bool UnregisterPrefab(LiteNetLibIdentity prefab) + { + if (prefab == null) + { + if (Manager.LogWarn) Logging.LogWarning(LogTag, "UnregisterPrefab - prefab is null."); + return false; + } + if (Manager.LogDev) Logging.Log(LogTag, $"UnregisterPrefab [{prefab.HashAssetId}] name [{prefab.name}]"); + return GuidToPrefabs.Remove(prefab.HashAssetId); + } + + public void ClearSpawnedObjects() + { + List objectIds = new List(SpawnedObjects.Keys); + for (int i = objectIds.Count - 1; i >= 0; --i) + { + uint objectId = objectIds[i]; + LiteNetLibIdentity spawnedObject; + if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) + { + // Destroy only non scene object + if (!SceneObjects.ContainsKey(objectId) && spawnedObject != null) + Destroy(spawnedObject.gameObject); + // Remove from asset spawned objects dictionary + SpawnedObjects.Remove(objectId); + } + } + SpawnedObjects.Clear(); + } + + public void ClearPooledObjects() + { + foreach (Queue queue in PooledObjects.Values) + { + while (queue.Count > 0) + { + LiteNetLibIdentity instance = queue.Dequeue(); + try + { + // I tried to avoid null exception but it still ocurring + if (instance != null) + Destroy(instance.gameObject); + } + catch { } + } + } + PooledObjects.Clear(); + } + + public void InitPoolingObjects() + { + foreach (int hashAssetId in GuidToPrefabs.Keys) + { + InitPoolingObject(hashAssetId); + } + } + + public void InitPoolingObject(int hashAssetId) + { + if (!GuidToPrefabs.ContainsKey(hashAssetId)) + { + Debug.LogWarning($"Cannot init prefab: {hashAssetId}, can't find the registered prefab."); + return; + } + + // Already init pool for the prefab + if (PooledObjects.ContainsKey(hashAssetId)) + return; + + LiteNetLibIdentity prefab = GuidToPrefabs[hashAssetId]; + // Don't create an instance for this prefab, if pooling size < 0 + if (prefab.PoolingSize <= 0) + return; + + Queue queue = new Queue(); + LiteNetLibIdentity tempInstance; + for (int i = 0; i < prefab.PoolingSize; ++i) + { + tempInstance = Instantiate(prefab); + tempInstance.IsPooledInstance = true; + tempInstance.gameObject.SetActive(false); + queue.Enqueue(tempInstance); + } + + PooledObjects[hashAssetId] = queue; + } + + public LiteNetLibIdentity GetObjectInstance(int hashAssetId) + { + return GetObjectInstance(hashAssetId, Vector3.zero, Quaternion.identity); + } + + public LiteNetLibIdentity GetObjectInstance(int hashAssetId, Vector3 position, Quaternion rotation) + { + if (PooledObjects.ContainsKey(hashAssetId) && PooledObjects[hashAssetId].Count > 0) + { + // Get pooled instance + LiteNetLibIdentity instance = PooledObjects[hashAssetId].Dequeue(); + instance.OnGetInstance(); + instance.transform.position = position; + instance.transform.rotation = rotation; + return instance; + } + + if (GuidToPrefabs.ContainsKey(hashAssetId)) + { + // Create a new instance + LiteNetLibIdentity instance = Instantiate(GuidToPrefabs[hashAssetId], position, rotation); + instance.gameObject.SetActive(false); + return instance; + } + + return null; + } + + public void PushInstanceBack(LiteNetLibIdentity instance) + { + if (instance == null) + { + Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance's is empty."); + return; + } + if (!instance.IsPooledInstance) + { + Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance is not pooled instance."); + return; + } + Queue queue; + if (!PooledObjects.TryGetValue(instance.HashAssetId, out queue)) + { + Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance's prefab does not initailized yet."); + return; + } + if (queue.Count >= instance.PoolingSize) + { + Destroy(instance.gameObject); + } + else + { + instance.gameObject.SetActive(false); + queue.Enqueue(instance); + } + } + + public void RegisterSceneObjects() + { + SceneObjects.Clear(); + LiteNetLibIdentity[] sceneObjects = FindObjectsOfType(); + for (int i = 0; i < sceneObjects.Length; ++i) + { + LiteNetLibIdentity sceneObject = sceneObjects[i]; + if (sceneObject.ObjectId > 0) + { + sceneObject.gameObject.SetActive(false); + SceneObjects[sceneObject.ObjectId] = sceneObject; + LiteNetLibIdentity.UpdateHighestObjectId(sceneObject.ObjectId); + } + } + } + + /// + /// This function will be called on start server and when network scene loaded to spawn scene objects + /// So each scene objects connection id will = -1 (No owning client) + /// + public void SpawnSceneObjects() + { + List sceneObjects = new List(SceneObjects.Values); + for (int i = 0; i < sceneObjects.Count; ++i) + { + LiteNetLibIdentity sceneObject = sceneObjects[i]; + NetworkSpawnScene(sceneObject.ObjectId, sceneObject.transform.position, sceneObject.transform.rotation); + } + } + + public LiteNetLibIdentity NetworkSpawnScene(uint objectId, Vector3 position, Quaternion rotation, long connectionId = -1) + { + if (!Manager.IsNetworkActive) + { + Logging.LogWarning(LogTag, "NetworkSpawnScene - Network is not active cannot spawn"); + return null; + } + + LiteNetLibIdentity identity; + if (!SceneObjects.TryGetValue(objectId, out identity)) + { + Logging.LogWarning(LogTag, $"NetworkSpawnScene - Object Id: {objectId} is not registered."); + return null; + } + + identity.gameObject.SetActive(true); + identity.Initial(Manager, true, objectId, connectionId); + identity.InitTransform(position, rotation); + identity.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); + if (Manager.IsServer) + identity.OnStartServer(); + if (Manager.IsClient) + identity.OnStartClient(); + if (connectionId >= 0 && connectionId == Manager.ClientConnectionId) + identity.OnStartOwnerClient(); + if (onObjectSpawn != null) + onObjectSpawn.Invoke(identity); + + return identity; + } + + public LiteNetLibIdentity NetworkSpawn(GameObject gameObject, uint objectId = 0, long connectionId = -1) + { + if (gameObject == null) + { + if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - gameObject is null."); + return null; + } + return NetworkSpawn(gameObject.GetComponent(), objectId, connectionId); + } + + public LiteNetLibIdentity NetworkSpawn(LiteNetLibIdentity identity, uint objectId = 0, long connectionId = -1) + { + if (identity == null) + { + if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - identity is null."); + return null; + } + + identity.gameObject.SetActive(true); + identity.Initial(Manager, false, objectId, connectionId); + identity.InitTransform(identity.transform.position, identity.transform.rotation); + identity.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); + if (Manager.IsServer) + identity.OnStartServer(); + if (Manager.IsClient) + identity.OnStartClient(); + if (connectionId >= 0 && connectionId == Manager.ClientConnectionId) + identity.OnStartOwnerClient(); + if (onObjectSpawn != null) + onObjectSpawn.Invoke(identity); + + return identity; + } + + public LiteNetLibIdentity NetworkSpawn(int hashAssetId, Vector3 position, Quaternion rotation, uint objectId = 0, long connectionId = -1) + { + if (!GuidToPrefabs.ContainsKey(hashAssetId)) + { + if (Manager.LogWarn) + Logging.LogWarning(LogTag, $"NetworkSpawn - Asset Id: {hashAssetId} is not registered."); + return null; + } + return NetworkSpawn(GetObjectInstance(hashAssetId, position, rotation), objectId, connectionId); + } + + public bool NetworkDestroy(GameObject gameObject, byte reasons) + { + if (gameObject == null) + { + if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkDestroy - gameObject is null."); + return false; + } + LiteNetLibIdentity identity = gameObject.GetComponent(); + if (identity == null) + { + if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - identity is null."); + return false; + } + return NetworkDestroy(identity.ObjectId, reasons); + } + + public bool NetworkDestroy(uint objectId, byte reasons) + { + if (!Manager.IsNetworkActive) + { + Logging.LogWarning(LogTag, "NetworkDestroy - Network is not active cannot destroy"); + return false; + } + + LiteNetLibIdentity spawnedObject; + if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) + { + // Call this function to tell behaviour that the identity is being destroyed + spawnedObject.OnNetworkDestroy(reasons); + if (onObjectDestroy != null) + onObjectDestroy.Invoke(spawnedObject); + // If the object is scene object, don't destroy just hide it, else destroy + if (SceneObjects.ContainsKey(objectId)) + { + spawnedObject.gameObject.SetActive(false); + } + else + { + if (spawnedObject.IsPooledInstance) + PushInstanceBack(spawnedObject); + else + Destroy(spawnedObject.gameObject); + } + return true; + } + else if (Manager.LogWarn) + { + Logging.LogWarning(LogTag, $"NetworkDestroy - Object Id: {objectId} is not spawned."); + } + return false; + } + + public bool SetObjectOwner(uint objectId, long connectionId) + { + if (!Manager.IsNetworkActive) + { + Logging.LogWarning(LogTag, "SetObjectOwner - Network is not active cannot set object owner"); + return false; + } + LiteNetLibIdentity spawnedObject; + if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) + { + if (spawnedObject.ConnectionId == connectionId) + return false; + + // If this is server, send message to clients to set object owner + if (Manager.IsServer) + { + foreach (long subscriber in spawnedObject.Subscribers) + { + if (subscriber == connectionId) + continue; + Manager.SendServerSetObjectOwner(subscriber, objectId, connectionId); + } + Manager.SendServerSetObjectOwner(connectionId, objectId, connectionId); + } + // Remove from player spawned objects dictionary and add to target connection id + LiteNetLibPlayer playerA; + LiteNetLibPlayer playerB; + if (Manager.TryGetPlayer(spawnedObject.ConnectionId, out playerA)) + playerA.SpawnedObjects.Remove(objectId); + if (Manager.TryGetPlayer(connectionId, out playerB)) + playerB.SpawnedObjects[spawnedObject.ObjectId] = spawnedObject; + // Set connection id + spawnedObject.ConnectionId = connectionId; + // Call set owner client event + spawnedObject.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); + return true; + } + else if (Manager.LogWarn) + Logging.LogWarning(LogTag, $"SetObjectOwner - Object Id: {objectId} is not spawned."); + + return false; + } + + public Vector3 GetPlayerSpawnPosition() + { + if (CacheSpawnPoints.Count == 0) + return Vector3.zero; + if (playerSpawnRandomly) + return CacheSpawnPoints[Random.Range(0, CacheSpawnPoints.Count)].GetRandomPosition(); + else + { + if (spawnPositionCounter >= CacheSpawnPoints.Count) + spawnPositionCounter = 0; + return CacheSpawnPoints[spawnPositionCounter++].GetRandomPosition(); + } + } + + public bool ContainsSceneObject(uint objectId) + { + return SceneObjects.ContainsKey(objectId); + } + + public bool TryGetSceneObject(uint objectId, out LiteNetLibIdentity identity) + { + return SceneObjects.TryGetValue(objectId, out identity); + } + + public bool TryGetSceneObject(uint objectId, out T result) where T : LiteNetLibBehaviour + { + result = null; + LiteNetLibIdentity identity; + if (SceneObjects.TryGetValue(objectId, out identity)) + { + result = identity.GetComponent(); + return result != null; + } + return false; + } + + public IEnumerable GetSceneObjects() + { + return SceneObjects.Values; + } + + public bool ContainsSpawnedObject(uint objectId) + { + return SpawnedObjects.ContainsKey(objectId); + } + + public bool TryGetSpawnedObject(uint objectId, out LiteNetLibIdentity identity) + { + return SpawnedObjects.TryGetValue(objectId, out identity); + } + + public bool TryGetSpawnedObject(uint objectId, out T result) where T : LiteNetLibBehaviour + { + result = null; + LiteNetLibIdentity identity; + if (SpawnedObjects.TryGetValue(objectId, out identity)) + { + result = identity.GetComponent(); + return result != null; + } + return false; + } + + public IEnumerable GetSpawnedObjects() + { + return SpawnedObjects.Values; + } + + public static void ResetSpawnPositionCounter() + { + spawnPositionCounter = 0; + } + } +} diff --git a/Scripts/LiteNetLibAssets.cs.meta b/Scripts/LiteNetLibAssets.cs.meta new file mode 100644 index 00000000..2eb5fa7e --- /dev/null +++ b/Scripts/LiteNetLibAssets.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 4884384bff23a9c439e7ce9681ea5724 +timeCreated: 1508751282 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibBehaviour.cs b/Scripts/LiteNetLibBehaviour.cs new file mode 100644 index 00000000..015a6bee --- /dev/null +++ b/Scripts/LiteNetLibBehaviour.cs @@ -0,0 +1,1755 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Linq; +using UnityEngine; +using LiteNetLib; +using LiteNetLib.Utils; +using UnityEngine.Profiling; +using System.Text; + +namespace LiteNetLibManager +{ + public partial class LiteNetLibBehaviour : MonoBehaviour, INetSerializable + { + private struct CacheFields + { + public List syncFields; + public List syncLists; + public List syncFieldsWithAttribute; + } + + private struct CacheFunctions + { + public List functions; + public List functionsCanCallByEveryone; + } + + [ReadOnly, SerializeField] + private byte behaviourIndex; + public byte BehaviourIndex + { + get { return behaviourIndex; } + } + + [Header("Behaviour Sync Options")] + public byte dataChannel; + public DeliveryMethod sendOptions; + [Tooltip("Interval to send network data")] + [Range(0.01f, 2f)] + public float sendInterval = 0.1f; + /// + /// How many times per second it will sync behaviour + /// + public float SendRate + { + get { return 1f / sendInterval; } + } + + private float sendCountDown; + + private static readonly Dictionary CacheSyncElements = new Dictionary(); + private static readonly Dictionary CacheElasticRpcs = new Dictionary(); + private static readonly Dictionary CacheTargetRpcs = new Dictionary(); + private static readonly Dictionary CacheAllRpcs = new Dictionary(); + private static readonly Dictionary CacheServerRpcs = new Dictionary(); + private static readonly Dictionary CacheOnChangeFunctions = new Dictionary(); + private static readonly Dictionary CacheOnUpdateFunctions = new Dictionary(); + private static readonly Dictionary CacheDyncnamicFunctionTypes = new Dictionary(); + + private readonly Dictionary targetRpcIds = new Dictionary(); + private readonly Dictionary allRpcIds = new Dictionary(); + private readonly Dictionary serverRpcIds = new Dictionary(); + + // Optimize garbage collector + private Type tempLookupType; + private HashSet tempLookupNames = new HashSet(); + private FieldInfo[] tempLookupFields; + private MethodInfo[] tempLookupMethods; + + private Type classType; + /// + /// This will be used when setup sync fields and sync lists + /// + public Type ClassType + { + get + { + if (classType == null) + classType = GetType(); + return classType; + } + } + + /// + /// This will be used when setup sync fields and sync lists as key for cached fields + /// + public string TypeName + { + get { return ClassType.FullName; } + } + + private bool isFoundIdentity; + private LiteNetLibIdentity identity; + public LiteNetLibIdentity Identity + { + get + { + if (!isFoundIdentity) + { + identity = GetComponent(); + if (identity == null) + identity = GetComponentInParent(); + isFoundIdentity = identity != null; + } + return identity; + } + } + + public long ConnectionId + { + get { return Identity.ConnectionId; } + } + + public uint ObjectId + { + get { return Identity.ObjectId; } + } + + public LiteNetLibGameManager Manager + { + get { return Identity.Manager; } + } + + public LiteNetLibPlayer Player + { + get { return Identity.Player; } + } + + public bool IsServer + { + get { return Identity.IsServer; } + } + + public bool IsClient + { + get { return Identity.IsClient; } + } + + public bool IsOwnerClient + { + get { return Identity.IsOwnerClient; } + } + + public bool IsHost + { + get { return IsServer && IsOwnerClient; } + } + + public bool IsOwnedByServer + { + get { return Identity.IsOwnedByServer; } + } + + public bool IsOwnerClientOrOwnedByServer + { + get { return Identity.IsOwnerClientOrOwnedByServer; } + } + + public bool IsSceneObject + { + get { return Identity.IsSceneObject; } + } + + private string logTag; + public virtual string LogTag + { + get + { + if (string.IsNullOrEmpty(logTag)) + logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; + return logTag; + } + } + + internal void NetworkUpdate(float deltaTime) + { + // Sync behaviour + if (!IsServer || !CanSyncBehaviour()) + return; + + // It's time to send update? + sendCountDown -= deltaTime; + if (sendCountDown > 0) + return; + + // Set count down + sendCountDown = sendInterval; + + Profiler.BeginSample("LiteNetLibBehaviour - Update Sync Behaviour"); + if (ShouldSyncBehaviour()) + { + LiteNetLibGameManager manager = Manager; + LiteNetLibServer server = manager.Server; + TransportHandler.WritePacket(server.Writer, GameMsgTypes.ServerSyncBehaviour); + Serialize(server.Writer); + foreach (long connectionId in manager.GetConnectionIds()) + { + if (Identity.HasSubscriberOrIsOwning(connectionId)) + server.SendMessage(connectionId, dataChannel, sendOptions, server.Writer); + } + } + Profiler.EndSample(); + } + + public void Setup(byte behaviourIndex) + { + this.behaviourIndex = behaviourIndex; + OnSetup(); + CacheElements(); + CacheRpcs(serverRpcIds, CacheElasticRpcs); + CacheRpcs(allRpcIds, CacheElasticRpcs); + CacheRpcs(targetRpcIds, CacheElasticRpcs); + CacheRpcs(serverRpcIds, CacheServerRpcs); + CacheRpcs(allRpcIds, CacheAllRpcs); + CacheRpcs(targetRpcIds, CacheTargetRpcs); + } + + private void CacheElements() + { + CacheFields tempCacheFields; + if (!CacheSyncElements.TryGetValue(TypeName, out tempCacheFields)) + { + tempCacheFields = new CacheFields() + { + syncFields = new List(), + syncLists = new List(), + syncFieldsWithAttribute = new List() + }; + tempLookupNames.Clear(); + tempLookupType = ClassType; + SyncFieldAttribute tempAttribute = null; + // Find for sync field and sync list from the class + while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) + { + tempLookupFields = tempLookupType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + foreach (FieldInfo lookupField in tempLookupFields) + { + // Avoid duplicate fields + if (tempLookupNames.Contains(lookupField.Name)) + continue; + + if (lookupField.FieldType.IsSubclassOf(typeof(LiteNetLibSyncField))) + { + tempCacheFields.syncFields.Add(lookupField); + } + else if (lookupField.FieldType.IsSubclassOf(typeof(LiteNetLibSyncList))) + { + tempCacheFields.syncLists.Add(lookupField); + } + else + { + // Must have [SyncField] attribute + tempAttribute = lookupField.GetCustomAttribute(); + if (tempAttribute != null) + tempCacheFields.syncFieldsWithAttribute.Add(lookupField); + } + + tempLookupNames.Add(lookupField.Name); + } + tempLookupType = tempLookupType.BaseType; + } + // Sort name to make sure the fields will be sync correctly by its index + tempCacheFields.syncFields.Sort((a, b) => a.Name.ToLower().CompareTo(b.Name.ToLower())); + tempCacheFields.syncLists.Sort((a, b) => a.Name.ToLower().CompareTo(b.Name.ToLower())); + CacheSyncElements.Add(TypeName, tempCacheFields); + } + SetupSyncElements(tempCacheFields.syncFields, Identity.SyncFields); + SetupSyncElements(tempCacheFields.syncLists, Identity.SyncLists); + SetupSyncFieldsWithAttribute(tempCacheFields.syncFieldsWithAttribute); + } + + private void SetupSyncElements(List fields, List elementList) where T : LiteNetLibElement + { + if (fields == null || fields.Count == 0) + return; + + foreach (FieldInfo field in fields) + { + try + { + RegisterSyncElement((T)field.GetValue(this), elementList); + } + catch (Exception ex) + { + if (Manager.LogFatal) + Logging.LogException(LogTag, ex); + } + } + } + + private void SetupSyncFieldsWithAttribute(List fieldInfos) + { + if (fieldInfos == null || fieldInfos.Count == 0) + return; + + StringBuilder stringBuilder = new StringBuilder(); + SyncFieldAttribute tempAttribute; + LiteNetLibSyncField tempSyncField; + MethodInfo tempOnChangeMethod; + MethodInfo tempOnUpdateMethod; + foreach (FieldInfo fieldInfo in fieldInfos) + { + try + { + tempAttribute = fieldInfo.GetCustomAttribute(); + // Find on change method + tempOnChangeMethod = null; + if (!string.IsNullOrEmpty(tempAttribute.onChangeMethodName)) + { + tempOnChangeMethod = FindAndCacheMethods(stringBuilder, tempAttribute.onChangeMethodName, fieldInfo, CacheOnChangeFunctions, (tempMethodParams) => + { + return tempMethodParams != null && tempMethodParams.Length == 1 && tempMethodParams[0].ParameterType == fieldInfo.FieldType; + }); + if (tempOnChangeMethod == null) + { + if (Manager.LogError) + Logging.LogError(LogTag, "Cannot find `on change` method named [" + tempAttribute.onChangeMethodName + "] from [" + TypeName + "], FYI the function must has 1 parameter with the same type with the field."); + } + } + // Find on update method + tempOnUpdateMethod = null; + if (!string.IsNullOrEmpty(tempAttribute.onUpdateMethodName)) + { + tempOnUpdateMethod = FindAndCacheMethods(stringBuilder, tempAttribute.onUpdateMethodName, fieldInfo, CacheOnUpdateFunctions, (tempMethodParams) => + { + return tempMethodParams == null || tempMethodParams.Length == 0; + }); + if (tempOnUpdateMethod == null) + { + if (Manager.LogError) + Logging.LogError(LogTag, "Cannot find `on update` method named [" + tempAttribute.onUpdateMethodName + "] from [" + TypeName + "], FYI the function must has 0 parameter."); + } + } + // Create new sync field container + tempSyncField = new LiteNetLibSyncFieldContainer(fieldInfo, this, tempOnChangeMethod, tempOnUpdateMethod); + tempSyncField.dataChannel = tempAttribute.dataChannel; + tempSyncField.deliveryMethod = tempAttribute.deliveryMethod; + tempSyncField.clientDataChannel = tempAttribute.clientDataChannel; + tempSyncField.clientDeliveryMethod = tempAttribute.clientDeliveryMethod; + tempSyncField.sendInterval = tempAttribute.sendInterval; + tempSyncField.syncBehaviour = tempAttribute.syncBehaviour; + tempSyncField.syncMode = tempAttribute.syncMode; + RegisterSyncElement(tempSyncField, Identity.SyncFields); + } + catch (Exception ex) + { + if (Manager.LogFatal) + Logging.LogException(LogTag, ex); + } + } + } + + private MethodInfo FindAndCacheMethods(StringBuilder stringBuilder, string methodName, FieldInfo fieldInfo, Dictionary dictionary, Func parameterValidator) + { + MethodInfo tempMethod; + string key = stringBuilder.Clear().Append(TypeName).Append('.').Append(methodName).ToString(); + if (!dictionary.TryGetValue(key, out tempMethod)) + { + // Not found hook function in cache dictionary, try find the function + tempLookupType = ClassType; + while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) + { + tempLookupMethods = tempLookupType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); + foreach (MethodInfo lookupMethod in tempLookupMethods) + { + // Return type must be `void` + if (lookupMethod.ReturnType != typeof(void)) + continue; + + // Not the function it's looking for + if (!lookupMethod.Name.Equals(methodName)) + continue; + + // Parameter not match + if (!parameterValidator.Invoke(lookupMethod.GetParameters())) + continue; + + // Found the function + tempMethod = lookupMethod; + break; + } + + // Found the function so exit the loop, don't find the function in base class + if (tempMethod != null) + break; + + tempLookupType = tempLookupType.BaseType; + } + // Add to cache dictionary althrough it's empty to avoid it try to lookup next time + dictionary.Add(key, tempMethod); + } + return tempMethod; + } + + private void CacheRpcs(Dictionary ids, Dictionary cacheDict) + where RpcType : RpcAttribute + { + CacheFunctions tempCacheFunctions; + if (!cacheDict.TryGetValue(TypeName, out tempCacheFunctions)) + { + tempCacheFunctions = new CacheFunctions() + { + functions = new List(), + functionsCanCallByEveryone = new List() + }; + tempLookupNames.Clear(); + tempLookupType = ClassType; + RpcType tempAttribute; + // Find for function with [Rpc] attribute to register as RPC + while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) + { + tempLookupMethods = tempLookupType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); + foreach (MethodInfo lookupMethod in tempLookupMethods) + { + // Avoid duplicate functions + if (tempLookupNames.Contains(lookupMethod.Name)) + continue; + + // Must have [Rpc] attribute + tempAttribute = lookupMethod.GetCustomAttribute(); + if (tempAttribute == null) + continue; + + // Return type must be `void` + if (lookupMethod.ReturnType != typeof(void)) + { + if (Manager.LogError) + Logging.LogError(LogTag, "Cannot register rpc [" + lookupMethod.Name + "] return type must be void"); + continue; + } + + if (!tempAttribute.canCallByEveryone) + tempCacheFunctions.functions.Add(lookupMethod); + else + tempCacheFunctions.functionsCanCallByEveryone.Add(lookupMethod); + tempLookupNames.Add(lookupMethod.Name); + } + tempLookupType = tempLookupType.BaseType; + } + cacheDict.Add(TypeName, tempCacheFunctions); + } + SetupRpcs(ids, tempCacheFunctions.functions, false); + SetupRpcs(ids, tempCacheFunctions.functionsCanCallByEveryone, true); + } + + private void SetupRpcs(Dictionary ids, List methodInfos, bool canCallByEveryone) + { + if (methodInfos == null || methodInfos.Count == 0) + return; + + string tempFunctionId; + Type[] tempParamTypes; + foreach (MethodInfo methodInfo in methodInfos) + { + tempFunctionId = MakeNetFunctionId(methodInfo); + if (!CacheDyncnamicFunctionTypes.TryGetValue(tempFunctionId, out tempParamTypes)) + { + tempParamTypes = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray(); + CacheDyncnamicFunctionTypes[tempFunctionId] = tempParamTypes; + } + RegisterRPC(ids, tempFunctionId, new LiteNetLibFunctionDynamic(tempParamTypes, this, methodInfo), canCallByEveryone); + } + } + + #region Sync Elements Registration + private void RegisterSyncElement(T element, List elementList) where T : LiteNetLibElement + { + int elementId = elementList.Count; + element.Setup(this, elementId); + elementList.Add(element); + } + + public void RegisterSyncField(T syncField) where T : LiteNetLibSyncField + { + RegisterSyncElement(syncField, Identity.SyncFields); + } + + public void RegisterSyncList(T syncList) where T : LiteNetLibSyncList + { + RegisterSyncElement(syncList, Identity.SyncLists); + } + #endregion + + #region RPCs Registration + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + /// + /// This is another synonym of `RegisterElasticRPC` + /// + public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterElasticRPC(func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + RegisterRPC(allRpcIds, func, canCallByEveryone); + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(serverRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(allRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + + public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(targetRpcIds, func, canCallByEveryone); + } + #endregion + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) + { + RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); + } + + private void RegisterRPC(Dictionary dict, string id, LiteNetLibFunction netFunction, bool canCallByEveryone) + { + if (dict.ContainsKey(id)) + { + if (Manager.LogError) + Logging.LogError(LogTag, "[" + TypeName + "] cannot register rpc with existed id [" + id + "]."); + return; + } + if (Identity.NetFunctions.Count >= int.MaxValue) + { + if (Manager.LogError) + Logging.LogError(LogTag, "[" + TypeName + "] cannot register rpc it's exceeds limit."); + return; + } + int elementId = Identity.NetFunctions.Count; + netFunction.Setup(this, elementId); + netFunction.CanCallByEveryone = canCallByEveryone; + Identity.NetFunctions.Add(netFunction); + dict[id] = elementId; + } + + #region Elastic RPC with receivers and parameters + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers) + { + RPC(func, receivers); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1) + { + RPC(func, receivers, param1); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2) + { + RPC(func, receivers, param1, param2); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) + { + RPC(func, receivers, param1, param2, param3); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) + { + RPC(func, receivers, param1, param2, param3, param4); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) + { + RPC(func, receivers, param1, param2, param3, param4, param5); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) + { + RPC(func, receivers, param1, param2, param3, param4, param5, param6); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) + { + RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) + { + RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) + { + RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) + { + RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + #endregion + + #region Elastic RPC with delivery method, receivers and parameters + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers) + { + RPC(func, dataChannel, deliveryMethod, receivers); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + /// + /// This is another synonym of `RPC` + /// + public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) + { + RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + #endregion + + #region All RPC or Server RPC with parameters + public void RPC(NetFunctionDelegate func) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered); + } + + public void RPC(NetFunctionDelegate func, T1 param1) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) + { + RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + #endregion + + #region All RPC or Server RPC with delivery method and parameters + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod) + { + RPC(func.Method.Name, dataChannel, deliveryMethod); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) + { + RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + #endregion + + #region Target RPC with connectionId and parameters + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId) + { + RPC(func, connectionId); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1) + { + RPC(func, connectionId, param1); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2) + { + RPC(func, connectionId, param1, param2); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3) + { + RPC(func, connectionId, param1, param2, param3); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4) + { + RPC(func, connectionId, param1, param2, param3, param4); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) + { + RPC(func, connectionId, param1, param2, param3, param4, param5); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) + { + RPC(func, connectionId, param1, param2, param3, param4, param5, param6); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) + { + RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) + { + RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) + { + RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` + /// + public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) + { + RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + + public void RPC(NetFunctionDelegate func, long connectionId) + { + RPC(func.Method.Name, connectionId); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1) + { + RPC(func.Method.Name, connectionId, param1); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2) + { + RPC(func.Method.Name, connectionId, param1, param2); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3) + { + RPC(func.Method.Name, connectionId, param1, param2, param3); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4) + { + RPC(func.Method.Name, connectionId, param1, param2, param3, param4); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) + { + RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) + { + RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) + { + RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) + { + RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) + { + RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) + { + RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + #endregion + + /// + /// This is another synonym of `RPC` which contains `receivers` and `parameters` + /// + public void CallNetFunction(string methodName, FunctionReceivers receivers, params object[] parameters) + { + RPC(methodName, receivers, parameters); + } + + /// + /// Call elastic RPC, it can be `All RPC` or `Server RPC` up to how you define `receivers` + /// + /// + /// + /// + public void RPC(string methodName, FunctionReceivers receivers, params object[] parameters) + { + RPC(methodName, 0, DeliveryMethod.ReliableOrdered, receivers, parameters); + } + + /// + /// This is another synonym of `RPC` which contains `dataChannel`, `deliveryMethod`, `receivers` and `parameters` + /// + public void CallNetFunction(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameters) + { + RPC(methodName, dataChannel, deliveryMethod, receivers, parameters); + } + + /// + /// Call elastic RPC, it can be `All RPC` or `Server RPC` up to how you define `receivers` + /// + /// + /// + /// + /// + /// + public void RPC(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameters) + { + int elementId; + switch (receivers) + { + case FunctionReceivers.All: + if (allRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) + { + Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, receivers, parameters); + } + else + { + if (Manager.LogError) + Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, any rpc [" + methodName + "] not found."); + } + break; + case FunctionReceivers.Server: + if (serverRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) + { + Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, receivers, parameters); + } + else + { + if (Manager.LogError) + Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, any rpc [" + methodName + "] not found."); + } + break; + default: + if (Manager.LogError) + Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, rpc [" + methodName + "] receives must be `All` or `Server`."); + break; + } + } + + /// + /// Call `All RPC` or `Server RPC`, if it's elastic RPC, it will call `All RPC` + /// + /// + /// + public void RPC(string methodName, params object[] parameters) + { + RPC(methodName, 0, DeliveryMethod.ReliableOrdered, parameters); + } + + /// + /// Call `All RPC` or `Server RPC`, if it's elastic RPC, it will call `All RPC` + /// + /// + /// + /// + /// + public void RPC(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, params object[] parameters) + { + int elementId; + if (allRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) + { + Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, FunctionReceivers.All, parameters); + } + else if (serverRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) + { + Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, FunctionReceivers.Server, parameters); + } + else + { + if (Manager.LogError) + Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, client or server rpc [" + methodName + "] not found."); + } + } + + /// + /// This is another synonym of `RPC` which contains `connectionId` and `parameters` + /// + public void CallNetFunction(string methodName, long connectionId, params object[] parameters) + { + RPC(methodName, connectionId, parameters); + } + + /// + /// Call function at target client by connection id + /// + /// + /// + /// + public void RPC(string methodName, long connectionId, params object[] parameters) + { + int elementId; + if (targetRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) + { + Identity.NetFunctions[elementId].Call(0, DeliveryMethod.ReliableOrdered, connectionId, parameters); + } + else + { + if (Manager.LogError) + Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, target rpc [" + methodName + "] not found."); + } + } + + private string MakeNetFunctionId(MethodInfo methodInfo) + { + return MakeNetFunctionId(methodInfo.Name); + } + + private string MakeNetFunctionId(string methodName) + { + return new StringBuilder(TypeName).Append('+').Append(methodName).ToString(); + } + + public void Serialize(NetDataWriter writer) + { + if (!IsServer) + return; + + writer.PutPackedUInt(Identity.ObjectId); + writer.Put(BehaviourIndex); + OnSerialize(writer); + } + + public void Deserialize(NetDataReader reader) + { + OnDeserialize(reader); + } + + public void SetOwnerClient(long connectionId) + { + Identity.SetOwnerClient(connectionId); + } + + public void NetworkDestroy() + { + Identity.NetworkDestroy(); + } + + public void NetworkDestroy(float delay) + { + Identity.NetworkDestroy(delay); + } + + public void ClientSendMessage(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { + if (!IsClient) + return; + Manager.ClientSendMessage(dataChannel, deliveryMethod, writer); + } + + public void ClientSendPacket(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) + { + if (!IsClient) + return; + Manager.ClientSendPacket(dataChannel, deliveryMethod, msgType, serializerDelegate); + } + + public void ServerSendMessage(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { + if (!IsServer) + return; + Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, writer); + } + + public void ServerSendPacket(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) + { + if (!IsServer) + return; + Manager.ServerSendPacket(connectionId, dataChannel, deliveryMethod, msgType, serializerDelegate); + } + + public void ServerSendMessageToAllConnections(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { + if (!IsServer) + return; + Manager.ServerSendMessageToAllConnections(dataChannel, deliveryMethod, writer); + } + + public void ServerSendPacketToAllConnections(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) + { + if (!IsServer) + return; + Manager.ServerSendPacketToAllConnections(dataChannel, deliveryMethod, msgType, serializerDelegate); + } + + public void ServerSendMessageToSubscribers(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + { + if (!IsServer) + return; + foreach (long connectionId in Manager.GetConnectionIds()) + { + if (Identity.HasSubscriber(connectionId)) + Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, writer); + } + } + + public void ServerSendPacketToSubscribers(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) + { + if (!IsServer) + return; + TransportHandler.WritePacket(Manager.Server.Writer, msgType, serializerDelegate); + foreach (long connectionId in Manager.GetConnectionIds()) + { + if (Identity.HasSubscriber(connectionId)) + Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, Manager.Server.Writer); + } + } + + /// + /// This function will be called when this behaviour spawned at server + /// + public virtual void OnStartServer() { } + + /// + /// This function will be called when this behaviour spawned at client (all client types `non-owner and owner`) + /// + public virtual void OnStartClient() { } + + /// + /// This function will be called when this behaviour spawned at owner-client + /// + public virtual void OnStartOwnerClient() { } + + /// + /// This function will be called when this client has been verified as owner client + /// + public virtual void OnSetOwnerClient(bool isOwnerClient) { } + + /// + /// This function will be called when this client receive spawn object message with position and rotation + /// + /// + /// + public virtual void InitTransform(Vector3 position, Quaternion rotation) { } + + /// + /// This function will be called when object destroy from server + /// + /// + public virtual void OnNetworkDestroy(byte reasons) { } + + /// + /// This function will be called when this behaviour have been setup by identity + /// You may do some initialize things within this function + /// + public virtual void OnSetup() { } + + /// + /// Override this function to define condition to sync behaviour data to client or not + /// + /// + public virtual bool CanSyncBehaviour() + { + return false; + } + + /// + /// Override this function to define condition to sync behaviour data to client when it should + /// + /// + public virtual bool ShouldSyncBehaviour() + { + return false; + } + + /// + /// Override this function to write custom data to send from server to client + /// + public virtual void OnSerialize(NetDataWriter writer) { } + + /// + /// Override this function to read data from server at client + /// + public virtual void OnDeserialize(NetDataReader reader) { } + + /// + /// Override this function to change object visibility when this added to player as subcribing + /// + public virtual void OnServerSubscribingAdded() { } + + /// + /// Override this function to change object visibility when this removed from player as subcribing + /// + public virtual void OnServerSubscribingRemoved() { } + } +} diff --git a/Scripts/LiteNetLibBehaviour.cs.meta b/Scripts/LiteNetLibBehaviour.cs.meta new file mode 100644 index 00000000..8f77957a --- /dev/null +++ b/Scripts/LiteNetLibBehaviour.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 1e3668c0fbd3f354489edb3a96824749 +timeCreated: 1508753155 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibElement.cs b/Scripts/LiteNetLibElement.cs new file mode 100644 index 00000000..91d847d5 --- /dev/null +++ b/Scripts/LiteNetLibElement.cs @@ -0,0 +1,105 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public struct LiteNetLibElementInfo + { + public uint objectId; + public int elementId; + public LiteNetLibElementInfo(uint objectId, int elementId) + { + this.objectId = objectId; + this.elementId = elementId; + } + + public static void SerializeInfo(LiteNetLibElementInfo info, NetDataWriter writer) + { + writer.PutPackedUInt(info.objectId); + writer.PutPackedUInt((uint)info.elementId); + } + + public static LiteNetLibElementInfo DeserializeInfo(NetDataReader reader) + { + return new LiteNetLibElementInfo(reader.GetPackedUInt(), (int)reader.GetPackedUInt()); + } + } + + public abstract class LiteNetLibElement + { + [ReadOnly, SerializeField] + protected LiteNetLibBehaviour behaviour; + public LiteNetLibBehaviour Behaviour + { + get { return behaviour; } + } + + public LiteNetLibIdentity Identity + { + get { return Behaviour.Identity; } + } + + public long ConnectionId + { + get { return !IsSetup ? -1 : Behaviour.ConnectionId; } + } + + public uint ObjectId + { + get { return !IsSetup ? 0 : Behaviour.ObjectId; } + } + + public LiteNetLibGameManager Manager + { + get { return Behaviour.Manager; } + } + + public virtual string LogTag + { + get { return (!IsSetup ? "(No Behaviour)" : Behaviour.LogTag) + "->" + ToString(); } + } + + public bool IsServer + { + get { return IsSetup && Behaviour.IsServer; } + } + + public bool IsClient + { + get { return IsSetup && Behaviour.IsClient; } + } + + public bool IsOwnerClient + { + get { return IsSetup && Behaviour.IsOwnerClient; } + } + + public bool IsSetup { get; private set; } + + [ReadOnly, SerializeField] + protected int elementId; + public int ElementId + { + get { return elementId; } + } + + public LiteNetLibElementInfo GetInfo() + { + return new LiteNetLibElementInfo(Behaviour.ObjectId, ElementId); + } + + internal virtual void Setup(LiteNetLibBehaviour behaviour, int elementId) + { + this.behaviour = behaviour; + this.elementId = elementId; + IsSetup = true; + } + + protected virtual bool CanSync() + { + return IsSetup; + } + } +} diff --git a/Scripts/LiteNetLibElement.cs.meta b/Scripts/LiteNetLibElement.cs.meta new file mode 100644 index 00000000..92395850 --- /dev/null +++ b/Scripts/LiteNetLibElement.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 6ef4e992e48d90a45ae6c3958a7df40d +timeCreated: 1511719678 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibFunction.cs b/Scripts/LiteNetLibFunction.cs new file mode 100644 index 00000000..4c86bd51 --- /dev/null +++ b/Scripts/LiteNetLibFunction.cs @@ -0,0 +1,471 @@ +using System; +using System.Reflection; +using LiteNetLib; +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public enum FunctionReceivers : byte + { + Target, + All, + Server, + } + + public class LiteNetLibFunction : LiteNetLibElement + { + protected readonly static NetDataWriter ServerWriter = new NetDataWriter(); + protected readonly static NetDataWriter ClientWriter = new NetDataWriter(); + + public readonly Type[] ParameterTypes; + public readonly object[] Parameters; + public bool CanCallByEveryone { get; set; } + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : this(0) + { + } + + protected LiteNetLibFunction(int parameterCount) + { + Parameters = new object[parameterCount]; + ParameterTypes = new Type[parameterCount]; + } + + protected LiteNetLibFunction(Type[] parameterTypes) + { + Parameters = new object[parameterTypes.Length]; + ParameterTypes = parameterTypes; + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + protected override bool CanSync() + { + return Behaviour != null && (IsServer || IsOwnerClient || CanCallByEveryone); + } + + internal virtual void HookCallback() + { + callback.Invoke(); + } + + protected void SendCall(byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, long targetConnectionId) + { + LiteNetLibGameManager manager = Manager; + LiteNetLibServer server = manager.Server; + LiteNetLibClient client = manager.Client; + if (manager.IsServer) + { + switch (receivers) + { + case FunctionReceivers.Target: + if (Identity.HasSubscriberOrIsOwning(targetConnectionId) && manager.ContainsConnectionId(targetConnectionId)) + { + // Prepare packet + TransportHandler.WritePacket(ServerWriter, GameMsgTypes.CallFunction); + SerializeForSend(ServerWriter); + // Send function call message from server to target client by target connection Id + server.SendMessage(targetConnectionId, dataChannel, deliveryMethod, ServerWriter); + } + break; + case FunctionReceivers.All: + // Send to all connections + foreach (long connectionId in manager.GetConnectionIds()) + { + if (manager.ClientConnectionId == connectionId) + { + // This is host's networking oject, so hook callback immediately + // Don't have to send message to the client, because it is currently run as both server and client + HookCallback(); + } + else if (Identity.HasSubscriberOrIsOwning(connectionId)) + { + // Prepare packet + TransportHandler.WritePacket(ServerWriter, GameMsgTypes.CallFunction); + SerializeForSend(ServerWriter); + // Send message to subscribing clients + server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); + } + } + if (!manager.IsClientConnected) + { + // It's not a host(client+host), it's just a server + // So hook callback immediately to do the function at server + HookCallback(); + } + break; + case FunctionReceivers.Server: + // Call server function at server + // So hook callback immediately to do the function at server + HookCallback(); + break; + } + } + else if (manager.IsClientConnected) + { + // Prepare packet + TransportHandler.WritePacket(ClientWriter, GameMsgTypes.CallFunction); + SerializeForClientSend(ClientWriter, receivers, targetConnectionId); + // Client send net function call to server + // Then the server will hook callback or forward message to other clients + client.SendMessage(dataChannel, deliveryMethod, ClientWriter); + } + } + + internal void SetParameters(params object[] parameterValues) + { + for (int i = 0; i < Parameters.Length; ++i) + { + if (i >= parameterValues.Length) + break; + Parameters[i] = parameterValues[i]; + } + } + + internal void Call(byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameterValues) + { + if (!CanSync()) + return; + + SetParameters(parameterValues); + SendCall(dataChannel, deliveryMethod, receivers, ConnectionId); + } + + internal void Call(byte dataChannel, DeliveryMethod deliveryMethod, long connectionId, params object[] parameterValues) + { + if (!CanSync()) + return; + + SetParameters(parameterValues); + SendCall(dataChannel, deliveryMethod, FunctionReceivers.Target, connectionId); + } + + internal void CallWithoutParametersSet(FunctionReceivers receivers) + { + if (!CanSync()) + return; + + SendCall(0, DeliveryMethod.ReliableOrdered, receivers, ConnectionId); + } + + internal void CallWithoutParametersSet(long connectionId) + { + if (!CanSync()) + return; + + SendCall(0, DeliveryMethod.ReliableOrdered, FunctionReceivers.Target, connectionId); + } + + private void SerializeForClientSend(NetDataWriter writer, FunctionReceivers receivers, long connectionId) + { + writer.Put((byte)receivers); + if (receivers == FunctionReceivers.Target) + writer.PutPackedLong(connectionId); + SerializeForSend(writer); + } + + private void SerializeForSend(NetDataWriter writer) + { + LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); + SerializeParameters(writer); + } + + public void DeserializeParameters(NetDataReader reader) + { + if (Parameters == null || Parameters.Length == 0) + return; + for (int i = 0; i < Parameters.Length; ++i) + { + if (ParameterTypes[i].IsArray) + Parameters[i] = reader.GetArray(ParameterTypes[i].GetElementType()); + else + Parameters[i] = reader.GetValue(ParameterTypes[i]); + } + } + + public void SerializeParameters(NetDataWriter writer) + { + if (Parameters == null || Parameters.Length == 0) + return; + for (int i = 0; i < Parameters.Length; ++i) + { + if (ParameterTypes[i].IsArray) + writer.PutArray(ParameterTypes[i].GetElementType(), Parameters[i]); + else + writer.PutValue(ParameterTypes[i], Parameters[i]); + } + } + } + + #region Implement for multiple parameter usages + public class LiteNetLibFunctionDynamic : LiteNetLibFunction + { + /// + /// The class which contain the function + /// + private object instance; + + private MethodInfo callback; + + public LiteNetLibFunctionDynamic(Type[] parameterTypes, object instance, MethodInfo callback) : base(parameterTypes) + { + this.instance = instance; + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback.Invoke(instance, Parameters); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(1) + { + ParameterTypes[0] = typeof(T1); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(2) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(3) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + ParameterTypes[2] = typeof(T3); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(4) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + ParameterTypes[2] = typeof(T3); + ParameterTypes[3] = typeof(T4); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(5) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + ParameterTypes[2] = typeof(T3); + ParameterTypes[3] = typeof(T4); + ParameterTypes[4] = typeof(T5); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(6) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + ParameterTypes[2] = typeof(T3); + ParameterTypes[3] = typeof(T4); + ParameterTypes[4] = typeof(T5); + ParameterTypes[5] = typeof(T6); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(7) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + ParameterTypes[2] = typeof(T3); + ParameterTypes[3] = typeof(T4); + ParameterTypes[4] = typeof(T5); + ParameterTypes[5] = typeof(T6); + ParameterTypes[6] = typeof(T7); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(8) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + ParameterTypes[2] = typeof(T3); + ParameterTypes[3] = typeof(T4); + ParameterTypes[4] = typeof(T5); + ParameterTypes[5] = typeof(T6); + ParameterTypes[6] = typeof(T7); + ParameterTypes[7] = typeof(T8); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(9) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + ParameterTypes[2] = typeof(T3); + ParameterTypes[3] = typeof(T4); + ParameterTypes[4] = typeof(T5); + ParameterTypes[5] = typeof(T6); + ParameterTypes[6] = typeof(T7); + ParameterTypes[7] = typeof(T8); + ParameterTypes[8] = typeof(T9); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7], (T9)Parameters[8]); + } + } + + public class LiteNetLibFunction : LiteNetLibFunction + { + private NetFunctionDelegate callback; + + protected LiteNetLibFunction() : base(10) + { + ParameterTypes[0] = typeof(T1); + ParameterTypes[1] = typeof(T2); + ParameterTypes[2] = typeof(T3); + ParameterTypes[3] = typeof(T4); + ParameterTypes[4] = typeof(T5); + ParameterTypes[5] = typeof(T6); + ParameterTypes[6] = typeof(T7); + ParameterTypes[7] = typeof(T8); + ParameterTypes[8] = typeof(T9); + ParameterTypes[9] = typeof(T10); + } + + public LiteNetLibFunction(NetFunctionDelegate callback) : this() + { + this.callback = callback; + } + + internal override sealed void HookCallback() + { + callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7], (T9)Parameters[8], (T10)Parameters[9]); + } + } + #endregion +} diff --git a/Scripts/LiteNetLibFunction.cs.meta b/Scripts/LiteNetLibFunction.cs.meta new file mode 100644 index 00000000..d95ea24a --- /dev/null +++ b/Scripts/LiteNetLibFunction.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 2fd014728a1d38448952ac768473cb6e +timeCreated: 1509024653 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibGameManager.cs b/Scripts/LiteNetLibGameManager.cs new file mode 100644 index 00000000..887e27cc --- /dev/null +++ b/Scripts/LiteNetLibGameManager.cs @@ -0,0 +1,1049 @@ +using UnityEngine; +using UnityEngine.SceneManagement; +using LiteNetLib; +using LiteNetLib.Utils; +using Cysharp.Threading.Tasks; +using System.Collections.Generic; +using System.Net.Sockets; + +namespace LiteNetLibManager +{ + [RequireComponent(typeof(LiteNetLibAssets))] + public class LiteNetLibGameManager : LiteNetLibManager + { + [Header("Game manager configs")] + public uint packetVersion = 1; + public float pingDuration = 1f; + public bool doNotEnterGameOnConnect; + public bool doNotDestroyOnSceneChanges; + + protected readonly Dictionary Players = new Dictionary(); + + private float _clientSendPingCountDown; + private float _serverSendPingCountDown; + private AsyncOperation _loadSceneAsyncOperation; + + public long ClientConnectionId { get; protected set; } + private long _rtt; + public long Rtt + { + get + { + if (IsServer) + return 0; + return _rtt; + } + } + private long _lastPingTime; + private long _totalRtt; + private int _rttCount; + public long Timestamp { get { return System.DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } } + /// + /// Unix timestamp (milliseconds) offsets from server + /// + public long ServerTimestampOffsets { get; protected set; } + /// + /// Server unix timestamp (milliseconds) + /// + public long ServerTimestamp + { + get + { + if (IsServer) + return Timestamp; + return Timestamp + ServerTimestampOffsets; + } + } + public string ServerSceneName { get; protected set; } + public LiteNetLibAssets Assets { get; protected set; } + public BaseInterestManager InterestManager { get; protected set; } + + protected virtual void Awake() + { + Assets = GetComponent(); + InterestManager = GetComponent(); + if (InterestManager == null) + InterestManager = gameObject.AddComponent(); + ServerSceneName = string.Empty; + if (doNotDestroyOnSceneChanges) + DontDestroyOnLoad(gameObject); + } + + protected override void FixedUpdate() + { + if (_loadSceneAsyncOperation == null) + { + if (IsClientConnected) + { + // Send ping from client + _clientSendPingCountDown -= Time.fixedDeltaTime; + if (_clientSendPingCountDown <= 0f) + { + SendClientPing(); + _clientSendPingCountDown = pingDuration; + } + } + if (IsServer) + { + // Send ping from server + _serverSendPingCountDown -= Time.fixedDeltaTime; + if (_serverSendPingCountDown <= 0f) + { + SendServerPing(); + _serverSendPingCountDown = pingDuration; + } + } + } + base.FixedUpdate(); + } + + public virtual uint PacketVersion() + { + return packetVersion; + } + + public bool TryGetPlayer(long connectionId, out LiteNetLibPlayer player) + { + return Players.TryGetValue(connectionId, out player); + } + + public bool ContainsPlayer(long connectionId) + { + return Players.ContainsKey(connectionId); + } + + public LiteNetLibPlayer GetPlayer(long connectionId) + { + return Players[connectionId]; + } + + public IEnumerable GetPlayers() + { + return Players.Values; + } + + public int PlayersCount + { + get { return Players.Count; } + } + + /// + /// Call this function to change gameplay scene at server, then the server will tell clients to change scene + /// + /// + public virtual void ServerSceneChange(string sceneName) + { + if (!IsServer) + return; + LoadSceneRoutine(sceneName, true).Forget(); + } + + /// + /// This function will be called to load scene async + /// + /// + /// + /// + private async UniTaskVoid LoadSceneRoutine(string sceneName, bool online) + { + if (_loadSceneAsyncOperation == null) + { + // If doNotDestroyOnSceneChanges not TRUE still not destroy this game object + // But it will be destroyed after scene loaded, if scene is offline scene + if (!doNotDestroyOnSceneChanges) + DontDestroyOnLoad(gameObject); + + if (online) + { + foreach (LiteNetLibPlayer player in Players.Values) + { + player.IsReady = false; + player.Subscribings.Clear(); + player.SpawnedObjects.Clear(); + } + Assets.Clear(true); + } + + if (LogDev) Logging.Log(LogTag, "Loading Scene: " + sceneName + " is online: " + online); + if (Assets.onLoadSceneStart != null) + Assets.onLoadSceneStart.Invoke(sceneName, online, 0f); + + _loadSceneAsyncOperation = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single); + while (_loadSceneAsyncOperation != null && !_loadSceneAsyncOperation.isDone) + { + if (Assets.onLoadSceneProgress != null) + Assets.onLoadSceneProgress.Invoke(sceneName, online, _loadSceneAsyncOperation.progress); + await UniTask.Yield(); + } + _loadSceneAsyncOperation = null; + + if (online) + { + Assets.Initialize(); + Assets.InitPoolingObjects(); + if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> Assets.Initialize()"); + if (IsClient) + { + // If it is host (both client and server) wait for client connection id before proceed server scene load + while (ClientConnectionId < 0) await UniTask.Yield(); + } + if (IsServer) + { + ServerSceneName = sceneName; + Assets.SpawnSceneObjects(); + if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> Assets.SpawnSceneObjects()"); + OnServerOnlineSceneLoaded(); + if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> OnServerOnlineSceneLoaded()"); + SendServerSceneChange(sceneName); + if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> SendServerSceneChange()"); + } + if (IsClient) + { + OnClientOnlineSceneLoaded(); + if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> OnClientOnlineSceneLoaded()"); + SendClientReady(); + if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> SendClientReady()"); + } + } + else if (!doNotDestroyOnSceneChanges) + { + // Destroy manager's game object if loaded scene is not online scene + Destroy(gameObject); + } + + if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " is online: " + online); + if (Assets.onLoadSceneFinish != null) + Assets.onLoadSceneFinish.Invoke(sceneName, online, 1f); + } + } + + protected override void RegisterMessages() + { + EnableRequestResponse(GameMsgTypes.Request, GameMsgTypes.Response); + // Request to server (response to client) + RegisterRequestToServer(GameReqTypes.EnterGame, HandleEnterGameRequest, HandleEnterGameResponse); + RegisterRequestToServer(GameReqTypes.ClientReady, HandleClientReadyRequest, HandleClientReadyResponse); + RegisterRequestToServer(GameReqTypes.ClientNotReady, HandleClientNotReadyRequest, HandleClientNotReadyResponse); + // Server messages + RegisterServerMessage(GameMsgTypes.CallFunction, HandleClientCallFunction); + RegisterServerMessage(GameMsgTypes.UpdateSyncField, HandleClientUpdateSyncField); + RegisterServerMessage(GameMsgTypes.InitialSyncField, HandleClientInitialSyncField); + RegisterServerMessage(GameMsgTypes.ClientSendTransform, HandleClientSendTransform); + RegisterServerMessage(GameMsgTypes.Ping, HandleClientPing); + RegisterServerMessage(GameMsgTypes.Pong, HandleClientPong); + // Client messages + RegisterClientMessage(GameMsgTypes.ServerSpawnSceneObject, HandleServerSpawnSceneObject); + RegisterClientMessage(GameMsgTypes.ServerSpawnObject, HandleServerSpawnObject); + RegisterClientMessage(GameMsgTypes.ServerDestroyObject, HandleServerDestroyObject); + RegisterClientMessage(GameMsgTypes.CallFunction, HandleServerCallFunction); + RegisterClientMessage(GameMsgTypes.UpdateSyncField, HandleServerUpdateSyncField); + RegisterClientMessage(GameMsgTypes.InitialSyncField, HandleServerInitialSyncField); + RegisterClientMessage(GameMsgTypes.OperateSyncList, HandleServerUpdateSyncList); + RegisterClientMessage(GameMsgTypes.ServerSyncBehaviour, HandleServerSyncBehaviour); + RegisterClientMessage(GameMsgTypes.ServerError, HandleServerError); + RegisterClientMessage(GameMsgTypes.ServerSceneChange, HandleServerSceneChange); + RegisterClientMessage(GameMsgTypes.ServerSetObjectOwner, HandleServerSetObjectOwner); + RegisterClientMessage(GameMsgTypes.Ping, HandleServerPing); + RegisterClientMessage(GameMsgTypes.Pong, HandleServerPong); + RegisterClientMessage(GameMsgTypes.Disconnect, HandleServerDisconnect); + } + + public async void KickClient(long connectionId, byte[] data) + { + if (!IsServer) + return; + ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.Disconnect, (writer) => writer.PutBytesWithLength(data)); + await UniTask.Delay(500); + ServerTransport.ServerDisconnect(connectionId); + } + + public void ResetRtt() + { + _rtt = 0; + _totalRtt = 0; + _rttCount = 0; + } + + public override void OnPeerConnected(long connectionId) + { + base.OnPeerConnected(connectionId); + if (!Players.ContainsKey(connectionId)) + Players.Add(connectionId, new LiteNetLibPlayer(this, connectionId)); + } + + public override void OnPeerDisconnected(long connectionId, DisconnectReason reason, SocketError socketError) + { + base.OnPeerDisconnected(connectionId, reason, socketError); + if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player)) + return; + player.ClearSubscribing(false); + player.DestroyObjectsWhenDisconnect(); + Players.Remove(connectionId); + } + + public override void OnClientConnected() + { + base.OnClientConnected(); + // Reset client connection id, will be received from server later + ClientConnectionId = -1; + ResetRtt(); + if (!doNotEnterGameOnConnect) + SendClientEnterGame(); + } + + public override void OnStartServer() + { + base.OnStartServer(); + // Reset client connection id, will be received from server later + ClientConnectionId = -1; + ResetRtt(); + if (!Assets.onlineScene.IsSet() || Assets.onlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) + { + ServerSceneName = SceneManager.GetActiveScene().name; + Assets.Initialize(); + Assets.SpawnSceneObjects(); + Assets.InitPoolingObjects(); + OnServerOnlineSceneLoaded(); + } + else + { + ServerSceneName = Assets.onlineScene.SceneName; + LoadSceneRoutine(Assets.onlineScene.SceneName, true).Forget(); + } + } + + public override void OnStopServer() + { + base.OnStopServer(); + ServerSceneName = string.Empty; + Players.Clear(); + Assets.Clear(); + if (Assets.offlineScene.IsSet() && !Assets.offlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) + LoadSceneRoutine(Assets.offlineScene.SceneName, false).Forget(); + } + + public override void OnStopClient() + { + base.OnStopClient(); + if (!IsServer) + { + Players.Clear(); + Assets.Clear(); + if (Assets.offlineScene.IsSet() && !Assets.offlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) + LoadSceneRoutine(Assets.offlineScene.SceneName, false).Forget(); + } + } + + #region Send messages functions + public void SendClientEnterGame() + { + if (!IsClientConnected) + return; + ClientSendRequest(GameReqTypes.EnterGame, new EnterGameRequestMessage() + { + packetVersion = PacketVersion(), + }, extraRequestSerializer: SerializeEnterGameData); + } + + public void SendClientReady() + { + if (!IsClientConnected) + return; + ClientSendRequest(GameReqTypes.ClientReady, EmptyMessage.Value, extraRequestSerializer: SerializeClientReadyData); + } + + public void SendClientNotReady() + { + if (!IsClientConnected) + return; + ClientSendRequest(GameReqTypes.ClientNotReady, EmptyMessage.Value); + } + + public void SendClientPing() + { + if (!IsClientConnected) + return; + ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.Ping, new PingMessage() + { + pingTime = Timestamp, + }); + } + + public void SendServerPing() + { + if (!IsServer) + return; + ServerSendPacketToAllConnections(0, DeliveryMethod.Unreliable, GameMsgTypes.Ping, new PingMessage() + { + pingTime = Timestamp, + }); + } + + public bool SendServerSpawnSceneObject(long connectionId, LiteNetLibIdentity identity) + { + if (!IsServer) + return false; + LiteNetLibPlayer player; + if (!Players.TryGetValue(connectionId, out player) || !player.IsReady) + return false; + ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSpawnSceneObject, new ServerSpawnSceneObjectMessage() + { + objectId = identity.ObjectId, + connectionId = identity.ConnectionId, + position = identity.transform.position, + rotation = identity.transform.rotation, + }, identity.WriteInitSyncFields); + return true; + } + + public bool SendServerSpawnObject(long connectionId, LiteNetLibIdentity identity) + { + if (!IsServer) + return false; + LiteNetLibPlayer player; + if (!Players.TryGetValue(connectionId, out player) || !player.IsReady) + return false; + ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSpawnObject, new ServerSpawnObjectMessage() + { + hashAssetId = identity.HashAssetId, + objectId = identity.ObjectId, + connectionId = identity.ConnectionId, + position = identity.transform.position, + rotation = identity.transform.rotation, + }, identity.WriteInitSyncFields); + return true; + } + + public void SendServerSpawnObjectWithData(long connectionId, LiteNetLibIdentity identity) + { + if (identity == null) + return; + + bool spawnObjectSent; + if (Assets.ContainsSceneObject(identity.ObjectId)) + spawnObjectSent = SendServerSpawnSceneObject(connectionId, identity); + else + spawnObjectSent = SendServerSpawnObject(connectionId, identity); + if (spawnObjectSent) + { + identity.SendInitSyncFields(connectionId); + identity.SendInitSyncLists(connectionId); + } + } + + public bool SendServerDestroyObject(long connectionId, uint objectId, byte reasons) + { + if (!IsServer) + return false; + if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player) || !player.IsReady) + return false; + ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerDestroyObject, new ServerDestroyObjectMessage() + { + objectId = objectId, + reasons = reasons, + }); + return true; + } + + public void SendServerError(bool shouldDisconnect, string errorMessage) + { + if (!IsServer) + return; + foreach (long connectionId in Server.ConnectionIds) + { + SendServerError(connectionId, shouldDisconnect, errorMessage); + } + } + + public void SendServerError(long connectionId, bool shouldDisconnect, string errorMessage) + { + if (!IsServer) + return; + if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player) || !player.IsReady) + return; + ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerDestroyObject, new ServerErrorMessage() + { + shouldDisconnect = shouldDisconnect, + errorMessage = errorMessage, + }); + } + + public void SendServerSceneChange(string sceneName) + { + if (!IsServer) + return; + foreach (long connectionId in Server.ConnectionIds) + { + if (IsClientConnected && connectionId == ClientConnectionId) + continue; + SendServerSceneChange(connectionId, sceneName); + } + } + + public void SendServerSceneChange(long connectionId, string sceneName) + { + if (!IsServer) + return; + ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSceneChange, new ServerSceneChangeMessage() + { + serverSceneName = sceneName, + }); + } + + public void SendServerSetObjectOwner(long connectionId, uint objectId, long ownerConnectionId) + { + if (!IsServer) + return; + ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSetObjectOwner, new ServerSetObjectOwner() + { + objectId = objectId, + connectionId = ownerConnectionId, + }); + } + #endregion + + #region Message Handlers + + protected virtual async UniTaskVoid HandleEnterGameRequest( + RequestHandlerData requestHandler, + EnterGameRequestMessage request, + RequestProceedResultDelegate result) + { + AckResponseCode responseCode = AckResponseCode.Error; + EnterGameResponseMessage response = new EnterGameResponseMessage(); + if (request.packetVersion == PacketVersion() && + await DeserializeEnterGameData(requestHandler.ConnectionId, requestHandler.Reader)) + { + responseCode = AckResponseCode.Success; + response.connectionId = requestHandler.ConnectionId; + response.serverSceneName = ServerSceneName; + } + result.Invoke(responseCode, response); + } + + protected virtual void HandleEnterGameResponse( + ResponseHandlerData responseHandler, + AckResponseCode responseCode, + EnterGameResponseMessage response) + { + if (responseCode == AckResponseCode.Success) + { + ClientConnectionId = response.connectionId; + if (IsClientConnected) + HandleServerSceneChange(response.serverSceneName); + } + else + { + if (LogError) Logging.LogError(LogTag, "Enter game request was refused by server, disconnecting..."); + OnClientConnectionRefused(); + } + } + + protected virtual async UniTaskVoid HandleClientReadyRequest( + RequestHandlerData requestHandler, + EmptyMessage request, + RequestProceedResultDelegate result) + { + AckResponseCode responseCode = AckResponseCode.Error; + if (await SetPlayerReady(requestHandler.ConnectionId, requestHandler.Reader)) + { + responseCode = AckResponseCode.Success; + } + result.Invoke(responseCode, EmptyMessage.Value); + } + + protected virtual void HandleClientReadyResponse( + ResponseHandlerData responseHandler, + AckResponseCode responseCode, + EmptyMessage response) + { + // Override this function to do something by response code + } + + protected virtual UniTaskVoid HandleClientNotReadyRequest( + RequestHandlerData requestHandler, + EmptyMessage request, + RequestProceedResultDelegate result) + { + AckResponseCode responseCode = AckResponseCode.Error; + if (SetPlayerNotReady(requestHandler.ConnectionId, requestHandler.Reader)) + { + responseCode = AckResponseCode.Success; + } + result.Invoke(responseCode, EmptyMessage.Value); + return default; + } + + protected void HandleClientNotReadyResponse( + ResponseHandlerData responseHandler, + AckResponseCode responseCode, + EmptyMessage response) + { + // Override this function to do something by response code + } + + protected virtual void HandleClientInitialSyncField(MessageHandlerData messageHandler) + { + // Field updated at owner-client, if this is server then multicast message to other clients + if (!IsServer) + return; + LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(info.objectId, out identity)) + { + LiteNetLibSyncField syncField = identity.GetSyncField(info); + // Sync field at server also have to be client multicast to allow it to multicast to other clients + if (syncField != null && syncField.syncMode == LiteNetLibSyncField.SyncMode.ClientMulticast) + { + // If this is server but it is not host, set data (deserialize) then pass to other clients + // If this is host don't set data because it's already did (in LiteNetLibSyncField class) + if (!identity.IsOwnerClient) + syncField.Deserialize(messageHandler.Reader, true); + // Send to other clients + foreach (long connectionId in Server.ConnectionIds) + { + // Don't send the update to owner client because it was updated before send update to server + if (connectionId == messageHandler.ConnectionId) + continue; + // Send update to clients except owner client + if (identity.HasSubscriberOrIsOwning(connectionId)) + syncField.SendUpdate(true, connectionId); + } + } + } + } + + protected virtual void HandleClientUpdateSyncField(MessageHandlerData messageHandler) + { + // Field updated at owner-client, if this is server then multicast message to other clients + if (!IsServer) + return; + LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(info.objectId, out identity)) + { + LiteNetLibSyncField syncField = identity.GetSyncField(info); + // Sync field at server also have to be client multicast to allow it to multicast to other clients + if (syncField != null && syncField.syncMode == LiteNetLibSyncField.SyncMode.ClientMulticast) + { + // If this is server but it is not host, set data (deserialize) then pass to other clients + // If this is host don't set data because it's already did (in LiteNetLibSyncField class) + if (!identity.IsOwnerClient) + syncField.Deserialize(messageHandler.Reader, false); + // Send to other clients + foreach (long connectionId in Server.ConnectionIds) + { + // Don't send the update to owner client because it was updated before send update to server + if (connectionId == messageHandler.ConnectionId) + continue; + // Send update to clients except owner client + if (identity.HasSubscriberOrIsOwning(connectionId)) + syncField.SendUpdate(false, connectionId); + } + } + } + } + + protected virtual void HandleClientCallFunction(MessageHandlerData messageHandler) + { + FunctionReceivers receivers = (FunctionReceivers)messageHandler.Reader.GetByte(); + long connectionId = -1; + if (receivers == FunctionReceivers.Target) + connectionId = messageHandler.Reader.GetPackedLong(); + LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(info.objectId, out identity)) + { + LiteNetLibFunction netFunction = identity.GetNetFunction(info); + if (netFunction == null) + { + // There is no net function that player try to call (player may try to hack) + return; + } + if (!netFunction.CanCallByEveryone && messageHandler.ConnectionId != identity.ConnectionId) + { + // The function not allowed anyone except owner client to call this net function + // And the client is also not the owner client + return; + } + if (receivers == FunctionReceivers.Server) + { + // Request from client to server, so hook callback at server immediately + identity.ProcessNetFunction(netFunction, messageHandler.Reader, true); + } + else + { + // Request from client to other clients, so hook callback later + identity.ProcessNetFunction(netFunction, messageHandler.Reader, false); + // Use call with out parameters set because parameters already set while process net function + if (receivers == FunctionReceivers.Target) + netFunction.CallWithoutParametersSet(connectionId); + else + netFunction.CallWithoutParametersSet(receivers); + } + } + } + + protected virtual void HandleClientSendTransform(MessageHandlerData messageHandler) + { + uint objectId = messageHandler.Reader.GetPackedUInt(); + byte behaviourIndex = messageHandler.Reader.GetByte(); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(objectId, out identity)) + { + LiteNetLibTransform netTransform; + if (identity.TryGetBehaviour(behaviourIndex, out netTransform)) + netTransform.HandleClientSendTransform(messageHandler.Reader); + } + } + + protected void HandleClientPing(MessageHandlerData messageHandler) + { + PingMessage message = messageHandler.ReadMessage(); + ServerSendPacket(messageHandler.ConnectionId, 0, DeliveryMethod.Unreliable, GameMsgTypes.Pong, new PongMessage() + { + pingTime = message.pingTime, + serverTime = Timestamp, + }); + } + + protected void HandleClientPong(MessageHandlerData messageHandler) + { + if (!Players.TryGetValue(messageHandler.ConnectionId, out LiteNetLibPlayer player)) + return; + PongMessage message = messageHandler.ReadMessage(); + if (player.LastPingTime < message.pingTime) + { + player.LastPingTime = message.pingTime; + long rtt = Timestamp - message.pingTime; + if (player.RttCount > 10) + { + player.TotalRtt = player.Rtt; + player.RttCount = 1; + } + player.TotalRtt += rtt; + player.RttCount++; + player.Rtt = player.TotalRtt / player.RttCount; + } + } + + protected virtual void HandleServerSpawnSceneObject(MessageHandlerData messageHandler) + { + ServerSpawnSceneObjectMessage message = messageHandler.ReadMessage(); + if (!IsServer) + Assets.NetworkSpawnScene(message.objectId, message.position, message.rotation, message.connectionId); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(message.objectId, out identity)) + { + // If it is not server, read its initial data + if (!IsServer) + { + identity.ResetSyncData(); + identity.ReadInitSyncFields(messageHandler.Reader); + } + // If it is host, it may hidden so show it + if (IsServer) + identity.OnServerSubscribingAdded(); + } + } + + protected virtual void HandleServerSpawnObject(MessageHandlerData messageHandler) + { + ServerSpawnObjectMessage message = messageHandler.ReadMessage(); + if (!IsServer) + Assets.NetworkSpawn(message.hashAssetId, message.position, message.rotation, message.objectId, message.connectionId); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(message.objectId, out identity)) + { + // If it is not server, read its initial data + if (!IsServer) + identity.ReadInitSyncFields(messageHandler.Reader); + // If it is host, it may hidden so show it + if (IsServer) + identity.OnServerSubscribingAdded(); + } + } + + protected virtual void HandleServerDestroyObject(MessageHandlerData messageHandler) + { + ServerDestroyObjectMessage message = messageHandler.ReadMessage(); + if (!IsServer) + { + Assets.NetworkDestroy(message.objectId, message.reasons); + } + else + { + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(message.objectId, out identity)) + identity.OnServerSubscribingRemoved(); + } + } + + protected virtual void HandleServerInitialSyncField(MessageHandlerData messageHandler) + { + // Field updated at server, if this is host (client and server) then skip it. + if (IsServer) + return; + LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(info.objectId, out identity)) + identity.ProcessSyncField(info, messageHandler.Reader, true); + } + + protected virtual void HandleServerUpdateSyncField(MessageHandlerData messageHandler) + { + // Field updated at server, if this is host (client and server) then skip it. + if (IsServer) + return; + LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(info.objectId, out identity)) + identity.ProcessSyncField(info, messageHandler.Reader, false); + } + + protected virtual void HandleServerCallFunction(MessageHandlerData messageHandler) + { + LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(info.objectId, out identity)) + { + // All function from server will be processed (because it's always trust server) + identity.ProcessNetFunction(info, messageHandler.Reader, true); + } + } + + protected virtual void HandleServerUpdateSyncList(MessageHandlerData messageHandler) + { + // List updated at server, if this is host (client and server) then skip it. + if (IsServer) + return; + LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(info.objectId, out identity)) + identity.ProcessSyncList(info, messageHandler.Reader); + } + + protected virtual void HandleServerSyncBehaviour(MessageHandlerData messageHandler) + { + // Behaviour sync from server, if this is host (client and server) then skip it. + if (IsServer) + return; + uint objectId = messageHandler.Reader.GetPackedUInt(); + byte behaviourIndex = messageHandler.Reader.GetByte(); + LiteNetLibIdentity identity; + if (Assets.TryGetSpawnedObject(objectId, out identity)) + identity.ProcessSyncBehaviour(behaviourIndex, messageHandler.Reader); + } + + protected virtual void HandleServerError(MessageHandlerData messageHandler) + { + // Error sent from server + ServerErrorMessage message = messageHandler.ReadMessage(); + OnServerError(message); + } + + protected virtual void HandleServerSceneChange(MessageHandlerData messageHandler) + { + // Received scene name from server + ServerSceneChangeMessage message = messageHandler.ReadMessage(); + HandleServerSceneChange(message.serverSceneName); + } + + protected void HandleServerSceneChange(string serverSceneName) + { + // Scene loaded at server, if this is host (client and server) then skip it. + if (IsServer) + return; + + if (string.IsNullOrEmpty(serverSceneName) || serverSceneName.Equals(SceneManager.GetActiveScene().name)) + { + Assets.Initialize(); + Assets.InitPoolingObjects(); + OnClientOnlineSceneLoaded(); + SendClientReady(); + } + else + { + // If scene is difference, load changing scene + LoadSceneRoutine(serverSceneName, true).Forget(); + } + } + + protected virtual void HandleServerSetObjectOwner(MessageHandlerData messageHandler) + { + // Object owner was set at server, if this is host (client and server) then skip it. + if (IsServer) + return; + ServerSetObjectOwner message = messageHandler.ReadMessage(); + Assets.SetObjectOwner(message.objectId, message.connectionId); + } + + protected void HandleServerPing(MessageHandlerData messageHandler) + { + PingMessage message = messageHandler.ReadMessage(); + // Send pong back to server (then server will calculates Rtt for this client later) + ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.Pong, new PongMessage() + { + pingTime = message.pingTime, + }); + } + + protected void HandleServerPong(MessageHandlerData messageHandler) + { + PongMessage message = messageHandler.ReadMessage(); + if (_lastPingTime < message.pingTime) + { + _lastPingTime = message.pingTime; + long rtt = Timestamp - message.pingTime; + if (_rttCount > 10) + { + _totalRtt = _rtt; + _rttCount = 1; + } + _totalRtt += rtt; + _rttCount++; + _rtt = _totalRtt / _rttCount; + // Calculate time offsets by device time offsets and RTT + ServerTimestampOffsets = (long)(message.serverTime - Timestamp + (Rtt * 0.5f)); + if (LogDev) Logging.Log(LogTag, "Rtt: " + Rtt + ", ServerTimestampOffsets: " + ServerTimestampOffsets); + } + } + + protected void HandleServerDisconnect(MessageHandlerData messageHandler) + { + Client.SetDisconnectData(messageHandler.Reader.GetBytesWithLength()); + } + #endregion + + /// + /// Overrride this function to send custom data when send enter game message + /// + /// + public virtual void SerializeEnterGameData(NetDataWriter writer) + { + + } + + /// + /// Override this function to read custom data that come with enter game message + /// + /// + /// + /// Return `true` if allow player to enter game. + public virtual async UniTask DeserializeEnterGameData(long connectionId, NetDataReader reader) + { + await UniTask.Yield(); + return true; + } + /// + /// Overrride this function to send custom data when send client ready message + /// + /// + public virtual void SerializeClientReadyData(NetDataWriter writer) + { + + } + + /// + /// Override this function to read custom data that come with client ready message + /// + /// + /// + /// + /// Return `true` if player is ready to play. + public virtual async UniTask DeserializeClientReadyData(LiteNetLibIdentity playerIdentity, long connectionId, NetDataReader reader) + { + await UniTask.Yield(); + return true; + } + + /// + /// Override this function to do anything after online scene loaded at server side + /// + public virtual void OnServerOnlineSceneLoaded() + { + + } + + /// + /// Override this function to do anything after online scene loaded at client side + /// + public virtual void OnClientOnlineSceneLoaded() + { + + } + + /// + /// Override this function to do anything after refused from server + /// + public virtual void OnClientConnectionRefused() + { + StopClient(); + } + + /// + /// Override this function to show error message / disconnect + /// + /// + public virtual void OnServerError(ServerErrorMessage message) + { + if (message.shouldDisconnect && !IsServer) + StopClient(); + } + + public virtual async UniTask SetPlayerReady(long connectionId, NetDataReader reader) + { + if (!IsServer) + return false; + + LiteNetLibPlayer player = Players[connectionId]; + if (player.IsReady) + return false; + player.IsReady = true; + if (!await DeserializeClientReadyData(SpawnPlayer(connectionId), connectionId, reader)) + { + player.IsReady = false; + return false; + } + + return true; + } + + public virtual bool SetPlayerNotReady(long connectionId, NetDataReader reader) + { + if (!IsServer) + return false; + + LiteNetLibPlayer player = Players[connectionId]; + if (!player.IsReady) + return false; + + player.IsReady = false; + player.ClearSubscribing(true); + player.DestroyObjectsWhenNotReady(); + return true; + } + + protected LiteNetLibIdentity SpawnPlayer(long connectionId) + { + if (Assets.PlayerPrefab == null) + return null; + return SpawnPlayer(connectionId, Assets.PlayerPrefab); + } + + protected LiteNetLibIdentity SpawnPlayer(long connectionId, LiteNetLibIdentity prefab) + { + if (prefab == null) + return null; + return SpawnPlayer(connectionId, prefab.HashAssetId); + } + + protected LiteNetLibIdentity SpawnPlayer(long connectionId, int hashAssetId) + { + LiteNetLibIdentity spawnedObject = Assets.NetworkSpawn(hashAssetId, Assets.GetPlayerSpawnPosition(), Quaternion.identity, 0, connectionId); + if (spawnedObject != null) + return spawnedObject; + return null; + } + } +} diff --git a/Scripts/LiteNetLibGameManager.cs.meta b/Scripts/LiteNetLibGameManager.cs.meta new file mode 100644 index 00000000..2c97d7d6 --- /dev/null +++ b/Scripts/LiteNetLibGameManager.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: ea8c7de787d565341b570116d5fa455a +timeCreated: 1508925027 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibIdentity.cs b/Scripts/LiteNetLibIdentity.cs new file mode 100644 index 00000000..f7690f7e --- /dev/null +++ b/Scripts/LiteNetLibIdentity.cs @@ -0,0 +1,843 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.SceneManagement; +#if UNITY_EDITOR +using UnityEditor; +using UnityEditor.SceneManagement; +#endif +using LiteNetLib.Utils; +using UnityEngine.Events; +using UnityEngine.Profiling; +using UnityEngine.Rendering; + +namespace LiteNetLibManager +{ + [DisallowMultipleComponent] + public sealed class LiteNetLibIdentity : MonoBehaviour + { + public static uint HighestObjectId { get; private set; } + [Tooltip("Asset ID will be hashed to uses as prefab instantiating reference, leave it empty to auto generate asset ID by asset path"), SerializeField] + private string assetId = string.Empty; + [ReadOnly, SerializeField] + private uint objectId = 0; + [Tooltip("If this is <= 0f, it will uses interest manager's `defaultVisibleRange` setting"), SerializeField] + private float visibleRange = 0f; + [Tooltip("If this is `TRUE` it will always visible no matter how far from player's objects"), SerializeField] + private bool alwaysVisible = false; + [Tooltip("If this is `TRUE` it will not destroy this network object when player disconnect the game"), SerializeField] + private bool doNotDestroyWhenDisconnect = false; + [Tooltip("If this is > 0, it will get instance from pooling system"), SerializeField] + private int poolingSize = 0; + + [Header("Events")] + public UnityEvent onGetInstance = new UnityEvent(); + + /// + /// This will be true when identity was spawned by manager + /// + public bool IsSpawned { get; private set; } + /// + /// This will be true when identity was requested to destroy + /// + public bool IsDestroyed { get; private set; } + /// + /// This will be true when identity setup + /// + public bool IsSetupBehaviours { get; private set; } + /// + /// Array of all behaviours + /// + public LiteNetLibBehaviour[] Behaviours { get; private set; } + /// + /// List of sync fields from all behaviours (include children behaviours) + /// + internal readonly List SyncFields = new List(); + /// + /// List of net functions from all behaviours (include children behaviours) + /// + internal readonly List NetFunctions = new List(); + /// + /// List of sync lists from all behaviours (include children behaviours) + /// + internal readonly List SyncLists = new List(); + /// + /// List of sync behaviours + /// + internal readonly List SyncBehaviours = new List(); + /// + /// List of networked objects which subscribed by this identity + /// + internal readonly HashSet Subscribings = new HashSet(); + /// + /// List of players which subscribe this identity + /// + internal readonly HashSet Subscribers = new HashSet(); + + public string AssetId { get { return assetId; } } + private int? hashAssetId; + public int HashAssetId + { + get + { + if (!hashAssetId.HasValue) + { + unchecked + { + int hash1 = 5381; + int hash2 = hash1; + + for (int i = 0; i < AssetId.Length && AssetId[i] != '\0'; i += 2) + { + hash1 = ((hash1 << 5) + hash1) ^ AssetId[i]; + if (i == AssetId.Length - 1 || AssetId[i + 1] == '\0') + break; + hash2 = ((hash2 << 5) + hash2) ^ AssetId[i + 1]; + } + + hashAssetId = hash1 + (hash2 * 1566083941); + } + } + return hashAssetId.Value; + } + } + public uint ObjectId { get { return objectId; } internal set { objectId = value; } } + public float VisibleRange { get { return visibleRange; } set { visibleRange = value; } } + public bool AlwaysVisible { get { return alwaysVisible; } set { alwaysVisible = value; } } + public bool DoNotDestroyWhenDisconnect { get { return doNotDestroyWhenDisconnect; } set { doNotDestroyWhenDisconnect = value; } } + public int PoolingSize { get { return poolingSize; } set { poolingSize = value; } } + public byte DataChannel { get; set; } = 0; + /// + /// If this is `TRUE` it will disallow other connections to subscribe this networked object + /// + public bool IsHide { get; set; } + /// + /// This will be used while `IsHide` is `TRUE` to allow some connections to subscribe this networked object + /// + public HashSet HideExceptions { get; } = new HashSet(); + public long ConnectionId { get; internal set; } = -1; + public bool IsPooledInstance { get; internal set; } = false; + public LiteNetLibGameManager Manager { get; internal set; } + + private string logTag; + public string LogTag + { + get + { + if (string.IsNullOrEmpty(logTag)) + logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; + return logTag; + } + } + + public LiteNetLibPlayer Player + { + get + { + LiteNetLibPlayer foundPlayer; + if (Manager == null || !Manager.TryGetPlayer(ConnectionId, out foundPlayer)) + return null; + return foundPlayer; + } + } + + public bool IsServer + { + get { return Manager != null && Manager.IsServer; } + } + + public bool IsClient + { + get { return Manager != null && Manager.IsClient; } + } + + public bool IsOwnerClient + { + get { return IsClient && Manager.ClientConnectionId >= 0 && ConnectionId >= 0 && Manager.ClientConnectionId == ConnectionId; } + } + + public bool IsHost + { + get { return IsServer && IsOwnerClient; } + } + + public bool IsOwnedByServer + { + get { return IsServer && ConnectionId < 0; } + } + + public bool IsOwnerClientOrOwnedByServer + { + get { return IsOwnerClient || IsOwnedByServer; } + } + + public bool IsSceneObject + { + get; private set; + } + + private float? destroyTime; + + private void FixedUpdate() + { + NetworkUpdate(Time.fixedDeltaTime); + } + + internal void NetworkUpdate(float deltaTime) + { + if (Manager == null || !IsSpawned) + return; + + if (destroyTime.HasValue && Time.fixedTime >= destroyTime.Value) + { + DestroyFromAssets(); + return; + } + + int loopCounter; + Profiler.BeginSample("LiteNetLibIdentity - SyncFields Update"); + for (loopCounter = 0; loopCounter < SyncFields.Count; ++loopCounter) + { + SyncFields[loopCounter].NetworkUpdate(deltaTime); + } + Profiler.EndSample(); + + Profiler.BeginSample("LiteNetLibIdentity - SyncLists Update"); + for (loopCounter = 0; loopCounter < SyncLists.Count; ++loopCounter) + { + SyncLists[loopCounter].SendOperations(); + } + Profiler.EndSample(); + + Profiler.BeginSample("LiteNetLibIdentity - SyncBehaviours Update"); + for (loopCounter = 0; loopCounter < SyncBehaviours.Count; ++loopCounter) + { + SyncBehaviours[loopCounter].NetworkUpdate(deltaTime); + } + Profiler.EndSample(); + } + + #region IDs generate in Editor +#if UNITY_EDITOR + private void OnValidate() + { + Event evt = Event.current; + if (evt != null && evt.commandName == "Duplicate") + { + // Reset asset ID to regenerate it + assetId = string.Empty; + } + SetupIDs(); + } + + [ContextMenu("Reorder Scene Object Id")] + public void ContextMenuReorderSceneObjectId() + { + ReorderSceneObjectId(); + } + + internal void AssignAssetID(GameObject prefab, bool clearAssetId = false) + { + if (clearAssetId) + assetId = string.Empty; + if (!string.IsNullOrEmpty(assetId)) + return; + assetId = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(prefab)); + } + + private bool ThisIsAPrefab() + { +#if UNITY_2018_3_OR_NEWER + return PrefabUtility.IsPartOfPrefabAsset(gameObject); +#else + PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject); + if (prefabType == PrefabType.Prefab) + return true; + return false; +#endif + } + + private bool ThisIsASceneObjectWithThatReferencesPrefabAsset(out GameObject prefab) + { + prefab = null; +#if UNITY_2018_3_OR_NEWER + if (!PrefabUtility.IsPartOfNonAssetPrefabInstance(gameObject)) + return false; +#else + PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject); + if (prefabType == PrefabType.None) + return false; +#endif +#if UNITY_2018_2_OR_NEWER + prefab = PrefabUtility.GetCorrespondingObjectFromSource(gameObject); +#else + prefab = (GameObject)PrefabUtility.GetPrefabParent(gameObject); +#endif + if (prefab == null) + { + Logging.LogError(LogTag, $"Failed to find prefab parent for scene object: {gameObject.name}."); + return false; + } + return true; + } + + internal void SetupIDs() + { + string oldAssetId = assetId; + uint oldObjectId = objectId; + GameObject prefab; + if (ThisIsAPrefab()) + { + // This is a prefab, can create prefab while playing so it will still assign asset ID and reset object ID + AssignAssetID(gameObject); + objectId = 0; + } + else if (ThisIsASceneObjectWithThatReferencesPrefabAsset(out prefab)) + { + if (!Application.isPlaying) + { + // This is a scene object with prefab link + AssignAssetID(prefab); + if (gameObject.scene == SceneManager.GetActiveScene()) + { + // Assign object id if it is in scene + AssignSceneObjectId(); + EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); + } + else + { + // Difference working scene?, clear object Id + objectId = 0; + } + } + } + else + { + if (!Application.isPlaying) + { + // This is a pure scene object (Not a prefab) + assetId = string.Empty; + if (gameObject.scene == SceneManager.GetActiveScene()) + { + // Assign object id if it is in scene + AssignSceneObjectId(); + EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); + } + else + { + // Difference working scene?, clear object Id + objectId = 0; + } + } + } + // Do not mark dirty while playing + if (!Application.isPlaying && (oldAssetId != assetId || oldObjectId != objectId)) + EditorUtility.SetDirty(this); + } +#endif + #endregion + + #region SyncField Functions + internal LiteNetLibSyncField ProcessSyncField(LiteNetLibElementInfo info, NetDataReader reader, bool isInitial) + { + return ProcessSyncField(GetSyncField(info), reader, isInitial); + } + + internal LiteNetLibSyncField ProcessSyncField(LiteNetLibSyncField syncField, NetDataReader reader, bool isInitial) + { + if (syncField == null) + return null; + syncField.Deserialize(reader, isInitial); + return syncField; + } + + internal LiteNetLibSyncField GetSyncField(LiteNetLibElementInfo info) + { + if (info.objectId != ObjectId) + return null; + if (info.elementId >= 0 && info.elementId < SyncFields.Count) + return SyncFields[info.elementId]; + if (Manager.LogError) + Logging.LogError(LogTag, $"Cannot find sync field: {info.elementId}."); + return null; + } + #endregion + + #region NetFunction Functions + internal LiteNetLibFunction ProcessNetFunction(LiteNetLibElementInfo info, NetDataReader reader, bool hookCallback) + { + return ProcessNetFunction(GetNetFunction(info), reader, hookCallback); + } + + internal LiteNetLibFunction ProcessNetFunction(LiteNetLibFunction netFunction, NetDataReader reader, bool hookCallback) + { + if (netFunction == null) + return null; + netFunction.DeserializeParameters(reader); + if (hookCallback) + netFunction.HookCallback(); + return netFunction; + } + + internal LiteNetLibFunction GetNetFunction(LiteNetLibElementInfo info) + { + if (info.objectId != ObjectId) + return null; + if (info.elementId >= 0 && info.elementId < NetFunctions.Count) + return NetFunctions[info.elementId]; + if (Manager.LogError) + Logging.LogError(LogTag, $"Cannot find net function: {info.elementId}."); + return null; + } + #endregion + + #region SyncList Functions + internal LiteNetLibSyncList ProcessSyncList(LiteNetLibElementInfo info, NetDataReader reader) + { + return ProcessSyncList(GetSyncList(info), reader); + } + + internal LiteNetLibSyncList ProcessSyncList(LiteNetLibSyncList syncList, NetDataReader reader) + { + if (syncList == null) + return null; + syncList.ProcessOperations(reader); + return syncList; + } + + internal LiteNetLibSyncList GetSyncList(LiteNetLibElementInfo info) + { + if (info.objectId != ObjectId) + return null; + if (info.elementId >= 0 && info.elementId < SyncLists.Count) + return SyncLists[info.elementId]; + if (Manager.LogError) + Logging.LogError(LogTag, $"Cannot find sync list: {info.elementId}."); + return null; + } + #endregion + + internal LiteNetLibBehaviour ProcessSyncBehaviour(byte behaviourIndex, NetDataReader reader) + { + if (behaviourIndex >= Behaviours.Length) + return null; + LiteNetLibBehaviour behaviour = Behaviours[behaviourIndex]; + behaviour.Deserialize(reader); + return behaviour; + } + + internal bool TryGetBehaviour(byte behaviourIndex, out T behaviour) + where T : LiteNetLibBehaviour + { + behaviour = null; + if (behaviourIndex >= Behaviours.Length) + return false; + behaviour = Behaviours[behaviourIndex] as T; + return behaviour != null; + } + + /// + /// This function will be called when send networked object spawning message, to write sync field data + /// + /// + internal void WriteInitSyncFields(NetDataWriter writer) + { + foreach (LiteNetLibSyncField field in SyncFields) + { + if (field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) + continue; + field.Serialize(writer); + } + } + + /// + /// This function will be called when receive networked object spawning message, to read sync field data + /// + /// + internal void ReadInitSyncFields(NetDataReader reader) + { + foreach (LiteNetLibSyncField field in SyncFields) + { + if (field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) + continue; + field.Deserialize(reader, true); + } + } + + /// + /// This function will be called after networked object spawning message was sent + /// + /// + internal void SendInitSyncFields(long connectionId) + { + foreach (LiteNetLibSyncField field in SyncFields) + { + if (!field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) + continue; + field.SendUpdate(true, connectionId); + } + } + + internal void SendInitSyncLists(long connectionId) + { + foreach (LiteNetLibSyncList list in SyncLists) + { + list.SendInitialList(connectionId); + } + } + + public bool IsSceneObjectExists(uint objectId) + { + if (Manager != null) + { + // If this is spawned while gameplay, find it by manager assets + return Manager.Assets.ContainsSceneObject(objectId); + } + // If this is now spawned while gameplay, find objects in scene + LiteNetLibIdentity[] netObjects = FindObjectsOfType(); + foreach (LiteNetLibIdentity netObject in netObjects) + { + if (netObject.objectId == objectId && netObject != this) + return true; + } + return false; + } + + /// + /// Initial Identity, will be called when spawned. If object id == 0, it will generate new object id + /// + /// + /// + /// + /// + internal void Initial(LiteNetLibGameManager manager, bool isSceneObject, uint objectId = 0, long connectionId = -1) + { + Manager = manager; + ObjectId = objectId; + ConnectionId = connectionId; + UpdateHighestObjectId(objectId); + IsDestroyed = false; + IsSpawned = true; + IsSceneObject = isSceneObject; + if (!IsSceneObject) + AssignSceneObjectId(); + + if (!IsSetupBehaviours) + { + // Setup behaviours index, we will use this as reference for network functions + // NOTE: Maximum network behaviour for a identity is 255 (included children) + Behaviours = GetComponentsInChildren(); + SyncBehaviours.Clear(); + byte loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].Setup(loopCounter); + if (Behaviours[loopCounter].CanSyncBehaviour()) + SyncBehaviours.Add(Behaviours[loopCounter]); + } + IsSetupBehaviours = true; + } + + // If this is host, hide it then will be showned when initialize subscribings + if (IsServer && IsClient) + OnServerSubscribingRemoved(); + + Manager.Assets.SpawnedObjects.Add(ObjectId, this); + if (IsServer && ConnectionId >= 0) + { + Player.SpawnedObjects.Add(ObjectId, this); + Player.Subscribe(ObjectId); + } + + Manager.InterestManager.NotifyNewObject(this); + } + + internal void OnSetOwnerClient(bool isOwnerClient) + { + int loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].OnSetOwnerClient(isOwnerClient); + } + } + + internal void InitTransform(Vector3 position, Quaternion rotation) + { + int loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].InitTransform(position, rotation); + } + } + + internal void OnStartServer() + { + int loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].OnStartServer(); + } + } + + internal void OnStartClient() + { + int loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].OnStartClient(); + } + } + + internal void OnStartOwnerClient() + { + int loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].OnStartOwnerClient(); + } + } + + internal void AssignSceneObjectId() + { + if (objectId == 0 || IsSceneObjectExists(objectId)) + objectId = GetNewObjectId(); + } + + internal static void ResetObjectId() + { + HighestObjectId = 0; + } + + internal static uint GetNewObjectId() + { + if (HighestObjectId == 0) + { + uint result = HighestObjectId; + LiteNetLibIdentity[] netObjects = FindObjectsOfType(); + foreach (LiteNetLibIdentity netObject in netObjects) + { + if (netObject.objectId > result) + result = netObject.objectId; + } + HighestObjectId = result; + } + ++HighestObjectId; + return HighestObjectId; + } + + internal static void ReorderSceneObjectId() + { + ResetObjectId(); + LiteNetLibIdentity[] netObjects = FindObjectsOfType(); + foreach (LiteNetLibIdentity netObject in netObjects) + { + netObject.objectId = ++HighestObjectId; +#if UNITY_EDITOR + // Do not mark dirty while playing + if (!Application.isPlaying) + EditorUtility.SetDirty(netObject); +#endif + } +#if UNITY_EDITOR + // Do not mark dirty while playing + if (!Application.isPlaying) + EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); +#endif + } + + internal static void UpdateHighestObjectId(uint objectId) + { + if (objectId > HighestObjectId) + HighestObjectId = objectId; + } + + public bool AddSubscriber(long connectionId) + { + return Subscribers.Add(connectionId); + } + + public bool RemoveSubscriber(long connectionId) + { + return Subscribers.Remove(connectionId); + } + + public bool HasSubscriber(long connectionId) + { + return Subscribers.Contains(connectionId); + } + + public int CountSubscribers() + { + return Subscribers.Count; + } + + public bool HasSubscriberOrIsOwning(long connectionId) + { + return connectionId == ConnectionId || HasSubscriber(connectionId); + } + + public void AddSubscribing(uint subscribing) + { + Subscribings.Add(subscribing); + Player.Subscribe(subscribing); + } + + public void RemoveSubscribing(uint subscribing) + { + Subscribings.Remove(subscribing); + Player.Unsubscribe(subscribing); + } + + public void UpdateSubscribings(HashSet newSubscribings) + { + if (!IsServer || ConnectionId < 0 || !Player.IsReady) + { + // This is not player's networked object + return; + } + // Always add controlled network object to subscribe it + LiteNetLibIdentity tempIdentity; + newSubscribings.Add(ObjectId); + foreach (uint oldSubscribing in Subscribings) + { + if (oldSubscribing == ObjectId) + continue; + if (!newSubscribings.Contains(oldSubscribing)) + { + Player.Unsubscribe(oldSubscribing); + if (Manager.LogDebug) + Logging.Log(LogTag, $"Player: {ConnectionId} unsubscribe object ID: {oldSubscribing}."); + } + } + Subscribings.Clear(); + foreach (uint newSubscribing in newSubscribings) + { + if (!Manager.Assets.TryGetSpawnedObject(newSubscribing, out tempIdentity) || + tempIdentity.IsDestroyed) + continue; + Subscribings.Add(newSubscribing); + Player.Subscribe(newSubscribing); + if (Manager.LogDebug) + Logging.Log(LogTag, $"Player: {ConnectionId} subscribe object ID: {newSubscribing}."); + } + } + + public bool IsHideFrom(LiteNetLibIdentity identity) + { + if (identity == null) + return true; + return IsHide && !HideExceptions.Contains(ConnectionId) && ConnectionId != identity.ConnectionId; + } + + public void OnServerSubscribingAdded() + { + int loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].OnServerSubscribingAdded(); + } + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) + return; + Renderer[] renderers = GetComponentsInChildren(true); + for (int i = 0; i < renderers.Length; ++i) + { + renderers[i].forceRenderingOff = false; + } + } + + public void OnServerSubscribingRemoved() + { + int loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].OnServerSubscribingRemoved(); + } + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) + return; + Renderer[] renderers = GetComponentsInChildren(true); + for (int i = 0; i < renderers.Length; ++i) + { + renderers[i].forceRenderingOff = true; + } + } + + public void SetOwnerClient(long connectionId) + { + if (!IsServer) + return; + + Manager.Assets.SetObjectOwner(ObjectId, connectionId); + } + + public void NetworkDestroy() + { + if (!IsServer) + return; + + DestroyFromAssets(); + } + + public void NetworkDestroy(float delay) + { + if (!IsServer) + return; + destroyTime = Time.fixedTime + delay; + } + + private void DestroyFromAssets() + { + if (!IsDestroyed && Manager.Assets.NetworkDestroy(ObjectId, DestroyObjectReasons.RequestedToDestroy)) + IsDestroyed = true; + destroyTime = null; + } + + internal void OnNetworkDestroy(byte reasons) + { + int loopCounter; + for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) + { + Behaviours[loopCounter].OnNetworkDestroy(reasons); + } + if (Manager.IsServer) + { + // If this is server, send message to clients to destroy object + LiteNetLibPlayer player; + foreach (long subscriber in Subscribers) + { + if (Manager.TryGetPlayer(subscriber, out player)) + { + player.Subscribings.Remove(objectId); + Manager.SendServerDestroyObject(subscriber, objectId, reasons); + } + } + // Delete object from owner player's spawned objects collection + if (ConnectionId >= 0) + Player.SpawnedObjects.Remove(ObjectId); + } + // Delete object from assets component + Manager.Assets.SpawnedObjects.Remove(ObjectId); + // Clear data + Subscribings.Clear(); + Subscribers.Clear(); + IsSpawned = false; + } + + internal void OnGetInstance() + { + ResetSyncData(); + onGetInstance.Invoke(); + } + + internal void ResetSyncData() + { + // Clear/reset syncing data + foreach (LiteNetLibSyncField field in SyncFields) + { + field.Reset(); + } + foreach (LiteNetLibSyncList list in SyncLists) + { + list.Reset(); + } + } + } +} diff --git a/Scripts/LiteNetLibIdentity.cs.meta b/Scripts/LiteNetLibIdentity.cs.meta new file mode 100644 index 00000000..512f6d9c --- /dev/null +++ b/Scripts/LiteNetLibIdentity.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 56367cc2ed44f1e49835e9c247771fd9 +timeCreated: 1508750760 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibPlayer.cs b/Scripts/LiteNetLibPlayer.cs new file mode 100644 index 00000000..400e7a43 --- /dev/null +++ b/Scripts/LiteNetLibPlayer.cs @@ -0,0 +1,122 @@ +using System.Collections.Generic; + +namespace LiteNetLibManager +{ + public class LiteNetLibPlayer + { + public LiteNetLibGameManager Manager { get; protected set; } + public long ConnectionId { get; protected set; } + public bool IsReady { get; set; } + public long Rtt { get; internal set; } + + internal long LastPingTime; + internal long TotalRtt; + internal int RttCount; + internal readonly HashSet Subscribings = new HashSet(); + internal readonly Dictionary SpawnedObjects = new Dictionary(); + + public LiteNetLibPlayer(LiteNetLibGameManager manager, long connectionId) + { + Manager = manager; + ConnectionId = connectionId; + } + + internal bool IsSubscribing(uint objectId) + { + return Subscribings.Contains(objectId); + } + + internal int CountSubscribing() + { + return Subscribings.Count; + } + + internal void Subscribe(uint objectId) + { + LiteNetLibIdentity identity; + if (Subscribings.Add(objectId) && Manager.Assets.TryGetSpawnedObject(objectId, out identity)) + { + identity.AddSubscriber(ConnectionId); + Manager.SendServerSpawnObjectWithData(ConnectionId, identity); + } + } + + internal void Unsubscribe(uint objectId) + { + LiteNetLibIdentity identity; + if (Subscribings.Remove(objectId) && Manager.Assets.TryGetSpawnedObject(objectId, out identity)) + { + identity.RemoveSubscriber(ConnectionId); + Manager.SendServerDestroyObject(ConnectionId, objectId, DestroyObjectReasons.RemovedFromSubscribing); + } + } + + internal void ClearSubscribing(bool destroyObjectsOnPeer) + { + // Remove player's subscribing and remove this player from subscribers + LiteNetLibIdentity identity; + foreach (uint objectId in Subscribings) + { + if (!Manager.Assets.TryGetSpawnedObject(objectId, out identity)) + continue; + identity.RemoveSubscriber(ConnectionId); + if (destroyObjectsOnPeer) + Manager.SendServerDestroyObject(ConnectionId, objectId, DestroyObjectReasons.RemovedFromSubscribing); + } + Subscribings.Clear(); + } + + internal void DestroyObjectsWhenNotReady() + { + List objectIds = new List(SpawnedObjects.Keys); + foreach (uint objectId in objectIds) + Manager.Assets.NetworkDestroy(objectId, DestroyObjectReasons.RequestedToDestroy); + SpawnedObjects.Clear(); + } + + internal void DestroyObjectsWhenDisconnect() + { + List objectIds = new List(SpawnedObjects.Keys); + foreach (uint objectId in objectIds) + { + if (SpawnedObjects[objectId].DoNotDestroyWhenDisconnect) + { + SpawnedObjects[objectId].ConnectionId = -1; + continue; + } + Manager.Assets.NetworkDestroy(objectId, DestroyObjectReasons.RequestedToDestroy); + } + SpawnedObjects.Clear(); + } + + public bool TryGetSpawnedObject(uint objectId, out LiteNetLibIdentity identity) + { + return SpawnedObjects.TryGetValue(objectId, out identity); + } + + public bool ContainsSpawnedObject(uint objectId) + { + return SpawnedObjects.ContainsKey(objectId); + } + + public LiteNetLibIdentity GetSpawnedObject(uint objectId) + { + return SpawnedObjects[objectId]; + } + + public IEnumerable GetSpawnedObjects() + { + return SpawnedObjects.Values; + } + + public IEnumerable GetSubscribingObjectIds() + { + return Subscribings; + } + + public int SpawnedObjectsCount + { + get { return SpawnedObjects.Count; } + } + } +} diff --git a/Scripts/LiteNetLibPlayer.cs.meta b/Scripts/LiteNetLibPlayer.cs.meta new file mode 100644 index 00000000..31a4ab3c --- /dev/null +++ b/Scripts/LiteNetLibPlayer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: b905784494aa1194883589d0008336d2 +timeCreated: 1518872995 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibSpawnPoint.cs b/Scripts/LiteNetLibSpawnPoint.cs new file mode 100644 index 00000000..9ba9554a --- /dev/null +++ b/Scripts/LiteNetLibSpawnPoint.cs @@ -0,0 +1,43 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace LiteNetLibManager +{ + public class LiteNetLibSpawnPoint : MonoBehaviour + { + [SerializeField] + private float radius = 0f; + + public Transform CacheTransform { get; private set; } + + public Vector3 Position + { + get { return CacheTransform.position; } + } + + private void Awake() + { + CacheTransform = transform; + } + +#if UNITY_EDITOR + private void OnDrawGizmos() + { + Color color = Color.green; + Gizmos.color = color; + Gizmos.DrawWireSphere(transform.position, radius); + color.a = 0.5f; + Gizmos.color = color; + Gizmos.DrawSphere(transform.position, radius); + } +#endif + + public Vector3 GetRandomPosition() + { + Vector3 offsets = Random.insideUnitSphere * radius; + offsets.y = 0; + return Position + offsets; + } + } +} diff --git a/Scripts/LiteNetLibSpawnPoint.cs.meta b/Scripts/LiteNetLibSpawnPoint.cs.meta new file mode 100644 index 00000000..d1d67a84 --- /dev/null +++ b/Scripts/LiteNetLibSpawnPoint.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: f2a1f142556b957428162f23ccf49bfd +timeCreated: 1524424716 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibSyncField.cs b/Scripts/LiteNetLibSyncField.cs new file mode 100644 index 00000000..8a615c55 --- /dev/null +++ b/Scripts/LiteNetLibSyncField.cs @@ -0,0 +1,693 @@ +using System; +using UnityEngine; +using LiteNetLib; +using LiteNetLib.Utils; +using System.Reflection; + +namespace LiteNetLibManager +{ + public abstract class LiteNetLibSyncField : LiteNetLibElement + { + protected readonly static NetDataWriter ServerWriter = new NetDataWriter(); + protected readonly static NetDataWriter ClientWriter = new NetDataWriter(); + + public enum SyncMode : byte + { + /// + /// Changes handle by server + /// Will send to connected clients when changes occurs on server + /// + ServerToClients, + /// + /// Changes handle by server + /// Will send to owner-client when changes occurs on server + /// + ServerToOwnerClient, + /// + /// Changes handle by owner-client + /// Will send to server then server multicast to other clients when changes occurs on owner-client + /// + ClientMulticast + } + + [Flags] + public enum SyncBehaviour : byte + { + Default = 0, + AlwaysSync = 1 << 0, + DoNotSyncInitialDataImmediately = 1 << 1, + DoNotSyncUpdate = 1 << 2, + } + + [Header("Generic Settings")] + [Tooltip("How it will sync data. If always sync, it will sync data although it has no changes. If don't sync initial data immediately, it will not sync initial data immdediately with networked object spawning message, it will sync later after spanwed. If don't sync update, it will not sync when data has changes.")] + public SyncBehaviour syncBehaviour; + [Tooltip("Who can sync data and sync to whom")] + public SyncMode syncMode; + [Tooltip("Interval to send networking data")] + [Range(0.01f, 2f)] + public float sendInterval = 0.1f; + + [Header("Server Sync Settings")] + [Tooltip("Sending data channel from server to clients")] + public byte dataChannel = 0; + [Tooltip("Sending method type from server to clients, default is `Sequenced`")] + public DeliveryMethod deliveryMethod = DeliveryMethod.Sequenced; + + [Header("Client Sync Settings (`syncMode` is `ClientMulticast` only)")] + [Tooltip("Sending data channel from clients to server (`syncMode` is `ClientMulticast` only)")] + public byte clientDataChannel = 0; + [Tooltip("Sending method type from clients to server (`syncMode` is `ClientMulticast` only), default is `Sequenced`")] + public DeliveryMethod clientDeliveryMethod = DeliveryMethod.Sequenced; + + private float sendCountDown; + private bool onChangeCalled; + protected object defaultValue; + + public abstract Type GetFieldType(); + public abstract object GetValue(); + public abstract void SetValue(object value); + internal abstract void OnChange(bool initial); + internal abstract bool HasUpdate(); + internal abstract void Updated(); + + public bool HasSyncBehaviourFlag(SyncBehaviour flag) + { + return (syncBehaviour & flag) == flag; + } + + internal void Reset() + { + SetValue(defaultValue); + } + + internal override sealed void Setup(LiteNetLibBehaviour behaviour, int elementId) + { + base.Setup(behaviour, elementId); + defaultValue = GetValue(); + // Invoke on change function with initial state = true + switch (syncMode) + { + case SyncMode.ServerToClients: + case SyncMode.ServerToOwnerClient: + if (IsServer) + OnChange(true); + break; + case SyncMode.ClientMulticast: + if (IsOwnerClient) + OnChange(true); + break; + } + } + + internal void NetworkUpdate(float deltaTime) + { + if (!CanSync()) + return; + + // Won't update + if (HasSyncBehaviourFlag(SyncBehaviour.DoNotSyncUpdate)) + return; + + // No update + if (!HasSyncBehaviourFlag(SyncBehaviour.AlwaysSync) && !HasUpdate()) + return; + + // Call `OnChange` if it's not called yet. + if ((HasSyncBehaviourFlag(SyncBehaviour.AlwaysSync) || HasUpdate()) && !onChangeCalled) + { + // Invoke on change function with initial state = false + switch (syncMode) + { + case SyncMode.ServerToClients: + case SyncMode.ServerToOwnerClient: + if (IsServer) + OnChange(false); + break; + case SyncMode.ClientMulticast: + if (IsOwnerClient) + OnChange(false); + break; + } + onChangeCalled = true; + } + + // It's time to send update? + sendCountDown -= deltaTime; + if (sendCountDown > 0f) + return; + + // Set count down + sendCountDown = sendInterval; + + // Send the update + SendUpdate(false); + + // Update already sent + Updated(); + + // Reset on change called state to call `OnChange` later when has update + onChangeCalled = false; + } + + public void UpdateImmediately() + { + sendCountDown = 0f; + NetworkUpdate(0f); + } + + internal void Deserialize(NetDataReader reader, bool isInitial) + { + DeserializeValue(reader); + OnChange(isInitial); + } + + internal void Serialize(NetDataWriter writer) + { + SerializeValue(writer); + } + + internal virtual void DeserializeValue(NetDataReader reader) + { + SetValue(reader.GetValue(GetFieldType())); + } + + internal virtual void SerializeValue(NetDataWriter writer) + { + writer.PutValue(GetFieldType(), GetValue()); + } + + internal void SendUpdate(bool isInitial, long connectionId) + { + if (!CanSync() || !IsServer) + return; + LiteNetLibGameManager manager = Manager; + LiteNetLibServer server = manager.Server; + TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); + SerializeForSend(ServerWriter); + if (manager.ContainsConnectionId(connectionId)) + server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); + } + + internal void SendUpdate(bool isInitial) + { + if (!CanSync()) + { + Logging.LogError(LogTag, "Error while set value, behaviour is empty"); + return; + } + LiteNetLibGameManager manager = Manager; + LiteNetLibServer server = manager.Server; + LiteNetLibClient client = manager.Client; + switch (syncMode) + { + case SyncMode.ServerToClients: + TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); + SerializeForSend(ServerWriter); + foreach (long connectionId in manager.GetConnectionIds()) + { + if (Identity.HasSubscriberOrIsOwning(connectionId)) + server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); + } + break; + case SyncMode.ServerToOwnerClient: + if (manager.ContainsConnectionId(ConnectionId)) + { + TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); + SerializeForSend(ServerWriter); + server.SendMessage(ConnectionId, dataChannel, deliveryMethod, ServerWriter); + } + break; + case SyncMode.ClientMulticast: + if (IsOwnerClient) + { + TransportHandler.WritePacket(ClientWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); + SerializeForSend(ClientWriter); + // Client send data to server, then server send to other clients, it should be reliable-ordered + client.SendMessage(clientDataChannel, clientDeliveryMethod, ClientWriter); + } + else if (IsServer) + { + TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); + SerializeForSend(ServerWriter); + foreach (long connectionId in manager.GetConnectionIds()) + { + if (Identity.HasSubscriberOrIsOwning(connectionId)) + server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); + } + } + break; + } + } + + private void SerializeForSend(NetDataWriter writer) + { + LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); + Serialize(writer); + } + + public override string ToString() + { + return GetValue().ToString(); + } + } + + public class LiteNetLibSyncFieldContainer : LiteNetLibSyncField + { + /// + /// The field which going to sync its value + /// + private FieldInfo field; + + /// + /// The class which contain the field + /// + private object instance; + + /// + /// Use this variable to tell that it has to update after value changed + /// + private bool hasUpdate; + + /// + /// This method will be invoked after value changed + /// + private MethodInfo onChangeMethod; + + /// + /// This method will be invoked after data sent + /// + private MethodInfo onUpdateMethod; + + /// + /// Use this value to check field's value changes + /// + private object value; + + public LiteNetLibSyncFieldContainer(FieldInfo field, object instance, MethodInfo onChangeMethod, MethodInfo onUpdateMethod) + { + this.field = field; + this.instance = instance; + this.onChangeMethod = onChangeMethod; + this.onUpdateMethod = onUpdateMethod; + value = field.GetValue(instance); + } + + public override sealed Type GetFieldType() + { + return field.FieldType; + } + + public override sealed object GetValue() + { + return field.GetValue(instance); + } + + public override sealed void SetValue(object value) + { + field.SetValue(instance, value); + } + + internal override sealed bool HasUpdate() + { + if (hasUpdate) + return true; + + if (value == null || !value.Equals(field.GetValue(instance))) + { + // Set value because it's going to sync later + value = field.GetValue(instance); + // Set `hasUpdate` to `TRUE` this value will turn to `FALSE` when `Updated()` called + hasUpdate = true; + } + + return hasUpdate; + } + + internal override void Updated() + { + if (onUpdateMethod != null) + onUpdateMethod.Invoke(instance, new object[0]); + hasUpdate = false; + } + + internal override sealed void OnChange(bool initial) + { + if (onChangeMethod != null) + onChangeMethod.Invoke(instance, new object[] { GetValue() }); + } + } + + public class LiteNetLibSyncField : LiteNetLibSyncField + { + public delegate void OnChangeDelegate(bool initial, TType value); + public delegate void OnUpdatedDelegate(); + /// + /// Action with initial state and value, this will be invoked after data changed + /// + public OnChangeDelegate onChange; + + /// + /// This will be invoked after data sent + /// + public OnUpdatedDelegate onUpdated; + + /// + /// Use this variable to tell that it has to update after value changed + /// + protected bool hasUpdate; + + [SerializeField] + protected TType value; + public TType Value + { + get { return value; } + set + { + if (IsValueChanged(value)) + { + this.value = value; + if (CanSync()) + hasUpdate = true; + } + } + } + + protected virtual bool IsValueChanged(TType newValue) + { + return value == null || !value.Equals(newValue); + } + + internal override bool HasUpdate() + { + return hasUpdate; + } + + internal override void Updated() + { + if (onUpdated != null) + onUpdated.Invoke(); + hasUpdate = false; + } + + public override sealed Type GetFieldType() + { + return typeof(TType); + } + + public override sealed object GetValue() + { + return Value; + } + + public override sealed void SetValue(object value) + { + Value = (TType)value; + } + + internal override sealed void OnChange(bool initial) + { + if (onChange != null) + onChange.Invoke(initial, Value); + } + + public static implicit operator TType(LiteNetLibSyncField field) + { + return field.Value; + } + } + + [Serializable] + public class SyncFieldArray : LiteNetLibSyncField + { + public TType this[int i] + { + get { return Value[i]; } + set + { + Value[i] = value; + hasUpdate = true; + } + } + + internal override void DeserializeValue(NetDataReader reader) + { + Value = reader.GetArray(); + } + + internal override void SerializeValue(NetDataWriter writer) + { + writer.PutArray(Value); + } + + public int Length { get { return Value.Length; } } + } + + #region Implement for general usages and serializable + [Serializable] + public class SyncFieldBool : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldBoolArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldByte : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldByteArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldChar : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldDouble : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldDoubleArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldFloat : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldFloatArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldInt : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldIntArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldLong : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldLongArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldSByte : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldShort : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldShortArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldString : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldUInt : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldUIntArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldULong : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldULongArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldUShort : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldUShortArray : SyncFieldArray + { + } + + [Serializable] + public class SyncFieldColor : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldQuaternion : LiteNetLibSyncField + { + [Tooltip("If angle between new value and old value >= this value, it will be determined that the value is changing")] + public float valueChangeAngle = 1f; + + protected override bool IsValueChanged(Quaternion newValue) + { + return Quaternion.Angle(value, newValue) >= valueChangeAngle; + } + } + + [Serializable] + public class SyncFieldVector2 : LiteNetLibSyncField + { + [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] + public float valueChangeDistance = 0.01f; + + protected override bool IsValueChanged(Vector2 newValue) + { + return Vector2.Distance(value, newValue) >= valueChangeDistance; + } + } + + [Serializable] + public class SyncFieldVector2Int : LiteNetLibSyncField + { + [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] + public float valueChangeDistance = 0.01f; + + protected override bool IsValueChanged(Vector2Int newValue) + { + return Vector2Int.Distance(value, newValue) >= valueChangeDistance; + } + } + + [Serializable] + public class SyncFieldVector3 : LiteNetLibSyncField + { + [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] + public float valueChangeDistance = 0.01f; + + protected override bool IsValueChanged(Vector3 newValue) + { + return Vector3.Distance(value, newValue) >= valueChangeDistance; + } + } + + [Serializable] + public class SyncFieldVector3Int : LiteNetLibSyncField + { + [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] + public float valueChangeDistance = 0.01f; + + protected override bool IsValueChanged(Vector3Int newValue) + { + return Vector3Int.Distance(value, newValue) >= valueChangeDistance; + } + } + + [Serializable] + public class SyncFieldVector4 : LiteNetLibSyncField + { + [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] + public float valueChangeDistance = 0.01f; + + protected override bool IsValueChanged(Vector4 newValue) + { + return Vector4.Distance(value, newValue) >= valueChangeDistance; + } + } + + [Serializable] + [Obsolete("SyncField already packed. So you don't have to use this class")] + public class SyncFieldPackedUShort : LiteNetLibSyncField + { + } + + [Serializable] + [Obsolete("SyncField already packed. So you don't have to use this class")] + public class SyncFieldPackedUInt : LiteNetLibSyncField + { + } + + [Serializable] + [Obsolete("SyncField already packed. So you don't have to use this class")] + public class SyncFieldPackedULong : LiteNetLibSyncField + { + } + + [Serializable] + [Obsolete("SyncField already packed. So you don't have to use this class")] + public class SyncFieldPackedShort : LiteNetLibSyncField + { + } + + [Serializable] + [Obsolete("SyncField already packed. So you don't have to use this class")] + public class SyncFieldPackedInt : LiteNetLibSyncField + { + } + + [Serializable] + [Obsolete("SyncField already packed. So you don't have to use this class")] + public class SyncFieldPackedLong : LiteNetLibSyncField + { + } + + [Serializable] + public class SyncFieldDirectionVector2 : LiteNetLibSyncField + { + protected override bool IsValueChanged(DirectionVector2 newValue) + { + return Value.x != newValue.x || Value.y != newValue.y; + } + } + + [Serializable] + public class SyncFieldDirectionVector3 : LiteNetLibSyncField + { + protected override bool IsValueChanged(DirectionVector3 newValue) + { + return Value.x != newValue.x || Value.y != newValue.y || Value.z != newValue.z; + } + } + #endregion +} diff --git a/Scripts/LiteNetLibSyncField.cs.meta b/Scripts/LiteNetLibSyncField.cs.meta new file mode 100644 index 00000000..cd10b767 --- /dev/null +++ b/Scripts/LiteNetLibSyncField.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: f13e8093d1ab8fd42ac6c519c60b1f30 +timeCreated: 1508947932 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibSyncList.cs b/Scripts/LiteNetLibSyncList.cs new file mode 100644 index 00000000..f5f163b9 --- /dev/null +++ b/Scripts/LiteNetLibSyncList.cs @@ -0,0 +1,609 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using LiteNetLib; +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public abstract partial class LiteNetLibSyncList : LiteNetLibElement + { + protected readonly static NetDataWriter Writer = new NetDataWriter(); + + public partial struct Operation + { + public const byte Add = 0; + public const byte Clear = 1; + public const byte Insert = 2; + public const byte RemoveAt = 3; + public const byte Set = 4; + public const byte Dirty = 5; + public const byte RemoveFirst = 6; + public const byte RemoveLast = 7; + public const byte AddInitial = 8; + + public Operation(byte value) + { + Value = value; + } + + public byte Value { get; private set; } + + public static implicit operator byte(Operation operation) + { + return operation.Value; + } + + public static implicit operator Operation(byte value) + { + return new Operation(value); + } + } + + public delegate void OnOperationDelegate(Operation op, int itemIndex); + + [Tooltip("Sending data channel")] + public byte dataChannel = 0; + [Tooltip("If this is `TRUE`, this will update to owner client only, default is `FALSE`")] + public bool forOwnerOnly = false; + public OnOperationDelegate onOperation; + + public abstract Type FieldType { get; } + public abstract int Count { get; } + internal abstract void Reset(); + internal abstract void SendInitialList(long connectionId); + internal abstract void SendOperations(); + internal abstract void ProcessOperations(NetDataReader reader); + + protected override bool CanSync() + { + return IsServer; + } + + internal override sealed void Setup(LiteNetLibBehaviour behaviour, int elementId) + { + base.Setup(behaviour, elementId); + if (Count > 0 && onOperation != null) + { + for (int i = 0; i < Count; ++i) + { + onOperation.Invoke(Operation.AddInitial, i); + } + } + } + } + + public class LiteNetLibSyncList : LiteNetLibSyncList, IList + { + protected struct OperationEntry + { + public Operation operation; + public int index; + public TType data; + public int count; + } + + protected readonly List list = new List(); + protected readonly List operationEntries = new List(); + + public TType this[int index] + { + get { return list[index]; } + set + { + if (IsSetup && !IsServer) + { + Logging.LogError(LogTag, "Cannot access sync list from client."); + return; + } + list[index] = value; + PrepareOperation(Operation.Set, index); + } + } + + public override sealed Type FieldType + { + get { return typeof(TType); } + } + + public override sealed int Count + { + get { return list.Count; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public TType Get(int index) + { + return this[index]; + } + + public void Set(int index, TType value) + { + this[index] = value; + } + + public void Add(TType item) + { + if (IsSetup && !CanSync()) + { + Logging.LogError(LogTag, "Cannot access sync list from client."); + return; + } + int index = list.Count; + list.Add(item); + PrepareOperation(Operation.Add, index); + } + + public void AddRange(IEnumerable collection) + { + if (IsSetup && !CanSync()) + { + Logging.LogError(LogTag, "Cannot access sync list from client."); + return; + } + foreach (TType item in collection) + { + Add(item); + } + } + + public void Insert(int index, TType item) + { + if (IsSetup && !CanSync()) + { + Logging.LogError(LogTag, "Cannot access sync list from client."); + return; + } + list.Insert(index, item); + PrepareOperation(Operation.Insert, index); + } + + public bool Contains(TType item) + { + return list.Contains(item); + } + + public int IndexOf(TType item) + { + return list.IndexOf(item); + } + + public bool Remove(TType value) + { + if (IsSetup && !CanSync()) + { + Logging.LogError(LogTag, "Cannot access sync list from client."); + return false; + } + int index = IndexOf(value); + if (index >= 0) + { + RemoveAt(index); + return true; + } + return false; + } + + public void RemoveAt(int index) + { + if (IsSetup && !CanSync()) + { + Logging.LogError(LogTag, "Cannot access sync list from client."); + return; + } + if (index == 0) + { + list.RemoveAt(index); + PrepareOperation(Operation.RemoveFirst, 0); + } + else if (index == list.Count - 1) + { + list.RemoveAt(index); + PrepareOperation(Operation.RemoveLast, index); + } + else + { + list.RemoveAt(index); + PrepareOperation(Operation.RemoveAt, index); + } + } + + public void Clear() + { + if (IsSetup && !CanSync()) + { + Logging.LogError(LogTag, "Cannot access sync list from client."); + return; + } + list.Clear(); + PrepareOperation(Operation.Clear, -1); + } + + public void CopyTo(TType[] array, int arrayIndex) + { + list.CopyTo(array, arrayIndex); + } + + public IEnumerator GetEnumerator() + { + return list.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return list.GetEnumerator(); + } + + public void Dirty(int index) + { + if (IsSetup && !CanSync()) + { + Logging.LogError(LogTag, "Cannot access sync list from client."); + return; + } + PrepareOperation(Operation.Dirty, index); + } + + internal override sealed void Reset() + { + list.Clear(); + operationEntries.Clear(); + } + + protected void PrepareOperation(Operation operation, int index) + { + OnOperation(operation, index); + PrepareOperation(operationEntries, operation, index); + } + + protected void PrepareOperation(List operationEntries, Operation operation, int index) + { + switch (operation) + { + case Operation.Clear: + operationEntries.Add(new OperationEntry() + { + operation = operation, + index = index, + count = 0, + }); + break; + case Operation.RemoveAt: + case Operation.RemoveFirst: + case Operation.RemoveLast: + operationEntries.Add(new OperationEntry() + { + operation = operation, + index = index, + count = 1, + }); + break; + default: + operationEntries.Add(new OperationEntry() + { + operation = operation, + index = index, + data = list[index], + count = 1, + }); + break; + } + } + + internal override sealed void SendInitialList(long connectionId) + { + if (!CanSync()) + return; + List addInitialOperationEntries = new List(); + for (int i = 0; i < Count; ++i) + { + if (!ContainsAddOperation(i)) + PrepareOperation(addInitialOperationEntries, Operation.AddInitial, i); + } + LiteNetLibServer server = Manager.Server; + TransportHandler.WritePacket(Writer, GameMsgTypes.OperateSyncList); + SerializeForSendOperations(Writer, addInitialOperationEntries); + server.SendMessage(connectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); + } + + private bool ContainsAddOperation(int index) + { + for (int i = 0; i < operationEntries.Count; ++i) + { + if (operationEntries[i].operation == Operation.Add && operationEntries[i].index == index) + return true; + } + return false; + } + + internal override sealed void SendOperations() + { + if (operationEntries.Count <= 0 || !CanSync()) + return; + LiteNetLibGameManager manager = Manager; + LiteNetLibServer server = manager.Server; + TransportHandler.WritePacket(Writer, GameMsgTypes.OperateSyncList); + SerializeForSendOperations(Writer, operationEntries); + operationEntries.Clear(); + if (forOwnerOnly) + { + if (manager.ContainsConnectionId(ConnectionId)) + server.SendMessage(ConnectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); + } + else + { + foreach (long connectionId in manager.GetConnectionIds()) + { + if (Identity.HasSubscriberOrIsOwning(connectionId)) + server.SendMessage(connectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); + } + } + } + + internal override sealed void ProcessOperations(NetDataReader reader) + { + int operationCount = reader.GetPackedInt(); + for (int i = 0; i < operationCount; ++i) + { + DeserializeOperation(reader); + } + } + + protected void SerializeForSendOperations(NetDataWriter writer, List operationEntries) + { + LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); + writer.PutPackedInt(operationEntries.Count); + for (int i = 0; i < operationEntries.Count; ++i) + { + SerializeOperation(writer, operationEntries[i]); + } + } + + protected void DeserializeOperation(NetDataReader reader) + { + Operation operation = reader.GetByte(); + int index = -1; + TType item; + switch (operation) + { + case Operation.Add: + case Operation.AddInitial: + item = DeserializeValueForAddOrInsert(index, reader); + index = list.Count; + list.Add(item); + break; + case Operation.Insert: + index = reader.GetInt(); + item = DeserializeValueForAddOrInsert(index, reader); + list.Insert(index, item); + break; + case Operation.Set: + case Operation.Dirty: + index = reader.GetInt(); + item = DeserializeValueForSetOrDirty(index, reader); + list[index] = item; + break; + case Operation.RemoveAt: + index = reader.GetInt(); + list.RemoveAt(index); + break; + case Operation.RemoveFirst: + index = 0; + list.RemoveAt(index); + break; + case Operation.RemoveLast: + index = list.Count - 1; + list.RemoveAt(index); + break; + case Operation.Clear: + list.Clear(); + break; + default: + index = reader.GetInt(); + item = DeserializeValueForCustomDirty(index, operation, reader); + list[index] = item; + break; + } + OnOperation(operation, index); + } + + protected void SerializeOperation(NetDataWriter writer, OperationEntry entry) + { + writer.Put((byte)entry.operation); + switch (entry.operation) + { + case Operation.Add: + case Operation.AddInitial: + SerializeValueForAddOrInsert(entry.index, writer, entry.data); + break; + case Operation.Insert: + writer.Put(entry.index); + SerializeValueForAddOrInsert(entry.index, writer, entry.data); + break; + case Operation.Set: + case Operation.Dirty: + writer.Put(entry.index); + SerializeValueForSetOrDirty(entry.index, writer, entry.data); + break; + case Operation.RemoveAt: + writer.Put(entry.index); + break; + case Operation.RemoveFirst: + case Operation.RemoveLast: + case Operation.Clear: + break; + default: + writer.Put(entry.index); + SerializeValueForCustomDirty(entry.index, entry.operation, writer, entry.data); + break; + } + } + + protected virtual TType DeserializeValue(NetDataReader reader) + { + return reader.GetValue(); + } + + protected virtual void SerializeValue(NetDataWriter writer, TType value) + { + writer.PutValue(value); + } + + protected virtual TType DeserializeValueForAddOrInsert(int index, NetDataReader reader) + { + return DeserializeValue(reader); + } + + protected virtual void SerializeValueForAddOrInsert(int index, NetDataWriter writer, TType value) + { + SerializeValue(writer, value); + } + + protected virtual TType DeserializeValueForSetOrDirty(int index, NetDataReader reader) + { + return DeserializeValue(reader); + } + + protected virtual void SerializeValueForSetOrDirty(int index, NetDataWriter writer, TType value) + { + SerializeValue(writer, value); + } + + protected virtual void SerializeValueForCustomDirty(int index, byte customOperation, NetDataWriter writer, TType value) + { + SerializeValue(writer, value); + } + + protected virtual TType DeserializeValueForCustomDirty(int index, byte customOperation, NetDataReader reader) + { + return DeserializeValue(reader); + } + + protected void OnOperation(Operation operation, int index) + { + if (onOperation != null) + onOperation.Invoke(operation, index); + } + } + + #region Implement for general usages and serializable + // Generics + + [Serializable] + public class SyncListBool : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListByte : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListChar : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListDouble : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListFloat : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListInt : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListLong : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListSByte : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListShort : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListString : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListUInt : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListULong : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListUShort : LiteNetLibSyncList + { + } + + // Unity + + [Serializable] + public class SyncListColor : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListQuaternion : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListVector2 : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListVector2Int : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListVector3 : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListVector3Int : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListVector4 : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListDirectionVector2 : LiteNetLibSyncList + { + } + + [Serializable] + public class SyncListDirectionVector3 : LiteNetLibSyncList + { + } + #endregion +} diff --git a/Scripts/LiteNetLibSyncList.cs.meta b/Scripts/LiteNetLibSyncList.cs.meta new file mode 100644 index 00000000..e9e0e82b --- /dev/null +++ b/Scripts/LiteNetLibSyncList.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: d5fb20391be68d949b2b768c055e3c15 +timeCreated: 1511713954 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibTransform.cs b/Scripts/LiteNetLibTransform.cs new file mode 100644 index 00000000..52333f01 --- /dev/null +++ b/Scripts/LiteNetLibTransform.cs @@ -0,0 +1,521 @@ +using LiteNetLib; +using LiteNetLib.Utils; +using UnityEngine; +using UnityEngine.AI; + +namespace LiteNetLibManager +{ + public class LiteNetLibTransform : LiteNetLibBehaviour + { + private struct TransformResult + { + public Vector3 position; + public Quaternion rotation; + public float timestamp; + } + + public enum SyncPositionOptions + { + Sync, + NotSync, + } + + public enum SyncRotationOptions + { + Sync, + NotSync, + CompressToUShort, + CompressToByte, + } + + public enum InterpolateMode + { + EstimatedSpeed, + FixedSpeed, + } + + public enum ExtrapolateMode + { + None, + EstimatedSpeed, + FixedSpeed, + } + + [Tooltip("Which transform you are going to sync, if it is empty it will use transform which this component attached to")] + public Transform syncingTransform; + [Tooltip("If this is TRUE, transform data will be sent from owner client to server to update to another clients")] + public bool ownerClientCanSendTransform; + [Tooltip("This will be used when `ownerClientCanSendTransform` is set to TRUE to send transform update from client to server")] + [Range(0.01f, 2f)] + public float ownerClientSendInterval = 0.1f; + public float snapThreshold = 5.0f; + public InterpolateMode interpolateMode = InterpolateMode.EstimatedSpeed; + public float fixedInterpolateSpeed; + public ExtrapolateMode extrapolateMode = ExtrapolateMode.None; + public float fixedExtrapolateSpeed; + [Header("Sync Position Settings")] + public SyncPositionOptions syncPositionX; + public SyncPositionOptions syncPositionY; + public SyncPositionOptions syncPositionZ; + [Header("Sync Rotation Settings")] + public SyncRotationOptions syncRotationX; + public SyncRotationOptions syncRotationY; + public SyncRotationOptions syncRotationZ; + + public System.Action onTeleport; + + #region Cache components + public NavMeshAgent CacheNavMeshAgent { get; private set; } + public Rigidbody CacheRigidbody3D { get; private set; } + public Rigidbody2D CacheRigidbody2D { get; private set; } + public CharacterController CacheCharacterController { get; private set; } + #endregion + + private bool syncingTransformIsIdentity; + // Interpolation related variables + private float ownerSendElapsed = 0f; + private float lastReceivedTime = 0f; + private float lastReceivedTimestamp = 0f; + private TransformResult currentInterpResult; + private TransformResult previousEndInterpResult; + private TransformResult endInterpResult; + + private void Awake() + { + if (syncingTransform == null) + syncingTransform = transform; + // Nav mesh agent is highest priority, then character controller + // Then Rigidbodies, that both 3d/2d are same priority + CacheNavMeshAgent = syncingTransform.GetComponent(); + if (CacheNavMeshAgent == null) + { + CacheCharacterController = syncingTransform.GetComponent(); + if (CacheCharacterController == null) + { + CacheRigidbody3D = syncingTransform.GetComponent(); + CacheRigidbody2D = syncingTransform.GetComponent(); + } + } + sendOptions = DeliveryMethod.Unreliable; + } + + private void OnValidate() + { + // Force set to `Unreliable` + sendOptions = DeliveryMethod.Unreliable; + } + + private void OnEnable() + { + InitInterpResults(syncingTransform.position, syncingTransform.rotation); + } + + public override void OnSetOwnerClient(bool isOwnerClient) + { + InitInterpResults(syncingTransform.position, syncingTransform.rotation); + } + + public override void InitTransform(Vector3 position, Quaternion rotation) + { + if (syncingTransformIsIdentity) + { + InitInterpResults(position, rotation); + Snap(position, rotation); + } + } + + private void InitInterpResults(Vector3 position, Quaternion rotation) + { + currentInterpResult = new TransformResult(); + currentInterpResult.position = position; + currentInterpResult.rotation = rotation; + currentInterpResult.timestamp = GetTimeStamp(); + previousEndInterpResult = currentInterpResult; + endInterpResult = currentInterpResult; + } + + public override void OnSetup() + { + base.OnSetup(); + RegisterNetFunction(NetFunction_Teleport); + if (syncingTransform == null) + syncingTransform = transform; + syncingTransformIsIdentity = syncingTransform == Identity.transform; + } + + private void NetFunction_Teleport(Vector3 position, Quaternion rotation) + { + InitInterpResults(position, rotation); + Snap(position, rotation); + if (onTeleport != null) + onTeleport.Invoke(position, rotation); + } + + /// + /// This function will be called at server after receive transform from clients + /// to interpolate and sync position to other clients + /// + /// + internal void HandleClientSendTransform(NetDataReader reader) + { + // Don't update transform follow client's request + // if not set "ownerClientCanSendTransform" to `TRUE` + // or it's this is owned by host + if (!ownerClientCanSendTransform || IsOwnerClient) + return; + TransformResult result = DeserializeResult(reader); + // Discard out of order results + if (result.timestamp <= lastReceivedTimestamp) + return; + lastReceivedTime = Time.fixedTime; + lastReceivedTimestamp = result.timestamp; + result.timestamp = GetTimeStamp(); + previousEndInterpResult = endInterpResult; + endInterpResult = result; + } + + /// + /// This function will be called at client to send transform + /// + /// + private void ClientSendTransform(TransformResult transformResult) + { + // Don't request to set transform if not set "canClientSendResult" to TRUE + if (!ownerClientCanSendTransform || !IsOwnerClient) + return; + Manager.ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.ClientSendTransform, (writer) => ClientSendTransformWriter(writer, transformResult)); + } + + private void ClientSendTransformWriter(NetDataWriter writer, TransformResult transformResult) + { + writer.PutPackedUInt(ObjectId); + writer.Put(BehaviourIndex); + SerializePositionAxis(writer, transformResult.position.x, syncPositionX); + SerializePositionAxis(writer, transformResult.position.y, syncPositionY); + SerializePositionAxis(writer, transformResult.position.z, syncPositionZ); + SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.x, syncRotationX); + SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.y, syncRotationY); + SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.z, syncRotationZ); + writer.Put(GetTimeStamp()); + } + + public void Teleport(Vector3 position, Quaternion rotation) + { + if (IsServer || (ownerClientCanSendTransform && IsOwnerClient)) + { + InitInterpResults(position, rotation); + Snap(position, rotation); + // This function can be called before networked object spawned + // to set initial object transform, so it won't be able to call net function yet. + // So have to avoid net function calling by check is behaviours already setup or not. + if (Identity.IsSetupBehaviours) + CallNetFunction(NetFunction_Teleport, FunctionReceivers.All, position, rotation); + } + } + + public override bool CanSyncBehaviour() + { + return true; + } + + public override bool ShouldSyncBehaviour() + { + return true; + } + + public override void OnSerialize(NetDataWriter writer) + { + SerializePositionAxis(writer, syncingTransform.position.x, syncPositionX); + SerializePositionAxis(writer, syncingTransform.position.y, syncPositionY); + SerializePositionAxis(writer, syncingTransform.position.z, syncPositionZ); + SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.x, syncRotationX); + SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.y, syncRotationY); + SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.z, syncRotationZ); + writer.Put(GetTimeStamp()); + } + + public override void OnDeserialize(NetDataReader reader) + { + // Update transform only non-owner client + if ((ownerClientCanSendTransform && IsOwnerClient) || IsServer) + return; + TransformResult result = DeserializeResult(reader); + // Discard out of order results + if (result.timestamp <= lastReceivedTimestamp) + return; + lastReceivedTime = Time.fixedTime; + lastReceivedTimestamp = result.timestamp; + result.timestamp = GetTimeStamp(); + previousEndInterpResult = endInterpResult; + endInterpResult = result; + } + + private TransformResult DeserializeResult(NetDataReader reader) + { + TransformResult result = new TransformResult(); + result.position = new Vector3( + DeserializePositionAxis(reader, syncPositionX, syncingTransform.position.x), + DeserializePositionAxis(reader, syncPositionY, syncingTransform.position.y), + DeserializePositionAxis(reader, syncPositionZ, syncingTransform.position.z)); + result.rotation = Quaternion.Euler( + DeserializeRotationAxis(reader, syncRotationX, syncingTransform.rotation.eulerAngles.x), + DeserializeRotationAxis(reader, syncRotationY, syncingTransform.rotation.eulerAngles.y), + DeserializeRotationAxis(reader, syncRotationZ, syncingTransform.rotation.eulerAngles.z)); + result.timestamp = reader.GetFloat(); + return result; + } + + private void SerializePositionAxis(NetDataWriter writer, float data, SyncPositionOptions syncOptions) + { + switch (syncOptions) + { + case SyncPositionOptions.Sync: + writer.Put(data); + break; + default: + case SyncPositionOptions.NotSync: + break; + } + } + + private void SerializeRotationAxis(NetDataWriter writer, float data, SyncRotationOptions syncOptions) + { + data = To360Angle(data); + switch (syncOptions) + { + case SyncRotationOptions.Sync: + writer.Put(data); + break; + case SyncRotationOptions.CompressToUShort: + writer.Put((ushort)(data * 100)); + break; + case SyncRotationOptions.CompressToByte: + writer.Put((byte)(data / 360f * 100)); + break; + default: + case SyncRotationOptions.NotSync: + break; + } + } + + private float DeserializePositionAxis(NetDataReader reader, SyncPositionOptions syncOptions, float defaultValue) + { + switch (syncOptions) + { + case SyncPositionOptions.Sync: + return reader.GetFloat(); + default: + case SyncPositionOptions.NotSync: + break; + } + return defaultValue; + } + + private float DeserializeRotationAxis(NetDataReader reader, SyncRotationOptions syncOptions, float defaultValue) + { + switch (syncOptions) + { + case SyncRotationOptions.Sync: + return reader.GetFloat(); + case SyncRotationOptions.CompressToUShort: + return (float)reader.GetUShort() * 0.01f; + case SyncRotationOptions.CompressToByte: + return (float)reader.GetByte() * 0.01f * 360f; + default: + case SyncRotationOptions.NotSync: + break; + } + return defaultValue; + } + + private void Update() + { + if (!IsServer && !IsClient) + return; + // Sending transform to all clients + if (IsServer) + { + // Interpolate transform that receives from clients + // So if this is no owning client (ConnectionId < 0), it won't interpolate + if (ownerClientCanSendTransform && !IsOwnerClient && ConnectionId >= 0) + UpdateTransform(Time.deltaTime); + } + // Interpolating results for non-owner client objects on clients + else if (!ownerClientCanSendTransform || !IsOwnerClient) + { + UpdateTransform(Time.deltaTime); + } + } + + private void FixedUpdate() + { + if (!IsServer && !IsClient) + return; + // Sending client transform result to server + // Don't send to server if it's server which already update transform result + // So only owner client can send transform result to server + if (ownerClientCanSendTransform && IsOwnerClient && !IsServer) + { + ownerSendElapsed += Time.fixedDeltaTime; + if (ownerSendElapsed >= ownerClientSendInterval) + { + // Send transform to server only when there are changes on transform + ClientSendTransform(new TransformResult() + { + position = syncingTransform.position, + rotation = syncingTransform.rotation, + timestamp = GetTimeStamp(), + }); + ownerSendElapsed = 0; + } + } + } + + private void UpdateTransform(float deltaTime) + { + if (ShouldSnap(endInterpResult.position)) + { + currentInterpResult.position = endInterpResult.position; + currentInterpResult.rotation = endInterpResult.rotation; + Snap(endInterpResult.position, endInterpResult.rotation); + } + else + { + if (IsOwnerClient && ownerClientCanSendTransform) + { + // If owner client can send transform, it won't interpolating transform at owner client + return; + } + // Calculate move speed by distance and time + float dist = Vector3.Distance(endInterpResult.position, previousEndInterpResult.position); + float timeDiff = endInterpResult.timestamp - previousEndInterpResult.timestamp; + float moveSpeed = 0f; + if (timeDiff > 0f) + moveSpeed = dist / timeDiff; + // Find extrapolated move by move direction, time passed (which calculated by current time and last received time) + // and calculate move speed or fixed extrapolate speed + Vector3 extrapolatedMove = Vector3.zero; + if (extrapolateMode != ExtrapolateMode.None) + { + float timePassed = Time.fixedTime - lastReceivedTime; + Vector3 moveDirection = (endInterpResult.position - previousEndInterpResult.position).normalized; + if (moveDirection.sqrMagnitude > 0f && timePassed > 0f) + { + switch (extrapolateMode) + { + case ExtrapolateMode.EstimatedSpeed: + extrapolatedMove = moveDirection * moveSpeed * timePassed; + break; + case ExtrapolateMode.FixedSpeed: + extrapolatedMove = moveDirection * fixedExtrapolateSpeed * timePassed; + break; + } + } + } + // Set interpolate move speed to fixed value if interpolate mode is fixed speed + if (interpolateMode == InterpolateMode.FixedSpeed) + moveSpeed = fixedInterpolateSpeed; + // Move it + currentInterpResult.position = Vector3.MoveTowards(currentInterpResult.position, endInterpResult.position + extrapolatedMove, moveSpeed * deltaTime); + currentInterpResult.rotation = Quaternion.Slerp(currentInterpResult.rotation, endInterpResult.rotation, (1f / timeDiff) * deltaTime); + Interpolate(currentInterpResult.position, currentInterpResult.rotation); + } + } + + private bool ShouldSnap(Vector3 targetPosition) + { + float dist; + if (CacheRigidbody2D != null) + dist = (CacheRigidbody2D.position - new Vector2(targetPosition.x, targetPosition.y)).sqrMagnitude; + else + dist = (syncingTransform.position - targetPosition).sqrMagnitude; + return dist > snapThreshold * snapThreshold; + } + + private void Snap(Vector3 position, Quaternion rotation) + { + if (CacheNavMeshAgent != null) + { + CacheNavMeshAgent.Warp(position); + syncingTransform.rotation = rotation; + } + else if (CacheRigidbody3D != null && !CacheRigidbody3D.isKinematic) + { + syncingTransform.position = position; + syncingTransform.rotation = rotation; + CacheRigidbody3D.position = position; + CacheRigidbody3D.rotation = rotation; + } + else if (CacheRigidbody2D != null && !CacheRigidbody2D.isKinematic) + { + syncingTransform.position = position; + syncingTransform.rotation = rotation; + CacheRigidbody2D.position = position; + CacheRigidbody2D.rotation = rotation.eulerAngles.z; + } + else + { + syncingTransform.position = position; + syncingTransform.rotation = rotation; + } + } + + private void Interpolate(Vector3 position, Quaternion rotation) + { + if (CacheNavMeshAgent != null) + { + CacheNavMeshAgent.Move(position - syncingTransform.position); + syncingTransform.rotation = rotation; + } + else if (CacheCharacterController != null) + { + syncingTransform.position = position; + syncingTransform.rotation = rotation; + } + else if (CacheRigidbody3D != null && !CacheRigidbody3D.isKinematic) + { + if (Vector3.Distance(position, CacheRigidbody3D.position) > 0f) + CacheRigidbody3D.MovePosition(position); + else + { + CacheRigidbody3D.velocity = Vector3.zero; + CacheRigidbody3D.MovePosition(position); + } + syncingTransform.rotation = rotation; + } + else if (CacheRigidbody2D != null && !CacheRigidbody2D.isKinematic) + { + if (Vector2.Distance(position, CacheRigidbody2D.position) > 0f) + CacheRigidbody2D.MovePosition(position); + else + { + CacheRigidbody2D.velocity = Vector2.zero; + CacheRigidbody2D.MovePosition(position); + } + syncingTransform.rotation = rotation; + } + else + { + syncingTransform.position = position; + syncingTransform.rotation = rotation; + } + } + + private float GetTimeStamp() + { + return Time.fixedTime; + } + + #region Math Utilities + public static float To360Angle(float angle) + { + float result = angle - Mathf.CeilToInt(angle / 360f) * 360f; + if (result < 0) + { + result += 360f; + } + return result; + } + #endregion + } +} diff --git a/Scripts/LiteNetLibTransform.cs.meta b/Scripts/LiteNetLibTransform.cs.meta new file mode 100644 index 00000000..c00d84ac --- /dev/null +++ b/Scripts/LiteNetLibTransform.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 8631d361478af9d4895c657221a7b4b1 +timeCreated: 1518974961 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/LiteNetLibVisibleChecker.cs b/Scripts/LiteNetLibVisibleChecker.cs new file mode 100644 index 00000000..127d365e --- /dev/null +++ b/Scripts/LiteNetLibVisibleChecker.cs @@ -0,0 +1,7 @@ +namespace LiteNetLibManager +{ + [System.Obsolete("This component is deprecated because interest management system is changed")] + public class LiteNetLibVisibleChecker : BaseLiteNetLibVisibleChecker + { + } +} diff --git a/Scripts/LiteNetLibVisibleChecker.cs.meta b/Scripts/LiteNetLibVisibleChecker.cs.meta new file mode 100644 index 00000000..71595f13 --- /dev/null +++ b/Scripts/LiteNetLibVisibleChecker.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 01d64c7b615199243b727eaa75d79574 +timeCreated: 1519828611 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/EnterGameRequestMessage.cs b/Scripts/Messages/EnterGameRequestMessage.cs new file mode 100644 index 00000000..54751ae5 --- /dev/null +++ b/Scripts/Messages/EnterGameRequestMessage.cs @@ -0,0 +1,19 @@ +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public struct EnterGameRequestMessage : INetSerializable + { + public uint packetVersion; + + public void Deserialize(NetDataReader reader) + { + packetVersion = reader.GetPackedUInt(); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutPackedUInt(packetVersion); + } + } +} diff --git a/Scripts/Messages/EnterGameRequestMessage.cs.meta b/Scripts/Messages/EnterGameRequestMessage.cs.meta new file mode 100644 index 00000000..867f8165 --- /dev/null +++ b/Scripts/Messages/EnterGameRequestMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d5f68ce278e65a49a39b690045b92f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/EnterGameResponseMessage.cs b/Scripts/Messages/EnterGameResponseMessage.cs new file mode 100644 index 00000000..9ba0b3c6 --- /dev/null +++ b/Scripts/Messages/EnterGameResponseMessage.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public class EnterGameResponseMessage : INetSerializable + { + public long connectionId; + public string serverSceneName; + + public void Deserialize(NetDataReader reader) + { + connectionId = reader.GetPackedLong(); + serverSceneName = reader.GetString(); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutPackedLong(connectionId); + writer.Put(serverSceneName); + } + } +} diff --git a/Scripts/Messages/EnterGameResponseMessage.cs.meta b/Scripts/Messages/EnterGameResponseMessage.cs.meta new file mode 100644 index 00000000..4048842a --- /dev/null +++ b/Scripts/Messages/EnterGameResponseMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37fe05c61ea31694d888887a9a7f81c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/GenericValueMessage.cs b/Scripts/Messages/GenericValueMessage.cs new file mode 100644 index 00000000..53f415b0 --- /dev/null +++ b/Scripts/Messages/GenericValueMessage.cs @@ -0,0 +1,188 @@ +using System; +using UnityEngine; +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public class GenericValueMessage : INetSerializable + { + public TType value; + + public void Deserialize(NetDataReader reader) + { + value = reader.GetValue(); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutValue(value); + } + } + + #region Implement for general usages and serializable + [Serializable] + public class BoolMessage : GenericValueMessage + { + } + + [Serializable] + public class BoolArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class ByteMessage : GenericValueMessage + { + } + + [Serializable] + public class ByteArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class CharMessage : GenericValueMessage + { + } + + [Serializable] + public class DoubleMessage : GenericValueMessage + { + } + + [Serializable] + public class DoubleArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class FloatMessage : GenericValueMessage + { + } + + [Serializable] + public class FloatArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class IntMessage : GenericValueMessage + { + } + + [Serializable] + public class IntArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class LongMessage : GenericValueMessage + { + } + + [Serializable] + public class LongArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class SByteMessage : GenericValueMessage + { + } + + [Serializable] + public class ShortMessage : GenericValueMessage + { + } + + [Serializable] + public class ShortArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class StringMessage : GenericValueMessage + { + } + + [Serializable] + public class UIntMessage : GenericValueMessage + { + } + + [Serializable] + public class UIntArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class ULongMessage : GenericValueMessage + { + } + + [Serializable] + public class ULongArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class UShortMessage : GenericValueMessage + { + } + + [Serializable] + public class UShortArrayMessage : GenericValueMessage + { + } + + [Serializable] + public class ColorMessage : GenericValueMessage + { + } + + [Serializable] + public class QuaternionMessage : GenericValueMessage + { + } + + [Serializable] + public class Vector2Message : GenericValueMessage + { + } + + [Serializable] + public class Vector2IntMessage : GenericValueMessage + { + } + + [Serializable] + public class Vector3Message : GenericValueMessage + { + } + + [Serializable] + public class Vector3IntMessage : GenericValueMessage + { + } + + [Serializable] + public class Vector4Message : GenericValueMessage + { + } + + [Serializable] + public class PackedUShortMessage : GenericValueMessage + { + } + + [Serializable] + public class PackedUIntMessage : GenericValueMessage + { + } + + [Serializable] + public class PackedULongMessage : GenericValueMessage + { + } + #endregion +} diff --git a/Scripts/Messages/GenericValueMessage.cs.meta b/Scripts/Messages/GenericValueMessage.cs.meta new file mode 100644 index 00000000..7bbfa2c8 --- /dev/null +++ b/Scripts/Messages/GenericValueMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11ec5c0f0e06d5c45ba82e2bf6c1fb2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/PingMessage.cs b/Scripts/Messages/PingMessage.cs new file mode 100644 index 00000000..ef09e496 --- /dev/null +++ b/Scripts/Messages/PingMessage.cs @@ -0,0 +1,19 @@ +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public struct PingMessage : INetSerializable + { + public long pingTime; + + public void Deserialize(NetDataReader reader) + { + pingTime = reader.GetPackedLong(); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutPackedLong(pingTime); + } + } +} diff --git a/Scripts/Messages/PingMessage.cs.meta b/Scripts/Messages/PingMessage.cs.meta new file mode 100644 index 00000000..803acc82 --- /dev/null +++ b/Scripts/Messages/PingMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88aad3795437e6645b550e242d147c13 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/PongMessage.cs b/Scripts/Messages/PongMessage.cs new file mode 100644 index 00000000..45bce529 --- /dev/null +++ b/Scripts/Messages/PongMessage.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public struct PongMessage : INetSerializable + { + public long pingTime; + public long serverTime; + + public void Deserialize(NetDataReader reader) + { + pingTime = reader.GetPackedLong(); + serverTime = reader.GetPackedLong(); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutPackedLong(pingTime); + writer.PutPackedLong(serverTime); + } + } +} diff --git a/Scripts/Messages/PongMessage.cs.meta b/Scripts/Messages/PongMessage.cs.meta new file mode 100644 index 00000000..987a9c4b --- /dev/null +++ b/Scripts/Messages/PongMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d3b5836388d4de4891673efc33eafd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/ServerDestroyObjectMessage.cs b/Scripts/Messages/ServerDestroyObjectMessage.cs new file mode 100644 index 00000000..b52a00cc --- /dev/null +++ b/Scripts/Messages/ServerDestroyObjectMessage.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public struct ServerDestroyObjectMessage : INetSerializable + { + public uint objectId; + public byte reasons; + + public void Deserialize(NetDataReader reader) + { + objectId = reader.GetPackedUInt(); + reasons = reader.GetByte(); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutPackedUInt(objectId); + writer.Put(reasons); + } + } +} diff --git a/Scripts/Messages/ServerDestroyObjectMessage.cs.meta b/Scripts/Messages/ServerDestroyObjectMessage.cs.meta new file mode 100644 index 00000000..724d0820 --- /dev/null +++ b/Scripts/Messages/ServerDestroyObjectMessage.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 58f4f8e22dbb4a94f874aceb5815dc44 +timeCreated: 1508932284 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/ServerErrorMessage.cs b/Scripts/Messages/ServerErrorMessage.cs new file mode 100644 index 00000000..9f6ecd64 --- /dev/null +++ b/Scripts/Messages/ServerErrorMessage.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public struct ServerErrorMessage : INetSerializable + { + public bool shouldDisconnect; + public string errorMessage; + + public void Deserialize(NetDataReader reader) + { + shouldDisconnect = reader.GetBool(); + errorMessage = reader.GetString(); + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(shouldDisconnect); + writer.Put(errorMessage); + } + } +} \ No newline at end of file diff --git a/Scripts/Messages/ServerErrorMessage.cs.meta b/Scripts/Messages/ServerErrorMessage.cs.meta new file mode 100644 index 00000000..ee5136df --- /dev/null +++ b/Scripts/Messages/ServerErrorMessage.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: b4d19b05d26f3854d83d967efef217e4 +timeCreated: 1519725292 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/ServerSceneChangeMessage.cs b/Scripts/Messages/ServerSceneChangeMessage.cs new file mode 100644 index 00000000..90c6e62b --- /dev/null +++ b/Scripts/Messages/ServerSceneChangeMessage.cs @@ -0,0 +1,19 @@ +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public struct ServerSceneChangeMessage : INetSerializable + { + public string serverSceneName; + + public void Deserialize(NetDataReader reader) + { + serverSceneName = reader.GetString(); + } + + public void Serialize(NetDataWriter writer) + { + writer.Put(serverSceneName); + } + } +} diff --git a/Scripts/Messages/ServerSceneChangeMessage.cs.meta b/Scripts/Messages/ServerSceneChangeMessage.cs.meta new file mode 100644 index 00000000..b26fb39b --- /dev/null +++ b/Scripts/Messages/ServerSceneChangeMessage.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: c69e59286bb7023469ad76ddcc7c4dad +timeCreated: 1525038105 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/ServerSetObjectOwner.cs b/Scripts/Messages/ServerSetObjectOwner.cs new file mode 100644 index 00000000..358fb3d0 --- /dev/null +++ b/Scripts/Messages/ServerSetObjectOwner.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +namespace LiteNetLibManager +{ + public struct ServerSetObjectOwner : INetSerializable + { + public uint objectId; + public long connectionId; + + public void Deserialize(NetDataReader reader) + { + objectId = reader.GetPackedUInt(); + connectionId = reader.GetPackedLong(); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutPackedUInt(objectId); + writer.PutPackedLong(connectionId); + } + } +} diff --git a/Scripts/Messages/ServerSetObjectOwner.cs.meta b/Scripts/Messages/ServerSetObjectOwner.cs.meta new file mode 100644 index 00000000..0a5878c0 --- /dev/null +++ b/Scripts/Messages/ServerSetObjectOwner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3015cf7812103846aa5fbb5cc484b38 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/ServerSpawnObjectMessage.cs b/Scripts/Messages/ServerSpawnObjectMessage.cs new file mode 100644 index 00000000..39c29677 --- /dev/null +++ b/Scripts/Messages/ServerSpawnObjectMessage.cs @@ -0,0 +1,36 @@ +using LiteNetLib.Utils; +using UnityEngine; + +namespace LiteNetLibManager +{ + public struct ServerSpawnObjectMessage : INetSerializable + { + public int hashAssetId; + public uint objectId; + public long connectionId; + public Vector3 position; + public Quaternion rotation; + + public void Deserialize(NetDataReader reader) + { + hashAssetId = reader.GetPackedInt(); + objectId = reader.GetPackedUInt(); + connectionId = reader.GetPackedLong(); + position = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); + rotation = Quaternion.Euler(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutPackedInt(hashAssetId); + writer.PutPackedUInt(objectId); + writer.PutPackedLong(connectionId); + writer.Put(position.x); + writer.Put(position.y); + writer.Put(position.z); + writer.Put(rotation.eulerAngles.x); + writer.Put(rotation.eulerAngles.y); + writer.Put(rotation.eulerAngles.z); + } + } +} diff --git a/Scripts/Messages/ServerSpawnObjectMessage.cs.meta b/Scripts/Messages/ServerSpawnObjectMessage.cs.meta new file mode 100644 index 00000000..5bd06b1f --- /dev/null +++ b/Scripts/Messages/ServerSpawnObjectMessage.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 9823c3024abd0c348bb5e297226e819a +timeCreated: 1508932284 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Messages/ServerSpawnSceneObjectMessage.cs b/Scripts/Messages/ServerSpawnSceneObjectMessage.cs new file mode 100644 index 00000000..95a63b48 --- /dev/null +++ b/Scripts/Messages/ServerSpawnSceneObjectMessage.cs @@ -0,0 +1,33 @@ +using LiteNetLib.Utils; +using UnityEngine; + +namespace LiteNetLibManager +{ + public struct ServerSpawnSceneObjectMessage : INetSerializable + { + public uint objectId; + public long connectionId; + public Vector3 position; + public Quaternion rotation; + + public void Deserialize(NetDataReader reader) + { + objectId = reader.GetPackedUInt(); + connectionId = reader.GetPackedLong(); + position = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); + rotation = Quaternion.Euler(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); + } + + public void Serialize(NetDataWriter writer) + { + writer.PutPackedUInt(objectId); + writer.PutPackedLong(connectionId); + writer.Put(position.x); + writer.Put(position.y); + writer.Put(position.z); + writer.Put(rotation.eulerAngles.x); + writer.Put(rotation.eulerAngles.y); + writer.Put(rotation.eulerAngles.z); + } + } +} diff --git a/Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta b/Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta new file mode 100644 index 00000000..65404916 --- /dev/null +++ b/Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 3a57f78648eb8cd4d900d0097f0bd20c +timeCreated: 1511672224 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 08d3a0e5dfc98c9e204a9d98268d92d9504ab4a1 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 01:33:45 +0700 Subject: [PATCH 28/58] Revert "Revert "feat: delete codes for Unity (GameApi)"" This reverts commit ca8a2f12556655ae9a0804a72cc471dfdb5db5fa. --- Scripts/Attributes.meta | 8 - Scripts/Attributes/AllRpcAttribute.cs | 9 - Scripts/Attributes/AllRpcAttribute.cs.meta | 11 - Scripts/Attributes/ElasticRpcAttribute.cs | 9 - .../Attributes/ElasticRpcAttribute.cs.meta | 11 - Scripts/Attributes/NetFunctionAttribute.cs | 9 - .../Attributes/NetFunctionAttribute.cs.meta | 11 - Scripts/Attributes/RpcAttribute.cs | 13 - Scripts/Attributes/RpcAttribute.cs.meta | 11 - Scripts/Attributes/ServerRpcAttribute.cs | 9 - Scripts/Attributes/ServerRpcAttribute.cs.meta | 11 - Scripts/Attributes/SyncFieldAttribute.cs | 46 - Scripts/Attributes/SyncFieldAttribute.cs.meta | 11 - Scripts/Attributes/TargetRpcAttribute.cs | 9 - Scripts/Attributes/TargetRpcAttribute.cs.meta | 11 - Scripts/BaseInterestManager.cs | 74 - Scripts/BaseInterestManager.cs.meta | 11 - Scripts/BaseLiteNetLibVisibleChecker.cs | 11 - Scripts/BaseLiteNetLibVisibleChecker.cs.meta | 11 - Scripts/DefaultInterestManager.cs | 47 - Scripts/DefaultInterestManager.cs.meta | 11 - Scripts/DestroyObjectReasons.cs | 9 - Scripts/DestroyObjectReasons.cs.meta | 11 - Scripts/Events.meta | 10 - Scripts/Events/LiteNetLibIdentityEvent.cs | 9 - .../Events/LiteNetLibIdentityEvent.cs.meta | 11 - Scripts/Events/LiteNetLibLoadSceneEvent.cs | 9 - .../Events/LiteNetLibLoadSceneEvent.cs.meta | 13 - Scripts/GameMsgTypes.cs | 24 - Scripts/GameMsgTypes.cs.meta | 11 - Scripts/GameReqTypes.cs | 9 - Scripts/GameReqTypes.cs.meta | 11 - Scripts/LiteNetLibAssets.cs | 515 ----- Scripts/LiteNetLibAssets.cs.meta | 13 - Scripts/LiteNetLibBehaviour.cs | 1755 ----------------- Scripts/LiteNetLibBehaviour.cs.meta | 13 - Scripts/LiteNetLibElement.cs | 105 - Scripts/LiteNetLibElement.cs.meta | 13 - Scripts/LiteNetLibFunction.cs | 471 ----- Scripts/LiteNetLibFunction.cs.meta | 13 - Scripts/LiteNetLibGameManager.cs | 1049 ---------- Scripts/LiteNetLibGameManager.cs.meta | 13 - Scripts/LiteNetLibIdentity.cs | 843 -------- Scripts/LiteNetLibIdentity.cs.meta | 13 - Scripts/LiteNetLibPlayer.cs | 122 -- Scripts/LiteNetLibPlayer.cs.meta | 13 - Scripts/LiteNetLibSpawnPoint.cs | 43 - Scripts/LiteNetLibSpawnPoint.cs.meta | 13 - Scripts/LiteNetLibSyncField.cs | 693 ------- Scripts/LiteNetLibSyncField.cs.meta | 13 - Scripts/LiteNetLibSyncList.cs | 609 ------ Scripts/LiteNetLibSyncList.cs.meta | 13 - Scripts/LiteNetLibTransform.cs | 521 ----- Scripts/LiteNetLibTransform.cs.meta | 13 - Scripts/LiteNetLibVisibleChecker.cs | 7 - Scripts/LiteNetLibVisibleChecker.cs.meta | 13 - Scripts/Messages/EnterGameRequestMessage.cs | 19 - .../Messages/EnterGameRequestMessage.cs.meta | 11 - Scripts/Messages/EnterGameResponseMessage.cs | 22 - .../Messages/EnterGameResponseMessage.cs.meta | 11 - Scripts/Messages/GenericValueMessage.cs | 188 -- Scripts/Messages/GenericValueMessage.cs.meta | 11 - Scripts/Messages/PingMessage.cs | 19 - Scripts/Messages/PingMessage.cs.meta | 11 - Scripts/Messages/PongMessage.cs | 22 - Scripts/Messages/PongMessage.cs.meta | 11 - .../Messages/ServerDestroyObjectMessage.cs | 22 - .../ServerDestroyObjectMessage.cs.meta | 13 - Scripts/Messages/ServerErrorMessage.cs | 22 - Scripts/Messages/ServerErrorMessage.cs.meta | 13 - Scripts/Messages/ServerSceneChangeMessage.cs | 19 - .../Messages/ServerSceneChangeMessage.cs.meta | 13 - Scripts/Messages/ServerSetObjectOwner.cs | 22 - Scripts/Messages/ServerSetObjectOwner.cs.meta | 11 - Scripts/Messages/ServerSpawnObjectMessage.cs | 36 - .../Messages/ServerSpawnObjectMessage.cs.meta | 13 - .../Messages/ServerSpawnSceneObjectMessage.cs | 33 - .../ServerSpawnSceneObjectMessage.cs.meta | 13 - 78 files changed, 7925 deletions(-) delete mode 100644 Scripts/Attributes.meta delete mode 100644 Scripts/Attributes/AllRpcAttribute.cs delete mode 100644 Scripts/Attributes/AllRpcAttribute.cs.meta delete mode 100644 Scripts/Attributes/ElasticRpcAttribute.cs delete mode 100644 Scripts/Attributes/ElasticRpcAttribute.cs.meta delete mode 100644 Scripts/Attributes/NetFunctionAttribute.cs delete mode 100644 Scripts/Attributes/NetFunctionAttribute.cs.meta delete mode 100644 Scripts/Attributes/RpcAttribute.cs delete mode 100644 Scripts/Attributes/RpcAttribute.cs.meta delete mode 100644 Scripts/Attributes/ServerRpcAttribute.cs delete mode 100644 Scripts/Attributes/ServerRpcAttribute.cs.meta delete mode 100644 Scripts/Attributes/SyncFieldAttribute.cs delete mode 100644 Scripts/Attributes/SyncFieldAttribute.cs.meta delete mode 100644 Scripts/Attributes/TargetRpcAttribute.cs delete mode 100644 Scripts/Attributes/TargetRpcAttribute.cs.meta delete mode 100644 Scripts/BaseInterestManager.cs delete mode 100644 Scripts/BaseInterestManager.cs.meta delete mode 100644 Scripts/BaseLiteNetLibVisibleChecker.cs delete mode 100644 Scripts/BaseLiteNetLibVisibleChecker.cs.meta delete mode 100644 Scripts/DefaultInterestManager.cs delete mode 100644 Scripts/DefaultInterestManager.cs.meta delete mode 100644 Scripts/DestroyObjectReasons.cs delete mode 100644 Scripts/DestroyObjectReasons.cs.meta delete mode 100644 Scripts/Events.meta delete mode 100644 Scripts/Events/LiteNetLibIdentityEvent.cs delete mode 100644 Scripts/Events/LiteNetLibIdentityEvent.cs.meta delete mode 100644 Scripts/Events/LiteNetLibLoadSceneEvent.cs delete mode 100644 Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta delete mode 100644 Scripts/GameMsgTypes.cs delete mode 100644 Scripts/GameMsgTypes.cs.meta delete mode 100644 Scripts/GameReqTypes.cs delete mode 100644 Scripts/GameReqTypes.cs.meta delete mode 100644 Scripts/LiteNetLibAssets.cs delete mode 100644 Scripts/LiteNetLibAssets.cs.meta delete mode 100644 Scripts/LiteNetLibBehaviour.cs delete mode 100644 Scripts/LiteNetLibBehaviour.cs.meta delete mode 100644 Scripts/LiteNetLibElement.cs delete mode 100644 Scripts/LiteNetLibElement.cs.meta delete mode 100644 Scripts/LiteNetLibFunction.cs delete mode 100644 Scripts/LiteNetLibFunction.cs.meta delete mode 100644 Scripts/LiteNetLibGameManager.cs delete mode 100644 Scripts/LiteNetLibGameManager.cs.meta delete mode 100644 Scripts/LiteNetLibIdentity.cs delete mode 100644 Scripts/LiteNetLibIdentity.cs.meta delete mode 100644 Scripts/LiteNetLibPlayer.cs delete mode 100644 Scripts/LiteNetLibPlayer.cs.meta delete mode 100644 Scripts/LiteNetLibSpawnPoint.cs delete mode 100644 Scripts/LiteNetLibSpawnPoint.cs.meta delete mode 100644 Scripts/LiteNetLibSyncField.cs delete mode 100644 Scripts/LiteNetLibSyncField.cs.meta delete mode 100644 Scripts/LiteNetLibSyncList.cs delete mode 100644 Scripts/LiteNetLibSyncList.cs.meta delete mode 100644 Scripts/LiteNetLibTransform.cs delete mode 100644 Scripts/LiteNetLibTransform.cs.meta delete mode 100644 Scripts/LiteNetLibVisibleChecker.cs delete mode 100644 Scripts/LiteNetLibVisibleChecker.cs.meta delete mode 100644 Scripts/Messages/EnterGameRequestMessage.cs delete mode 100644 Scripts/Messages/EnterGameRequestMessage.cs.meta delete mode 100644 Scripts/Messages/EnterGameResponseMessage.cs delete mode 100644 Scripts/Messages/EnterGameResponseMessage.cs.meta delete mode 100644 Scripts/Messages/GenericValueMessage.cs delete mode 100644 Scripts/Messages/GenericValueMessage.cs.meta delete mode 100644 Scripts/Messages/PingMessage.cs delete mode 100644 Scripts/Messages/PingMessage.cs.meta delete mode 100644 Scripts/Messages/PongMessage.cs delete mode 100644 Scripts/Messages/PongMessage.cs.meta delete mode 100644 Scripts/Messages/ServerDestroyObjectMessage.cs delete mode 100644 Scripts/Messages/ServerDestroyObjectMessage.cs.meta delete mode 100644 Scripts/Messages/ServerErrorMessage.cs delete mode 100644 Scripts/Messages/ServerErrorMessage.cs.meta delete mode 100644 Scripts/Messages/ServerSceneChangeMessage.cs delete mode 100644 Scripts/Messages/ServerSceneChangeMessage.cs.meta delete mode 100644 Scripts/Messages/ServerSetObjectOwner.cs delete mode 100644 Scripts/Messages/ServerSetObjectOwner.cs.meta delete mode 100644 Scripts/Messages/ServerSpawnObjectMessage.cs delete mode 100644 Scripts/Messages/ServerSpawnObjectMessage.cs.meta delete mode 100644 Scripts/Messages/ServerSpawnSceneObjectMessage.cs delete mode 100644 Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta diff --git a/Scripts/Attributes.meta b/Scripts/Attributes.meta deleted file mode 100644 index c359d2c1..00000000 --- a/Scripts/Attributes.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2e2c381232fb17f4ba5116c6644d357b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/AllRpcAttribute.cs b/Scripts/Attributes/AllRpcAttribute.cs deleted file mode 100644 index f9ca9338..00000000 --- a/Scripts/Attributes/AllRpcAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class AllRpcAttribute : RpcAttribute - { - } -} diff --git a/Scripts/Attributes/AllRpcAttribute.cs.meta b/Scripts/Attributes/AllRpcAttribute.cs.meta deleted file mode 100644 index eb5113b7..00000000 --- a/Scripts/Attributes/AllRpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 24f4ce169ace902478a464b82f69e284 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/ElasticRpcAttribute.cs b/Scripts/Attributes/ElasticRpcAttribute.cs deleted file mode 100644 index 6aa0b852..00000000 --- a/Scripts/Attributes/ElasticRpcAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class ElasticRpcAttribute : RpcAttribute - { - } -} diff --git a/Scripts/Attributes/ElasticRpcAttribute.cs.meta b/Scripts/Attributes/ElasticRpcAttribute.cs.meta deleted file mode 100644 index 155d55e0..00000000 --- a/Scripts/Attributes/ElasticRpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5654a2358c8bcb844ad984f229c15fed -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/NetFunctionAttribute.cs b/Scripts/Attributes/NetFunctionAttribute.cs deleted file mode 100644 index 859fb9d3..00000000 --- a/Scripts/Attributes/NetFunctionAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class NetFunctionAttribute : ElasticRpcAttribute - { - } -} diff --git a/Scripts/Attributes/NetFunctionAttribute.cs.meta b/Scripts/Attributes/NetFunctionAttribute.cs.meta deleted file mode 100644 index e5b721ab..00000000 --- a/Scripts/Attributes/NetFunctionAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0fe7e812fc00d644f971c72e4195d10a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/RpcAttribute.cs b/Scripts/Attributes/RpcAttribute.cs deleted file mode 100644 index 7d23263c..00000000 --- a/Scripts/Attributes/RpcAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public abstract class RpcAttribute : Attribute - { - /// - /// If is true non-owner client can call the object's net function - /// - public bool canCallByEveryone = false; - } -} diff --git a/Scripts/Attributes/RpcAttribute.cs.meta b/Scripts/Attributes/RpcAttribute.cs.meta deleted file mode 100644 index 05e33df7..00000000 --- a/Scripts/Attributes/RpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 922389d8923e4dc40a79bfb30ec4cb95 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/ServerRpcAttribute.cs b/Scripts/Attributes/ServerRpcAttribute.cs deleted file mode 100644 index 6de847ac..00000000 --- a/Scripts/Attributes/ServerRpcAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class ServerRpcAttribute : RpcAttribute - { - } -} diff --git a/Scripts/Attributes/ServerRpcAttribute.cs.meta b/Scripts/Attributes/ServerRpcAttribute.cs.meta deleted file mode 100644 index eeffefbe..00000000 --- a/Scripts/Attributes/ServerRpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 36c1b5b0980dabf4dba82bc55fbc25c6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/SyncFieldAttribute.cs b/Scripts/Attributes/SyncFieldAttribute.cs deleted file mode 100644 index 8ca37aea..00000000 --- a/Scripts/Attributes/SyncFieldAttribute.cs +++ /dev/null @@ -1,46 +0,0 @@ -using LiteNetLib; -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)] - public class SyncFieldAttribute : Attribute - { - /// - /// Sending data channel from server to clients - /// - public byte dataChannel = 0; - /// - /// Sending method type from server to clients - /// - public DeliveryMethod deliveryMethod = DeliveryMethod.ReliableOrdered; - /// - /// Sending data channel from clients to server (while `syncMode` is `ClientMulticast` only) - /// - public byte clientDataChannel = 0; - /// - /// Sending method type from clients to server (while `syncMode` is `ClientMulticast` only) - /// - public DeliveryMethod clientDeliveryMethod = DeliveryMethod.ReliableOrdered; - /// - /// Interval to send network data - /// - public float sendInterval = 0.1f; - /// - /// How it will sync data. If always sync, it will sync data although it has no changes. If don't sync initial data immediately, it will not sync initial data immdediately with networked object spawning message, it will sync later after spanwed. If don't sync update, it will not sync when data has changes. - /// - public LiteNetLibSyncField.SyncBehaviour syncBehaviour = LiteNetLibSyncField.SyncBehaviour.Default; - /// - /// Who can sync data and sync to whom - /// - public LiteNetLibSyncField.SyncMode syncMode = LiteNetLibSyncField.SyncMode.ServerToClients; - /// - /// Method name which will be invoked when data changed - /// - public string onChangeMethodName = string.Empty; - /// - /// Method name which will be invoked when data sent - /// - public string onUpdateMethodName = string.Empty; - } -} diff --git a/Scripts/Attributes/SyncFieldAttribute.cs.meta b/Scripts/Attributes/SyncFieldAttribute.cs.meta deleted file mode 100644 index f3119616..00000000 --- a/Scripts/Attributes/SyncFieldAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 87ccb352ef1e4234cba4a002c09dd7c0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/TargetRpcAttribute.cs b/Scripts/Attributes/TargetRpcAttribute.cs deleted file mode 100644 index 19bf4b98..00000000 --- a/Scripts/Attributes/TargetRpcAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace LiteNetLibManager -{ - [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] - public class TargetRpcAttribute : RpcAttribute - { - } -} diff --git a/Scripts/Attributes/TargetRpcAttribute.cs.meta b/Scripts/Attributes/TargetRpcAttribute.cs.meta deleted file mode 100644 index 00616fb3..00000000 --- a/Scripts/Attributes/TargetRpcAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1f4dc3f2443322941bd8c9593ac1836c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/BaseInterestManager.cs b/Scripts/BaseInterestManager.cs deleted file mode 100644 index 286eed90..00000000 --- a/Scripts/BaseInterestManager.cs +++ /dev/null @@ -1,74 +0,0 @@ -using UnityEngine; - -namespace LiteNetLibManager -{ - [DisallowMultipleComponent] - public abstract class BaseInterestManager : MonoBehaviour - { - [Tooltip("Default visible range will be used when Identity's visible range is <= 0f")] - public float defaultVisibleRange = 80f; - public LiteNetLibGameManager Manager { get; protected set; } - public bool IsServer { get { return Manager.IsServer; } } - - protected virtual void Awake() - { - Manager = GetComponent(); - } - - public void NotifyNewObject(LiteNetLibIdentity newObject) - { - if (!IsServer) - { - // Notifies by server only - return; - } - // Subscribe old objects, if it should - if (newObject.ConnectionId >= 0 && newObject.Player.IsReady) - { - foreach (LiteNetLibIdentity target in Manager.Assets.GetSpawnedObjects()) - { - // Subscribe, it may subscribe or may not, up to how subscribe function implemented - Subscribe(newObject, target); - } - } - // Notify to other players - foreach (LiteNetLibPlayer player in Manager.GetPlayers()) - { - if (!player.IsReady || player.ConnectionId == newObject.ConnectionId) - { - // Don't subscribe if player not ready or the object is owned by the player - continue; - } - foreach (LiteNetLibIdentity subscriber in player.GetSpawnedObjects()) - { - // Subscribe, it may subscribe or may not, up to how subscribe function implemented - Subscribe(subscriber, newObject); - } - } - } - - public float GetVisibleRange(LiteNetLibIdentity identity) - { - return identity.VisibleRange > 0f ? identity.VisibleRange : defaultVisibleRange; - } - - public virtual bool ShouldSubscribe(LiteNetLibIdentity subscriber, LiteNetLibIdentity target, bool checkRange = true) - { - if (subscriber == null || target == null || subscriber.ConnectionId < 0) - return false; - if (subscriber.ConnectionId == target.ConnectionId) - return true; - return !target.IsHideFrom(subscriber) && (!checkRange || target.AlwaysVisible || Vector3.Distance(subscriber.transform.position, target.transform.position) <= GetVisibleRange(target)); - } - - public virtual bool Subscribe(LiteNetLibIdentity subscriber, LiteNetLibIdentity target) - { - if (ShouldSubscribe(subscriber, target)) - { - subscriber.AddSubscribing(target.ObjectId); - return true; - } - return false; - } - } -} diff --git a/Scripts/BaseInterestManager.cs.meta b/Scripts/BaseInterestManager.cs.meta deleted file mode 100644 index 988825ce..00000000 --- a/Scripts/BaseInterestManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 14432c40583017d4e8beb2be9b8ec43e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/BaseLiteNetLibVisibleChecker.cs b/Scripts/BaseLiteNetLibVisibleChecker.cs deleted file mode 100644 index 0de0940c..00000000 --- a/Scripts/BaseLiteNetLibVisibleChecker.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace LiteNetLibManager -{ - [DisallowMultipleComponent] - [System.Obsolete("This component is deprecated because interest management system is changed")] - public abstract class BaseLiteNetLibVisibleChecker : MonoBehaviour - { - } -} diff --git a/Scripts/BaseLiteNetLibVisibleChecker.cs.meta b/Scripts/BaseLiteNetLibVisibleChecker.cs.meta deleted file mode 100644 index 8c948435..00000000 --- a/Scripts/BaseLiteNetLibVisibleChecker.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a7058a555827f9a478fea05cbc44cb0e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/DefaultInterestManager.cs b/Scripts/DefaultInterestManager.cs deleted file mode 100644 index 100e2364..00000000 --- a/Scripts/DefaultInterestManager.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace LiteNetLibManager -{ - public class DefaultInterestManager : BaseInterestManager - { - [Tooltip("Update every ? seconds")] - public float updateInterval = 1f; - - private float updateCountDown = 0f; - - private void Update() - { - if (!IsServer) - { - // Update at server only - return; - } - updateCountDown -= Time.unscaledDeltaTime; - if (updateCountDown <= 0f) - { - updateCountDown = updateInterval; - HashSet subscribings = new HashSet(); - foreach (LiteNetLibPlayer player in Manager.GetPlayers()) - { - if (!player.IsReady) - { - // Don't subscribe if player not ready - continue; - } - foreach (LiteNetLibIdentity playerObject in player.GetSpawnedObjects()) - { - // Update subscribing list, it will unsubscribe objects which is not in this list - subscribings.Clear(); - foreach (LiteNetLibIdentity spawnedObject in Manager.Assets.GetSpawnedObjects()) - { - if (ShouldSubscribe(playerObject, spawnedObject)) - subscribings.Add(spawnedObject.ObjectId); - } - playerObject.UpdateSubscribings(subscribings); - } - } - } - } - } -} diff --git a/Scripts/DefaultInterestManager.cs.meta b/Scripts/DefaultInterestManager.cs.meta deleted file mode 100644 index 72c83b7b..00000000 --- a/Scripts/DefaultInterestManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a1ccd9ce8d0d28d4fb1d2e56e08bc6ef -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/DestroyObjectReasons.cs b/Scripts/DestroyObjectReasons.cs deleted file mode 100644 index b036566f..00000000 --- a/Scripts/DestroyObjectReasons.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace LiteNetLibManager -{ - public static partial class DestroyObjectReasons - { - public const byte RequestedToDestroy = 0; - public const byte RemovedFromSubscribing = 1; - public const byte Highest = 1; - } -} diff --git a/Scripts/DestroyObjectReasons.cs.meta b/Scripts/DestroyObjectReasons.cs.meta deleted file mode 100644 index a6a846ee..00000000 --- a/Scripts/DestroyObjectReasons.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bf5e4e67b2edd55469fac12498be27a6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Events.meta b/Scripts/Events.meta deleted file mode 100644 index 464631d8..00000000 --- a/Scripts/Events.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 202557d6bd6392b4a8e26f3e1cbfbcdf -folderAsset: yes -timeCreated: 1525035216 -licenseType: Free -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Events/LiteNetLibIdentityEvent.cs b/Scripts/Events/LiteNetLibIdentityEvent.cs deleted file mode 100644 index 452886c2..00000000 --- a/Scripts/Events/LiteNetLibIdentityEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEngine.Events; - -namespace LiteNetLibManager -{ - [System.Serializable] - public class LiteNetLibIdentityEvent : UnityEvent - { - } -} diff --git a/Scripts/Events/LiteNetLibIdentityEvent.cs.meta b/Scripts/Events/LiteNetLibIdentityEvent.cs.meta deleted file mode 100644 index 5783ffb2..00000000 --- a/Scripts/Events/LiteNetLibIdentityEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 74e03bd06ca73434590bb4486608c477 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Events/LiteNetLibLoadSceneEvent.cs b/Scripts/Events/LiteNetLibLoadSceneEvent.cs deleted file mode 100644 index 05100d27..00000000 --- a/Scripts/Events/LiteNetLibLoadSceneEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEngine.Events; - -namespace LiteNetLibManager -{ - [System.Serializable] - public class LiteNetLibLoadSceneEvent : UnityEvent - { - } -} diff --git a/Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta b/Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta deleted file mode 100644 index a573e4b7..00000000 --- a/Scripts/Events/LiteNetLibLoadSceneEvent.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 9ad5883371559724ca569b77258ec07b -timeCreated: 1525035242 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameMsgTypes.cs b/Scripts/GameMsgTypes.cs deleted file mode 100644 index 95c0f35c..00000000 --- a/Scripts/GameMsgTypes.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace LiteNetLibManager -{ - public static partial class GameMsgTypes - { - public const ushort Request = 0; - public const ushort Response = 1; - public const ushort CallFunction = 3; - public const ushort ServerSpawnSceneObject = 4; - public const ushort ServerSpawnObject = 5; - public const ushort ServerDestroyObject = 6; - public const ushort UpdateSyncField = 7; - public const ushort InitialSyncField = 8; - public const ushort OperateSyncList = 9; - public const ushort ServerSyncBehaviour = 11; - public const ushort ServerError = 12; - public const ushort ServerSceneChange = 13; - public const ushort ClientSendTransform = 14; - public const ushort ServerSetObjectOwner = 15; - public const ushort Ping = 16; - public const ushort Pong = 17; - public const ushort Disconnect = 18; - public const ushort Highest = 18; - } -} diff --git a/Scripts/GameMsgTypes.cs.meta b/Scripts/GameMsgTypes.cs.meta deleted file mode 100644 index 3eac67e5..00000000 --- a/Scripts/GameMsgTypes.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3a03ecc48c1a8a54eb4abe116d9bb35b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameReqTypes.cs b/Scripts/GameReqTypes.cs deleted file mode 100644 index 4905f8f8..00000000 --- a/Scripts/GameReqTypes.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace LiteNetLibManager -{ - public static partial class GameReqTypes - { - public const ushort EnterGame = 0; - public const ushort ClientReady = 1; - public const ushort ClientNotReady = 2; - } -} diff --git a/Scripts/GameReqTypes.cs.meta b/Scripts/GameReqTypes.cs.meta deleted file mode 100644 index 63f1c5bb..00000000 --- a/Scripts/GameReqTypes.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b8a4fd8828789514c891003b9e990dbb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibAssets.cs b/Scripts/LiteNetLibAssets.cs deleted file mode 100644 index b6c96a0a..00000000 --- a/Scripts/LiteNetLibAssets.cs +++ /dev/null @@ -1,515 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Events; - -namespace LiteNetLibManager -{ - public class LiteNetLibAssets : MonoBehaviour - { - private static int spawnPositionCounter = 0; - public bool playerSpawnRandomly; - public LiteNetLibIdentity playerPrefab; - public LiteNetLibIdentity[] spawnablePrefabs; - public LiteNetLibIdentity PlayerPrefab { get; protected set; } - public SceneField offlineScene; - public SceneField onlineScene; - public UnityEvent onInitialize; - public LiteNetLibLoadSceneEvent onLoadSceneStart; - public LiteNetLibLoadSceneEvent onLoadSceneProgress; - public LiteNetLibLoadSceneEvent onLoadSceneFinish; - public LiteNetLibIdentityEvent onObjectSpawn; - public LiteNetLibIdentityEvent onObjectDestroy; - - internal readonly List CacheSpawnPoints = new List(); - internal readonly Dictionary GuidToPrefabs = new Dictionary(); - internal readonly Dictionary SceneObjects = new Dictionary(); - internal readonly Dictionary SpawnedObjects = new Dictionary(); - internal readonly Dictionary> PooledObjects = new Dictionary>(); - - public LiteNetLibGameManager Manager { get; private set; } - private string logTag; - public string LogTag - { - get - { - if (string.IsNullOrEmpty(logTag)) - logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; - return logTag; - } - } - - private void Awake() - { - Manager = GetComponent(); - } - - public void Initialize() - { - if (onInitialize != null) - onInitialize.Invoke(); - RegisterPrefabs(); - RegisterSpawnPoints(); - RegisterSceneObjects(); - } - - public void Clear(bool doNotResetObjectId = false) - { - ClearSpawnedObjects(); - ClearPooledObjects(); - CacheSpawnPoints.Clear(); - SceneObjects.Clear(); - ResetSpawnPositionCounter(); - if (!doNotResetObjectId) - LiteNetLibIdentity.ResetObjectId(); - } - - public void RegisterSpawnPoints() - { - CacheSpawnPoints.Clear(); - CacheSpawnPoints.AddRange(FindObjectsOfType()); - } - - public void RegisterPrefabs() - { - for (int i = 0; i < spawnablePrefabs.Length; ++i) - { - LiteNetLibIdentity registeringPrefab = spawnablePrefabs[i]; - RegisterPrefab(registeringPrefab); - } - if (playerPrefab != null) - { - PlayerPrefab = playerPrefab; - RegisterPrefab(playerPrefab); - } - } - - public void RegisterPrefab(LiteNetLibIdentity prefab) - { - if (prefab == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "RegisterPrefab - prefab is null."); - return; - } - if (Manager.LogDev) Logging.Log(LogTag, $"RegisterPrefab [{prefab.HashAssetId}] name [{prefab.name}]"); - GuidToPrefabs[prefab.HashAssetId] = prefab; - } - - public bool UnregisterPrefab(LiteNetLibIdentity prefab) - { - if (prefab == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "UnregisterPrefab - prefab is null."); - return false; - } - if (Manager.LogDev) Logging.Log(LogTag, $"UnregisterPrefab [{prefab.HashAssetId}] name [{prefab.name}]"); - return GuidToPrefabs.Remove(prefab.HashAssetId); - } - - public void ClearSpawnedObjects() - { - List objectIds = new List(SpawnedObjects.Keys); - for (int i = objectIds.Count - 1; i >= 0; --i) - { - uint objectId = objectIds[i]; - LiteNetLibIdentity spawnedObject; - if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) - { - // Destroy only non scene object - if (!SceneObjects.ContainsKey(objectId) && spawnedObject != null) - Destroy(spawnedObject.gameObject); - // Remove from asset spawned objects dictionary - SpawnedObjects.Remove(objectId); - } - } - SpawnedObjects.Clear(); - } - - public void ClearPooledObjects() - { - foreach (Queue queue in PooledObjects.Values) - { - while (queue.Count > 0) - { - LiteNetLibIdentity instance = queue.Dequeue(); - try - { - // I tried to avoid null exception but it still ocurring - if (instance != null) - Destroy(instance.gameObject); - } - catch { } - } - } - PooledObjects.Clear(); - } - - public void InitPoolingObjects() - { - foreach (int hashAssetId in GuidToPrefabs.Keys) - { - InitPoolingObject(hashAssetId); - } - } - - public void InitPoolingObject(int hashAssetId) - { - if (!GuidToPrefabs.ContainsKey(hashAssetId)) - { - Debug.LogWarning($"Cannot init prefab: {hashAssetId}, can't find the registered prefab."); - return; - } - - // Already init pool for the prefab - if (PooledObjects.ContainsKey(hashAssetId)) - return; - - LiteNetLibIdentity prefab = GuidToPrefabs[hashAssetId]; - // Don't create an instance for this prefab, if pooling size < 0 - if (prefab.PoolingSize <= 0) - return; - - Queue queue = new Queue(); - LiteNetLibIdentity tempInstance; - for (int i = 0; i < prefab.PoolingSize; ++i) - { - tempInstance = Instantiate(prefab); - tempInstance.IsPooledInstance = true; - tempInstance.gameObject.SetActive(false); - queue.Enqueue(tempInstance); - } - - PooledObjects[hashAssetId] = queue; - } - - public LiteNetLibIdentity GetObjectInstance(int hashAssetId) - { - return GetObjectInstance(hashAssetId, Vector3.zero, Quaternion.identity); - } - - public LiteNetLibIdentity GetObjectInstance(int hashAssetId, Vector3 position, Quaternion rotation) - { - if (PooledObjects.ContainsKey(hashAssetId) && PooledObjects[hashAssetId].Count > 0) - { - // Get pooled instance - LiteNetLibIdentity instance = PooledObjects[hashAssetId].Dequeue(); - instance.OnGetInstance(); - instance.transform.position = position; - instance.transform.rotation = rotation; - return instance; - } - - if (GuidToPrefabs.ContainsKey(hashAssetId)) - { - // Create a new instance - LiteNetLibIdentity instance = Instantiate(GuidToPrefabs[hashAssetId], position, rotation); - instance.gameObject.SetActive(false); - return instance; - } - - return null; - } - - public void PushInstanceBack(LiteNetLibIdentity instance) - { - if (instance == null) - { - Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance's is empty."); - return; - } - if (!instance.IsPooledInstance) - { - Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance is not pooled instance."); - return; - } - Queue queue; - if (!PooledObjects.TryGetValue(instance.HashAssetId, out queue)) - { - Debug.LogWarning($"[PoolSystem] Cannot push back ({instance.gameObject}). The instance's prefab does not initailized yet."); - return; - } - if (queue.Count >= instance.PoolingSize) - { - Destroy(instance.gameObject); - } - else - { - instance.gameObject.SetActive(false); - queue.Enqueue(instance); - } - } - - public void RegisterSceneObjects() - { - SceneObjects.Clear(); - LiteNetLibIdentity[] sceneObjects = FindObjectsOfType(); - for (int i = 0; i < sceneObjects.Length; ++i) - { - LiteNetLibIdentity sceneObject = sceneObjects[i]; - if (sceneObject.ObjectId > 0) - { - sceneObject.gameObject.SetActive(false); - SceneObjects[sceneObject.ObjectId] = sceneObject; - LiteNetLibIdentity.UpdateHighestObjectId(sceneObject.ObjectId); - } - } - } - - /// - /// This function will be called on start server and when network scene loaded to spawn scene objects - /// So each scene objects connection id will = -1 (No owning client) - /// - public void SpawnSceneObjects() - { - List sceneObjects = new List(SceneObjects.Values); - for (int i = 0; i < sceneObjects.Count; ++i) - { - LiteNetLibIdentity sceneObject = sceneObjects[i]; - NetworkSpawnScene(sceneObject.ObjectId, sceneObject.transform.position, sceneObject.transform.rotation); - } - } - - public LiteNetLibIdentity NetworkSpawnScene(uint objectId, Vector3 position, Quaternion rotation, long connectionId = -1) - { - if (!Manager.IsNetworkActive) - { - Logging.LogWarning(LogTag, "NetworkSpawnScene - Network is not active cannot spawn"); - return null; - } - - LiteNetLibIdentity identity; - if (!SceneObjects.TryGetValue(objectId, out identity)) - { - Logging.LogWarning(LogTag, $"NetworkSpawnScene - Object Id: {objectId} is not registered."); - return null; - } - - identity.gameObject.SetActive(true); - identity.Initial(Manager, true, objectId, connectionId); - identity.InitTransform(position, rotation); - identity.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); - if (Manager.IsServer) - identity.OnStartServer(); - if (Manager.IsClient) - identity.OnStartClient(); - if (connectionId >= 0 && connectionId == Manager.ClientConnectionId) - identity.OnStartOwnerClient(); - if (onObjectSpawn != null) - onObjectSpawn.Invoke(identity); - - return identity; - } - - public LiteNetLibIdentity NetworkSpawn(GameObject gameObject, uint objectId = 0, long connectionId = -1) - { - if (gameObject == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - gameObject is null."); - return null; - } - return NetworkSpawn(gameObject.GetComponent(), objectId, connectionId); - } - - public LiteNetLibIdentity NetworkSpawn(LiteNetLibIdentity identity, uint objectId = 0, long connectionId = -1) - { - if (identity == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - identity is null."); - return null; - } - - identity.gameObject.SetActive(true); - identity.Initial(Manager, false, objectId, connectionId); - identity.InitTransform(identity.transform.position, identity.transform.rotation); - identity.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); - if (Manager.IsServer) - identity.OnStartServer(); - if (Manager.IsClient) - identity.OnStartClient(); - if (connectionId >= 0 && connectionId == Manager.ClientConnectionId) - identity.OnStartOwnerClient(); - if (onObjectSpawn != null) - onObjectSpawn.Invoke(identity); - - return identity; - } - - public LiteNetLibIdentity NetworkSpawn(int hashAssetId, Vector3 position, Quaternion rotation, uint objectId = 0, long connectionId = -1) - { - if (!GuidToPrefabs.ContainsKey(hashAssetId)) - { - if (Manager.LogWarn) - Logging.LogWarning(LogTag, $"NetworkSpawn - Asset Id: {hashAssetId} is not registered."); - return null; - } - return NetworkSpawn(GetObjectInstance(hashAssetId, position, rotation), objectId, connectionId); - } - - public bool NetworkDestroy(GameObject gameObject, byte reasons) - { - if (gameObject == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkDestroy - gameObject is null."); - return false; - } - LiteNetLibIdentity identity = gameObject.GetComponent(); - if (identity == null) - { - if (Manager.LogWarn) Logging.LogWarning(LogTag, "NetworkSpawn - identity is null."); - return false; - } - return NetworkDestroy(identity.ObjectId, reasons); - } - - public bool NetworkDestroy(uint objectId, byte reasons) - { - if (!Manager.IsNetworkActive) - { - Logging.LogWarning(LogTag, "NetworkDestroy - Network is not active cannot destroy"); - return false; - } - - LiteNetLibIdentity spawnedObject; - if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) - { - // Call this function to tell behaviour that the identity is being destroyed - spawnedObject.OnNetworkDestroy(reasons); - if (onObjectDestroy != null) - onObjectDestroy.Invoke(spawnedObject); - // If the object is scene object, don't destroy just hide it, else destroy - if (SceneObjects.ContainsKey(objectId)) - { - spawnedObject.gameObject.SetActive(false); - } - else - { - if (spawnedObject.IsPooledInstance) - PushInstanceBack(spawnedObject); - else - Destroy(spawnedObject.gameObject); - } - return true; - } - else if (Manager.LogWarn) - { - Logging.LogWarning(LogTag, $"NetworkDestroy - Object Id: {objectId} is not spawned."); - } - return false; - } - - public bool SetObjectOwner(uint objectId, long connectionId) - { - if (!Manager.IsNetworkActive) - { - Logging.LogWarning(LogTag, "SetObjectOwner - Network is not active cannot set object owner"); - return false; - } - LiteNetLibIdentity spawnedObject; - if (SpawnedObjects.TryGetValue(objectId, out spawnedObject)) - { - if (spawnedObject.ConnectionId == connectionId) - return false; - - // If this is server, send message to clients to set object owner - if (Manager.IsServer) - { - foreach (long subscriber in spawnedObject.Subscribers) - { - if (subscriber == connectionId) - continue; - Manager.SendServerSetObjectOwner(subscriber, objectId, connectionId); - } - Manager.SendServerSetObjectOwner(connectionId, objectId, connectionId); - } - // Remove from player spawned objects dictionary and add to target connection id - LiteNetLibPlayer playerA; - LiteNetLibPlayer playerB; - if (Manager.TryGetPlayer(spawnedObject.ConnectionId, out playerA)) - playerA.SpawnedObjects.Remove(objectId); - if (Manager.TryGetPlayer(connectionId, out playerB)) - playerB.SpawnedObjects[spawnedObject.ObjectId] = spawnedObject; - // Set connection id - spawnedObject.ConnectionId = connectionId; - // Call set owner client event - spawnedObject.OnSetOwnerClient(connectionId >= 0 && connectionId == Manager.ClientConnectionId); - return true; - } - else if (Manager.LogWarn) - Logging.LogWarning(LogTag, $"SetObjectOwner - Object Id: {objectId} is not spawned."); - - return false; - } - - public Vector3 GetPlayerSpawnPosition() - { - if (CacheSpawnPoints.Count == 0) - return Vector3.zero; - if (playerSpawnRandomly) - return CacheSpawnPoints[Random.Range(0, CacheSpawnPoints.Count)].GetRandomPosition(); - else - { - if (spawnPositionCounter >= CacheSpawnPoints.Count) - spawnPositionCounter = 0; - return CacheSpawnPoints[spawnPositionCounter++].GetRandomPosition(); - } - } - - public bool ContainsSceneObject(uint objectId) - { - return SceneObjects.ContainsKey(objectId); - } - - public bool TryGetSceneObject(uint objectId, out LiteNetLibIdentity identity) - { - return SceneObjects.TryGetValue(objectId, out identity); - } - - public bool TryGetSceneObject(uint objectId, out T result) where T : LiteNetLibBehaviour - { - result = null; - LiteNetLibIdentity identity; - if (SceneObjects.TryGetValue(objectId, out identity)) - { - result = identity.GetComponent(); - return result != null; - } - return false; - } - - public IEnumerable GetSceneObjects() - { - return SceneObjects.Values; - } - - public bool ContainsSpawnedObject(uint objectId) - { - return SpawnedObjects.ContainsKey(objectId); - } - - public bool TryGetSpawnedObject(uint objectId, out LiteNetLibIdentity identity) - { - return SpawnedObjects.TryGetValue(objectId, out identity); - } - - public bool TryGetSpawnedObject(uint objectId, out T result) where T : LiteNetLibBehaviour - { - result = null; - LiteNetLibIdentity identity; - if (SpawnedObjects.TryGetValue(objectId, out identity)) - { - result = identity.GetComponent(); - return result != null; - } - return false; - } - - public IEnumerable GetSpawnedObjects() - { - return SpawnedObjects.Values; - } - - public static void ResetSpawnPositionCounter() - { - spawnPositionCounter = 0; - } - } -} diff --git a/Scripts/LiteNetLibAssets.cs.meta b/Scripts/LiteNetLibAssets.cs.meta deleted file mode 100644 index 2eb5fa7e..00000000 --- a/Scripts/LiteNetLibAssets.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 4884384bff23a9c439e7ce9681ea5724 -timeCreated: 1508751282 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibBehaviour.cs b/Scripts/LiteNetLibBehaviour.cs deleted file mode 100644 index 015a6bee..00000000 --- a/Scripts/LiteNetLibBehaviour.cs +++ /dev/null @@ -1,1755 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Linq; -using UnityEngine; -using LiteNetLib; -using LiteNetLib.Utils; -using UnityEngine.Profiling; -using System.Text; - -namespace LiteNetLibManager -{ - public partial class LiteNetLibBehaviour : MonoBehaviour, INetSerializable - { - private struct CacheFields - { - public List syncFields; - public List syncLists; - public List syncFieldsWithAttribute; - } - - private struct CacheFunctions - { - public List functions; - public List functionsCanCallByEveryone; - } - - [ReadOnly, SerializeField] - private byte behaviourIndex; - public byte BehaviourIndex - { - get { return behaviourIndex; } - } - - [Header("Behaviour Sync Options")] - public byte dataChannel; - public DeliveryMethod sendOptions; - [Tooltip("Interval to send network data")] - [Range(0.01f, 2f)] - public float sendInterval = 0.1f; - /// - /// How many times per second it will sync behaviour - /// - public float SendRate - { - get { return 1f / sendInterval; } - } - - private float sendCountDown; - - private static readonly Dictionary CacheSyncElements = new Dictionary(); - private static readonly Dictionary CacheElasticRpcs = new Dictionary(); - private static readonly Dictionary CacheTargetRpcs = new Dictionary(); - private static readonly Dictionary CacheAllRpcs = new Dictionary(); - private static readonly Dictionary CacheServerRpcs = new Dictionary(); - private static readonly Dictionary CacheOnChangeFunctions = new Dictionary(); - private static readonly Dictionary CacheOnUpdateFunctions = new Dictionary(); - private static readonly Dictionary CacheDyncnamicFunctionTypes = new Dictionary(); - - private readonly Dictionary targetRpcIds = new Dictionary(); - private readonly Dictionary allRpcIds = new Dictionary(); - private readonly Dictionary serverRpcIds = new Dictionary(); - - // Optimize garbage collector - private Type tempLookupType; - private HashSet tempLookupNames = new HashSet(); - private FieldInfo[] tempLookupFields; - private MethodInfo[] tempLookupMethods; - - private Type classType; - /// - /// This will be used when setup sync fields and sync lists - /// - public Type ClassType - { - get - { - if (classType == null) - classType = GetType(); - return classType; - } - } - - /// - /// This will be used when setup sync fields and sync lists as key for cached fields - /// - public string TypeName - { - get { return ClassType.FullName; } - } - - private bool isFoundIdentity; - private LiteNetLibIdentity identity; - public LiteNetLibIdentity Identity - { - get - { - if (!isFoundIdentity) - { - identity = GetComponent(); - if (identity == null) - identity = GetComponentInParent(); - isFoundIdentity = identity != null; - } - return identity; - } - } - - public long ConnectionId - { - get { return Identity.ConnectionId; } - } - - public uint ObjectId - { - get { return Identity.ObjectId; } - } - - public LiteNetLibGameManager Manager - { - get { return Identity.Manager; } - } - - public LiteNetLibPlayer Player - { - get { return Identity.Player; } - } - - public bool IsServer - { - get { return Identity.IsServer; } - } - - public bool IsClient - { - get { return Identity.IsClient; } - } - - public bool IsOwnerClient - { - get { return Identity.IsOwnerClient; } - } - - public bool IsHost - { - get { return IsServer && IsOwnerClient; } - } - - public bool IsOwnedByServer - { - get { return Identity.IsOwnedByServer; } - } - - public bool IsOwnerClientOrOwnedByServer - { - get { return Identity.IsOwnerClientOrOwnedByServer; } - } - - public bool IsSceneObject - { - get { return Identity.IsSceneObject; } - } - - private string logTag; - public virtual string LogTag - { - get - { - if (string.IsNullOrEmpty(logTag)) - logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; - return logTag; - } - } - - internal void NetworkUpdate(float deltaTime) - { - // Sync behaviour - if (!IsServer || !CanSyncBehaviour()) - return; - - // It's time to send update? - sendCountDown -= deltaTime; - if (sendCountDown > 0) - return; - - // Set count down - sendCountDown = sendInterval; - - Profiler.BeginSample("LiteNetLibBehaviour - Update Sync Behaviour"); - if (ShouldSyncBehaviour()) - { - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - TransportHandler.WritePacket(server.Writer, GameMsgTypes.ServerSyncBehaviour); - Serialize(server.Writer); - foreach (long connectionId in manager.GetConnectionIds()) - { - if (Identity.HasSubscriberOrIsOwning(connectionId)) - server.SendMessage(connectionId, dataChannel, sendOptions, server.Writer); - } - } - Profiler.EndSample(); - } - - public void Setup(byte behaviourIndex) - { - this.behaviourIndex = behaviourIndex; - OnSetup(); - CacheElements(); - CacheRpcs(serverRpcIds, CacheElasticRpcs); - CacheRpcs(allRpcIds, CacheElasticRpcs); - CacheRpcs(targetRpcIds, CacheElasticRpcs); - CacheRpcs(serverRpcIds, CacheServerRpcs); - CacheRpcs(allRpcIds, CacheAllRpcs); - CacheRpcs(targetRpcIds, CacheTargetRpcs); - } - - private void CacheElements() - { - CacheFields tempCacheFields; - if (!CacheSyncElements.TryGetValue(TypeName, out tempCacheFields)) - { - tempCacheFields = new CacheFields() - { - syncFields = new List(), - syncLists = new List(), - syncFieldsWithAttribute = new List() - }; - tempLookupNames.Clear(); - tempLookupType = ClassType; - SyncFieldAttribute tempAttribute = null; - // Find for sync field and sync list from the class - while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) - { - tempLookupFields = tempLookupType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - foreach (FieldInfo lookupField in tempLookupFields) - { - // Avoid duplicate fields - if (tempLookupNames.Contains(lookupField.Name)) - continue; - - if (lookupField.FieldType.IsSubclassOf(typeof(LiteNetLibSyncField))) - { - tempCacheFields.syncFields.Add(lookupField); - } - else if (lookupField.FieldType.IsSubclassOf(typeof(LiteNetLibSyncList))) - { - tempCacheFields.syncLists.Add(lookupField); - } - else - { - // Must have [SyncField] attribute - tempAttribute = lookupField.GetCustomAttribute(); - if (tempAttribute != null) - tempCacheFields.syncFieldsWithAttribute.Add(lookupField); - } - - tempLookupNames.Add(lookupField.Name); - } - tempLookupType = tempLookupType.BaseType; - } - // Sort name to make sure the fields will be sync correctly by its index - tempCacheFields.syncFields.Sort((a, b) => a.Name.ToLower().CompareTo(b.Name.ToLower())); - tempCacheFields.syncLists.Sort((a, b) => a.Name.ToLower().CompareTo(b.Name.ToLower())); - CacheSyncElements.Add(TypeName, tempCacheFields); - } - SetupSyncElements(tempCacheFields.syncFields, Identity.SyncFields); - SetupSyncElements(tempCacheFields.syncLists, Identity.SyncLists); - SetupSyncFieldsWithAttribute(tempCacheFields.syncFieldsWithAttribute); - } - - private void SetupSyncElements(List fields, List elementList) where T : LiteNetLibElement - { - if (fields == null || fields.Count == 0) - return; - - foreach (FieldInfo field in fields) - { - try - { - RegisterSyncElement((T)field.GetValue(this), elementList); - } - catch (Exception ex) - { - if (Manager.LogFatal) - Logging.LogException(LogTag, ex); - } - } - } - - private void SetupSyncFieldsWithAttribute(List fieldInfos) - { - if (fieldInfos == null || fieldInfos.Count == 0) - return; - - StringBuilder stringBuilder = new StringBuilder(); - SyncFieldAttribute tempAttribute; - LiteNetLibSyncField tempSyncField; - MethodInfo tempOnChangeMethod; - MethodInfo tempOnUpdateMethod; - foreach (FieldInfo fieldInfo in fieldInfos) - { - try - { - tempAttribute = fieldInfo.GetCustomAttribute(); - // Find on change method - tempOnChangeMethod = null; - if (!string.IsNullOrEmpty(tempAttribute.onChangeMethodName)) - { - tempOnChangeMethod = FindAndCacheMethods(stringBuilder, tempAttribute.onChangeMethodName, fieldInfo, CacheOnChangeFunctions, (tempMethodParams) => - { - return tempMethodParams != null && tempMethodParams.Length == 1 && tempMethodParams[0].ParameterType == fieldInfo.FieldType; - }); - if (tempOnChangeMethod == null) - { - if (Manager.LogError) - Logging.LogError(LogTag, "Cannot find `on change` method named [" + tempAttribute.onChangeMethodName + "] from [" + TypeName + "], FYI the function must has 1 parameter with the same type with the field."); - } - } - // Find on update method - tempOnUpdateMethod = null; - if (!string.IsNullOrEmpty(tempAttribute.onUpdateMethodName)) - { - tempOnUpdateMethod = FindAndCacheMethods(stringBuilder, tempAttribute.onUpdateMethodName, fieldInfo, CacheOnUpdateFunctions, (tempMethodParams) => - { - return tempMethodParams == null || tempMethodParams.Length == 0; - }); - if (tempOnUpdateMethod == null) - { - if (Manager.LogError) - Logging.LogError(LogTag, "Cannot find `on update` method named [" + tempAttribute.onUpdateMethodName + "] from [" + TypeName + "], FYI the function must has 0 parameter."); - } - } - // Create new sync field container - tempSyncField = new LiteNetLibSyncFieldContainer(fieldInfo, this, tempOnChangeMethod, tempOnUpdateMethod); - tempSyncField.dataChannel = tempAttribute.dataChannel; - tempSyncField.deliveryMethod = tempAttribute.deliveryMethod; - tempSyncField.clientDataChannel = tempAttribute.clientDataChannel; - tempSyncField.clientDeliveryMethod = tempAttribute.clientDeliveryMethod; - tempSyncField.sendInterval = tempAttribute.sendInterval; - tempSyncField.syncBehaviour = tempAttribute.syncBehaviour; - tempSyncField.syncMode = tempAttribute.syncMode; - RegisterSyncElement(tempSyncField, Identity.SyncFields); - } - catch (Exception ex) - { - if (Manager.LogFatal) - Logging.LogException(LogTag, ex); - } - } - } - - private MethodInfo FindAndCacheMethods(StringBuilder stringBuilder, string methodName, FieldInfo fieldInfo, Dictionary dictionary, Func parameterValidator) - { - MethodInfo tempMethod; - string key = stringBuilder.Clear().Append(TypeName).Append('.').Append(methodName).ToString(); - if (!dictionary.TryGetValue(key, out tempMethod)) - { - // Not found hook function in cache dictionary, try find the function - tempLookupType = ClassType; - while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) - { - tempLookupMethods = tempLookupType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); - foreach (MethodInfo lookupMethod in tempLookupMethods) - { - // Return type must be `void` - if (lookupMethod.ReturnType != typeof(void)) - continue; - - // Not the function it's looking for - if (!lookupMethod.Name.Equals(methodName)) - continue; - - // Parameter not match - if (!parameterValidator.Invoke(lookupMethod.GetParameters())) - continue; - - // Found the function - tempMethod = lookupMethod; - break; - } - - // Found the function so exit the loop, don't find the function in base class - if (tempMethod != null) - break; - - tempLookupType = tempLookupType.BaseType; - } - // Add to cache dictionary althrough it's empty to avoid it try to lookup next time - dictionary.Add(key, tempMethod); - } - return tempMethod; - } - - private void CacheRpcs(Dictionary ids, Dictionary cacheDict) - where RpcType : RpcAttribute - { - CacheFunctions tempCacheFunctions; - if (!cacheDict.TryGetValue(TypeName, out tempCacheFunctions)) - { - tempCacheFunctions = new CacheFunctions() - { - functions = new List(), - functionsCanCallByEveryone = new List() - }; - tempLookupNames.Clear(); - tempLookupType = ClassType; - RpcType tempAttribute; - // Find for function with [Rpc] attribute to register as RPC - while (tempLookupType != null && tempLookupType != typeof(LiteNetLibBehaviour)) - { - tempLookupMethods = tempLookupType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); - foreach (MethodInfo lookupMethod in tempLookupMethods) - { - // Avoid duplicate functions - if (tempLookupNames.Contains(lookupMethod.Name)) - continue; - - // Must have [Rpc] attribute - tempAttribute = lookupMethod.GetCustomAttribute(); - if (tempAttribute == null) - continue; - - // Return type must be `void` - if (lookupMethod.ReturnType != typeof(void)) - { - if (Manager.LogError) - Logging.LogError(LogTag, "Cannot register rpc [" + lookupMethod.Name + "] return type must be void"); - continue; - } - - if (!tempAttribute.canCallByEveryone) - tempCacheFunctions.functions.Add(lookupMethod); - else - tempCacheFunctions.functionsCanCallByEveryone.Add(lookupMethod); - tempLookupNames.Add(lookupMethod.Name); - } - tempLookupType = tempLookupType.BaseType; - } - cacheDict.Add(TypeName, tempCacheFunctions); - } - SetupRpcs(ids, tempCacheFunctions.functions, false); - SetupRpcs(ids, tempCacheFunctions.functionsCanCallByEveryone, true); - } - - private void SetupRpcs(Dictionary ids, List methodInfos, bool canCallByEveryone) - { - if (methodInfos == null || methodInfos.Count == 0) - return; - - string tempFunctionId; - Type[] tempParamTypes; - foreach (MethodInfo methodInfo in methodInfos) - { - tempFunctionId = MakeNetFunctionId(methodInfo); - if (!CacheDyncnamicFunctionTypes.TryGetValue(tempFunctionId, out tempParamTypes)) - { - tempParamTypes = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray(); - CacheDyncnamicFunctionTypes[tempFunctionId] = tempParamTypes; - } - RegisterRPC(ids, tempFunctionId, new LiteNetLibFunctionDynamic(tempParamTypes, this, methodInfo), canCallByEveryone); - } - } - - #region Sync Elements Registration - private void RegisterSyncElement(T element, List elementList) where T : LiteNetLibElement - { - int elementId = elementList.Count; - element.Setup(this, elementId); - elementList.Add(element); - } - - public void RegisterSyncField(T syncField) where T : LiteNetLibSyncField - { - RegisterSyncElement(syncField, Identity.SyncFields); - } - - public void RegisterSyncList(T syncList) where T : LiteNetLibSyncList - { - RegisterSyncElement(syncList, Identity.SyncLists); - } - #endregion - - #region RPCs Registration - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - /// - /// This is another synonym of `RegisterElasticRPC` - /// - public void RegisterNetFunction(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterElasticRPC(func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterElasticRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - RegisterRPC(allRpcIds, func, canCallByEveryone); - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterServerRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(serverRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterAllRPC(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(allRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - - public void RegisterTargetRpc(NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(targetRpcIds, func, canCallByEveryone); - } - #endregion - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, NetFunctionDelegate func, bool canCallByEveryone = false) - { - RegisterRPC(dict, MakeNetFunctionId(func.Method), new LiteNetLibFunction(func), canCallByEveryone); - } - - private void RegisterRPC(Dictionary dict, string id, LiteNetLibFunction netFunction, bool canCallByEveryone) - { - if (dict.ContainsKey(id)) - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot register rpc with existed id [" + id + "]."); - return; - } - if (Identity.NetFunctions.Count >= int.MaxValue) - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot register rpc it's exceeds limit."); - return; - } - int elementId = Identity.NetFunctions.Count; - netFunction.Setup(this, elementId); - netFunction.CanCallByEveryone = canCallByEveryone; - Identity.NetFunctions.Add(netFunction); - dict[id] = elementId; - } - - #region Elastic RPC with receivers and parameters - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers) - { - RPC(func, receivers); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1) - { - RPC(func, receivers, param1); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2) - { - RPC(func, receivers, param1, param2); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) - { - RPC(func, receivers, param1, param2, param3); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func, receivers, param1, param2, param3, param4); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func, receivers, param1, param2, param3, param4, param5); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - #region Elastic RPC with delivery method, receivers and parameters - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers) - { - RPC(func, dataChannel, deliveryMethod, receivers); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - /// - /// This is another synonym of `RPC` - /// - public void CallNetFunction(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, receivers, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - #region All RPC or Server RPC with parameters - public void RPC(NetFunctionDelegate func) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered); - } - - public void RPC(NetFunctionDelegate func, T1 param1) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, 0, DeliveryMethod.ReliableOrdered, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - #region All RPC or Server RPC with delivery method and parameters - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod) - { - RPC(func.Method.Name, dataChannel, deliveryMethod); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, byte dataChannel, DeliveryMethod deliveryMethod, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, dataChannel, deliveryMethod, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - #region Target RPC with connectionId and parameters - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId) - { - RPC(func, connectionId); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1) - { - RPC(func, connectionId, param1); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2) - { - RPC(func, connectionId, param1, param2); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3) - { - RPC(func, connectionId, param1, param2, param3); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func, connectionId, param1, param2, param3, param4); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func, connectionId, param1, param2, param3, param4, param5); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` - /// - public void CallNetFunction(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - - public void RPC(NetFunctionDelegate func, long connectionId) - { - RPC(func.Method.Name, connectionId); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1) - { - RPC(func.Method.Name, connectionId, param1); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2) - { - RPC(func.Method.Name, connectionId, param1, param2); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3) - { - RPC(func.Method.Name, connectionId, param1, param2, param3); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9); - } - - public void RPC(NetFunctionDelegate func, long connectionId, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10) - { - RPC(func.Method.Name, connectionId, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); - } - #endregion - - /// - /// This is another synonym of `RPC` which contains `receivers` and `parameters` - /// - public void CallNetFunction(string methodName, FunctionReceivers receivers, params object[] parameters) - { - RPC(methodName, receivers, parameters); - } - - /// - /// Call elastic RPC, it can be `All RPC` or `Server RPC` up to how you define `receivers` - /// - /// - /// - /// - public void RPC(string methodName, FunctionReceivers receivers, params object[] parameters) - { - RPC(methodName, 0, DeliveryMethod.ReliableOrdered, receivers, parameters); - } - - /// - /// This is another synonym of `RPC` which contains `dataChannel`, `deliveryMethod`, `receivers` and `parameters` - /// - public void CallNetFunction(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameters) - { - RPC(methodName, dataChannel, deliveryMethod, receivers, parameters); - } - - /// - /// Call elastic RPC, it can be `All RPC` or `Server RPC` up to how you define `receivers` - /// - /// - /// - /// - /// - /// - public void RPC(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameters) - { - int elementId; - switch (receivers) - { - case FunctionReceivers.All: - if (allRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, receivers, parameters); - } - else - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, any rpc [" + methodName + "] not found."); - } - break; - case FunctionReceivers.Server: - if (serverRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, receivers, parameters); - } - else - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, any rpc [" + methodName + "] not found."); - } - break; - default: - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, rpc [" + methodName + "] receives must be `All` or `Server`."); - break; - } - } - - /// - /// Call `All RPC` or `Server RPC`, if it's elastic RPC, it will call `All RPC` - /// - /// - /// - public void RPC(string methodName, params object[] parameters) - { - RPC(methodName, 0, DeliveryMethod.ReliableOrdered, parameters); - } - - /// - /// Call `All RPC` or `Server RPC`, if it's elastic RPC, it will call `All RPC` - /// - /// - /// - /// - /// - public void RPC(string methodName, byte dataChannel, DeliveryMethod deliveryMethod, params object[] parameters) - { - int elementId; - if (allRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, FunctionReceivers.All, parameters); - } - else if (serverRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(dataChannel, deliveryMethod, FunctionReceivers.Server, parameters); - } - else - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, client or server rpc [" + methodName + "] not found."); - } - } - - /// - /// This is another synonym of `RPC` which contains `connectionId` and `parameters` - /// - public void CallNetFunction(string methodName, long connectionId, params object[] parameters) - { - RPC(methodName, connectionId, parameters); - } - - /// - /// Call function at target client by connection id - /// - /// - /// - /// - public void RPC(string methodName, long connectionId, params object[] parameters) - { - int elementId; - if (targetRpcIds.TryGetValue(MakeNetFunctionId(methodName), out elementId)) - { - Identity.NetFunctions[elementId].Call(0, DeliveryMethod.ReliableOrdered, connectionId, parameters); - } - else - { - if (Manager.LogError) - Logging.LogError(LogTag, "[" + TypeName + "] cannot call rpc, target rpc [" + methodName + "] not found."); - } - } - - private string MakeNetFunctionId(MethodInfo methodInfo) - { - return MakeNetFunctionId(methodInfo.Name); - } - - private string MakeNetFunctionId(string methodName) - { - return new StringBuilder(TypeName).Append('+').Append(methodName).ToString(); - } - - public void Serialize(NetDataWriter writer) - { - if (!IsServer) - return; - - writer.PutPackedUInt(Identity.ObjectId); - writer.Put(BehaviourIndex); - OnSerialize(writer); - } - - public void Deserialize(NetDataReader reader) - { - OnDeserialize(reader); - } - - public void SetOwnerClient(long connectionId) - { - Identity.SetOwnerClient(connectionId); - } - - public void NetworkDestroy() - { - Identity.NetworkDestroy(); - } - - public void NetworkDestroy(float delay) - { - Identity.NetworkDestroy(delay); - } - - public void ClientSendMessage(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsClient) - return; - Manager.ClientSendMessage(dataChannel, deliveryMethod, writer); - } - - public void ClientSendPacket(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) - { - if (!IsClient) - return; - Manager.ClientSendPacket(dataChannel, deliveryMethod, msgType, serializerDelegate); - } - - public void ServerSendMessage(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsServer) - return; - Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, writer); - } - - public void ServerSendPacket(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) - { - if (!IsServer) - return; - Manager.ServerSendPacket(connectionId, dataChannel, deliveryMethod, msgType, serializerDelegate); - } - - public void ServerSendMessageToAllConnections(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsServer) - return; - Manager.ServerSendMessageToAllConnections(dataChannel, deliveryMethod, writer); - } - - public void ServerSendPacketToAllConnections(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) - { - if (!IsServer) - return; - Manager.ServerSendPacketToAllConnections(dataChannel, deliveryMethod, msgType, serializerDelegate); - } - - public void ServerSendMessageToSubscribers(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsServer) - return; - foreach (long connectionId in Manager.GetConnectionIds()) - { - if (Identity.HasSubscriber(connectionId)) - Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, writer); - } - } - - public void ServerSendPacketToSubscribers(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializerDelegate) - { - if (!IsServer) - return; - TransportHandler.WritePacket(Manager.Server.Writer, msgType, serializerDelegate); - foreach (long connectionId in Manager.GetConnectionIds()) - { - if (Identity.HasSubscriber(connectionId)) - Manager.ServerSendMessage(connectionId, dataChannel, deliveryMethod, Manager.Server.Writer); - } - } - - /// - /// This function will be called when this behaviour spawned at server - /// - public virtual void OnStartServer() { } - - /// - /// This function will be called when this behaviour spawned at client (all client types `non-owner and owner`) - /// - public virtual void OnStartClient() { } - - /// - /// This function will be called when this behaviour spawned at owner-client - /// - public virtual void OnStartOwnerClient() { } - - /// - /// This function will be called when this client has been verified as owner client - /// - public virtual void OnSetOwnerClient(bool isOwnerClient) { } - - /// - /// This function will be called when this client receive spawn object message with position and rotation - /// - /// - /// - public virtual void InitTransform(Vector3 position, Quaternion rotation) { } - - /// - /// This function will be called when object destroy from server - /// - /// - public virtual void OnNetworkDestroy(byte reasons) { } - - /// - /// This function will be called when this behaviour have been setup by identity - /// You may do some initialize things within this function - /// - public virtual void OnSetup() { } - - /// - /// Override this function to define condition to sync behaviour data to client or not - /// - /// - public virtual bool CanSyncBehaviour() - { - return false; - } - - /// - /// Override this function to define condition to sync behaviour data to client when it should - /// - /// - public virtual bool ShouldSyncBehaviour() - { - return false; - } - - /// - /// Override this function to write custom data to send from server to client - /// - public virtual void OnSerialize(NetDataWriter writer) { } - - /// - /// Override this function to read data from server at client - /// - public virtual void OnDeserialize(NetDataReader reader) { } - - /// - /// Override this function to change object visibility when this added to player as subcribing - /// - public virtual void OnServerSubscribingAdded() { } - - /// - /// Override this function to change object visibility when this removed from player as subcribing - /// - public virtual void OnServerSubscribingRemoved() { } - } -} diff --git a/Scripts/LiteNetLibBehaviour.cs.meta b/Scripts/LiteNetLibBehaviour.cs.meta deleted file mode 100644 index 8f77957a..00000000 --- a/Scripts/LiteNetLibBehaviour.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 1e3668c0fbd3f354489edb3a96824749 -timeCreated: 1508753155 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibElement.cs b/Scripts/LiteNetLibElement.cs deleted file mode 100644 index 91d847d5..00000000 --- a/Scripts/LiteNetLibElement.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct LiteNetLibElementInfo - { - public uint objectId; - public int elementId; - public LiteNetLibElementInfo(uint objectId, int elementId) - { - this.objectId = objectId; - this.elementId = elementId; - } - - public static void SerializeInfo(LiteNetLibElementInfo info, NetDataWriter writer) - { - writer.PutPackedUInt(info.objectId); - writer.PutPackedUInt((uint)info.elementId); - } - - public static LiteNetLibElementInfo DeserializeInfo(NetDataReader reader) - { - return new LiteNetLibElementInfo(reader.GetPackedUInt(), (int)reader.GetPackedUInt()); - } - } - - public abstract class LiteNetLibElement - { - [ReadOnly, SerializeField] - protected LiteNetLibBehaviour behaviour; - public LiteNetLibBehaviour Behaviour - { - get { return behaviour; } - } - - public LiteNetLibIdentity Identity - { - get { return Behaviour.Identity; } - } - - public long ConnectionId - { - get { return !IsSetup ? -1 : Behaviour.ConnectionId; } - } - - public uint ObjectId - { - get { return !IsSetup ? 0 : Behaviour.ObjectId; } - } - - public LiteNetLibGameManager Manager - { - get { return Behaviour.Manager; } - } - - public virtual string LogTag - { - get { return (!IsSetup ? "(No Behaviour)" : Behaviour.LogTag) + "->" + ToString(); } - } - - public bool IsServer - { - get { return IsSetup && Behaviour.IsServer; } - } - - public bool IsClient - { - get { return IsSetup && Behaviour.IsClient; } - } - - public bool IsOwnerClient - { - get { return IsSetup && Behaviour.IsOwnerClient; } - } - - public bool IsSetup { get; private set; } - - [ReadOnly, SerializeField] - protected int elementId; - public int ElementId - { - get { return elementId; } - } - - public LiteNetLibElementInfo GetInfo() - { - return new LiteNetLibElementInfo(Behaviour.ObjectId, ElementId); - } - - internal virtual void Setup(LiteNetLibBehaviour behaviour, int elementId) - { - this.behaviour = behaviour; - this.elementId = elementId; - IsSetup = true; - } - - protected virtual bool CanSync() - { - return IsSetup; - } - } -} diff --git a/Scripts/LiteNetLibElement.cs.meta b/Scripts/LiteNetLibElement.cs.meta deleted file mode 100644 index 92395850..00000000 --- a/Scripts/LiteNetLibElement.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 6ef4e992e48d90a45ae6c3958a7df40d -timeCreated: 1511719678 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibFunction.cs b/Scripts/LiteNetLibFunction.cs deleted file mode 100644 index 4c86bd51..00000000 --- a/Scripts/LiteNetLibFunction.cs +++ /dev/null @@ -1,471 +0,0 @@ -using System; -using System.Reflection; -using LiteNetLib; -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public enum FunctionReceivers : byte - { - Target, - All, - Server, - } - - public class LiteNetLibFunction : LiteNetLibElement - { - protected readonly static NetDataWriter ServerWriter = new NetDataWriter(); - protected readonly static NetDataWriter ClientWriter = new NetDataWriter(); - - public readonly Type[] ParameterTypes; - public readonly object[] Parameters; - public bool CanCallByEveryone { get; set; } - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : this(0) - { - } - - protected LiteNetLibFunction(int parameterCount) - { - Parameters = new object[parameterCount]; - ParameterTypes = new Type[parameterCount]; - } - - protected LiteNetLibFunction(Type[] parameterTypes) - { - Parameters = new object[parameterTypes.Length]; - ParameterTypes = parameterTypes; - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - protected override bool CanSync() - { - return Behaviour != null && (IsServer || IsOwnerClient || CanCallByEveryone); - } - - internal virtual void HookCallback() - { - callback.Invoke(); - } - - protected void SendCall(byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, long targetConnectionId) - { - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - LiteNetLibClient client = manager.Client; - if (manager.IsServer) - { - switch (receivers) - { - case FunctionReceivers.Target: - if (Identity.HasSubscriberOrIsOwning(targetConnectionId) && manager.ContainsConnectionId(targetConnectionId)) - { - // Prepare packet - TransportHandler.WritePacket(ServerWriter, GameMsgTypes.CallFunction); - SerializeForSend(ServerWriter); - // Send function call message from server to target client by target connection Id - server.SendMessage(targetConnectionId, dataChannel, deliveryMethod, ServerWriter); - } - break; - case FunctionReceivers.All: - // Send to all connections - foreach (long connectionId in manager.GetConnectionIds()) - { - if (manager.ClientConnectionId == connectionId) - { - // This is host's networking oject, so hook callback immediately - // Don't have to send message to the client, because it is currently run as both server and client - HookCallback(); - } - else if (Identity.HasSubscriberOrIsOwning(connectionId)) - { - // Prepare packet - TransportHandler.WritePacket(ServerWriter, GameMsgTypes.CallFunction); - SerializeForSend(ServerWriter); - // Send message to subscribing clients - server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); - } - } - if (!manager.IsClientConnected) - { - // It's not a host(client+host), it's just a server - // So hook callback immediately to do the function at server - HookCallback(); - } - break; - case FunctionReceivers.Server: - // Call server function at server - // So hook callback immediately to do the function at server - HookCallback(); - break; - } - } - else if (manager.IsClientConnected) - { - // Prepare packet - TransportHandler.WritePacket(ClientWriter, GameMsgTypes.CallFunction); - SerializeForClientSend(ClientWriter, receivers, targetConnectionId); - // Client send net function call to server - // Then the server will hook callback or forward message to other clients - client.SendMessage(dataChannel, deliveryMethod, ClientWriter); - } - } - - internal void SetParameters(params object[] parameterValues) - { - for (int i = 0; i < Parameters.Length; ++i) - { - if (i >= parameterValues.Length) - break; - Parameters[i] = parameterValues[i]; - } - } - - internal void Call(byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, params object[] parameterValues) - { - if (!CanSync()) - return; - - SetParameters(parameterValues); - SendCall(dataChannel, deliveryMethod, receivers, ConnectionId); - } - - internal void Call(byte dataChannel, DeliveryMethod deliveryMethod, long connectionId, params object[] parameterValues) - { - if (!CanSync()) - return; - - SetParameters(parameterValues); - SendCall(dataChannel, deliveryMethod, FunctionReceivers.Target, connectionId); - } - - internal void CallWithoutParametersSet(FunctionReceivers receivers) - { - if (!CanSync()) - return; - - SendCall(0, DeliveryMethod.ReliableOrdered, receivers, ConnectionId); - } - - internal void CallWithoutParametersSet(long connectionId) - { - if (!CanSync()) - return; - - SendCall(0, DeliveryMethod.ReliableOrdered, FunctionReceivers.Target, connectionId); - } - - private void SerializeForClientSend(NetDataWriter writer, FunctionReceivers receivers, long connectionId) - { - writer.Put((byte)receivers); - if (receivers == FunctionReceivers.Target) - writer.PutPackedLong(connectionId); - SerializeForSend(writer); - } - - private void SerializeForSend(NetDataWriter writer) - { - LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); - SerializeParameters(writer); - } - - public void DeserializeParameters(NetDataReader reader) - { - if (Parameters == null || Parameters.Length == 0) - return; - for (int i = 0; i < Parameters.Length; ++i) - { - if (ParameterTypes[i].IsArray) - Parameters[i] = reader.GetArray(ParameterTypes[i].GetElementType()); - else - Parameters[i] = reader.GetValue(ParameterTypes[i]); - } - } - - public void SerializeParameters(NetDataWriter writer) - { - if (Parameters == null || Parameters.Length == 0) - return; - for (int i = 0; i < Parameters.Length; ++i) - { - if (ParameterTypes[i].IsArray) - writer.PutArray(ParameterTypes[i].GetElementType(), Parameters[i]); - else - writer.PutValue(ParameterTypes[i], Parameters[i]); - } - } - } - - #region Implement for multiple parameter usages - public class LiteNetLibFunctionDynamic : LiteNetLibFunction - { - /// - /// The class which contain the function - /// - private object instance; - - private MethodInfo callback; - - public LiteNetLibFunctionDynamic(Type[] parameterTypes, object instance, MethodInfo callback) : base(parameterTypes) - { - this.instance = instance; - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback.Invoke(instance, Parameters); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(1) - { - ParameterTypes[0] = typeof(T1); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(2) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(3) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(4) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(5) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(6) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(7) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - ParameterTypes[6] = typeof(T7); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(8) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - ParameterTypes[6] = typeof(T7); - ParameterTypes[7] = typeof(T8); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(9) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - ParameterTypes[6] = typeof(T7); - ParameterTypes[7] = typeof(T8); - ParameterTypes[8] = typeof(T9); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7], (T9)Parameters[8]); - } - } - - public class LiteNetLibFunction : LiteNetLibFunction - { - private NetFunctionDelegate callback; - - protected LiteNetLibFunction() : base(10) - { - ParameterTypes[0] = typeof(T1); - ParameterTypes[1] = typeof(T2); - ParameterTypes[2] = typeof(T3); - ParameterTypes[3] = typeof(T4); - ParameterTypes[4] = typeof(T5); - ParameterTypes[5] = typeof(T6); - ParameterTypes[6] = typeof(T7); - ParameterTypes[7] = typeof(T8); - ParameterTypes[8] = typeof(T9); - ParameterTypes[9] = typeof(T10); - } - - public LiteNetLibFunction(NetFunctionDelegate callback) : this() - { - this.callback = callback; - } - - internal override sealed void HookCallback() - { - callback((T1)Parameters[0], (T2)Parameters[1], (T3)Parameters[2], (T4)Parameters[3], (T5)Parameters[4], (T6)Parameters[5], (T7)Parameters[6], (T8)Parameters[7], (T9)Parameters[8], (T10)Parameters[9]); - } - } - #endregion -} diff --git a/Scripts/LiteNetLibFunction.cs.meta b/Scripts/LiteNetLibFunction.cs.meta deleted file mode 100644 index d95ea24a..00000000 --- a/Scripts/LiteNetLibFunction.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 2fd014728a1d38448952ac768473cb6e -timeCreated: 1509024653 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibGameManager.cs b/Scripts/LiteNetLibGameManager.cs deleted file mode 100644 index 887e27cc..00000000 --- a/Scripts/LiteNetLibGameManager.cs +++ /dev/null @@ -1,1049 +0,0 @@ -using UnityEngine; -using UnityEngine.SceneManagement; -using LiteNetLib; -using LiteNetLib.Utils; -using Cysharp.Threading.Tasks; -using System.Collections.Generic; -using System.Net.Sockets; - -namespace LiteNetLibManager -{ - [RequireComponent(typeof(LiteNetLibAssets))] - public class LiteNetLibGameManager : LiteNetLibManager - { - [Header("Game manager configs")] - public uint packetVersion = 1; - public float pingDuration = 1f; - public bool doNotEnterGameOnConnect; - public bool doNotDestroyOnSceneChanges; - - protected readonly Dictionary Players = new Dictionary(); - - private float _clientSendPingCountDown; - private float _serverSendPingCountDown; - private AsyncOperation _loadSceneAsyncOperation; - - public long ClientConnectionId { get; protected set; } - private long _rtt; - public long Rtt - { - get - { - if (IsServer) - return 0; - return _rtt; - } - } - private long _lastPingTime; - private long _totalRtt; - private int _rttCount; - public long Timestamp { get { return System.DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } } - /// - /// Unix timestamp (milliseconds) offsets from server - /// - public long ServerTimestampOffsets { get; protected set; } - /// - /// Server unix timestamp (milliseconds) - /// - public long ServerTimestamp - { - get - { - if (IsServer) - return Timestamp; - return Timestamp + ServerTimestampOffsets; - } - } - public string ServerSceneName { get; protected set; } - public LiteNetLibAssets Assets { get; protected set; } - public BaseInterestManager InterestManager { get; protected set; } - - protected virtual void Awake() - { - Assets = GetComponent(); - InterestManager = GetComponent(); - if (InterestManager == null) - InterestManager = gameObject.AddComponent(); - ServerSceneName = string.Empty; - if (doNotDestroyOnSceneChanges) - DontDestroyOnLoad(gameObject); - } - - protected override void FixedUpdate() - { - if (_loadSceneAsyncOperation == null) - { - if (IsClientConnected) - { - // Send ping from client - _clientSendPingCountDown -= Time.fixedDeltaTime; - if (_clientSendPingCountDown <= 0f) - { - SendClientPing(); - _clientSendPingCountDown = pingDuration; - } - } - if (IsServer) - { - // Send ping from server - _serverSendPingCountDown -= Time.fixedDeltaTime; - if (_serverSendPingCountDown <= 0f) - { - SendServerPing(); - _serverSendPingCountDown = pingDuration; - } - } - } - base.FixedUpdate(); - } - - public virtual uint PacketVersion() - { - return packetVersion; - } - - public bool TryGetPlayer(long connectionId, out LiteNetLibPlayer player) - { - return Players.TryGetValue(connectionId, out player); - } - - public bool ContainsPlayer(long connectionId) - { - return Players.ContainsKey(connectionId); - } - - public LiteNetLibPlayer GetPlayer(long connectionId) - { - return Players[connectionId]; - } - - public IEnumerable GetPlayers() - { - return Players.Values; - } - - public int PlayersCount - { - get { return Players.Count; } - } - - /// - /// Call this function to change gameplay scene at server, then the server will tell clients to change scene - /// - /// - public virtual void ServerSceneChange(string sceneName) - { - if (!IsServer) - return; - LoadSceneRoutine(sceneName, true).Forget(); - } - - /// - /// This function will be called to load scene async - /// - /// - /// - /// - private async UniTaskVoid LoadSceneRoutine(string sceneName, bool online) - { - if (_loadSceneAsyncOperation == null) - { - // If doNotDestroyOnSceneChanges not TRUE still not destroy this game object - // But it will be destroyed after scene loaded, if scene is offline scene - if (!doNotDestroyOnSceneChanges) - DontDestroyOnLoad(gameObject); - - if (online) - { - foreach (LiteNetLibPlayer player in Players.Values) - { - player.IsReady = false; - player.Subscribings.Clear(); - player.SpawnedObjects.Clear(); - } - Assets.Clear(true); - } - - if (LogDev) Logging.Log(LogTag, "Loading Scene: " + sceneName + " is online: " + online); - if (Assets.onLoadSceneStart != null) - Assets.onLoadSceneStart.Invoke(sceneName, online, 0f); - - _loadSceneAsyncOperation = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single); - while (_loadSceneAsyncOperation != null && !_loadSceneAsyncOperation.isDone) - { - if (Assets.onLoadSceneProgress != null) - Assets.onLoadSceneProgress.Invoke(sceneName, online, _loadSceneAsyncOperation.progress); - await UniTask.Yield(); - } - _loadSceneAsyncOperation = null; - - if (online) - { - Assets.Initialize(); - Assets.InitPoolingObjects(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> Assets.Initialize()"); - if (IsClient) - { - // If it is host (both client and server) wait for client connection id before proceed server scene load - while (ClientConnectionId < 0) await UniTask.Yield(); - } - if (IsServer) - { - ServerSceneName = sceneName; - Assets.SpawnSceneObjects(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> Assets.SpawnSceneObjects()"); - OnServerOnlineSceneLoaded(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> OnServerOnlineSceneLoaded()"); - SendServerSceneChange(sceneName); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> SendServerSceneChange()"); - } - if (IsClient) - { - OnClientOnlineSceneLoaded(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> OnClientOnlineSceneLoaded()"); - SendClientReady(); - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " -> SendClientReady()"); - } - } - else if (!doNotDestroyOnSceneChanges) - { - // Destroy manager's game object if loaded scene is not online scene - Destroy(gameObject); - } - - if (LogDev) Logging.Log(LogTag, "Loaded Scene: " + sceneName + " is online: " + online); - if (Assets.onLoadSceneFinish != null) - Assets.onLoadSceneFinish.Invoke(sceneName, online, 1f); - } - } - - protected override void RegisterMessages() - { - EnableRequestResponse(GameMsgTypes.Request, GameMsgTypes.Response); - // Request to server (response to client) - RegisterRequestToServer(GameReqTypes.EnterGame, HandleEnterGameRequest, HandleEnterGameResponse); - RegisterRequestToServer(GameReqTypes.ClientReady, HandleClientReadyRequest, HandleClientReadyResponse); - RegisterRequestToServer(GameReqTypes.ClientNotReady, HandleClientNotReadyRequest, HandleClientNotReadyResponse); - // Server messages - RegisterServerMessage(GameMsgTypes.CallFunction, HandleClientCallFunction); - RegisterServerMessage(GameMsgTypes.UpdateSyncField, HandleClientUpdateSyncField); - RegisterServerMessage(GameMsgTypes.InitialSyncField, HandleClientInitialSyncField); - RegisterServerMessage(GameMsgTypes.ClientSendTransform, HandleClientSendTransform); - RegisterServerMessage(GameMsgTypes.Ping, HandleClientPing); - RegisterServerMessage(GameMsgTypes.Pong, HandleClientPong); - // Client messages - RegisterClientMessage(GameMsgTypes.ServerSpawnSceneObject, HandleServerSpawnSceneObject); - RegisterClientMessage(GameMsgTypes.ServerSpawnObject, HandleServerSpawnObject); - RegisterClientMessage(GameMsgTypes.ServerDestroyObject, HandleServerDestroyObject); - RegisterClientMessage(GameMsgTypes.CallFunction, HandleServerCallFunction); - RegisterClientMessage(GameMsgTypes.UpdateSyncField, HandleServerUpdateSyncField); - RegisterClientMessage(GameMsgTypes.InitialSyncField, HandleServerInitialSyncField); - RegisterClientMessage(GameMsgTypes.OperateSyncList, HandleServerUpdateSyncList); - RegisterClientMessage(GameMsgTypes.ServerSyncBehaviour, HandleServerSyncBehaviour); - RegisterClientMessage(GameMsgTypes.ServerError, HandleServerError); - RegisterClientMessage(GameMsgTypes.ServerSceneChange, HandleServerSceneChange); - RegisterClientMessage(GameMsgTypes.ServerSetObjectOwner, HandleServerSetObjectOwner); - RegisterClientMessage(GameMsgTypes.Ping, HandleServerPing); - RegisterClientMessage(GameMsgTypes.Pong, HandleServerPong); - RegisterClientMessage(GameMsgTypes.Disconnect, HandleServerDisconnect); - } - - public async void KickClient(long connectionId, byte[] data) - { - if (!IsServer) - return; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.Disconnect, (writer) => writer.PutBytesWithLength(data)); - await UniTask.Delay(500); - ServerTransport.ServerDisconnect(connectionId); - } - - public void ResetRtt() - { - _rtt = 0; - _totalRtt = 0; - _rttCount = 0; - } - - public override void OnPeerConnected(long connectionId) - { - base.OnPeerConnected(connectionId); - if (!Players.ContainsKey(connectionId)) - Players.Add(connectionId, new LiteNetLibPlayer(this, connectionId)); - } - - public override void OnPeerDisconnected(long connectionId, DisconnectReason reason, SocketError socketError) - { - base.OnPeerDisconnected(connectionId, reason, socketError); - if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player)) - return; - player.ClearSubscribing(false); - player.DestroyObjectsWhenDisconnect(); - Players.Remove(connectionId); - } - - public override void OnClientConnected() - { - base.OnClientConnected(); - // Reset client connection id, will be received from server later - ClientConnectionId = -1; - ResetRtt(); - if (!doNotEnterGameOnConnect) - SendClientEnterGame(); - } - - public override void OnStartServer() - { - base.OnStartServer(); - // Reset client connection id, will be received from server later - ClientConnectionId = -1; - ResetRtt(); - if (!Assets.onlineScene.IsSet() || Assets.onlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) - { - ServerSceneName = SceneManager.GetActiveScene().name; - Assets.Initialize(); - Assets.SpawnSceneObjects(); - Assets.InitPoolingObjects(); - OnServerOnlineSceneLoaded(); - } - else - { - ServerSceneName = Assets.onlineScene.SceneName; - LoadSceneRoutine(Assets.onlineScene.SceneName, true).Forget(); - } - } - - public override void OnStopServer() - { - base.OnStopServer(); - ServerSceneName = string.Empty; - Players.Clear(); - Assets.Clear(); - if (Assets.offlineScene.IsSet() && !Assets.offlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) - LoadSceneRoutine(Assets.offlineScene.SceneName, false).Forget(); - } - - public override void OnStopClient() - { - base.OnStopClient(); - if (!IsServer) - { - Players.Clear(); - Assets.Clear(); - if (Assets.offlineScene.IsSet() && !Assets.offlineScene.SceneName.Equals(SceneManager.GetActiveScene().name)) - LoadSceneRoutine(Assets.offlineScene.SceneName, false).Forget(); - } - } - - #region Send messages functions - public void SendClientEnterGame() - { - if (!IsClientConnected) - return; - ClientSendRequest(GameReqTypes.EnterGame, new EnterGameRequestMessage() - { - packetVersion = PacketVersion(), - }, extraRequestSerializer: SerializeEnterGameData); - } - - public void SendClientReady() - { - if (!IsClientConnected) - return; - ClientSendRequest(GameReqTypes.ClientReady, EmptyMessage.Value, extraRequestSerializer: SerializeClientReadyData); - } - - public void SendClientNotReady() - { - if (!IsClientConnected) - return; - ClientSendRequest(GameReqTypes.ClientNotReady, EmptyMessage.Value); - } - - public void SendClientPing() - { - if (!IsClientConnected) - return; - ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.Ping, new PingMessage() - { - pingTime = Timestamp, - }); - } - - public void SendServerPing() - { - if (!IsServer) - return; - ServerSendPacketToAllConnections(0, DeliveryMethod.Unreliable, GameMsgTypes.Ping, new PingMessage() - { - pingTime = Timestamp, - }); - } - - public bool SendServerSpawnSceneObject(long connectionId, LiteNetLibIdentity identity) - { - if (!IsServer) - return false; - LiteNetLibPlayer player; - if (!Players.TryGetValue(connectionId, out player) || !player.IsReady) - return false; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSpawnSceneObject, new ServerSpawnSceneObjectMessage() - { - objectId = identity.ObjectId, - connectionId = identity.ConnectionId, - position = identity.transform.position, - rotation = identity.transform.rotation, - }, identity.WriteInitSyncFields); - return true; - } - - public bool SendServerSpawnObject(long connectionId, LiteNetLibIdentity identity) - { - if (!IsServer) - return false; - LiteNetLibPlayer player; - if (!Players.TryGetValue(connectionId, out player) || !player.IsReady) - return false; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSpawnObject, new ServerSpawnObjectMessage() - { - hashAssetId = identity.HashAssetId, - objectId = identity.ObjectId, - connectionId = identity.ConnectionId, - position = identity.transform.position, - rotation = identity.transform.rotation, - }, identity.WriteInitSyncFields); - return true; - } - - public void SendServerSpawnObjectWithData(long connectionId, LiteNetLibIdentity identity) - { - if (identity == null) - return; - - bool spawnObjectSent; - if (Assets.ContainsSceneObject(identity.ObjectId)) - spawnObjectSent = SendServerSpawnSceneObject(connectionId, identity); - else - spawnObjectSent = SendServerSpawnObject(connectionId, identity); - if (spawnObjectSent) - { - identity.SendInitSyncFields(connectionId); - identity.SendInitSyncLists(connectionId); - } - } - - public bool SendServerDestroyObject(long connectionId, uint objectId, byte reasons) - { - if (!IsServer) - return false; - if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player) || !player.IsReady) - return false; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerDestroyObject, new ServerDestroyObjectMessage() - { - objectId = objectId, - reasons = reasons, - }); - return true; - } - - public void SendServerError(bool shouldDisconnect, string errorMessage) - { - if (!IsServer) - return; - foreach (long connectionId in Server.ConnectionIds) - { - SendServerError(connectionId, shouldDisconnect, errorMessage); - } - } - - public void SendServerError(long connectionId, bool shouldDisconnect, string errorMessage) - { - if (!IsServer) - return; - if (!Players.TryGetValue(connectionId, out LiteNetLibPlayer player) || !player.IsReady) - return; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerDestroyObject, new ServerErrorMessage() - { - shouldDisconnect = shouldDisconnect, - errorMessage = errorMessage, - }); - } - - public void SendServerSceneChange(string sceneName) - { - if (!IsServer) - return; - foreach (long connectionId in Server.ConnectionIds) - { - if (IsClientConnected && connectionId == ClientConnectionId) - continue; - SendServerSceneChange(connectionId, sceneName); - } - } - - public void SendServerSceneChange(long connectionId, string sceneName) - { - if (!IsServer) - return; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSceneChange, new ServerSceneChangeMessage() - { - serverSceneName = sceneName, - }); - } - - public void SendServerSetObjectOwner(long connectionId, uint objectId, long ownerConnectionId) - { - if (!IsServer) - return; - ServerSendPacket(connectionId, 0, DeliveryMethod.ReliableOrdered, GameMsgTypes.ServerSetObjectOwner, new ServerSetObjectOwner() - { - objectId = objectId, - connectionId = ownerConnectionId, - }); - } - #endregion - - #region Message Handlers - - protected virtual async UniTaskVoid HandleEnterGameRequest( - RequestHandlerData requestHandler, - EnterGameRequestMessage request, - RequestProceedResultDelegate result) - { - AckResponseCode responseCode = AckResponseCode.Error; - EnterGameResponseMessage response = new EnterGameResponseMessage(); - if (request.packetVersion == PacketVersion() && - await DeserializeEnterGameData(requestHandler.ConnectionId, requestHandler.Reader)) - { - responseCode = AckResponseCode.Success; - response.connectionId = requestHandler.ConnectionId; - response.serverSceneName = ServerSceneName; - } - result.Invoke(responseCode, response); - } - - protected virtual void HandleEnterGameResponse( - ResponseHandlerData responseHandler, - AckResponseCode responseCode, - EnterGameResponseMessage response) - { - if (responseCode == AckResponseCode.Success) - { - ClientConnectionId = response.connectionId; - if (IsClientConnected) - HandleServerSceneChange(response.serverSceneName); - } - else - { - if (LogError) Logging.LogError(LogTag, "Enter game request was refused by server, disconnecting..."); - OnClientConnectionRefused(); - } - } - - protected virtual async UniTaskVoid HandleClientReadyRequest( - RequestHandlerData requestHandler, - EmptyMessage request, - RequestProceedResultDelegate result) - { - AckResponseCode responseCode = AckResponseCode.Error; - if (await SetPlayerReady(requestHandler.ConnectionId, requestHandler.Reader)) - { - responseCode = AckResponseCode.Success; - } - result.Invoke(responseCode, EmptyMessage.Value); - } - - protected virtual void HandleClientReadyResponse( - ResponseHandlerData responseHandler, - AckResponseCode responseCode, - EmptyMessage response) - { - // Override this function to do something by response code - } - - protected virtual UniTaskVoid HandleClientNotReadyRequest( - RequestHandlerData requestHandler, - EmptyMessage request, - RequestProceedResultDelegate result) - { - AckResponseCode responseCode = AckResponseCode.Error; - if (SetPlayerNotReady(requestHandler.ConnectionId, requestHandler.Reader)) - { - responseCode = AckResponseCode.Success; - } - result.Invoke(responseCode, EmptyMessage.Value); - return default; - } - - protected void HandleClientNotReadyResponse( - ResponseHandlerData responseHandler, - AckResponseCode responseCode, - EmptyMessage response) - { - // Override this function to do something by response code - } - - protected virtual void HandleClientInitialSyncField(MessageHandlerData messageHandler) - { - // Field updated at owner-client, if this is server then multicast message to other clients - if (!IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - { - LiteNetLibSyncField syncField = identity.GetSyncField(info); - // Sync field at server also have to be client multicast to allow it to multicast to other clients - if (syncField != null && syncField.syncMode == LiteNetLibSyncField.SyncMode.ClientMulticast) - { - // If this is server but it is not host, set data (deserialize) then pass to other clients - // If this is host don't set data because it's already did (in LiteNetLibSyncField class) - if (!identity.IsOwnerClient) - syncField.Deserialize(messageHandler.Reader, true); - // Send to other clients - foreach (long connectionId in Server.ConnectionIds) - { - // Don't send the update to owner client because it was updated before send update to server - if (connectionId == messageHandler.ConnectionId) - continue; - // Send update to clients except owner client - if (identity.HasSubscriberOrIsOwning(connectionId)) - syncField.SendUpdate(true, connectionId); - } - } - } - } - - protected virtual void HandleClientUpdateSyncField(MessageHandlerData messageHandler) - { - // Field updated at owner-client, if this is server then multicast message to other clients - if (!IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - { - LiteNetLibSyncField syncField = identity.GetSyncField(info); - // Sync field at server also have to be client multicast to allow it to multicast to other clients - if (syncField != null && syncField.syncMode == LiteNetLibSyncField.SyncMode.ClientMulticast) - { - // If this is server but it is not host, set data (deserialize) then pass to other clients - // If this is host don't set data because it's already did (in LiteNetLibSyncField class) - if (!identity.IsOwnerClient) - syncField.Deserialize(messageHandler.Reader, false); - // Send to other clients - foreach (long connectionId in Server.ConnectionIds) - { - // Don't send the update to owner client because it was updated before send update to server - if (connectionId == messageHandler.ConnectionId) - continue; - // Send update to clients except owner client - if (identity.HasSubscriberOrIsOwning(connectionId)) - syncField.SendUpdate(false, connectionId); - } - } - } - } - - protected virtual void HandleClientCallFunction(MessageHandlerData messageHandler) - { - FunctionReceivers receivers = (FunctionReceivers)messageHandler.Reader.GetByte(); - long connectionId = -1; - if (receivers == FunctionReceivers.Target) - connectionId = messageHandler.Reader.GetPackedLong(); - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - { - LiteNetLibFunction netFunction = identity.GetNetFunction(info); - if (netFunction == null) - { - // There is no net function that player try to call (player may try to hack) - return; - } - if (!netFunction.CanCallByEveryone && messageHandler.ConnectionId != identity.ConnectionId) - { - // The function not allowed anyone except owner client to call this net function - // And the client is also not the owner client - return; - } - if (receivers == FunctionReceivers.Server) - { - // Request from client to server, so hook callback at server immediately - identity.ProcessNetFunction(netFunction, messageHandler.Reader, true); - } - else - { - // Request from client to other clients, so hook callback later - identity.ProcessNetFunction(netFunction, messageHandler.Reader, false); - // Use call with out parameters set because parameters already set while process net function - if (receivers == FunctionReceivers.Target) - netFunction.CallWithoutParametersSet(connectionId); - else - netFunction.CallWithoutParametersSet(receivers); - } - } - } - - protected virtual void HandleClientSendTransform(MessageHandlerData messageHandler) - { - uint objectId = messageHandler.Reader.GetPackedUInt(); - byte behaviourIndex = messageHandler.Reader.GetByte(); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(objectId, out identity)) - { - LiteNetLibTransform netTransform; - if (identity.TryGetBehaviour(behaviourIndex, out netTransform)) - netTransform.HandleClientSendTransform(messageHandler.Reader); - } - } - - protected void HandleClientPing(MessageHandlerData messageHandler) - { - PingMessage message = messageHandler.ReadMessage(); - ServerSendPacket(messageHandler.ConnectionId, 0, DeliveryMethod.Unreliable, GameMsgTypes.Pong, new PongMessage() - { - pingTime = message.pingTime, - serverTime = Timestamp, - }); - } - - protected void HandleClientPong(MessageHandlerData messageHandler) - { - if (!Players.TryGetValue(messageHandler.ConnectionId, out LiteNetLibPlayer player)) - return; - PongMessage message = messageHandler.ReadMessage(); - if (player.LastPingTime < message.pingTime) - { - player.LastPingTime = message.pingTime; - long rtt = Timestamp - message.pingTime; - if (player.RttCount > 10) - { - player.TotalRtt = player.Rtt; - player.RttCount = 1; - } - player.TotalRtt += rtt; - player.RttCount++; - player.Rtt = player.TotalRtt / player.RttCount; - } - } - - protected virtual void HandleServerSpawnSceneObject(MessageHandlerData messageHandler) - { - ServerSpawnSceneObjectMessage message = messageHandler.ReadMessage(); - if (!IsServer) - Assets.NetworkSpawnScene(message.objectId, message.position, message.rotation, message.connectionId); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(message.objectId, out identity)) - { - // If it is not server, read its initial data - if (!IsServer) - { - identity.ResetSyncData(); - identity.ReadInitSyncFields(messageHandler.Reader); - } - // If it is host, it may hidden so show it - if (IsServer) - identity.OnServerSubscribingAdded(); - } - } - - protected virtual void HandleServerSpawnObject(MessageHandlerData messageHandler) - { - ServerSpawnObjectMessage message = messageHandler.ReadMessage(); - if (!IsServer) - Assets.NetworkSpawn(message.hashAssetId, message.position, message.rotation, message.objectId, message.connectionId); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(message.objectId, out identity)) - { - // If it is not server, read its initial data - if (!IsServer) - identity.ReadInitSyncFields(messageHandler.Reader); - // If it is host, it may hidden so show it - if (IsServer) - identity.OnServerSubscribingAdded(); - } - } - - protected virtual void HandleServerDestroyObject(MessageHandlerData messageHandler) - { - ServerDestroyObjectMessage message = messageHandler.ReadMessage(); - if (!IsServer) - { - Assets.NetworkDestroy(message.objectId, message.reasons); - } - else - { - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(message.objectId, out identity)) - identity.OnServerSubscribingRemoved(); - } - } - - protected virtual void HandleServerInitialSyncField(MessageHandlerData messageHandler) - { - // Field updated at server, if this is host (client and server) then skip it. - if (IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - identity.ProcessSyncField(info, messageHandler.Reader, true); - } - - protected virtual void HandleServerUpdateSyncField(MessageHandlerData messageHandler) - { - // Field updated at server, if this is host (client and server) then skip it. - if (IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - identity.ProcessSyncField(info, messageHandler.Reader, false); - } - - protected virtual void HandleServerCallFunction(MessageHandlerData messageHandler) - { - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - { - // All function from server will be processed (because it's always trust server) - identity.ProcessNetFunction(info, messageHandler.Reader, true); - } - } - - protected virtual void HandleServerUpdateSyncList(MessageHandlerData messageHandler) - { - // List updated at server, if this is host (client and server) then skip it. - if (IsServer) - return; - LiteNetLibElementInfo info = LiteNetLibElementInfo.DeserializeInfo(messageHandler.Reader); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(info.objectId, out identity)) - identity.ProcessSyncList(info, messageHandler.Reader); - } - - protected virtual void HandleServerSyncBehaviour(MessageHandlerData messageHandler) - { - // Behaviour sync from server, if this is host (client and server) then skip it. - if (IsServer) - return; - uint objectId = messageHandler.Reader.GetPackedUInt(); - byte behaviourIndex = messageHandler.Reader.GetByte(); - LiteNetLibIdentity identity; - if (Assets.TryGetSpawnedObject(objectId, out identity)) - identity.ProcessSyncBehaviour(behaviourIndex, messageHandler.Reader); - } - - protected virtual void HandleServerError(MessageHandlerData messageHandler) - { - // Error sent from server - ServerErrorMessage message = messageHandler.ReadMessage(); - OnServerError(message); - } - - protected virtual void HandleServerSceneChange(MessageHandlerData messageHandler) - { - // Received scene name from server - ServerSceneChangeMessage message = messageHandler.ReadMessage(); - HandleServerSceneChange(message.serverSceneName); - } - - protected void HandleServerSceneChange(string serverSceneName) - { - // Scene loaded at server, if this is host (client and server) then skip it. - if (IsServer) - return; - - if (string.IsNullOrEmpty(serverSceneName) || serverSceneName.Equals(SceneManager.GetActiveScene().name)) - { - Assets.Initialize(); - Assets.InitPoolingObjects(); - OnClientOnlineSceneLoaded(); - SendClientReady(); - } - else - { - // If scene is difference, load changing scene - LoadSceneRoutine(serverSceneName, true).Forget(); - } - } - - protected virtual void HandleServerSetObjectOwner(MessageHandlerData messageHandler) - { - // Object owner was set at server, if this is host (client and server) then skip it. - if (IsServer) - return; - ServerSetObjectOwner message = messageHandler.ReadMessage(); - Assets.SetObjectOwner(message.objectId, message.connectionId); - } - - protected void HandleServerPing(MessageHandlerData messageHandler) - { - PingMessage message = messageHandler.ReadMessage(); - // Send pong back to server (then server will calculates Rtt for this client later) - ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.Pong, new PongMessage() - { - pingTime = message.pingTime, - }); - } - - protected void HandleServerPong(MessageHandlerData messageHandler) - { - PongMessage message = messageHandler.ReadMessage(); - if (_lastPingTime < message.pingTime) - { - _lastPingTime = message.pingTime; - long rtt = Timestamp - message.pingTime; - if (_rttCount > 10) - { - _totalRtt = _rtt; - _rttCount = 1; - } - _totalRtt += rtt; - _rttCount++; - _rtt = _totalRtt / _rttCount; - // Calculate time offsets by device time offsets and RTT - ServerTimestampOffsets = (long)(message.serverTime - Timestamp + (Rtt * 0.5f)); - if (LogDev) Logging.Log(LogTag, "Rtt: " + Rtt + ", ServerTimestampOffsets: " + ServerTimestampOffsets); - } - } - - protected void HandleServerDisconnect(MessageHandlerData messageHandler) - { - Client.SetDisconnectData(messageHandler.Reader.GetBytesWithLength()); - } - #endregion - - /// - /// Overrride this function to send custom data when send enter game message - /// - /// - public virtual void SerializeEnterGameData(NetDataWriter writer) - { - - } - - /// - /// Override this function to read custom data that come with enter game message - /// - /// - /// - /// Return `true` if allow player to enter game. - public virtual async UniTask DeserializeEnterGameData(long connectionId, NetDataReader reader) - { - await UniTask.Yield(); - return true; - } - /// - /// Overrride this function to send custom data when send client ready message - /// - /// - public virtual void SerializeClientReadyData(NetDataWriter writer) - { - - } - - /// - /// Override this function to read custom data that come with client ready message - /// - /// - /// - /// - /// Return `true` if player is ready to play. - public virtual async UniTask DeserializeClientReadyData(LiteNetLibIdentity playerIdentity, long connectionId, NetDataReader reader) - { - await UniTask.Yield(); - return true; - } - - /// - /// Override this function to do anything after online scene loaded at server side - /// - public virtual void OnServerOnlineSceneLoaded() - { - - } - - /// - /// Override this function to do anything after online scene loaded at client side - /// - public virtual void OnClientOnlineSceneLoaded() - { - - } - - /// - /// Override this function to do anything after refused from server - /// - public virtual void OnClientConnectionRefused() - { - StopClient(); - } - - /// - /// Override this function to show error message / disconnect - /// - /// - public virtual void OnServerError(ServerErrorMessage message) - { - if (message.shouldDisconnect && !IsServer) - StopClient(); - } - - public virtual async UniTask SetPlayerReady(long connectionId, NetDataReader reader) - { - if (!IsServer) - return false; - - LiteNetLibPlayer player = Players[connectionId]; - if (player.IsReady) - return false; - player.IsReady = true; - if (!await DeserializeClientReadyData(SpawnPlayer(connectionId), connectionId, reader)) - { - player.IsReady = false; - return false; - } - - return true; - } - - public virtual bool SetPlayerNotReady(long connectionId, NetDataReader reader) - { - if (!IsServer) - return false; - - LiteNetLibPlayer player = Players[connectionId]; - if (!player.IsReady) - return false; - - player.IsReady = false; - player.ClearSubscribing(true); - player.DestroyObjectsWhenNotReady(); - return true; - } - - protected LiteNetLibIdentity SpawnPlayer(long connectionId) - { - if (Assets.PlayerPrefab == null) - return null; - return SpawnPlayer(connectionId, Assets.PlayerPrefab); - } - - protected LiteNetLibIdentity SpawnPlayer(long connectionId, LiteNetLibIdentity prefab) - { - if (prefab == null) - return null; - return SpawnPlayer(connectionId, prefab.HashAssetId); - } - - protected LiteNetLibIdentity SpawnPlayer(long connectionId, int hashAssetId) - { - LiteNetLibIdentity spawnedObject = Assets.NetworkSpawn(hashAssetId, Assets.GetPlayerSpawnPosition(), Quaternion.identity, 0, connectionId); - if (spawnedObject != null) - return spawnedObject; - return null; - } - } -} diff --git a/Scripts/LiteNetLibGameManager.cs.meta b/Scripts/LiteNetLibGameManager.cs.meta deleted file mode 100644 index 2c97d7d6..00000000 --- a/Scripts/LiteNetLibGameManager.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: ea8c7de787d565341b570116d5fa455a -timeCreated: 1508925027 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibIdentity.cs b/Scripts/LiteNetLibIdentity.cs deleted file mode 100644 index f7690f7e..00000000 --- a/Scripts/LiteNetLibIdentity.cs +++ /dev/null @@ -1,843 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.SceneManagement; -#if UNITY_EDITOR -using UnityEditor; -using UnityEditor.SceneManagement; -#endif -using LiteNetLib.Utils; -using UnityEngine.Events; -using UnityEngine.Profiling; -using UnityEngine.Rendering; - -namespace LiteNetLibManager -{ - [DisallowMultipleComponent] - public sealed class LiteNetLibIdentity : MonoBehaviour - { - public static uint HighestObjectId { get; private set; } - [Tooltip("Asset ID will be hashed to uses as prefab instantiating reference, leave it empty to auto generate asset ID by asset path"), SerializeField] - private string assetId = string.Empty; - [ReadOnly, SerializeField] - private uint objectId = 0; - [Tooltip("If this is <= 0f, it will uses interest manager's `defaultVisibleRange` setting"), SerializeField] - private float visibleRange = 0f; - [Tooltip("If this is `TRUE` it will always visible no matter how far from player's objects"), SerializeField] - private bool alwaysVisible = false; - [Tooltip("If this is `TRUE` it will not destroy this network object when player disconnect the game"), SerializeField] - private bool doNotDestroyWhenDisconnect = false; - [Tooltip("If this is > 0, it will get instance from pooling system"), SerializeField] - private int poolingSize = 0; - - [Header("Events")] - public UnityEvent onGetInstance = new UnityEvent(); - - /// - /// This will be true when identity was spawned by manager - /// - public bool IsSpawned { get; private set; } - /// - /// This will be true when identity was requested to destroy - /// - public bool IsDestroyed { get; private set; } - /// - /// This will be true when identity setup - /// - public bool IsSetupBehaviours { get; private set; } - /// - /// Array of all behaviours - /// - public LiteNetLibBehaviour[] Behaviours { get; private set; } - /// - /// List of sync fields from all behaviours (include children behaviours) - /// - internal readonly List SyncFields = new List(); - /// - /// List of net functions from all behaviours (include children behaviours) - /// - internal readonly List NetFunctions = new List(); - /// - /// List of sync lists from all behaviours (include children behaviours) - /// - internal readonly List SyncLists = new List(); - /// - /// List of sync behaviours - /// - internal readonly List SyncBehaviours = new List(); - /// - /// List of networked objects which subscribed by this identity - /// - internal readonly HashSet Subscribings = new HashSet(); - /// - /// List of players which subscribe this identity - /// - internal readonly HashSet Subscribers = new HashSet(); - - public string AssetId { get { return assetId; } } - private int? hashAssetId; - public int HashAssetId - { - get - { - if (!hashAssetId.HasValue) - { - unchecked - { - int hash1 = 5381; - int hash2 = hash1; - - for (int i = 0; i < AssetId.Length && AssetId[i] != '\0'; i += 2) - { - hash1 = ((hash1 << 5) + hash1) ^ AssetId[i]; - if (i == AssetId.Length - 1 || AssetId[i + 1] == '\0') - break; - hash2 = ((hash2 << 5) + hash2) ^ AssetId[i + 1]; - } - - hashAssetId = hash1 + (hash2 * 1566083941); - } - } - return hashAssetId.Value; - } - } - public uint ObjectId { get { return objectId; } internal set { objectId = value; } } - public float VisibleRange { get { return visibleRange; } set { visibleRange = value; } } - public bool AlwaysVisible { get { return alwaysVisible; } set { alwaysVisible = value; } } - public bool DoNotDestroyWhenDisconnect { get { return doNotDestroyWhenDisconnect; } set { doNotDestroyWhenDisconnect = value; } } - public int PoolingSize { get { return poolingSize; } set { poolingSize = value; } } - public byte DataChannel { get; set; } = 0; - /// - /// If this is `TRUE` it will disallow other connections to subscribe this networked object - /// - public bool IsHide { get; set; } - /// - /// This will be used while `IsHide` is `TRUE` to allow some connections to subscribe this networked object - /// - public HashSet HideExceptions { get; } = new HashSet(); - public long ConnectionId { get; internal set; } = -1; - public bool IsPooledInstance { get; internal set; } = false; - public LiteNetLibGameManager Manager { get; internal set; } - - private string logTag; - public string LogTag - { - get - { - if (string.IsNullOrEmpty(logTag)) - logTag = $"{Manager.LogTag}->{name}({GetType().Name})"; - return logTag; - } - } - - public LiteNetLibPlayer Player - { - get - { - LiteNetLibPlayer foundPlayer; - if (Manager == null || !Manager.TryGetPlayer(ConnectionId, out foundPlayer)) - return null; - return foundPlayer; - } - } - - public bool IsServer - { - get { return Manager != null && Manager.IsServer; } - } - - public bool IsClient - { - get { return Manager != null && Manager.IsClient; } - } - - public bool IsOwnerClient - { - get { return IsClient && Manager.ClientConnectionId >= 0 && ConnectionId >= 0 && Manager.ClientConnectionId == ConnectionId; } - } - - public bool IsHost - { - get { return IsServer && IsOwnerClient; } - } - - public bool IsOwnedByServer - { - get { return IsServer && ConnectionId < 0; } - } - - public bool IsOwnerClientOrOwnedByServer - { - get { return IsOwnerClient || IsOwnedByServer; } - } - - public bool IsSceneObject - { - get; private set; - } - - private float? destroyTime; - - private void FixedUpdate() - { - NetworkUpdate(Time.fixedDeltaTime); - } - - internal void NetworkUpdate(float deltaTime) - { - if (Manager == null || !IsSpawned) - return; - - if (destroyTime.HasValue && Time.fixedTime >= destroyTime.Value) - { - DestroyFromAssets(); - return; - } - - int loopCounter; - Profiler.BeginSample("LiteNetLibIdentity - SyncFields Update"); - for (loopCounter = 0; loopCounter < SyncFields.Count; ++loopCounter) - { - SyncFields[loopCounter].NetworkUpdate(deltaTime); - } - Profiler.EndSample(); - - Profiler.BeginSample("LiteNetLibIdentity - SyncLists Update"); - for (loopCounter = 0; loopCounter < SyncLists.Count; ++loopCounter) - { - SyncLists[loopCounter].SendOperations(); - } - Profiler.EndSample(); - - Profiler.BeginSample("LiteNetLibIdentity - SyncBehaviours Update"); - for (loopCounter = 0; loopCounter < SyncBehaviours.Count; ++loopCounter) - { - SyncBehaviours[loopCounter].NetworkUpdate(deltaTime); - } - Profiler.EndSample(); - } - - #region IDs generate in Editor -#if UNITY_EDITOR - private void OnValidate() - { - Event evt = Event.current; - if (evt != null && evt.commandName == "Duplicate") - { - // Reset asset ID to regenerate it - assetId = string.Empty; - } - SetupIDs(); - } - - [ContextMenu("Reorder Scene Object Id")] - public void ContextMenuReorderSceneObjectId() - { - ReorderSceneObjectId(); - } - - internal void AssignAssetID(GameObject prefab, bool clearAssetId = false) - { - if (clearAssetId) - assetId = string.Empty; - if (!string.IsNullOrEmpty(assetId)) - return; - assetId = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(prefab)); - } - - private bool ThisIsAPrefab() - { -#if UNITY_2018_3_OR_NEWER - return PrefabUtility.IsPartOfPrefabAsset(gameObject); -#else - PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject); - if (prefabType == PrefabType.Prefab) - return true; - return false; -#endif - } - - private bool ThisIsASceneObjectWithThatReferencesPrefabAsset(out GameObject prefab) - { - prefab = null; -#if UNITY_2018_3_OR_NEWER - if (!PrefabUtility.IsPartOfNonAssetPrefabInstance(gameObject)) - return false; -#else - PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject); - if (prefabType == PrefabType.None) - return false; -#endif -#if UNITY_2018_2_OR_NEWER - prefab = PrefabUtility.GetCorrespondingObjectFromSource(gameObject); -#else - prefab = (GameObject)PrefabUtility.GetPrefabParent(gameObject); -#endif - if (prefab == null) - { - Logging.LogError(LogTag, $"Failed to find prefab parent for scene object: {gameObject.name}."); - return false; - } - return true; - } - - internal void SetupIDs() - { - string oldAssetId = assetId; - uint oldObjectId = objectId; - GameObject prefab; - if (ThisIsAPrefab()) - { - // This is a prefab, can create prefab while playing so it will still assign asset ID and reset object ID - AssignAssetID(gameObject); - objectId = 0; - } - else if (ThisIsASceneObjectWithThatReferencesPrefabAsset(out prefab)) - { - if (!Application.isPlaying) - { - // This is a scene object with prefab link - AssignAssetID(prefab); - if (gameObject.scene == SceneManager.GetActiveScene()) - { - // Assign object id if it is in scene - AssignSceneObjectId(); - EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); - } - else - { - // Difference working scene?, clear object Id - objectId = 0; - } - } - } - else - { - if (!Application.isPlaying) - { - // This is a pure scene object (Not a prefab) - assetId = string.Empty; - if (gameObject.scene == SceneManager.GetActiveScene()) - { - // Assign object id if it is in scene - AssignSceneObjectId(); - EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); - } - else - { - // Difference working scene?, clear object Id - objectId = 0; - } - } - } - // Do not mark dirty while playing - if (!Application.isPlaying && (oldAssetId != assetId || oldObjectId != objectId)) - EditorUtility.SetDirty(this); - } -#endif - #endregion - - #region SyncField Functions - internal LiteNetLibSyncField ProcessSyncField(LiteNetLibElementInfo info, NetDataReader reader, bool isInitial) - { - return ProcessSyncField(GetSyncField(info), reader, isInitial); - } - - internal LiteNetLibSyncField ProcessSyncField(LiteNetLibSyncField syncField, NetDataReader reader, bool isInitial) - { - if (syncField == null) - return null; - syncField.Deserialize(reader, isInitial); - return syncField; - } - - internal LiteNetLibSyncField GetSyncField(LiteNetLibElementInfo info) - { - if (info.objectId != ObjectId) - return null; - if (info.elementId >= 0 && info.elementId < SyncFields.Count) - return SyncFields[info.elementId]; - if (Manager.LogError) - Logging.LogError(LogTag, $"Cannot find sync field: {info.elementId}."); - return null; - } - #endregion - - #region NetFunction Functions - internal LiteNetLibFunction ProcessNetFunction(LiteNetLibElementInfo info, NetDataReader reader, bool hookCallback) - { - return ProcessNetFunction(GetNetFunction(info), reader, hookCallback); - } - - internal LiteNetLibFunction ProcessNetFunction(LiteNetLibFunction netFunction, NetDataReader reader, bool hookCallback) - { - if (netFunction == null) - return null; - netFunction.DeserializeParameters(reader); - if (hookCallback) - netFunction.HookCallback(); - return netFunction; - } - - internal LiteNetLibFunction GetNetFunction(LiteNetLibElementInfo info) - { - if (info.objectId != ObjectId) - return null; - if (info.elementId >= 0 && info.elementId < NetFunctions.Count) - return NetFunctions[info.elementId]; - if (Manager.LogError) - Logging.LogError(LogTag, $"Cannot find net function: {info.elementId}."); - return null; - } - #endregion - - #region SyncList Functions - internal LiteNetLibSyncList ProcessSyncList(LiteNetLibElementInfo info, NetDataReader reader) - { - return ProcessSyncList(GetSyncList(info), reader); - } - - internal LiteNetLibSyncList ProcessSyncList(LiteNetLibSyncList syncList, NetDataReader reader) - { - if (syncList == null) - return null; - syncList.ProcessOperations(reader); - return syncList; - } - - internal LiteNetLibSyncList GetSyncList(LiteNetLibElementInfo info) - { - if (info.objectId != ObjectId) - return null; - if (info.elementId >= 0 && info.elementId < SyncLists.Count) - return SyncLists[info.elementId]; - if (Manager.LogError) - Logging.LogError(LogTag, $"Cannot find sync list: {info.elementId}."); - return null; - } - #endregion - - internal LiteNetLibBehaviour ProcessSyncBehaviour(byte behaviourIndex, NetDataReader reader) - { - if (behaviourIndex >= Behaviours.Length) - return null; - LiteNetLibBehaviour behaviour = Behaviours[behaviourIndex]; - behaviour.Deserialize(reader); - return behaviour; - } - - internal bool TryGetBehaviour(byte behaviourIndex, out T behaviour) - where T : LiteNetLibBehaviour - { - behaviour = null; - if (behaviourIndex >= Behaviours.Length) - return false; - behaviour = Behaviours[behaviourIndex] as T; - return behaviour != null; - } - - /// - /// This function will be called when send networked object spawning message, to write sync field data - /// - /// - internal void WriteInitSyncFields(NetDataWriter writer) - { - foreach (LiteNetLibSyncField field in SyncFields) - { - if (field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) - continue; - field.Serialize(writer); - } - } - - /// - /// This function will be called when receive networked object spawning message, to read sync field data - /// - /// - internal void ReadInitSyncFields(NetDataReader reader) - { - foreach (LiteNetLibSyncField field in SyncFields) - { - if (field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) - continue; - field.Deserialize(reader, true); - } - } - - /// - /// This function will be called after networked object spawning message was sent - /// - /// - internal void SendInitSyncFields(long connectionId) - { - foreach (LiteNetLibSyncField field in SyncFields) - { - if (!field.HasSyncBehaviourFlag(LiteNetLibSyncField.SyncBehaviour.DoNotSyncInitialDataImmediately)) - continue; - field.SendUpdate(true, connectionId); - } - } - - internal void SendInitSyncLists(long connectionId) - { - foreach (LiteNetLibSyncList list in SyncLists) - { - list.SendInitialList(connectionId); - } - } - - public bool IsSceneObjectExists(uint objectId) - { - if (Manager != null) - { - // If this is spawned while gameplay, find it by manager assets - return Manager.Assets.ContainsSceneObject(objectId); - } - // If this is now spawned while gameplay, find objects in scene - LiteNetLibIdentity[] netObjects = FindObjectsOfType(); - foreach (LiteNetLibIdentity netObject in netObjects) - { - if (netObject.objectId == objectId && netObject != this) - return true; - } - return false; - } - - /// - /// Initial Identity, will be called when spawned. If object id == 0, it will generate new object id - /// - /// - /// - /// - /// - internal void Initial(LiteNetLibGameManager manager, bool isSceneObject, uint objectId = 0, long connectionId = -1) - { - Manager = manager; - ObjectId = objectId; - ConnectionId = connectionId; - UpdateHighestObjectId(objectId); - IsDestroyed = false; - IsSpawned = true; - IsSceneObject = isSceneObject; - if (!IsSceneObject) - AssignSceneObjectId(); - - if (!IsSetupBehaviours) - { - // Setup behaviours index, we will use this as reference for network functions - // NOTE: Maximum network behaviour for a identity is 255 (included children) - Behaviours = GetComponentsInChildren(); - SyncBehaviours.Clear(); - byte loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].Setup(loopCounter); - if (Behaviours[loopCounter].CanSyncBehaviour()) - SyncBehaviours.Add(Behaviours[loopCounter]); - } - IsSetupBehaviours = true; - } - - // If this is host, hide it then will be showned when initialize subscribings - if (IsServer && IsClient) - OnServerSubscribingRemoved(); - - Manager.Assets.SpawnedObjects.Add(ObjectId, this); - if (IsServer && ConnectionId >= 0) - { - Player.SpawnedObjects.Add(ObjectId, this); - Player.Subscribe(ObjectId); - } - - Manager.InterestManager.NotifyNewObject(this); - } - - internal void OnSetOwnerClient(bool isOwnerClient) - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnSetOwnerClient(isOwnerClient); - } - } - - internal void InitTransform(Vector3 position, Quaternion rotation) - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].InitTransform(position, rotation); - } - } - - internal void OnStartServer() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnStartServer(); - } - } - - internal void OnStartClient() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnStartClient(); - } - } - - internal void OnStartOwnerClient() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnStartOwnerClient(); - } - } - - internal void AssignSceneObjectId() - { - if (objectId == 0 || IsSceneObjectExists(objectId)) - objectId = GetNewObjectId(); - } - - internal static void ResetObjectId() - { - HighestObjectId = 0; - } - - internal static uint GetNewObjectId() - { - if (HighestObjectId == 0) - { - uint result = HighestObjectId; - LiteNetLibIdentity[] netObjects = FindObjectsOfType(); - foreach (LiteNetLibIdentity netObject in netObjects) - { - if (netObject.objectId > result) - result = netObject.objectId; - } - HighestObjectId = result; - } - ++HighestObjectId; - return HighestObjectId; - } - - internal static void ReorderSceneObjectId() - { - ResetObjectId(); - LiteNetLibIdentity[] netObjects = FindObjectsOfType(); - foreach (LiteNetLibIdentity netObject in netObjects) - { - netObject.objectId = ++HighestObjectId; -#if UNITY_EDITOR - // Do not mark dirty while playing - if (!Application.isPlaying) - EditorUtility.SetDirty(netObject); -#endif - } -#if UNITY_EDITOR - // Do not mark dirty while playing - if (!Application.isPlaying) - EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); -#endif - } - - internal static void UpdateHighestObjectId(uint objectId) - { - if (objectId > HighestObjectId) - HighestObjectId = objectId; - } - - public bool AddSubscriber(long connectionId) - { - return Subscribers.Add(connectionId); - } - - public bool RemoveSubscriber(long connectionId) - { - return Subscribers.Remove(connectionId); - } - - public bool HasSubscriber(long connectionId) - { - return Subscribers.Contains(connectionId); - } - - public int CountSubscribers() - { - return Subscribers.Count; - } - - public bool HasSubscriberOrIsOwning(long connectionId) - { - return connectionId == ConnectionId || HasSubscriber(connectionId); - } - - public void AddSubscribing(uint subscribing) - { - Subscribings.Add(subscribing); - Player.Subscribe(subscribing); - } - - public void RemoveSubscribing(uint subscribing) - { - Subscribings.Remove(subscribing); - Player.Unsubscribe(subscribing); - } - - public void UpdateSubscribings(HashSet newSubscribings) - { - if (!IsServer || ConnectionId < 0 || !Player.IsReady) - { - // This is not player's networked object - return; - } - // Always add controlled network object to subscribe it - LiteNetLibIdentity tempIdentity; - newSubscribings.Add(ObjectId); - foreach (uint oldSubscribing in Subscribings) - { - if (oldSubscribing == ObjectId) - continue; - if (!newSubscribings.Contains(oldSubscribing)) - { - Player.Unsubscribe(oldSubscribing); - if (Manager.LogDebug) - Logging.Log(LogTag, $"Player: {ConnectionId} unsubscribe object ID: {oldSubscribing}."); - } - } - Subscribings.Clear(); - foreach (uint newSubscribing in newSubscribings) - { - if (!Manager.Assets.TryGetSpawnedObject(newSubscribing, out tempIdentity) || - tempIdentity.IsDestroyed) - continue; - Subscribings.Add(newSubscribing); - Player.Subscribe(newSubscribing); - if (Manager.LogDebug) - Logging.Log(LogTag, $"Player: {ConnectionId} subscribe object ID: {newSubscribing}."); - } - } - - public bool IsHideFrom(LiteNetLibIdentity identity) - { - if (identity == null) - return true; - return IsHide && !HideExceptions.Contains(ConnectionId) && ConnectionId != identity.ConnectionId; - } - - public void OnServerSubscribingAdded() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnServerSubscribingAdded(); - } - if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) - return; - Renderer[] renderers = GetComponentsInChildren(true); - for (int i = 0; i < renderers.Length; ++i) - { - renderers[i].forceRenderingOff = false; - } - } - - public void OnServerSubscribingRemoved() - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnServerSubscribingRemoved(); - } - if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) - return; - Renderer[] renderers = GetComponentsInChildren(true); - for (int i = 0; i < renderers.Length; ++i) - { - renderers[i].forceRenderingOff = true; - } - } - - public void SetOwnerClient(long connectionId) - { - if (!IsServer) - return; - - Manager.Assets.SetObjectOwner(ObjectId, connectionId); - } - - public void NetworkDestroy() - { - if (!IsServer) - return; - - DestroyFromAssets(); - } - - public void NetworkDestroy(float delay) - { - if (!IsServer) - return; - destroyTime = Time.fixedTime + delay; - } - - private void DestroyFromAssets() - { - if (!IsDestroyed && Manager.Assets.NetworkDestroy(ObjectId, DestroyObjectReasons.RequestedToDestroy)) - IsDestroyed = true; - destroyTime = null; - } - - internal void OnNetworkDestroy(byte reasons) - { - int loopCounter; - for (loopCounter = 0; loopCounter < Behaviours.Length; ++loopCounter) - { - Behaviours[loopCounter].OnNetworkDestroy(reasons); - } - if (Manager.IsServer) - { - // If this is server, send message to clients to destroy object - LiteNetLibPlayer player; - foreach (long subscriber in Subscribers) - { - if (Manager.TryGetPlayer(subscriber, out player)) - { - player.Subscribings.Remove(objectId); - Manager.SendServerDestroyObject(subscriber, objectId, reasons); - } - } - // Delete object from owner player's spawned objects collection - if (ConnectionId >= 0) - Player.SpawnedObjects.Remove(ObjectId); - } - // Delete object from assets component - Manager.Assets.SpawnedObjects.Remove(ObjectId); - // Clear data - Subscribings.Clear(); - Subscribers.Clear(); - IsSpawned = false; - } - - internal void OnGetInstance() - { - ResetSyncData(); - onGetInstance.Invoke(); - } - - internal void ResetSyncData() - { - // Clear/reset syncing data - foreach (LiteNetLibSyncField field in SyncFields) - { - field.Reset(); - } - foreach (LiteNetLibSyncList list in SyncLists) - { - list.Reset(); - } - } - } -} diff --git a/Scripts/LiteNetLibIdentity.cs.meta b/Scripts/LiteNetLibIdentity.cs.meta deleted file mode 100644 index 512f6d9c..00000000 --- a/Scripts/LiteNetLibIdentity.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 56367cc2ed44f1e49835e9c247771fd9 -timeCreated: 1508750760 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibPlayer.cs b/Scripts/LiteNetLibPlayer.cs deleted file mode 100644 index 400e7a43..00000000 --- a/Scripts/LiteNetLibPlayer.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System.Collections.Generic; - -namespace LiteNetLibManager -{ - public class LiteNetLibPlayer - { - public LiteNetLibGameManager Manager { get; protected set; } - public long ConnectionId { get; protected set; } - public bool IsReady { get; set; } - public long Rtt { get; internal set; } - - internal long LastPingTime; - internal long TotalRtt; - internal int RttCount; - internal readonly HashSet Subscribings = new HashSet(); - internal readonly Dictionary SpawnedObjects = new Dictionary(); - - public LiteNetLibPlayer(LiteNetLibGameManager manager, long connectionId) - { - Manager = manager; - ConnectionId = connectionId; - } - - internal bool IsSubscribing(uint objectId) - { - return Subscribings.Contains(objectId); - } - - internal int CountSubscribing() - { - return Subscribings.Count; - } - - internal void Subscribe(uint objectId) - { - LiteNetLibIdentity identity; - if (Subscribings.Add(objectId) && Manager.Assets.TryGetSpawnedObject(objectId, out identity)) - { - identity.AddSubscriber(ConnectionId); - Manager.SendServerSpawnObjectWithData(ConnectionId, identity); - } - } - - internal void Unsubscribe(uint objectId) - { - LiteNetLibIdentity identity; - if (Subscribings.Remove(objectId) && Manager.Assets.TryGetSpawnedObject(objectId, out identity)) - { - identity.RemoveSubscriber(ConnectionId); - Manager.SendServerDestroyObject(ConnectionId, objectId, DestroyObjectReasons.RemovedFromSubscribing); - } - } - - internal void ClearSubscribing(bool destroyObjectsOnPeer) - { - // Remove player's subscribing and remove this player from subscribers - LiteNetLibIdentity identity; - foreach (uint objectId in Subscribings) - { - if (!Manager.Assets.TryGetSpawnedObject(objectId, out identity)) - continue; - identity.RemoveSubscriber(ConnectionId); - if (destroyObjectsOnPeer) - Manager.SendServerDestroyObject(ConnectionId, objectId, DestroyObjectReasons.RemovedFromSubscribing); - } - Subscribings.Clear(); - } - - internal void DestroyObjectsWhenNotReady() - { - List objectIds = new List(SpawnedObjects.Keys); - foreach (uint objectId in objectIds) - Manager.Assets.NetworkDestroy(objectId, DestroyObjectReasons.RequestedToDestroy); - SpawnedObjects.Clear(); - } - - internal void DestroyObjectsWhenDisconnect() - { - List objectIds = new List(SpawnedObjects.Keys); - foreach (uint objectId in objectIds) - { - if (SpawnedObjects[objectId].DoNotDestroyWhenDisconnect) - { - SpawnedObjects[objectId].ConnectionId = -1; - continue; - } - Manager.Assets.NetworkDestroy(objectId, DestroyObjectReasons.RequestedToDestroy); - } - SpawnedObjects.Clear(); - } - - public bool TryGetSpawnedObject(uint objectId, out LiteNetLibIdentity identity) - { - return SpawnedObjects.TryGetValue(objectId, out identity); - } - - public bool ContainsSpawnedObject(uint objectId) - { - return SpawnedObjects.ContainsKey(objectId); - } - - public LiteNetLibIdentity GetSpawnedObject(uint objectId) - { - return SpawnedObjects[objectId]; - } - - public IEnumerable GetSpawnedObjects() - { - return SpawnedObjects.Values; - } - - public IEnumerable GetSubscribingObjectIds() - { - return Subscribings; - } - - public int SpawnedObjectsCount - { - get { return SpawnedObjects.Count; } - } - } -} diff --git a/Scripts/LiteNetLibPlayer.cs.meta b/Scripts/LiteNetLibPlayer.cs.meta deleted file mode 100644 index 31a4ab3c..00000000 --- a/Scripts/LiteNetLibPlayer.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: b905784494aa1194883589d0008336d2 -timeCreated: 1518872995 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibSpawnPoint.cs b/Scripts/LiteNetLibSpawnPoint.cs deleted file mode 100644 index 9ba9554a..00000000 --- a/Scripts/LiteNetLibSpawnPoint.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace LiteNetLibManager -{ - public class LiteNetLibSpawnPoint : MonoBehaviour - { - [SerializeField] - private float radius = 0f; - - public Transform CacheTransform { get; private set; } - - public Vector3 Position - { - get { return CacheTransform.position; } - } - - private void Awake() - { - CacheTransform = transform; - } - -#if UNITY_EDITOR - private void OnDrawGizmos() - { - Color color = Color.green; - Gizmos.color = color; - Gizmos.DrawWireSphere(transform.position, radius); - color.a = 0.5f; - Gizmos.color = color; - Gizmos.DrawSphere(transform.position, radius); - } -#endif - - public Vector3 GetRandomPosition() - { - Vector3 offsets = Random.insideUnitSphere * radius; - offsets.y = 0; - return Position + offsets; - } - } -} diff --git a/Scripts/LiteNetLibSpawnPoint.cs.meta b/Scripts/LiteNetLibSpawnPoint.cs.meta deleted file mode 100644 index d1d67a84..00000000 --- a/Scripts/LiteNetLibSpawnPoint.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: f2a1f142556b957428162f23ccf49bfd -timeCreated: 1524424716 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibSyncField.cs b/Scripts/LiteNetLibSyncField.cs deleted file mode 100644 index 8a615c55..00000000 --- a/Scripts/LiteNetLibSyncField.cs +++ /dev/null @@ -1,693 +0,0 @@ -using System; -using UnityEngine; -using LiteNetLib; -using LiteNetLib.Utils; -using System.Reflection; - -namespace LiteNetLibManager -{ - public abstract class LiteNetLibSyncField : LiteNetLibElement - { - protected readonly static NetDataWriter ServerWriter = new NetDataWriter(); - protected readonly static NetDataWriter ClientWriter = new NetDataWriter(); - - public enum SyncMode : byte - { - /// - /// Changes handle by server - /// Will send to connected clients when changes occurs on server - /// - ServerToClients, - /// - /// Changes handle by server - /// Will send to owner-client when changes occurs on server - /// - ServerToOwnerClient, - /// - /// Changes handle by owner-client - /// Will send to server then server multicast to other clients when changes occurs on owner-client - /// - ClientMulticast - } - - [Flags] - public enum SyncBehaviour : byte - { - Default = 0, - AlwaysSync = 1 << 0, - DoNotSyncInitialDataImmediately = 1 << 1, - DoNotSyncUpdate = 1 << 2, - } - - [Header("Generic Settings")] - [Tooltip("How it will sync data. If always sync, it will sync data although it has no changes. If don't sync initial data immediately, it will not sync initial data immdediately with networked object spawning message, it will sync later after spanwed. If don't sync update, it will not sync when data has changes.")] - public SyncBehaviour syncBehaviour; - [Tooltip("Who can sync data and sync to whom")] - public SyncMode syncMode; - [Tooltip("Interval to send networking data")] - [Range(0.01f, 2f)] - public float sendInterval = 0.1f; - - [Header("Server Sync Settings")] - [Tooltip("Sending data channel from server to clients")] - public byte dataChannel = 0; - [Tooltip("Sending method type from server to clients, default is `Sequenced`")] - public DeliveryMethod deliveryMethod = DeliveryMethod.Sequenced; - - [Header("Client Sync Settings (`syncMode` is `ClientMulticast` only)")] - [Tooltip("Sending data channel from clients to server (`syncMode` is `ClientMulticast` only)")] - public byte clientDataChannel = 0; - [Tooltip("Sending method type from clients to server (`syncMode` is `ClientMulticast` only), default is `Sequenced`")] - public DeliveryMethod clientDeliveryMethod = DeliveryMethod.Sequenced; - - private float sendCountDown; - private bool onChangeCalled; - protected object defaultValue; - - public abstract Type GetFieldType(); - public abstract object GetValue(); - public abstract void SetValue(object value); - internal abstract void OnChange(bool initial); - internal abstract bool HasUpdate(); - internal abstract void Updated(); - - public bool HasSyncBehaviourFlag(SyncBehaviour flag) - { - return (syncBehaviour & flag) == flag; - } - - internal void Reset() - { - SetValue(defaultValue); - } - - internal override sealed void Setup(LiteNetLibBehaviour behaviour, int elementId) - { - base.Setup(behaviour, elementId); - defaultValue = GetValue(); - // Invoke on change function with initial state = true - switch (syncMode) - { - case SyncMode.ServerToClients: - case SyncMode.ServerToOwnerClient: - if (IsServer) - OnChange(true); - break; - case SyncMode.ClientMulticast: - if (IsOwnerClient) - OnChange(true); - break; - } - } - - internal void NetworkUpdate(float deltaTime) - { - if (!CanSync()) - return; - - // Won't update - if (HasSyncBehaviourFlag(SyncBehaviour.DoNotSyncUpdate)) - return; - - // No update - if (!HasSyncBehaviourFlag(SyncBehaviour.AlwaysSync) && !HasUpdate()) - return; - - // Call `OnChange` if it's not called yet. - if ((HasSyncBehaviourFlag(SyncBehaviour.AlwaysSync) || HasUpdate()) && !onChangeCalled) - { - // Invoke on change function with initial state = false - switch (syncMode) - { - case SyncMode.ServerToClients: - case SyncMode.ServerToOwnerClient: - if (IsServer) - OnChange(false); - break; - case SyncMode.ClientMulticast: - if (IsOwnerClient) - OnChange(false); - break; - } - onChangeCalled = true; - } - - // It's time to send update? - sendCountDown -= deltaTime; - if (sendCountDown > 0f) - return; - - // Set count down - sendCountDown = sendInterval; - - // Send the update - SendUpdate(false); - - // Update already sent - Updated(); - - // Reset on change called state to call `OnChange` later when has update - onChangeCalled = false; - } - - public void UpdateImmediately() - { - sendCountDown = 0f; - NetworkUpdate(0f); - } - - internal void Deserialize(NetDataReader reader, bool isInitial) - { - DeserializeValue(reader); - OnChange(isInitial); - } - - internal void Serialize(NetDataWriter writer) - { - SerializeValue(writer); - } - - internal virtual void DeserializeValue(NetDataReader reader) - { - SetValue(reader.GetValue(GetFieldType())); - } - - internal virtual void SerializeValue(NetDataWriter writer) - { - writer.PutValue(GetFieldType(), GetValue()); - } - - internal void SendUpdate(bool isInitial, long connectionId) - { - if (!CanSync() || !IsServer) - return; - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ServerWriter); - if (manager.ContainsConnectionId(connectionId)) - server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); - } - - internal void SendUpdate(bool isInitial) - { - if (!CanSync()) - { - Logging.LogError(LogTag, "Error while set value, behaviour is empty"); - return; - } - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - LiteNetLibClient client = manager.Client; - switch (syncMode) - { - case SyncMode.ServerToClients: - TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ServerWriter); - foreach (long connectionId in manager.GetConnectionIds()) - { - if (Identity.HasSubscriberOrIsOwning(connectionId)) - server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); - } - break; - case SyncMode.ServerToOwnerClient: - if (manager.ContainsConnectionId(ConnectionId)) - { - TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ServerWriter); - server.SendMessage(ConnectionId, dataChannel, deliveryMethod, ServerWriter); - } - break; - case SyncMode.ClientMulticast: - if (IsOwnerClient) - { - TransportHandler.WritePacket(ClientWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ClientWriter); - // Client send data to server, then server send to other clients, it should be reliable-ordered - client.SendMessage(clientDataChannel, clientDeliveryMethod, ClientWriter); - } - else if (IsServer) - { - TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField); - SerializeForSend(ServerWriter); - foreach (long connectionId in manager.GetConnectionIds()) - { - if (Identity.HasSubscriberOrIsOwning(connectionId)) - server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter); - } - } - break; - } - } - - private void SerializeForSend(NetDataWriter writer) - { - LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); - Serialize(writer); - } - - public override string ToString() - { - return GetValue().ToString(); - } - } - - public class LiteNetLibSyncFieldContainer : LiteNetLibSyncField - { - /// - /// The field which going to sync its value - /// - private FieldInfo field; - - /// - /// The class which contain the field - /// - private object instance; - - /// - /// Use this variable to tell that it has to update after value changed - /// - private bool hasUpdate; - - /// - /// This method will be invoked after value changed - /// - private MethodInfo onChangeMethod; - - /// - /// This method will be invoked after data sent - /// - private MethodInfo onUpdateMethod; - - /// - /// Use this value to check field's value changes - /// - private object value; - - public LiteNetLibSyncFieldContainer(FieldInfo field, object instance, MethodInfo onChangeMethod, MethodInfo onUpdateMethod) - { - this.field = field; - this.instance = instance; - this.onChangeMethod = onChangeMethod; - this.onUpdateMethod = onUpdateMethod; - value = field.GetValue(instance); - } - - public override sealed Type GetFieldType() - { - return field.FieldType; - } - - public override sealed object GetValue() - { - return field.GetValue(instance); - } - - public override sealed void SetValue(object value) - { - field.SetValue(instance, value); - } - - internal override sealed bool HasUpdate() - { - if (hasUpdate) - return true; - - if (value == null || !value.Equals(field.GetValue(instance))) - { - // Set value because it's going to sync later - value = field.GetValue(instance); - // Set `hasUpdate` to `TRUE` this value will turn to `FALSE` when `Updated()` called - hasUpdate = true; - } - - return hasUpdate; - } - - internal override void Updated() - { - if (onUpdateMethod != null) - onUpdateMethod.Invoke(instance, new object[0]); - hasUpdate = false; - } - - internal override sealed void OnChange(bool initial) - { - if (onChangeMethod != null) - onChangeMethod.Invoke(instance, new object[] { GetValue() }); - } - } - - public class LiteNetLibSyncField : LiteNetLibSyncField - { - public delegate void OnChangeDelegate(bool initial, TType value); - public delegate void OnUpdatedDelegate(); - /// - /// Action with initial state and value, this will be invoked after data changed - /// - public OnChangeDelegate onChange; - - /// - /// This will be invoked after data sent - /// - public OnUpdatedDelegate onUpdated; - - /// - /// Use this variable to tell that it has to update after value changed - /// - protected bool hasUpdate; - - [SerializeField] - protected TType value; - public TType Value - { - get { return value; } - set - { - if (IsValueChanged(value)) - { - this.value = value; - if (CanSync()) - hasUpdate = true; - } - } - } - - protected virtual bool IsValueChanged(TType newValue) - { - return value == null || !value.Equals(newValue); - } - - internal override bool HasUpdate() - { - return hasUpdate; - } - - internal override void Updated() - { - if (onUpdated != null) - onUpdated.Invoke(); - hasUpdate = false; - } - - public override sealed Type GetFieldType() - { - return typeof(TType); - } - - public override sealed object GetValue() - { - return Value; - } - - public override sealed void SetValue(object value) - { - Value = (TType)value; - } - - internal override sealed void OnChange(bool initial) - { - if (onChange != null) - onChange.Invoke(initial, Value); - } - - public static implicit operator TType(LiteNetLibSyncField field) - { - return field.Value; - } - } - - [Serializable] - public class SyncFieldArray : LiteNetLibSyncField - { - public TType this[int i] - { - get { return Value[i]; } - set - { - Value[i] = value; - hasUpdate = true; - } - } - - internal override void DeserializeValue(NetDataReader reader) - { - Value = reader.GetArray(); - } - - internal override void SerializeValue(NetDataWriter writer) - { - writer.PutArray(Value); - } - - public int Length { get { return Value.Length; } } - } - - #region Implement for general usages and serializable - [Serializable] - public class SyncFieldBool : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldBoolArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldByte : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldByteArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldChar : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldDouble : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldDoubleArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldFloat : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldFloatArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldInt : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldIntArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldLong : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldLongArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldSByte : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldShort : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldShortArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldString : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldUInt : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldUIntArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldULong : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldULongArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldUShort : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldUShortArray : SyncFieldArray - { - } - - [Serializable] - public class SyncFieldColor : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldQuaternion : LiteNetLibSyncField - { - [Tooltip("If angle between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeAngle = 1f; - - protected override bool IsValueChanged(Quaternion newValue) - { - return Quaternion.Angle(value, newValue) >= valueChangeAngle; - } - } - - [Serializable] - public class SyncFieldVector2 : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector2 newValue) - { - return Vector2.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - public class SyncFieldVector2Int : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector2Int newValue) - { - return Vector2Int.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - public class SyncFieldVector3 : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector3 newValue) - { - return Vector3.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - public class SyncFieldVector3Int : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector3Int newValue) - { - return Vector3Int.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - public class SyncFieldVector4 : LiteNetLibSyncField - { - [Tooltip("If distance between new value and old value >= this value, it will be determined that the value is changing")] - public float valueChangeDistance = 0.01f; - - protected override bool IsValueChanged(Vector4 newValue) - { - return Vector4.Distance(value, newValue) >= valueChangeDistance; - } - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedUShort : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedUInt : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedULong : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedShort : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedInt : LiteNetLibSyncField - { - } - - [Serializable] - [Obsolete("SyncField already packed. So you don't have to use this class")] - public class SyncFieldPackedLong : LiteNetLibSyncField - { - } - - [Serializable] - public class SyncFieldDirectionVector2 : LiteNetLibSyncField - { - protected override bool IsValueChanged(DirectionVector2 newValue) - { - return Value.x != newValue.x || Value.y != newValue.y; - } - } - - [Serializable] - public class SyncFieldDirectionVector3 : LiteNetLibSyncField - { - protected override bool IsValueChanged(DirectionVector3 newValue) - { - return Value.x != newValue.x || Value.y != newValue.y || Value.z != newValue.z; - } - } - #endregion -} diff --git a/Scripts/LiteNetLibSyncField.cs.meta b/Scripts/LiteNetLibSyncField.cs.meta deleted file mode 100644 index cd10b767..00000000 --- a/Scripts/LiteNetLibSyncField.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: f13e8093d1ab8fd42ac6c519c60b1f30 -timeCreated: 1508947932 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibSyncList.cs b/Scripts/LiteNetLibSyncList.cs deleted file mode 100644 index f5f163b9..00000000 --- a/Scripts/LiteNetLibSyncList.cs +++ /dev/null @@ -1,609 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using LiteNetLib; -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public abstract partial class LiteNetLibSyncList : LiteNetLibElement - { - protected readonly static NetDataWriter Writer = new NetDataWriter(); - - public partial struct Operation - { - public const byte Add = 0; - public const byte Clear = 1; - public const byte Insert = 2; - public const byte RemoveAt = 3; - public const byte Set = 4; - public const byte Dirty = 5; - public const byte RemoveFirst = 6; - public const byte RemoveLast = 7; - public const byte AddInitial = 8; - - public Operation(byte value) - { - Value = value; - } - - public byte Value { get; private set; } - - public static implicit operator byte(Operation operation) - { - return operation.Value; - } - - public static implicit operator Operation(byte value) - { - return new Operation(value); - } - } - - public delegate void OnOperationDelegate(Operation op, int itemIndex); - - [Tooltip("Sending data channel")] - public byte dataChannel = 0; - [Tooltip("If this is `TRUE`, this will update to owner client only, default is `FALSE`")] - public bool forOwnerOnly = false; - public OnOperationDelegate onOperation; - - public abstract Type FieldType { get; } - public abstract int Count { get; } - internal abstract void Reset(); - internal abstract void SendInitialList(long connectionId); - internal abstract void SendOperations(); - internal abstract void ProcessOperations(NetDataReader reader); - - protected override bool CanSync() - { - return IsServer; - } - - internal override sealed void Setup(LiteNetLibBehaviour behaviour, int elementId) - { - base.Setup(behaviour, elementId); - if (Count > 0 && onOperation != null) - { - for (int i = 0; i < Count; ++i) - { - onOperation.Invoke(Operation.AddInitial, i); - } - } - } - } - - public class LiteNetLibSyncList : LiteNetLibSyncList, IList - { - protected struct OperationEntry - { - public Operation operation; - public int index; - public TType data; - public int count; - } - - protected readonly List list = new List(); - protected readonly List operationEntries = new List(); - - public TType this[int index] - { - get { return list[index]; } - set - { - if (IsSetup && !IsServer) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - list[index] = value; - PrepareOperation(Operation.Set, index); - } - } - - public override sealed Type FieldType - { - get { return typeof(TType); } - } - - public override sealed int Count - { - get { return list.Count; } - } - - public bool IsReadOnly - { - get { return false; } - } - - public TType Get(int index) - { - return this[index]; - } - - public void Set(int index, TType value) - { - this[index] = value; - } - - public void Add(TType item) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - int index = list.Count; - list.Add(item); - PrepareOperation(Operation.Add, index); - } - - public void AddRange(IEnumerable collection) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - foreach (TType item in collection) - { - Add(item); - } - } - - public void Insert(int index, TType item) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - list.Insert(index, item); - PrepareOperation(Operation.Insert, index); - } - - public bool Contains(TType item) - { - return list.Contains(item); - } - - public int IndexOf(TType item) - { - return list.IndexOf(item); - } - - public bool Remove(TType value) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return false; - } - int index = IndexOf(value); - if (index >= 0) - { - RemoveAt(index); - return true; - } - return false; - } - - public void RemoveAt(int index) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - if (index == 0) - { - list.RemoveAt(index); - PrepareOperation(Operation.RemoveFirst, 0); - } - else if (index == list.Count - 1) - { - list.RemoveAt(index); - PrepareOperation(Operation.RemoveLast, index); - } - else - { - list.RemoveAt(index); - PrepareOperation(Operation.RemoveAt, index); - } - } - - public void Clear() - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - list.Clear(); - PrepareOperation(Operation.Clear, -1); - } - - public void CopyTo(TType[] array, int arrayIndex) - { - list.CopyTo(array, arrayIndex); - } - - public IEnumerator GetEnumerator() - { - return list.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return list.GetEnumerator(); - } - - public void Dirty(int index) - { - if (IsSetup && !CanSync()) - { - Logging.LogError(LogTag, "Cannot access sync list from client."); - return; - } - PrepareOperation(Operation.Dirty, index); - } - - internal override sealed void Reset() - { - list.Clear(); - operationEntries.Clear(); - } - - protected void PrepareOperation(Operation operation, int index) - { - OnOperation(operation, index); - PrepareOperation(operationEntries, operation, index); - } - - protected void PrepareOperation(List operationEntries, Operation operation, int index) - { - switch (operation) - { - case Operation.Clear: - operationEntries.Add(new OperationEntry() - { - operation = operation, - index = index, - count = 0, - }); - break; - case Operation.RemoveAt: - case Operation.RemoveFirst: - case Operation.RemoveLast: - operationEntries.Add(new OperationEntry() - { - operation = operation, - index = index, - count = 1, - }); - break; - default: - operationEntries.Add(new OperationEntry() - { - operation = operation, - index = index, - data = list[index], - count = 1, - }); - break; - } - } - - internal override sealed void SendInitialList(long connectionId) - { - if (!CanSync()) - return; - List addInitialOperationEntries = new List(); - for (int i = 0; i < Count; ++i) - { - if (!ContainsAddOperation(i)) - PrepareOperation(addInitialOperationEntries, Operation.AddInitial, i); - } - LiteNetLibServer server = Manager.Server; - TransportHandler.WritePacket(Writer, GameMsgTypes.OperateSyncList); - SerializeForSendOperations(Writer, addInitialOperationEntries); - server.SendMessage(connectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); - } - - private bool ContainsAddOperation(int index) - { - for (int i = 0; i < operationEntries.Count; ++i) - { - if (operationEntries[i].operation == Operation.Add && operationEntries[i].index == index) - return true; - } - return false; - } - - internal override sealed void SendOperations() - { - if (operationEntries.Count <= 0 || !CanSync()) - return; - LiteNetLibGameManager manager = Manager; - LiteNetLibServer server = manager.Server; - TransportHandler.WritePacket(Writer, GameMsgTypes.OperateSyncList); - SerializeForSendOperations(Writer, operationEntries); - operationEntries.Clear(); - if (forOwnerOnly) - { - if (manager.ContainsConnectionId(ConnectionId)) - server.SendMessage(ConnectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); - } - else - { - foreach (long connectionId in manager.GetConnectionIds()) - { - if (Identity.HasSubscriberOrIsOwning(connectionId)) - server.SendMessage(connectionId, dataChannel, DeliveryMethod.ReliableOrdered, Writer); - } - } - } - - internal override sealed void ProcessOperations(NetDataReader reader) - { - int operationCount = reader.GetPackedInt(); - for (int i = 0; i < operationCount; ++i) - { - DeserializeOperation(reader); - } - } - - protected void SerializeForSendOperations(NetDataWriter writer, List operationEntries) - { - LiteNetLibElementInfo.SerializeInfo(GetInfo(), writer); - writer.PutPackedInt(operationEntries.Count); - for (int i = 0; i < operationEntries.Count; ++i) - { - SerializeOperation(writer, operationEntries[i]); - } - } - - protected void DeserializeOperation(NetDataReader reader) - { - Operation operation = reader.GetByte(); - int index = -1; - TType item; - switch (operation) - { - case Operation.Add: - case Operation.AddInitial: - item = DeserializeValueForAddOrInsert(index, reader); - index = list.Count; - list.Add(item); - break; - case Operation.Insert: - index = reader.GetInt(); - item = DeserializeValueForAddOrInsert(index, reader); - list.Insert(index, item); - break; - case Operation.Set: - case Operation.Dirty: - index = reader.GetInt(); - item = DeserializeValueForSetOrDirty(index, reader); - list[index] = item; - break; - case Operation.RemoveAt: - index = reader.GetInt(); - list.RemoveAt(index); - break; - case Operation.RemoveFirst: - index = 0; - list.RemoveAt(index); - break; - case Operation.RemoveLast: - index = list.Count - 1; - list.RemoveAt(index); - break; - case Operation.Clear: - list.Clear(); - break; - default: - index = reader.GetInt(); - item = DeserializeValueForCustomDirty(index, operation, reader); - list[index] = item; - break; - } - OnOperation(operation, index); - } - - protected void SerializeOperation(NetDataWriter writer, OperationEntry entry) - { - writer.Put((byte)entry.operation); - switch (entry.operation) - { - case Operation.Add: - case Operation.AddInitial: - SerializeValueForAddOrInsert(entry.index, writer, entry.data); - break; - case Operation.Insert: - writer.Put(entry.index); - SerializeValueForAddOrInsert(entry.index, writer, entry.data); - break; - case Operation.Set: - case Operation.Dirty: - writer.Put(entry.index); - SerializeValueForSetOrDirty(entry.index, writer, entry.data); - break; - case Operation.RemoveAt: - writer.Put(entry.index); - break; - case Operation.RemoveFirst: - case Operation.RemoveLast: - case Operation.Clear: - break; - default: - writer.Put(entry.index); - SerializeValueForCustomDirty(entry.index, entry.operation, writer, entry.data); - break; - } - } - - protected virtual TType DeserializeValue(NetDataReader reader) - { - return reader.GetValue(); - } - - protected virtual void SerializeValue(NetDataWriter writer, TType value) - { - writer.PutValue(value); - } - - protected virtual TType DeserializeValueForAddOrInsert(int index, NetDataReader reader) - { - return DeserializeValue(reader); - } - - protected virtual void SerializeValueForAddOrInsert(int index, NetDataWriter writer, TType value) - { - SerializeValue(writer, value); - } - - protected virtual TType DeserializeValueForSetOrDirty(int index, NetDataReader reader) - { - return DeserializeValue(reader); - } - - protected virtual void SerializeValueForSetOrDirty(int index, NetDataWriter writer, TType value) - { - SerializeValue(writer, value); - } - - protected virtual void SerializeValueForCustomDirty(int index, byte customOperation, NetDataWriter writer, TType value) - { - SerializeValue(writer, value); - } - - protected virtual TType DeserializeValueForCustomDirty(int index, byte customOperation, NetDataReader reader) - { - return DeserializeValue(reader); - } - - protected void OnOperation(Operation operation, int index) - { - if (onOperation != null) - onOperation.Invoke(operation, index); - } - } - - #region Implement for general usages and serializable - // Generics - - [Serializable] - public class SyncListBool : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListByte : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListChar : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListDouble : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListFloat : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListInt : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListLong : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListSByte : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListShort : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListString : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListUInt : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListULong : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListUShort : LiteNetLibSyncList - { - } - - // Unity - - [Serializable] - public class SyncListColor : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListQuaternion : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector2 : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector2Int : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector3 : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector3Int : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListVector4 : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListDirectionVector2 : LiteNetLibSyncList - { - } - - [Serializable] - public class SyncListDirectionVector3 : LiteNetLibSyncList - { - } - #endregion -} diff --git a/Scripts/LiteNetLibSyncList.cs.meta b/Scripts/LiteNetLibSyncList.cs.meta deleted file mode 100644 index e9e0e82b..00000000 --- a/Scripts/LiteNetLibSyncList.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: d5fb20391be68d949b2b768c055e3c15 -timeCreated: 1511713954 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibTransform.cs b/Scripts/LiteNetLibTransform.cs deleted file mode 100644 index 52333f01..00000000 --- a/Scripts/LiteNetLibTransform.cs +++ /dev/null @@ -1,521 +0,0 @@ -using LiteNetLib; -using LiteNetLib.Utils; -using UnityEngine; -using UnityEngine.AI; - -namespace LiteNetLibManager -{ - public class LiteNetLibTransform : LiteNetLibBehaviour - { - private struct TransformResult - { - public Vector3 position; - public Quaternion rotation; - public float timestamp; - } - - public enum SyncPositionOptions - { - Sync, - NotSync, - } - - public enum SyncRotationOptions - { - Sync, - NotSync, - CompressToUShort, - CompressToByte, - } - - public enum InterpolateMode - { - EstimatedSpeed, - FixedSpeed, - } - - public enum ExtrapolateMode - { - None, - EstimatedSpeed, - FixedSpeed, - } - - [Tooltip("Which transform you are going to sync, if it is empty it will use transform which this component attached to")] - public Transform syncingTransform; - [Tooltip("If this is TRUE, transform data will be sent from owner client to server to update to another clients")] - public bool ownerClientCanSendTransform; - [Tooltip("This will be used when `ownerClientCanSendTransform` is set to TRUE to send transform update from client to server")] - [Range(0.01f, 2f)] - public float ownerClientSendInterval = 0.1f; - public float snapThreshold = 5.0f; - public InterpolateMode interpolateMode = InterpolateMode.EstimatedSpeed; - public float fixedInterpolateSpeed; - public ExtrapolateMode extrapolateMode = ExtrapolateMode.None; - public float fixedExtrapolateSpeed; - [Header("Sync Position Settings")] - public SyncPositionOptions syncPositionX; - public SyncPositionOptions syncPositionY; - public SyncPositionOptions syncPositionZ; - [Header("Sync Rotation Settings")] - public SyncRotationOptions syncRotationX; - public SyncRotationOptions syncRotationY; - public SyncRotationOptions syncRotationZ; - - public System.Action onTeleport; - - #region Cache components - public NavMeshAgent CacheNavMeshAgent { get; private set; } - public Rigidbody CacheRigidbody3D { get; private set; } - public Rigidbody2D CacheRigidbody2D { get; private set; } - public CharacterController CacheCharacterController { get; private set; } - #endregion - - private bool syncingTransformIsIdentity; - // Interpolation related variables - private float ownerSendElapsed = 0f; - private float lastReceivedTime = 0f; - private float lastReceivedTimestamp = 0f; - private TransformResult currentInterpResult; - private TransformResult previousEndInterpResult; - private TransformResult endInterpResult; - - private void Awake() - { - if (syncingTransform == null) - syncingTransform = transform; - // Nav mesh agent is highest priority, then character controller - // Then Rigidbodies, that both 3d/2d are same priority - CacheNavMeshAgent = syncingTransform.GetComponent(); - if (CacheNavMeshAgent == null) - { - CacheCharacterController = syncingTransform.GetComponent(); - if (CacheCharacterController == null) - { - CacheRigidbody3D = syncingTransform.GetComponent(); - CacheRigidbody2D = syncingTransform.GetComponent(); - } - } - sendOptions = DeliveryMethod.Unreliable; - } - - private void OnValidate() - { - // Force set to `Unreliable` - sendOptions = DeliveryMethod.Unreliable; - } - - private void OnEnable() - { - InitInterpResults(syncingTransform.position, syncingTransform.rotation); - } - - public override void OnSetOwnerClient(bool isOwnerClient) - { - InitInterpResults(syncingTransform.position, syncingTransform.rotation); - } - - public override void InitTransform(Vector3 position, Quaternion rotation) - { - if (syncingTransformIsIdentity) - { - InitInterpResults(position, rotation); - Snap(position, rotation); - } - } - - private void InitInterpResults(Vector3 position, Quaternion rotation) - { - currentInterpResult = new TransformResult(); - currentInterpResult.position = position; - currentInterpResult.rotation = rotation; - currentInterpResult.timestamp = GetTimeStamp(); - previousEndInterpResult = currentInterpResult; - endInterpResult = currentInterpResult; - } - - public override void OnSetup() - { - base.OnSetup(); - RegisterNetFunction(NetFunction_Teleport); - if (syncingTransform == null) - syncingTransform = transform; - syncingTransformIsIdentity = syncingTransform == Identity.transform; - } - - private void NetFunction_Teleport(Vector3 position, Quaternion rotation) - { - InitInterpResults(position, rotation); - Snap(position, rotation); - if (onTeleport != null) - onTeleport.Invoke(position, rotation); - } - - /// - /// This function will be called at server after receive transform from clients - /// to interpolate and sync position to other clients - /// - /// - internal void HandleClientSendTransform(NetDataReader reader) - { - // Don't update transform follow client's request - // if not set "ownerClientCanSendTransform" to `TRUE` - // or it's this is owned by host - if (!ownerClientCanSendTransform || IsOwnerClient) - return; - TransformResult result = DeserializeResult(reader); - // Discard out of order results - if (result.timestamp <= lastReceivedTimestamp) - return; - lastReceivedTime = Time.fixedTime; - lastReceivedTimestamp = result.timestamp; - result.timestamp = GetTimeStamp(); - previousEndInterpResult = endInterpResult; - endInterpResult = result; - } - - /// - /// This function will be called at client to send transform - /// - /// - private void ClientSendTransform(TransformResult transformResult) - { - // Don't request to set transform if not set "canClientSendResult" to TRUE - if (!ownerClientCanSendTransform || !IsOwnerClient) - return; - Manager.ClientSendPacket(0, DeliveryMethod.Unreliable, GameMsgTypes.ClientSendTransform, (writer) => ClientSendTransformWriter(writer, transformResult)); - } - - private void ClientSendTransformWriter(NetDataWriter writer, TransformResult transformResult) - { - writer.PutPackedUInt(ObjectId); - writer.Put(BehaviourIndex); - SerializePositionAxis(writer, transformResult.position.x, syncPositionX); - SerializePositionAxis(writer, transformResult.position.y, syncPositionY); - SerializePositionAxis(writer, transformResult.position.z, syncPositionZ); - SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.x, syncRotationX); - SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.y, syncRotationY); - SerializeRotationAxis(writer, transformResult.rotation.eulerAngles.z, syncRotationZ); - writer.Put(GetTimeStamp()); - } - - public void Teleport(Vector3 position, Quaternion rotation) - { - if (IsServer || (ownerClientCanSendTransform && IsOwnerClient)) - { - InitInterpResults(position, rotation); - Snap(position, rotation); - // This function can be called before networked object spawned - // to set initial object transform, so it won't be able to call net function yet. - // So have to avoid net function calling by check is behaviours already setup or not. - if (Identity.IsSetupBehaviours) - CallNetFunction(NetFunction_Teleport, FunctionReceivers.All, position, rotation); - } - } - - public override bool CanSyncBehaviour() - { - return true; - } - - public override bool ShouldSyncBehaviour() - { - return true; - } - - public override void OnSerialize(NetDataWriter writer) - { - SerializePositionAxis(writer, syncingTransform.position.x, syncPositionX); - SerializePositionAxis(writer, syncingTransform.position.y, syncPositionY); - SerializePositionAxis(writer, syncingTransform.position.z, syncPositionZ); - SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.x, syncRotationX); - SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.y, syncRotationY); - SerializeRotationAxis(writer, syncingTransform.rotation.eulerAngles.z, syncRotationZ); - writer.Put(GetTimeStamp()); - } - - public override void OnDeserialize(NetDataReader reader) - { - // Update transform only non-owner client - if ((ownerClientCanSendTransform && IsOwnerClient) || IsServer) - return; - TransformResult result = DeserializeResult(reader); - // Discard out of order results - if (result.timestamp <= lastReceivedTimestamp) - return; - lastReceivedTime = Time.fixedTime; - lastReceivedTimestamp = result.timestamp; - result.timestamp = GetTimeStamp(); - previousEndInterpResult = endInterpResult; - endInterpResult = result; - } - - private TransformResult DeserializeResult(NetDataReader reader) - { - TransformResult result = new TransformResult(); - result.position = new Vector3( - DeserializePositionAxis(reader, syncPositionX, syncingTransform.position.x), - DeserializePositionAxis(reader, syncPositionY, syncingTransform.position.y), - DeserializePositionAxis(reader, syncPositionZ, syncingTransform.position.z)); - result.rotation = Quaternion.Euler( - DeserializeRotationAxis(reader, syncRotationX, syncingTransform.rotation.eulerAngles.x), - DeserializeRotationAxis(reader, syncRotationY, syncingTransform.rotation.eulerAngles.y), - DeserializeRotationAxis(reader, syncRotationZ, syncingTransform.rotation.eulerAngles.z)); - result.timestamp = reader.GetFloat(); - return result; - } - - private void SerializePositionAxis(NetDataWriter writer, float data, SyncPositionOptions syncOptions) - { - switch (syncOptions) - { - case SyncPositionOptions.Sync: - writer.Put(data); - break; - default: - case SyncPositionOptions.NotSync: - break; - } - } - - private void SerializeRotationAxis(NetDataWriter writer, float data, SyncRotationOptions syncOptions) - { - data = To360Angle(data); - switch (syncOptions) - { - case SyncRotationOptions.Sync: - writer.Put(data); - break; - case SyncRotationOptions.CompressToUShort: - writer.Put((ushort)(data * 100)); - break; - case SyncRotationOptions.CompressToByte: - writer.Put((byte)(data / 360f * 100)); - break; - default: - case SyncRotationOptions.NotSync: - break; - } - } - - private float DeserializePositionAxis(NetDataReader reader, SyncPositionOptions syncOptions, float defaultValue) - { - switch (syncOptions) - { - case SyncPositionOptions.Sync: - return reader.GetFloat(); - default: - case SyncPositionOptions.NotSync: - break; - } - return defaultValue; - } - - private float DeserializeRotationAxis(NetDataReader reader, SyncRotationOptions syncOptions, float defaultValue) - { - switch (syncOptions) - { - case SyncRotationOptions.Sync: - return reader.GetFloat(); - case SyncRotationOptions.CompressToUShort: - return (float)reader.GetUShort() * 0.01f; - case SyncRotationOptions.CompressToByte: - return (float)reader.GetByte() * 0.01f * 360f; - default: - case SyncRotationOptions.NotSync: - break; - } - return defaultValue; - } - - private void Update() - { - if (!IsServer && !IsClient) - return; - // Sending transform to all clients - if (IsServer) - { - // Interpolate transform that receives from clients - // So if this is no owning client (ConnectionId < 0), it won't interpolate - if (ownerClientCanSendTransform && !IsOwnerClient && ConnectionId >= 0) - UpdateTransform(Time.deltaTime); - } - // Interpolating results for non-owner client objects on clients - else if (!ownerClientCanSendTransform || !IsOwnerClient) - { - UpdateTransform(Time.deltaTime); - } - } - - private void FixedUpdate() - { - if (!IsServer && !IsClient) - return; - // Sending client transform result to server - // Don't send to server if it's server which already update transform result - // So only owner client can send transform result to server - if (ownerClientCanSendTransform && IsOwnerClient && !IsServer) - { - ownerSendElapsed += Time.fixedDeltaTime; - if (ownerSendElapsed >= ownerClientSendInterval) - { - // Send transform to server only when there are changes on transform - ClientSendTransform(new TransformResult() - { - position = syncingTransform.position, - rotation = syncingTransform.rotation, - timestamp = GetTimeStamp(), - }); - ownerSendElapsed = 0; - } - } - } - - private void UpdateTransform(float deltaTime) - { - if (ShouldSnap(endInterpResult.position)) - { - currentInterpResult.position = endInterpResult.position; - currentInterpResult.rotation = endInterpResult.rotation; - Snap(endInterpResult.position, endInterpResult.rotation); - } - else - { - if (IsOwnerClient && ownerClientCanSendTransform) - { - // If owner client can send transform, it won't interpolating transform at owner client - return; - } - // Calculate move speed by distance and time - float dist = Vector3.Distance(endInterpResult.position, previousEndInterpResult.position); - float timeDiff = endInterpResult.timestamp - previousEndInterpResult.timestamp; - float moveSpeed = 0f; - if (timeDiff > 0f) - moveSpeed = dist / timeDiff; - // Find extrapolated move by move direction, time passed (which calculated by current time and last received time) - // and calculate move speed or fixed extrapolate speed - Vector3 extrapolatedMove = Vector3.zero; - if (extrapolateMode != ExtrapolateMode.None) - { - float timePassed = Time.fixedTime - lastReceivedTime; - Vector3 moveDirection = (endInterpResult.position - previousEndInterpResult.position).normalized; - if (moveDirection.sqrMagnitude > 0f && timePassed > 0f) - { - switch (extrapolateMode) - { - case ExtrapolateMode.EstimatedSpeed: - extrapolatedMove = moveDirection * moveSpeed * timePassed; - break; - case ExtrapolateMode.FixedSpeed: - extrapolatedMove = moveDirection * fixedExtrapolateSpeed * timePassed; - break; - } - } - } - // Set interpolate move speed to fixed value if interpolate mode is fixed speed - if (interpolateMode == InterpolateMode.FixedSpeed) - moveSpeed = fixedInterpolateSpeed; - // Move it - currentInterpResult.position = Vector3.MoveTowards(currentInterpResult.position, endInterpResult.position + extrapolatedMove, moveSpeed * deltaTime); - currentInterpResult.rotation = Quaternion.Slerp(currentInterpResult.rotation, endInterpResult.rotation, (1f / timeDiff) * deltaTime); - Interpolate(currentInterpResult.position, currentInterpResult.rotation); - } - } - - private bool ShouldSnap(Vector3 targetPosition) - { - float dist; - if (CacheRigidbody2D != null) - dist = (CacheRigidbody2D.position - new Vector2(targetPosition.x, targetPosition.y)).sqrMagnitude; - else - dist = (syncingTransform.position - targetPosition).sqrMagnitude; - return dist > snapThreshold * snapThreshold; - } - - private void Snap(Vector3 position, Quaternion rotation) - { - if (CacheNavMeshAgent != null) - { - CacheNavMeshAgent.Warp(position); - syncingTransform.rotation = rotation; - } - else if (CacheRigidbody3D != null && !CacheRigidbody3D.isKinematic) - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - CacheRigidbody3D.position = position; - CacheRigidbody3D.rotation = rotation; - } - else if (CacheRigidbody2D != null && !CacheRigidbody2D.isKinematic) - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - CacheRigidbody2D.position = position; - CacheRigidbody2D.rotation = rotation.eulerAngles.z; - } - else - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - } - } - - private void Interpolate(Vector3 position, Quaternion rotation) - { - if (CacheNavMeshAgent != null) - { - CacheNavMeshAgent.Move(position - syncingTransform.position); - syncingTransform.rotation = rotation; - } - else if (CacheCharacterController != null) - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - } - else if (CacheRigidbody3D != null && !CacheRigidbody3D.isKinematic) - { - if (Vector3.Distance(position, CacheRigidbody3D.position) > 0f) - CacheRigidbody3D.MovePosition(position); - else - { - CacheRigidbody3D.velocity = Vector3.zero; - CacheRigidbody3D.MovePosition(position); - } - syncingTransform.rotation = rotation; - } - else if (CacheRigidbody2D != null && !CacheRigidbody2D.isKinematic) - { - if (Vector2.Distance(position, CacheRigidbody2D.position) > 0f) - CacheRigidbody2D.MovePosition(position); - else - { - CacheRigidbody2D.velocity = Vector2.zero; - CacheRigidbody2D.MovePosition(position); - } - syncingTransform.rotation = rotation; - } - else - { - syncingTransform.position = position; - syncingTransform.rotation = rotation; - } - } - - private float GetTimeStamp() - { - return Time.fixedTime; - } - - #region Math Utilities - public static float To360Angle(float angle) - { - float result = angle - Mathf.CeilToInt(angle / 360f) * 360f; - if (result < 0) - { - result += 360f; - } - return result; - } - #endregion - } -} diff --git a/Scripts/LiteNetLibTransform.cs.meta b/Scripts/LiteNetLibTransform.cs.meta deleted file mode 100644 index c00d84ac..00000000 --- a/Scripts/LiteNetLibTransform.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 8631d361478af9d4895c657221a7b4b1 -timeCreated: 1518974961 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/LiteNetLibVisibleChecker.cs b/Scripts/LiteNetLibVisibleChecker.cs deleted file mode 100644 index 127d365e..00000000 --- a/Scripts/LiteNetLibVisibleChecker.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace LiteNetLibManager -{ - [System.Obsolete("This component is deprecated because interest management system is changed")] - public class LiteNetLibVisibleChecker : BaseLiteNetLibVisibleChecker - { - } -} diff --git a/Scripts/LiteNetLibVisibleChecker.cs.meta b/Scripts/LiteNetLibVisibleChecker.cs.meta deleted file mode 100644 index 71595f13..00000000 --- a/Scripts/LiteNetLibVisibleChecker.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 01d64c7b615199243b727eaa75d79574 -timeCreated: 1519828611 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/EnterGameRequestMessage.cs b/Scripts/Messages/EnterGameRequestMessage.cs deleted file mode 100644 index 54751ae5..00000000 --- a/Scripts/Messages/EnterGameRequestMessage.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct EnterGameRequestMessage : INetSerializable - { - public uint packetVersion; - - public void Deserialize(NetDataReader reader) - { - packetVersion = reader.GetPackedUInt(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedUInt(packetVersion); - } - } -} diff --git a/Scripts/Messages/EnterGameRequestMessage.cs.meta b/Scripts/Messages/EnterGameRequestMessage.cs.meta deleted file mode 100644 index 867f8165..00000000 --- a/Scripts/Messages/EnterGameRequestMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2d5f68ce278e65a49a39b690045b92f3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/EnterGameResponseMessage.cs b/Scripts/Messages/EnterGameResponseMessage.cs deleted file mode 100644 index 9ba0b3c6..00000000 --- a/Scripts/Messages/EnterGameResponseMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public class EnterGameResponseMessage : INetSerializable - { - public long connectionId; - public string serverSceneName; - - public void Deserialize(NetDataReader reader) - { - connectionId = reader.GetPackedLong(); - serverSceneName = reader.GetString(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedLong(connectionId); - writer.Put(serverSceneName); - } - } -} diff --git a/Scripts/Messages/EnterGameResponseMessage.cs.meta b/Scripts/Messages/EnterGameResponseMessage.cs.meta deleted file mode 100644 index 4048842a..00000000 --- a/Scripts/Messages/EnterGameResponseMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 37fe05c61ea31694d888887a9a7f81c3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/GenericValueMessage.cs b/Scripts/Messages/GenericValueMessage.cs deleted file mode 100644 index 53f415b0..00000000 --- a/Scripts/Messages/GenericValueMessage.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System; -using UnityEngine; -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public class GenericValueMessage : INetSerializable - { - public TType value; - - public void Deserialize(NetDataReader reader) - { - value = reader.GetValue(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutValue(value); - } - } - - #region Implement for general usages and serializable - [Serializable] - public class BoolMessage : GenericValueMessage - { - } - - [Serializable] - public class BoolArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class ByteMessage : GenericValueMessage - { - } - - [Serializable] - public class ByteArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class CharMessage : GenericValueMessage - { - } - - [Serializable] - public class DoubleMessage : GenericValueMessage - { - } - - [Serializable] - public class DoubleArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class FloatMessage : GenericValueMessage - { - } - - [Serializable] - public class FloatArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class IntMessage : GenericValueMessage - { - } - - [Serializable] - public class IntArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class LongMessage : GenericValueMessage - { - } - - [Serializable] - public class LongArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class SByteMessage : GenericValueMessage - { - } - - [Serializable] - public class ShortMessage : GenericValueMessage - { - } - - [Serializable] - public class ShortArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class StringMessage : GenericValueMessage - { - } - - [Serializable] - public class UIntMessage : GenericValueMessage - { - } - - [Serializable] - public class UIntArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class ULongMessage : GenericValueMessage - { - } - - [Serializable] - public class ULongArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class UShortMessage : GenericValueMessage - { - } - - [Serializable] - public class UShortArrayMessage : GenericValueMessage - { - } - - [Serializable] - public class ColorMessage : GenericValueMessage - { - } - - [Serializable] - public class QuaternionMessage : GenericValueMessage - { - } - - [Serializable] - public class Vector2Message : GenericValueMessage - { - } - - [Serializable] - public class Vector2IntMessage : GenericValueMessage - { - } - - [Serializable] - public class Vector3Message : GenericValueMessage - { - } - - [Serializable] - public class Vector3IntMessage : GenericValueMessage - { - } - - [Serializable] - public class Vector4Message : GenericValueMessage - { - } - - [Serializable] - public class PackedUShortMessage : GenericValueMessage - { - } - - [Serializable] - public class PackedUIntMessage : GenericValueMessage - { - } - - [Serializable] - public class PackedULongMessage : GenericValueMessage - { - } - #endregion -} diff --git a/Scripts/Messages/GenericValueMessage.cs.meta b/Scripts/Messages/GenericValueMessage.cs.meta deleted file mode 100644 index 7bbfa2c8..00000000 --- a/Scripts/Messages/GenericValueMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 11ec5c0f0e06d5c45ba82e2bf6c1fb2d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/PingMessage.cs b/Scripts/Messages/PingMessage.cs deleted file mode 100644 index ef09e496..00000000 --- a/Scripts/Messages/PingMessage.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct PingMessage : INetSerializable - { - public long pingTime; - - public void Deserialize(NetDataReader reader) - { - pingTime = reader.GetPackedLong(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedLong(pingTime); - } - } -} diff --git a/Scripts/Messages/PingMessage.cs.meta b/Scripts/Messages/PingMessage.cs.meta deleted file mode 100644 index 803acc82..00000000 --- a/Scripts/Messages/PingMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 88aad3795437e6645b550e242d147c13 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/PongMessage.cs b/Scripts/Messages/PongMessage.cs deleted file mode 100644 index 45bce529..00000000 --- a/Scripts/Messages/PongMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct PongMessage : INetSerializable - { - public long pingTime; - public long serverTime; - - public void Deserialize(NetDataReader reader) - { - pingTime = reader.GetPackedLong(); - serverTime = reader.GetPackedLong(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedLong(pingTime); - writer.PutPackedLong(serverTime); - } - } -} diff --git a/Scripts/Messages/PongMessage.cs.meta b/Scripts/Messages/PongMessage.cs.meta deleted file mode 100644 index 987a9c4b..00000000 --- a/Scripts/Messages/PongMessage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0d3b5836388d4de4891673efc33eafd3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/ServerDestroyObjectMessage.cs b/Scripts/Messages/ServerDestroyObjectMessage.cs deleted file mode 100644 index b52a00cc..00000000 --- a/Scripts/Messages/ServerDestroyObjectMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct ServerDestroyObjectMessage : INetSerializable - { - public uint objectId; - public byte reasons; - - public void Deserialize(NetDataReader reader) - { - objectId = reader.GetPackedUInt(); - reasons = reader.GetByte(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedUInt(objectId); - writer.Put(reasons); - } - } -} diff --git a/Scripts/Messages/ServerDestroyObjectMessage.cs.meta b/Scripts/Messages/ServerDestroyObjectMessage.cs.meta deleted file mode 100644 index 724d0820..00000000 --- a/Scripts/Messages/ServerDestroyObjectMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 58f4f8e22dbb4a94f874aceb5815dc44 -timeCreated: 1508932284 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/ServerErrorMessage.cs b/Scripts/Messages/ServerErrorMessage.cs deleted file mode 100644 index 9f6ecd64..00000000 --- a/Scripts/Messages/ServerErrorMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct ServerErrorMessage : INetSerializable - { - public bool shouldDisconnect; - public string errorMessage; - - public void Deserialize(NetDataReader reader) - { - shouldDisconnect = reader.GetBool(); - errorMessage = reader.GetString(); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(shouldDisconnect); - writer.Put(errorMessage); - } - } -} \ No newline at end of file diff --git a/Scripts/Messages/ServerErrorMessage.cs.meta b/Scripts/Messages/ServerErrorMessage.cs.meta deleted file mode 100644 index ee5136df..00000000 --- a/Scripts/Messages/ServerErrorMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: b4d19b05d26f3854d83d967efef217e4 -timeCreated: 1519725292 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/ServerSceneChangeMessage.cs b/Scripts/Messages/ServerSceneChangeMessage.cs deleted file mode 100644 index 90c6e62b..00000000 --- a/Scripts/Messages/ServerSceneChangeMessage.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct ServerSceneChangeMessage : INetSerializable - { - public string serverSceneName; - - public void Deserialize(NetDataReader reader) - { - serverSceneName = reader.GetString(); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(serverSceneName); - } - } -} diff --git a/Scripts/Messages/ServerSceneChangeMessage.cs.meta b/Scripts/Messages/ServerSceneChangeMessage.cs.meta deleted file mode 100644 index b26fb39b..00000000 --- a/Scripts/Messages/ServerSceneChangeMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: c69e59286bb7023469ad76ddcc7c4dad -timeCreated: 1525038105 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/ServerSetObjectOwner.cs b/Scripts/Messages/ServerSetObjectOwner.cs deleted file mode 100644 index 358fb3d0..00000000 --- a/Scripts/Messages/ServerSetObjectOwner.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteNetLib.Utils; - -namespace LiteNetLibManager -{ - public struct ServerSetObjectOwner : INetSerializable - { - public uint objectId; - public long connectionId; - - public void Deserialize(NetDataReader reader) - { - objectId = reader.GetPackedUInt(); - connectionId = reader.GetPackedLong(); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedUInt(objectId); - writer.PutPackedLong(connectionId); - } - } -} diff --git a/Scripts/Messages/ServerSetObjectOwner.cs.meta b/Scripts/Messages/ServerSetObjectOwner.cs.meta deleted file mode 100644 index 0a5878c0..00000000 --- a/Scripts/Messages/ServerSetObjectOwner.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d3015cf7812103846aa5fbb5cc484b38 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/ServerSpawnObjectMessage.cs b/Scripts/Messages/ServerSpawnObjectMessage.cs deleted file mode 100644 index 39c29677..00000000 --- a/Scripts/Messages/ServerSpawnObjectMessage.cs +++ /dev/null @@ -1,36 +0,0 @@ -using LiteNetLib.Utils; -using UnityEngine; - -namespace LiteNetLibManager -{ - public struct ServerSpawnObjectMessage : INetSerializable - { - public int hashAssetId; - public uint objectId; - public long connectionId; - public Vector3 position; - public Quaternion rotation; - - public void Deserialize(NetDataReader reader) - { - hashAssetId = reader.GetPackedInt(); - objectId = reader.GetPackedUInt(); - connectionId = reader.GetPackedLong(); - position = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - rotation = Quaternion.Euler(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedInt(hashAssetId); - writer.PutPackedUInt(objectId); - writer.PutPackedLong(connectionId); - writer.Put(position.x); - writer.Put(position.y); - writer.Put(position.z); - writer.Put(rotation.eulerAngles.x); - writer.Put(rotation.eulerAngles.y); - writer.Put(rotation.eulerAngles.z); - } - } -} diff --git a/Scripts/Messages/ServerSpawnObjectMessage.cs.meta b/Scripts/Messages/ServerSpawnObjectMessage.cs.meta deleted file mode 100644 index 5bd06b1f..00000000 --- a/Scripts/Messages/ServerSpawnObjectMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 9823c3024abd0c348bb5e297226e819a -timeCreated: 1508932284 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Messages/ServerSpawnSceneObjectMessage.cs b/Scripts/Messages/ServerSpawnSceneObjectMessage.cs deleted file mode 100644 index 95a63b48..00000000 --- a/Scripts/Messages/ServerSpawnSceneObjectMessage.cs +++ /dev/null @@ -1,33 +0,0 @@ -using LiteNetLib.Utils; -using UnityEngine; - -namespace LiteNetLibManager -{ - public struct ServerSpawnSceneObjectMessage : INetSerializable - { - public uint objectId; - public long connectionId; - public Vector3 position; - public Quaternion rotation; - - public void Deserialize(NetDataReader reader) - { - objectId = reader.GetPackedUInt(); - connectionId = reader.GetPackedLong(); - position = new Vector3(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - rotation = Quaternion.Euler(reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); - } - - public void Serialize(NetDataWriter writer) - { - writer.PutPackedUInt(objectId); - writer.PutPackedLong(connectionId); - writer.Put(position.x); - writer.Put(position.y); - writer.Put(position.z); - writer.Put(rotation.eulerAngles.x); - writer.Put(rotation.eulerAngles.y); - writer.Put(rotation.eulerAngles.z); - } - } -} diff --git a/Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta b/Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta deleted file mode 100644 index 65404916..00000000 --- a/Scripts/Messages/ServerSpawnSceneObjectMessage.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 3a57f78648eb8cd4d900d0097f0bd20c -timeCreated: 1511672224 -licenseType: Pro -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 1eb93c4492fb5fc05474908d58fb1c5c9aa486a9 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 06:01:26 +0700 Subject: [PATCH 29/58] Add process update function --- Scripts/LiteNetLibManager.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Scripts/LiteNetLibManager.cs b/Scripts/LiteNetLibManager.cs index 648afefe..88b4ae9f 100644 --- a/Scripts/LiteNetLibManager.cs +++ b/Scripts/LiteNetLibManager.cs @@ -111,6 +111,11 @@ protected void InitTransportAndHandlers() RegisterMessages(); } + public void ProcessUpdate() + { + FixedUpdate(); + } + protected virtual void FixedUpdate() { if (IsServer) From cbf394322950970f8c7f56bf96714b65d33d3fbb Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 06:36:04 +0700 Subject: [PATCH 30/58] Add NetCoreServer into dep list --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fe746bc4..1f559822 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,5 @@ The document: https://insthync.github.io/LiteNetLibManager - LiteNetLib - UniTask - ZLogger -- ZString \ No newline at end of file +- ZString +- NetCoreServer \ No newline at end of file From 2d3d86d53440732167769f42bf2f54dd2c5a2e1e Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 06:55:33 +0700 Subject: [PATCH 31/58] feat: cast to IPEndpoint to make it work --- Scripts/Transports/WebSocket/WsTransportClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/Transports/WebSocket/WsTransportClient.cs b/Scripts/Transports/WebSocket/WsTransportClient.cs index 9513d289..a05b94a1 100644 --- a/Scripts/Transports/WebSocket/WsTransportClient.cs +++ b/Scripts/Transports/WebSocket/WsTransportClient.cs @@ -18,9 +18,9 @@ public WsTransportClient(ConcurrentQueue eventQueue, IPAddre public override void OnWsConnecting(HttpRequest request) { - Uri uri = new Uri($"wss://{Endpoint.Address}:{Endpoint.Port}"); + Uri uri = new Uri($"wss://{((IPEndPoint)Endpoint).Address}:{((IPEndPoint)Endpoint).Port}"); request.SetBegin("GET", uri.PathAndQuery); - request.SetHeader("Host", Endpoint.Port == 80 ? uri.DnsSafeHost : uri.Authority); + request.SetHeader("Host", ((IPEndPoint)Endpoint).Port == 80 ? uri.DnsSafeHost : uri.Authority); request.SetHeader("Upgrade", "websocket"); request.SetHeader("Connection", "Upgrade"); request.SetHeader("Sec-WebSocket-Key", Convert.ToBase64String(WsNonce)); From 40f8021ecd1248a2e0c26705e48e1d7dd47f34fe Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 07:20:41 +0700 Subject: [PATCH 32/58] Revert "Revert "feat: delete codes for Unity (PackedVariables)"" This reverts commit d6854692b8ef7f5dc987f5a7ed8be36111aae5f7. --- Scripts/PackedVariables/DirectionVector2.cs | 31 ----------------- .../PackedVariables/DirectionVector2.cs.meta | 11 ------- Scripts/PackedVariables/DirectionVector3.cs | 33 ------------------- .../PackedVariables/DirectionVector3.cs.meta | 11 ------- 4 files changed, 86 deletions(-) delete mode 100644 Scripts/PackedVariables/DirectionVector2.cs delete mode 100644 Scripts/PackedVariables/DirectionVector2.cs.meta delete mode 100644 Scripts/PackedVariables/DirectionVector3.cs delete mode 100644 Scripts/PackedVariables/DirectionVector3.cs.meta diff --git a/Scripts/PackedVariables/DirectionVector2.cs b/Scripts/PackedVariables/DirectionVector2.cs deleted file mode 100644 index 502f3e4a..00000000 --- a/Scripts/PackedVariables/DirectionVector2.cs +++ /dev/null @@ -1,31 +0,0 @@ -using UnityEngine; -using LiteNetLib.Utils; - -public struct DirectionVector2 : INetSerializable -{ - public static implicit operator DirectionVector2(Vector2 value) { return new DirectionVector2(value); } - public static implicit operator DirectionVector2(Vector3 value) { return new DirectionVector2(value); } - public static implicit operator Vector2(DirectionVector2 value) { return new Vector2((float)value.x / 100f, (float)value.y / 100f); } - public static implicit operator Vector3(DirectionVector2 value) { return new Vector2((float)value.x / 100f, (float)value.y / 100f); } - - public sbyte x; - public sbyte y; - - public DirectionVector2(Vector2 vector2) - { - x = (sbyte)(vector2.x * 100); - y = (sbyte)(vector2.y * 100); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(x); - writer.Put(y); - } - - public void Deserialize(NetDataReader reader) - { - x = reader.GetSByte(); - y = reader.GetSByte(); - } -} diff --git a/Scripts/PackedVariables/DirectionVector2.cs.meta b/Scripts/PackedVariables/DirectionVector2.cs.meta deleted file mode 100644 index 65cf13fe..00000000 --- a/Scripts/PackedVariables/DirectionVector2.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 614856a984a532b41af2b7d04e5daac7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/PackedVariables/DirectionVector3.cs b/Scripts/PackedVariables/DirectionVector3.cs deleted file mode 100644 index 1c481bf5..00000000 --- a/Scripts/PackedVariables/DirectionVector3.cs +++ /dev/null @@ -1,33 +0,0 @@ -using UnityEngine; -using LiteNetLib.Utils; - -public struct DirectionVector3 : INetSerializable -{ - public static implicit operator DirectionVector3(Vector3 value) { return new DirectionVector3(value); } - public static implicit operator Vector3(DirectionVector3 value) { return new Vector3((float)value.x / 100f, (float)value.y / 100f, (float)value.z / 100f); } - - public sbyte x; - public sbyte y; - public sbyte z; - - public DirectionVector3(Vector3 vector3) - { - x = (sbyte)(vector3.x * 100); - y = (sbyte)(vector3.y * 100); - z = (sbyte)(vector3.z * 100); - } - - public void Serialize(NetDataWriter writer) - { - writer.Put(x); - writer.Put(y); - writer.Put(z); - } - - public void Deserialize(NetDataReader reader) - { - x = reader.GetSByte(); - y = reader.GetSByte(); - z = reader.GetSByte(); - } -} diff --git a/Scripts/PackedVariables/DirectionVector3.cs.meta b/Scripts/PackedVariables/DirectionVector3.cs.meta deleted file mode 100644 index 69f23628..00000000 --- a/Scripts/PackedVariables/DirectionVector3.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 708f62165f063f04caf500f67a4a3311 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From f61b0e355e0e250717695753c0e3effc051d6ca1 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Thu, 27 Apr 2023 07:33:53 +0700 Subject: [PATCH 33/58] feat: cast to IPEndpoint to make it work --- Scripts/Transports/WebSocket/WssTransportClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/Transports/WebSocket/WssTransportClient.cs b/Scripts/Transports/WebSocket/WssTransportClient.cs index 9de033a3..49a165e1 100644 --- a/Scripts/Transports/WebSocket/WssTransportClient.cs +++ b/Scripts/Transports/WebSocket/WssTransportClient.cs @@ -18,9 +18,9 @@ public WssTransportClient(ConcurrentQueue eventQueue, SslCon public override void OnWsConnecting(HttpRequest request) { - Uri uri = new Uri($"wss://{Endpoint.Address}:{Endpoint.Port}"); + Uri uri = new Uri($"wss://{((IPEndPoint)Endpoint).Address}:{((IPEndPoint)Endpoint).Port}"); request.SetBegin("GET", uri.PathAndQuery); - request.SetHeader("Host", Endpoint.Port == 443 ? uri.DnsSafeHost : uri.Authority); + request.SetHeader("Host", ((IPEndPoint)Endpoint).Port == 443 ? uri.DnsSafeHost : uri.Authority); request.SetHeader("Upgrade", "websocket"); request.SetHeader("Connection", "Upgrade"); request.SetHeader("Sec-WebSocket-Key", Convert.ToBase64String(WsNonce)); From 032dfbc8c187ec38ab6afbe9e579b98b6ac3750c Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Sun, 30 Apr 2023 03:31:25 +0700 Subject: [PATCH 34/58] improve: add log tag when write log --- Scripts/TransportHandler.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Scripts/TransportHandler.cs b/Scripts/TransportHandler.cs index 6a3ecab7..1afc1af0 100644 --- a/Scripts/TransportHandler.cs +++ b/Scripts/TransportHandler.cs @@ -43,7 +43,7 @@ public bool EnableRequestResponse(ushort requestMessageType, ushort responseMess messageHandlers.ContainsKey(requestMessageType) || messageHandlers.ContainsKey(responseMessageType)) { - Logging.LogError($"Cannot enable request-response feature, request/response message type must be different and not registered."); + Logging.LogError(LogTag, $"Cannot enable request-response feature, request/response message type must be different and not registered."); DisableRequestResponse(); return false; } @@ -154,13 +154,13 @@ protected bool CreateAndWriteRequest( if (!responseHandlers.ContainsKey(requestType)) { responseDelegate.Invoke(new ResponseHandlerData(nextRequestId++, this, -1, null), AckResponseCode.Unimplemented, EmptyMessage.Value); - Logging.LogError($"Cannot create request. Request type: {requestType} not registered."); + Logging.LogError(LogTag, $"Cannot create request. Request type: {requestType} not registered."); return false; } if (!responseHandlers[requestType].IsRequestTypeValid(typeof(TRequest))) { responseDelegate.Invoke(new ResponseHandlerData(nextRequestId++, this, -1, null), AckResponseCode.Unimplemented, EmptyMessage.Value); - Logging.LogError($"Cannot create request. Request type: {requestType}, {typeof(TRequest)} is not valid message type."); + Logging.LogError(LogTag, $"Cannot create request. Request type: {requestType}, {typeof(TRequest)} is not valid message type."); return false; } // Create request @@ -192,7 +192,7 @@ private void ProceedRequest( { // No request-response handler RequestProceeded(connectionId, requestId, AckResponseCode.Unimplemented, EmptyMessage.Value, null); - Logging.LogError($"Cannot proceed request {requestType} not registered."); + Logging.LogError(LogTag, $"Cannot proceed request {requestType} not registered."); return; } // Invoke request and create response @@ -290,7 +290,7 @@ public void RegisterMessageHandler( { if (RequestResponseEnabled && (RequestMessageType == messageType || ResponseMessageType == messageType)) { - Logging.LogError($"Cannot register message, message type must be difference to request/response message types."); + Logging.LogError(LogTag, $"Cannot register message, message type must be difference to request/response message types."); return; } messageHandlers[messageType] = handlerDelegate; From 3691cfb85b8a0b52b911dba71a03c83deed60f45 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Sun, 30 Apr 2023 04:40:57 +0700 Subject: [PATCH 35/58] improve: set log format --- Scripts/Logging/LogManager.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Scripts/Logging/LogManager.cs b/Scripts/Logging/LogManager.cs index 61e22cf0..f4943876 100644 --- a/Scripts/Logging/LogManager.cs +++ b/Scripts/Logging/LogManager.cs @@ -61,15 +61,14 @@ static LogManager() public static void Initialize() { - // Standard LoggerFactory does not work on IL2CPP, - // But you can use ZLogger's UnityLoggerFactory instead, - // it works on IL2CPP, all platforms(includes mobile). DefaultLoggerManager = new LoggerManager(LoggerFactory.Create(builder => { // or more configuration, you can use builder.AddFilter - builder.ClearProviders(); builder.SetMinimumLevel(LogLevel.Trace); - builder.AddZLoggerConsole(); + builder.AddZLoggerConsole((options) => + { + options.PrefixFormatter = PrefixFormatterConfigure; + }); })); DefaultLoggerManager.Logger.LogInformation("===== Logger Initialized ====="); From 93dc3a43c14abec8a4cdb071a92025e269d8ce60 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Sun, 14 May 2023 07:58:43 +0700 Subject: [PATCH 36/58] feat: implement logic updater for fixed time updating --- Scripts/LiteNetLibDelegates.cs | 14 +--- Scripts/LiteNetLibManager.cs | 100 ++++++++++++++++++++--------- Scripts/Utils/LogicUpdater.cs | 95 +++++++++++++++++++++++++++ Scripts/Utils/LogicUpdater.cs.meta | 11 ++++ 4 files changed, 179 insertions(+), 41 deletions(-) create mode 100644 Scripts/Utils/LogicUpdater.cs create mode 100644 Scripts/Utils/LogicUpdater.cs.meta diff --git a/Scripts/LiteNetLibDelegates.cs b/Scripts/LiteNetLibDelegates.cs index 3067fa6a..bc46647f 100644 --- a/Scripts/LiteNetLibDelegates.cs +++ b/Scripts/LiteNetLibDelegates.cs @@ -3,6 +3,7 @@ namespace LiteNetLibManager { + public delegate void SerializerDelegate(NetDataWriter writer); public delegate void MessageHandlerDelegate(MessageHandlerData messageHandler); public delegate void RequestProceedResultDelegate(AckResponseCode responseCode, TResponse response, SerializerDelegate extraResponseSerializer = null) where TResponse : INetSerializable; @@ -12,18 +13,7 @@ public delegate UniTaskVoid RequestDelegate(RequestHandlerD where TResponse : INetSerializable; public delegate void ResponseDelegate(ResponseHandlerData responseHandler, AckResponseCode responseCode, TResponse response) where TResponse : INetSerializable; - public delegate void SerializerDelegate(NetDataWriter writer); - public delegate void NetFunctionDelegate(); - public delegate void NetFunctionDelegate(T1 param1); - public delegate void NetFunctionDelegate(T1 param1, T2 param2); - public delegate void NetFunctionDelegate(T1 param1, T2 param2, T3 param3); - public delegate void NetFunctionDelegate(T1 param1, T2 param2, T3 param3, T4 param4); - public delegate void NetFunctionDelegate(T1 param1, T2 param2, T3 param3, T4 param4, T5 param5); - public delegate void NetFunctionDelegate(T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6); - public delegate void NetFunctionDelegate(T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7); - public delegate void NetFunctionDelegate(T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8); - public delegate void NetFunctionDelegate(T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9); - public delegate void NetFunctionDelegate(T1 param1, T2 param2, T3 param3, T4 param4, T5 param5, T6 param6, T7 param7, T8 param8, T9 param9, T10 param10); + public delegate void LogicUpdateDelegate(LogicUpdater updater); public static class DelegateExtensions { diff --git a/Scripts/LiteNetLibManager.cs b/Scripts/LiteNetLibManager.cs index 88b4ae9f..99ece390 100644 --- a/Scripts/LiteNetLibManager.cs +++ b/Scripts/LiteNetLibManager.cs @@ -29,39 +29,44 @@ public class LiteNetLibManager public bool webSocketSecure = false; public string webSocketCertificateFilePath = string.Empty; public string webSocketCertificatePassword = string.Empty; + public byte updateFps = 20; public int maxConnections = 4; - private BaseTransportFactory transportFactory; + + private BaseTransportFactory _transportFactory; public BaseTransportFactory TransportFactory { - get { return transportFactory; } - set { transportFactory = value; } + get { return _transportFactory; } + set { _transportFactory = value; } } - private ITransport offlineTransport; - private ITransport clientTransport; + private ITransport _offlineTransport; + private ITransport _clientTransport; public ITransport ClientTransport { - get { return IsOfflineConnection ? offlineTransport : clientTransport; } + get { return IsOfflineConnection ? _offlineTransport : _clientTransport; } } - private ITransport serverTransport; + private ITransport _serverTransport; public ITransport ServerTransport { - get { return IsOfflineConnection ? offlineTransport : serverTransport; } + get { return IsOfflineConnection ? _offlineTransport : _serverTransport; } } public bool IsOfflineConnection { get; protected set; } - private string logTag; + private string _logTag; public virtual string LogTag { get { - if (string.IsNullOrEmpty(logTag)) - logTag = $"{GetType().Name}"; - return logTag; + if (string.IsNullOrEmpty(_logTag)) + _logTag = $"{GetType().Name}"; + return _logTag; } } + private LogicUpdater _serverUpdater; + private LogicUpdater _clientUpdater; + public LiteNetLibManager() { InitTransportAndHandlers(); @@ -71,41 +76,41 @@ protected void PrepareTransportFactory() { if (useWebSocket) { - if (transportFactory == null || !(transportFactory is IWebSocketTransportFactory)) + if (_transportFactory == null || !(_transportFactory is IWebSocketTransportFactory)) { WebSocketTransportFactory webSocketTransportFactory = new WebSocketTransportFactory(); webSocketTransportFactory.Secure = webSocketSecure; webSocketTransportFactory.CertificateFilePath = webSocketCertificateFilePath; webSocketTransportFactory.CertificatePassword = webSocketCertificatePassword; - transportFactory = webSocketTransportFactory; + _transportFactory = webSocketTransportFactory; } } else { - if (transportFactory == null) - transportFactory = new LiteNetLibTransportFactory(); + if (_transportFactory == null) + _transportFactory = new LiteNetLibTransportFactory(); } } public void PrepareClientTransport() { PrepareTransportFactory(); - if (clientTransport != null) - clientTransport.Destroy(); - clientTransport = transportFactory.Build(); + if (_clientTransport != null) + _clientTransport.Destroy(); + _clientTransport = _transportFactory.Build(); } public void PrepareServerTransport() { PrepareTransportFactory(); - if (serverTransport != null) - serverTransport.Destroy(); - serverTransport = transportFactory.Build(); + if (_serverTransport != null) + _serverTransport.Destroy(); + _serverTransport = _transportFactory.Build(); } protected void InitTransportAndHandlers() { - offlineTransport = new OfflineTransport(); + _offlineTransport = new OfflineTransport(); Client = new LiteNetLibClient(this); Server = new LiteNetLibServer(this); RegisterMessages(); @@ -113,24 +118,49 @@ protected void InitTransportAndHandlers() public void ProcessUpdate() { - FixedUpdate(); + Update(); } - protected virtual void FixedUpdate() + protected virtual void Update() { if (IsServer) + { + _serverUpdater.Update(); Server.Update(); + } if (IsClient) + { + _clientUpdater.Update(); Client.Update(); + } + } + + protected virtual void OnServerUpdate(LogicUpdater updater) + { + } + + protected virtual void OnClientUpdate(LogicUpdater updater) + { } protected virtual void OnDestroy() { StopHost(); - if (clientTransport != null) - clientTransport.Destroy(); - if (serverTransport != null) - serverTransport.Destroy(); + if (_clientTransport != null) + _clientTransport.Destroy(); + if (_serverTransport != null) + _serverTransport.Destroy(); + } + + protected virtual void OnApplicationQuit() + { +#if UNITY_EDITOR + StopHost(); + if (_clientTransport != null) + _clientTransport.Destroy(); + if (_serverTransport != null) + _serverTransport.Destroy(); +#endif } /// @@ -152,6 +182,10 @@ public virtual bool StartServer() if (LogError) Logging.LogError(LogTag, $"Cannot start server at port: {networkPort}."); return false; } + if (_serverUpdater != null) + _serverUpdater.Stop(); + _serverUpdater = new LogicUpdater(updateFps, OnServerUpdate); + _serverUpdater.Start(); IsServer = true; OnStartServer(); return true; @@ -179,6 +213,10 @@ public virtual bool StartClient(string networkAddress, int networkPort) if (LogError) Logging.LogError(LogTag, $"Cannot connect to {networkAddress}:{networkPort}."); return false; } + if (_clientUpdater != null) + _clientUpdater.Stop(); + _clientUpdater = new LogicUpdater(updateFps, OnClientUpdate); + _clientUpdater.Start(); IsClient = true; OnStartClient(Client); return true; @@ -213,6 +251,8 @@ public void StopServer() return; if (LogInfo) Logging.Log(LogTag, "StopServer"); + if (_serverUpdater != null) + _serverUpdater.Stop(); IsServer = false; Server.StopServer(); OnStopServer(); @@ -230,6 +270,8 @@ public void StopClient() return; if (LogInfo) Logging.Log(LogTag, "StopClient"); + if (_clientUpdater != null) + _clientUpdater.Stop(); IsClient = false; Client.StopClient(); OnStopClient(); diff --git a/Scripts/Utils/LogicUpdater.cs b/Scripts/Utils/LogicUpdater.cs new file mode 100644 index 00000000..89d2c51d --- /dev/null +++ b/Scripts/Utils/LogicUpdater.cs @@ -0,0 +1,95 @@ +using System.Diagnostics; + +namespace LiteNetLibManager +{ + public class LogicUpdater + { + private const int MaxTicksPerUpdate = 5; + /// + /// FPS of game logic + /// + public int FramesPerSecond { get; private set; } + + /// + /// Fixed delta time + /// + public double DeltaTime { get; private set; } + + /// + /// Fixed delta time (float for less precision) + /// + public float DeltaTimeF { get; private set; } + public double VisualDeltaTime { get; private set; } + + + private readonly long _deltaTimeTicks; + private long _accumulator; + private long _lastTime; + + private readonly Stopwatch _stopwatch; + private readonly double _stopwatchFrequency; + private readonly LogicUpdateDelegate _action; + + public LogicUpdater(byte framesPerSecond, LogicUpdateDelegate action) + { + FramesPerSecond = framesPerSecond; + DeltaTime = 1.0 / framesPerSecond; + DeltaTimeF = (float)DeltaTime; + _stopwatch = new Stopwatch(); + _stopwatchFrequency = 1.0 / Stopwatch.Frequency; + _deltaTimeTicks = (long)(DeltaTime * Stopwatch.Frequency); + _action = action; + } + + public void Start() + { + Reset(); + } + + public void Stop() + { + _stopwatch.Stop(); + } + + public void Reset() + { + VisualDeltaTime = 0.0; + _accumulator = 0; + _lastTime = 0; + _stopwatch.Restart(); + } + + protected virtual void OnAction() + { + if (_action != null) + _action.Invoke(this); + } + + /// + /// Main update method, updates internal fixed timer and do all other stuff + /// + public virtual void Update() + { + long elapsedTicks = _stopwatch.ElapsedTicks; + long ticksDelta = elapsedTicks - _lastTime; + VisualDeltaTime = ticksDelta * _stopwatchFrequency; + _accumulator += ticksDelta; + _lastTime = elapsedTicks; + + int updates = 0; + while (_accumulator >= _deltaTimeTicks) + { + // Lag + if (updates >= MaxTicksPerUpdate) + { + _accumulator = 0; + return; + } + OnAction(); + + _accumulator -= _deltaTimeTicks; + updates++; + } + } + } +} diff --git a/Scripts/Utils/LogicUpdater.cs.meta b/Scripts/Utils/LogicUpdater.cs.meta new file mode 100644 index 00000000..15cbc6f1 --- /dev/null +++ b/Scripts/Utils/LogicUpdater.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b1efa91fae56f348a40eab325a1d220 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 41c155902ac0d1cefbf973d5c0c96b78e1325001 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Tue, 27 Jun 2023 16:22:35 +0700 Subject: [PATCH 37/58] improve: allow to write any kind of list and dictionary --- Scripts/Extensions/NetDataWriterExtension.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/Extensions/NetDataWriterExtension.cs b/Scripts/Extensions/NetDataWriterExtension.cs index a5db112a..4ce531ee 100644 --- a/Scripts/Extensions/NetDataWriterExtension.cs +++ b/Scripts/Extensions/NetDataWriterExtension.cs @@ -232,7 +232,7 @@ public static void PutArray(this NetDataWriter writer, Type type, object array) } } - public static void PutList(this NetDataWriter writer, List list) + public static void PutList(this NetDataWriter writer, IList list) { if (list == null) { @@ -246,7 +246,7 @@ public static void PutList(this NetDataWriter writer, List list) } } - public static void PutDictionary(this NetDataWriter writer, Dictionary dict) + public static void PutDictionary(this NetDataWriter writer, IDictionary dict) { if (dict == null) { From 252d0e000dceee5980b276e53d59661c940c62b8 Mon Sep 17 00:00:00 2001 From: insthync Date: Tue, 7 May 2024 16:03:49 +0700 Subject: [PATCH 38/58] feat: delete unused extra serializer from request handler, tell client when error occurs at server. --- Scripts/LiteNetLibDelegates.cs | 12 +++++----- .../LiteNetLibRequestHandler.cs | 24 +++++++++++++------ Scripts/TransportHandler.cs | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/Scripts/LiteNetLibDelegates.cs b/Scripts/LiteNetLibDelegates.cs index bc46647f..d3e7d79f 100644 --- a/Scripts/LiteNetLibDelegates.cs +++ b/Scripts/LiteNetLibDelegates.cs @@ -5,9 +5,9 @@ namespace LiteNetLibManager { public delegate void SerializerDelegate(NetDataWriter writer); public delegate void MessageHandlerDelegate(MessageHandlerData messageHandler); - public delegate void RequestProceedResultDelegate(AckResponseCode responseCode, TResponse response, SerializerDelegate extraResponseSerializer = null) + public delegate void RequestProceedResultDelegate(AckResponseCode responseCode, TResponse response) where TResponse : INetSerializable; - public delegate void RequestProceededDelegate(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response, SerializerDelegate extraResponseSerializer); + public delegate void RequestProceededDelegate(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response); public delegate UniTaskVoid RequestDelegate(RequestHandlerData requestHandler, TRequest request, RequestProceedResultDelegate responseProceedResult) where TRequest : INetSerializable where TResponse : INetSerializable; @@ -17,16 +17,16 @@ public delegate void ResponseDelegate(ResponseHandlerData responseHan public static class DelegateExtensions { - public static void InvokeSuccess(this RequestProceedResultDelegate target, TResponse response, SerializerDelegate responseExtraSerializer = null) + public static void InvokeSuccess(this RequestProceedResultDelegate target, TResponse response) where TResponse : INetSerializable { - target.Invoke(AckResponseCode.Success, response, responseExtraSerializer); + target.Invoke(AckResponseCode.Success, response); } - public static void InvokeError(this RequestProceedResultDelegate target, TResponse response, SerializerDelegate responseExtraSerializer = null) + public static void InvokeError(this RequestProceedResultDelegate target, TResponse response) where TResponse : INetSerializable { - target.Invoke(AckResponseCode.Error, response, responseExtraSerializer); + target.Invoke(AckResponseCode.Error, response); } } } diff --git a/Scripts/RequestResponse/LiteNetLibRequestHandler.cs b/Scripts/RequestResponse/LiteNetLibRequestHandler.cs index a16c6288..0f7d01eb 100644 --- a/Scripts/RequestResponse/LiteNetLibRequestHandler.cs +++ b/Scripts/RequestResponse/LiteNetLibRequestHandler.cs @@ -11,21 +11,31 @@ public struct LiteNetLibRequestHandler : ILiteNetLibRequest where TRequest : INetSerializable, new() where TResponse : INetSerializable, new() { - private RequestDelegate requestHandler; + private TransportHandler _transportHandler; + private RequestDelegate _requestHandler; - public LiteNetLibRequestHandler(RequestDelegate requestHandler) + public LiteNetLibRequestHandler(TransportHandler transportHandler, RequestDelegate requestHandler) { - this.requestHandler = requestHandler; + _transportHandler = transportHandler; + _requestHandler = requestHandler; } public void InvokeRequest(RequestHandlerData requestHandlerData, RequestProceededDelegate responseProceedHandler) { TRequest request = new TRequest(); - if (requestHandlerData.Reader != null) - request.Deserialize(requestHandlerData.Reader); - if (requestHandler != null) + string logTag = _transportHandler == null ? string.Empty : _transportHandler.LogTag; + try { - requestHandler.Invoke(requestHandlerData, request, (responseCode, response, extraResponseSerializer) => responseProceedHandler.Invoke(requestHandlerData.ConnectionId, requestHandlerData.RequestId, responseCode, response, extraResponseSerializer)); + if (requestHandlerData.Reader != null) + request.Deserialize(requestHandlerData.Reader); + if (_requestHandler != null) + _requestHandler.Invoke(requestHandlerData, request, (responseCode, response) => responseProceedHandler.Invoke(requestHandlerData.ConnectionId, requestHandlerData.RequestId, responseCode, response)); + } + catch (System.Exception ex) + { + responseProceedHandler.Invoke(requestHandlerData.ConnectionId, requestHandlerData.RequestId, AckResponseCode.Error, new TResponse()); + Logging.LogError(logTag, $"Error occuring while proceed request {requestHandlerData.RequestType}"); + Logging.LogException(logTag, ex); } } } diff --git a/Scripts/TransportHandler.cs b/Scripts/TransportHandler.cs index 1afc1af0..4e570c21 100644 --- a/Scripts/TransportHandler.cs +++ b/Scripts/TransportHandler.cs @@ -250,7 +250,7 @@ public void RegisterRequestHandler( where TRequest : INetSerializable, new() where TResponse : INetSerializable, new() { - requestHandlers[requestType] = new LiteNetLibRequestHandler(handlerDelegate); + requestHandlers[requestType] = new LiteNetLibRequestHandler(LogTag, handlerDelegate); } public void UnregisterRequestHandler(ushort requestType) From 10e9881e6d36ac7266bad2c00f341626ea0aee25 Mon Sep 17 00:00:00 2001 From: insthync Date: Tue, 7 May 2024 16:04:53 +0700 Subject: [PATCH 39/58] feat: delete unused extra serializer from request handler, tell client when error occurs at server. --- Scripts/TransportHandler.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Scripts/TransportHandler.cs b/Scripts/TransportHandler.cs index 4e570c21..e6e3dea6 100644 --- a/Scripts/TransportHandler.cs +++ b/Scripts/TransportHandler.cs @@ -191,7 +191,7 @@ private void ProceedRequest( if (!requestHandlers.ContainsKey(requestType)) { // No request-response handler - RequestProceeded(connectionId, requestId, AckResponseCode.Unimplemented, EmptyMessage.Value, null); + RequestProceeded(connectionId, requestId, AckResponseCode.Unimplemented, EmptyMessage.Value); Logging.LogError(LogTag, $"Cannot proceed request {requestType} not registered."); return; } @@ -207,7 +207,7 @@ private void ProceedRequest( /// /// /// - private void RequestProceeded(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response, SerializerDelegate extraResponseSerializer) + private void RequestProceeded(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response) { // Write response Writer.Reset(); @@ -215,8 +215,6 @@ private void RequestProceeded(long connectionId, uint requestId, AckResponseCode Writer.PutPackedUInt(requestId); Writer.PutValue(responseCode); Writer.Put(response); - if (extraResponseSerializer != null) - extraResponseSerializer.Invoke(Writer); // Send response SendMessage(connectionId, 0, DeliveryMethod.ReliableUnordered, Writer); } @@ -250,7 +248,7 @@ public void RegisterRequestHandler( where TRequest : INetSerializable, new() where TResponse : INetSerializable, new() { - requestHandlers[requestType] = new LiteNetLibRequestHandler(LogTag, handlerDelegate); + requestHandlers[requestType] = new LiteNetLibRequestHandler(this, handlerDelegate); } public void UnregisterRequestHandler(ushort requestType) From f958aa7a0afdc341ee58b0060bcfcf2fe826fc02 Mon Sep 17 00:00:00 2001 From: insthync Date: Tue, 7 May 2024 16:13:25 +0700 Subject: [PATCH 40/58] feat: update codes follow `main` branch --- Scripts/LiteNetLibClient.cs | 39 +++++++++--------- Scripts/LiteNetLibServer.cs | 37 +++++++++-------- Scripts/TransportHandler.cs | 79 +++++++++++++++++++------------------ 3 files changed, 78 insertions(+), 77 deletions(-) diff --git a/Scripts/LiteNetLibClient.cs b/Scripts/LiteNetLibClient.cs index ec5cb5c4..e6865379 100644 --- a/Scripts/LiteNetLibClient.cs +++ b/Scripts/LiteNetLibClient.cs @@ -1,6 +1,7 @@ using Cysharp.Threading.Tasks; using LiteNetLib; using LiteNetLib.Utils; +using System.Threading.Tasks; namespace LiteNetLibManager { @@ -8,9 +9,9 @@ public class LiteNetLibClient : TransportHandler { public LiteNetLibManager Manager { get; protected set; } public override string LogTag { get { return (Manager == null ? "(No Manager)" : Manager.LogTag) + "->LiteNetLibClient"; } } - private bool isNetworkActive; - public override bool IsNetworkActive { get { return isNetworkActive; } } - private byte[] disconnectData; + private bool _isNetworkActive; + public override bool IsNetworkActive { get { return _isNetworkActive; } } + private byte[] _disconnectData; public LiteNetLibClient(LiteNetLibManager manager) : base() { @@ -24,14 +25,14 @@ public LiteNetLibClient(ITransport transport) : base(transport) public void SetDisconnectData(byte[] data) { - disconnectData = data; + _disconnectData = data; } public void Update() { if (!IsNetworkActive) return; - while (Transport.ClientReceive(out tempEventData)) + while (Transport.ClientReceive(out TransportEventData tempEventData)) { OnClientReceive(tempEventData); } @@ -45,8 +46,8 @@ public bool StartClient(string address, int port) return false; } // Clear and reset request Id - requestCallbacks.Clear(); - if (isNetworkActive = Transport.StartClient(address, port)) + _requestCallbacks.Clear(); + if (_isNetworkActive = Transport.StartClient(address, port)) { OnStartClient(); return true; @@ -59,7 +60,7 @@ protected virtual void OnStartClient() { } public void StopClient() { Transport.StopClient(); - isNetworkActive = false; + _isNetworkActive = false; OnStopClient(); } @@ -77,13 +78,13 @@ public virtual void OnClientReceive(TransportEventData eventData) ReadPacket(-1, eventData.reader); break; case ENetworkEvent.DisconnectEvent: - if (Manager.LogInfo) Logging.Log(LogTag, "OnClientDisconnected peer. disconnectInfo.Reason: " + eventData.disconnectInfo.Reason); + if (Manager.LogInfo) Logging.Log(LogTag, $"OnClientDisconnected peer. disconnectInfo.Reason: {eventData.disconnectInfo.Reason}"); Manager.StopClient(); - Manager.OnClientDisconnected(eventData.disconnectInfo.Reason, eventData.disconnectInfo.SocketErrorCode, disconnectData); - disconnectData = null; + Manager.OnClientDisconnected(eventData.disconnectInfo.Reason, eventData.disconnectInfo.SocketErrorCode, _disconnectData); + _disconnectData = null; break; case ENetworkEvent.ErrorEvent: - if (Manager.LogError) Logging.LogError(LogTag, "OnClientNetworkError endPoint: " + eventData.endPoint + " socketErrorCode " + eventData.socketError + " errorMessage " + eventData.errorMessage); + if (Manager.LogError) Logging.LogError(LogTag, $"OnClientNetworkError endPoint: {eventData.endPoint} socketErrorCode {eventData.socketError} errorMessage {eventData.errorMessage}"); Manager.OnClientNetworkError(eventData.endPoint, eventData.socketError); break; } @@ -101,18 +102,18 @@ public void SendMessage(byte dataChannel, DeliveryMethod deliveryMethod, NetData public void SendPacket(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializer) { - WritePacket(Writer, msgType, serializer); + WritePacket(s_Writer, msgType, serializer); // Send packet to server, so connection id will not being used - SendMessage(dataChannel, deliveryMethod, Writer); + SendMessage(dataChannel, deliveryMethod, s_Writer); } public bool SendRequest(ushort requestType, TRequest request, ResponseDelegate responseDelegate = null, int millisecondsTimeout = 30000, SerializerDelegate extraSerializer = null) where TRequest : INetSerializable, new() { - if (!CreateAndWriteRequest(Writer, requestType, request, responseDelegate, millisecondsTimeout, extraSerializer)) + if (!CreateAndWriteRequest(s_Writer, requestType, request, responseDelegate, millisecondsTimeout, extraSerializer)) return false; // Send request to server, so connection id will not being used - SendMessage(0, DeliveryMethod.ReliableUnordered, Writer); + SendMessage(0, DeliveryMethod.ReliableUnordered, s_Writer); return true; } @@ -123,7 +124,7 @@ public async UniTask> SendRequestAsync responseData = default; // Create request - CreateAndWriteRequest(Writer, requestType, request, (requestHandler, responseCode, response) => + CreateAndWriteRequest(s_Writer, requestType, request, (requestHandler, responseCode, response) => { if (!(response is TResponse)) response = default(TResponse); @@ -131,7 +132,7 @@ public async UniTask> SendRequestAsync> SendRequestAsyncLiteNetLibServer"; } } - private bool isNetworkActive; - public override bool IsNetworkActive { get { return isNetworkActive; } } + private bool _isNetworkActive; + public override bool IsNetworkActive { get { return _isNetworkActive; } } public int ServerPort { get; protected set; } - public HashSet ConnectionIds { get; private set; } = new HashSet(); public LiteNetLibServer(LiteNetLibManager manager) : base() @@ -29,7 +28,7 @@ public void Update() { if (!IsNetworkActive) return; - while (Transport.ServerReceive(out tempEventData)) + while (Transport.ServerReceive(out TransportEventData tempEventData)) { OnServerReceive(tempEventData); } @@ -43,10 +42,10 @@ public bool StartServer(int port, int maxConnections) return false; } // Clear and reset request Id - requestCallbacks.Clear(); + _requestCallbacks.Clear(); // Store server port, it will be used by local client to connect when start hosting ServerPort = port; - if (isNetworkActive = Transport.StartServer(port, maxConnections)) + if (_isNetworkActive = Transport.StartServer(port, maxConnections)) { OnStartServer(); return true; @@ -60,7 +59,7 @@ public void StopServer() { Transport.StopServer(); ServerPort = 0; - isNetworkActive = false; + _isNetworkActive = false; OnStopServer(); } @@ -71,7 +70,7 @@ public virtual void OnServerReceive(TransportEventData eventData) switch (eventData.type) { case ENetworkEvent.ConnectEvent: - if (Manager.LogInfo) Logging.Log(LogTag, "OnPeerConnected peer.ConnectionId: " + eventData.connectionId); + if (Manager.LogInfo) Logging.Log(LogTag, $"OnPeerConnected peer.ConnectionId: {eventData.connectionId}"); ConnectionIds.Add(eventData.connectionId); Manager.OnPeerConnected(eventData.connectionId); break; @@ -79,12 +78,12 @@ public virtual void OnServerReceive(TransportEventData eventData) ReadPacket(eventData.connectionId, eventData.reader); break; case ENetworkEvent.DisconnectEvent: - if (Manager.LogInfo) Logging.Log(LogTag, "OnPeerDisconnected peer.ConnectionId: " + eventData.connectionId + " disconnectInfo.Reason: " + eventData.disconnectInfo.Reason); + if (Manager.LogInfo) Logging.Log(LogTag, $"OnPeerDisconnected peer.ConnectionId: {eventData.connectionId} disconnectInfo.Reason: {eventData.disconnectInfo.Reason}"); ConnectionIds.Remove(eventData.connectionId); Manager.OnPeerDisconnected(eventData.connectionId, eventData.disconnectInfo.Reason, eventData.disconnectInfo.SocketErrorCode); break; case ENetworkEvent.ErrorEvent: - if (Manager.LogError) Logging.LogError(LogTag, "OnPeerNetworkError endPoint: " + eventData.endPoint + " socketErrorCode " + eventData.socketError + " errorMessage " + eventData.errorMessage); + if (Manager.LogError) Logging.LogError(LogTag, $"OnPeerNetworkError endPoint: {eventData.endPoint} socketErrorCode {eventData.socketError} errorMessage {eventData.errorMessage}"); Manager.OnPeerNetworkError(eventData.endPoint, eventData.socketError); break; } @@ -97,8 +96,8 @@ public override void SendMessage(long connectionId, byte dataChannel, DeliveryMe public void SendPacket(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializer) { - WritePacket(Writer, msgType, serializer); - SendMessage(connectionId, dataChannel, deliveryMethod, Writer); + WritePacket(s_Writer, msgType, serializer); + SendMessage(connectionId, dataChannel, deliveryMethod, s_Writer); } public void SendMessageToAllConnections(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) @@ -111,16 +110,16 @@ public void SendMessageToAllConnections(byte dataChannel, DeliveryMethod deliver public void SendPacketToAllConnections(byte dataChannel, DeliveryMethod deliveryMethod, ushort msgType, SerializerDelegate serializer) { - WritePacket(Writer, msgType, serializer); - SendMessageToAllConnections(dataChannel, deliveryMethod, Writer); + WritePacket(s_Writer, msgType, serializer); + SendMessageToAllConnections(dataChannel, deliveryMethod, s_Writer); } public bool SendRequest(long connectionId, ushort requestType, TRequest request, ResponseDelegate responseDelegate = null, int millisecondsTimeout = 30000, SerializerDelegate extraRequestSerializer = null) where TRequest : INetSerializable, new() { - if (!CreateAndWriteRequest(Writer, requestType, request, responseDelegate, millisecondsTimeout, extraRequestSerializer)) + if (!CreateAndWriteRequest(s_Writer, requestType, request, responseDelegate, millisecondsTimeout, extraRequestSerializer)) return false; - SendMessage(connectionId, 0, DeliveryMethod.ReliableUnordered, Writer); + SendMessage(connectionId, 0, DeliveryMethod.ReliableUnordered, s_Writer); return true; } @@ -131,7 +130,7 @@ public async UniTask> SendRequestAsync responseData = default; // Create request - CreateAndWriteRequest(Writer, requestType, request, (requestHandler, responseCode, response) => + CreateAndWriteRequest(s_Writer, requestType, request, (requestHandler, responseCode, response) => { if (!(response is TResponse)) response = default(TResponse); @@ -139,7 +138,7 @@ public async UniTask> SendRequestAsync> SendRequestAsync messageHandlers = new Dictionary(); - protected readonly Dictionary requestHandlers = new Dictionary(); - protected readonly Dictionary responseHandlers = new Dictionary(); - protected readonly ConcurrentDictionary requestCallbacks = new ConcurrentDictionary(); - protected uint nextRequestId; - protected TransportEventData tempEventData; - public int RequestsCount { get { return requestCallbacks.Count; } } + protected readonly Dictionary _messageHandlers = new Dictionary(); + protected readonly Dictionary _requestHandlers = new Dictionary(); + protected readonly Dictionary _responseHandlers = new Dictionary(); + protected readonly ConcurrentDictionary _requestCallbacks = new ConcurrentDictionary(); + protected uint _nextRequestId; + + public int RequestsCount { get { return _requestCallbacks.Count; } } public TransportHandler() { RequestResponseEnabled = false; RequestMessageType = 0; ResponseMessageType = 0; - nextRequestId = 1; + _nextRequestId = 1; } public TransportHandler(ITransport transport) : this() @@ -40,8 +41,8 @@ public TransportHandler(ITransport transport) : this() public bool EnableRequestResponse(ushort requestMessageType, ushort responseMessageType) { if (requestMessageType == responseMessageType || - messageHandlers.ContainsKey(requestMessageType) || - messageHandlers.ContainsKey(responseMessageType)) + _messageHandlers.ContainsKey(requestMessageType) || + _messageHandlers.ContainsKey(responseMessageType)) { Logging.LogError(LogTag, $"Cannot enable request-response feature, request/response message type must be different and not registered."); DisableRequestResponse(); @@ -73,9 +74,9 @@ protected void ReadPacket(long connectionId, NetDataReader reader) ProceedResponse(connectionId, reader); return; } - if (!messageHandlers.ContainsKey(messageType)) + if (!_messageHandlers.ContainsKey(messageType)) return; - messageHandlers[messageType].Invoke(new MessageHandlerData(messageType, this, connectionId, reader)); + _messageHandlers[messageType].Invoke(new MessageHandlerData(messageType, this, connectionId, reader)); } public static void WritePacket( @@ -108,9 +109,9 @@ private uint CreateRequest( ILiteNetLibResponseHandler responseHandler, ResponseDelegate responseDelegate) { - uint requestId = nextRequestId++; + uint requestId = _nextRequestId++; // Get response callback by request type - requestCallbacks.TryAdd(requestId, new LiteNetLibRequestCallback(requestId, this, responseHandler, responseDelegate)); + _requestCallbacks.TryAdd(requestId, new LiteNetLibRequestCallback(requestId, this, responseHandler, responseDelegate)); return requestId; } @@ -126,7 +127,7 @@ private async UniTaskVoid HandleRequestTimeout(uint requestId, int millisecondsT { await Task.Delay(millisecondsTimeout); LiteNetLibRequestCallback callback; - if (requestCallbacks.TryRemove(requestId, out callback)) + if (_requestCallbacks.TryRemove(requestId, out callback)) callback.ResponseTimeout(); } } @@ -151,20 +152,20 @@ protected bool CreateAndWriteRequest( SerializerDelegate extraRequestSerializer) where TRequest : INetSerializable, new() { - if (!responseHandlers.ContainsKey(requestType)) + if (!_responseHandlers.ContainsKey(requestType)) { - responseDelegate.Invoke(new ResponseHandlerData(nextRequestId++, this, -1, null), AckResponseCode.Unimplemented, EmptyMessage.Value); + responseDelegate.Invoke(new ResponseHandlerData(_nextRequestId++, this, -1, null), AckResponseCode.Unimplemented, EmptyMessage.Value); Logging.LogError(LogTag, $"Cannot create request. Request type: {requestType} not registered."); return false; } - if (!responseHandlers[requestType].IsRequestTypeValid(typeof(TRequest))) + if (!_responseHandlers[requestType].IsRequestTypeValid(typeof(TRequest))) { - responseDelegate.Invoke(new ResponseHandlerData(nextRequestId++, this, -1, null), AckResponseCode.Unimplemented, EmptyMessage.Value); + responseDelegate.Invoke(new ResponseHandlerData(_nextRequestId++, this, -1, null), AckResponseCode.Unimplemented, EmptyMessage.Value); Logging.LogError(LogTag, $"Cannot create request. Request type: {requestType}, {typeof(TRequest)} is not valid message type."); return false; } // Create request - uint requestId = CreateRequest(responseHandlers[requestType], responseDelegate); + uint requestId = CreateRequest(_responseHandlers[requestType], responseDelegate); HandleRequestTimeout(requestId, millisecondsTimeout).Forget(); // Write request writer.Reset(); @@ -188,7 +189,7 @@ private void ProceedRequest( { ushort requestType = reader.GetPackedUShort(); uint requestId = reader.GetPackedUInt(); - if (!requestHandlers.ContainsKey(requestType)) + if (!_requestHandlers.ContainsKey(requestType)) { // No request-response handler RequestProceeded(connectionId, requestId, AckResponseCode.Unimplemented, EmptyMessage.Value); @@ -196,7 +197,7 @@ private void ProceedRequest( return; } // Invoke request and create response - requestHandlers[requestType].InvokeRequest(new RequestHandlerData(requestType, requestId, this, connectionId, reader), RequestProceeded); + _requestHandlers[requestType].InvokeRequest(new RequestHandlerData(requestType, requestId, this, connectionId, reader), RequestProceeded); } /// @@ -210,13 +211,13 @@ private void ProceedRequest( private void RequestProceeded(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response) { // Write response - Writer.Reset(); - Writer.PutPackedUShort(ResponseMessageType); - Writer.PutPackedUInt(requestId); - Writer.PutValue(responseCode); - Writer.Put(response); + s_Writer.Reset(); + s_Writer.PutPackedUShort(ResponseMessageType); + s_Writer.PutPackedUInt(requestId); + s_Writer.PutValue(responseCode); + s_Writer.Put(response); // Send response - SendMessage(connectionId, 0, DeliveryMethod.ReliableUnordered, Writer); + SendMessage(connectionId, 0, DeliveryMethod.ReliableUnordered, s_Writer); } /// @@ -228,10 +229,10 @@ private void ProceedResponse(long connectionId, NetDataReader reader) { uint requestId = reader.GetPackedUInt(); AckResponseCode responseCode = reader.GetValue(); - if (requestCallbacks.ContainsKey(requestId)) + if (_requestCallbacks.ContainsKey(requestId)) { - requestCallbacks[requestId].Response(connectionId, reader, responseCode); - requestCallbacks.TryRemove(requestId, out _); + _requestCallbacks[requestId].Response(connectionId, reader, responseCode); + _requestCallbacks.TryRemove(requestId, out _); } } @@ -248,12 +249,12 @@ public void RegisterRequestHandler( where TRequest : INetSerializable, new() where TResponse : INetSerializable, new() { - requestHandlers[requestType] = new LiteNetLibRequestHandler(this, handlerDelegate); + _requestHandlers[requestType] = new LiteNetLibRequestHandler(this, handlerDelegate); } public void UnregisterRequestHandler(ushort requestType) { - requestHandlers.Remove(requestType); + _requestHandlers.Remove(requestType); } /// @@ -269,12 +270,12 @@ public void RegisterResponseHandler( where TRequest : INetSerializable, new() where TResponse : INetSerializable, new() { - responseHandlers[requestType] = new LiteNetLibResponseHandler(handlerDelegate); + _responseHandlers[requestType] = new LiteNetLibResponseHandler(handlerDelegate); } public void UnregisterResponseHandler(ushort requestType) { - responseHandlers.Remove(requestType); + _responseHandlers.Remove(requestType); } /// @@ -291,12 +292,12 @@ public void RegisterMessageHandler( Logging.LogError(LogTag, $"Cannot register message, message type must be difference to request/response message types."); return; } - messageHandlers[messageType] = handlerDelegate; + _messageHandlers[messageType] = handlerDelegate; } public void UnregisterMessageHandler(ushort messageType) { - messageHandlers.Remove(messageType); + _messageHandlers.Remove(messageType); } } -} +} \ No newline at end of file From b8d57bdb94eb6b817a236fe119093023e2c8f285 Mon Sep 17 00:00:00 2001 From: insthync Date: Tue, 7 May 2024 16:14:47 +0700 Subject: [PATCH 41/58] chore: delete unused namespaces --- Scripts/LiteNetLibClient.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Scripts/LiteNetLibClient.cs b/Scripts/LiteNetLibClient.cs index e6865379..52633d7f 100644 --- a/Scripts/LiteNetLibClient.cs +++ b/Scripts/LiteNetLibClient.cs @@ -1,7 +1,6 @@ using Cysharp.Threading.Tasks; using LiteNetLib; using LiteNetLib.Utils; -using System.Threading.Tasks; namespace LiteNetLibManager { From be94c437459c51e13064673500095289e7dbd6f9 Mon Sep 17 00:00:00 2001 From: insthync Date: Thu, 16 May 2024 01:09:34 +0700 Subject: [PATCH 42/58] feat: bring back response's extra serializer --- Scripts/LiteNetLibDelegates.cs | 12 +++++----- Scripts/RequestResponse/AckResponseCode.cs | 1 + .../LiteNetLibRequestHandler.cs | 22 +++++-------------- .../LiteNetLibResponseHandler.cs | 3 ++- Scripts/TransportHandler.cs | 19 ++++++++++++---- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Scripts/LiteNetLibDelegates.cs b/Scripts/LiteNetLibDelegates.cs index d3e7d79f..9a8efc95 100644 --- a/Scripts/LiteNetLibDelegates.cs +++ b/Scripts/LiteNetLibDelegates.cs @@ -5,9 +5,9 @@ namespace LiteNetLibManager { public delegate void SerializerDelegate(NetDataWriter writer); public delegate void MessageHandlerDelegate(MessageHandlerData messageHandler); - public delegate void RequestProceedResultDelegate(AckResponseCode responseCode, TResponse response) + public delegate void RequestProceedResultDelegate(AckResponseCode responseCode, TResponse response, SerializerDelegate extraResponseSerializer = null) where TResponse : INetSerializable; - public delegate void RequestProceededDelegate(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response); + public delegate void RequestProceededDelegate(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response, SerializerDelegate extraResponseSerializer); public delegate UniTaskVoid RequestDelegate(RequestHandlerData requestHandler, TRequest request, RequestProceedResultDelegate responseProceedResult) where TRequest : INetSerializable where TResponse : INetSerializable; @@ -17,16 +17,16 @@ public delegate void ResponseDelegate(ResponseHandlerData responseHan public static class DelegateExtensions { - public static void InvokeSuccess(this RequestProceedResultDelegate target, TResponse response) + public static void InvokeSuccess(this RequestProceedResultDelegate target, TResponse response, SerializerDelegate extraResponseSerializer = null) where TResponse : INetSerializable { - target.Invoke(AckResponseCode.Success, response); + target.Invoke(AckResponseCode.Success, response, extraResponseSerializer); } - public static void InvokeError(this RequestProceedResultDelegate target, TResponse response) + public static void InvokeError(this RequestProceedResultDelegate target, TResponse response, SerializerDelegate extraResponseSerializer = null) where TResponse : INetSerializable { - target.Invoke(AckResponseCode.Error, response); + target.Invoke(AckResponseCode.Error, response, extraResponseSerializer); } } } diff --git a/Scripts/RequestResponse/AckResponseCode.cs b/Scripts/RequestResponse/AckResponseCode.cs index 9d685e18..a5636dcf 100644 --- a/Scripts/RequestResponse/AckResponseCode.cs +++ b/Scripts/RequestResponse/AckResponseCode.cs @@ -6,5 +6,6 @@ public enum AckResponseCode : byte Timeout = 1, Error = 2, Unimplemented = 3, + Exception = 4, } } diff --git a/Scripts/RequestResponse/LiteNetLibRequestHandler.cs b/Scripts/RequestResponse/LiteNetLibRequestHandler.cs index 0f7d01eb..1e25e669 100644 --- a/Scripts/RequestResponse/LiteNetLibRequestHandler.cs +++ b/Scripts/RequestResponse/LiteNetLibRequestHandler.cs @@ -11,32 +11,20 @@ public struct LiteNetLibRequestHandler : ILiteNetLibRequest where TRequest : INetSerializable, new() where TResponse : INetSerializable, new() { - private TransportHandler _transportHandler; private RequestDelegate _requestHandler; - public LiteNetLibRequestHandler(TransportHandler transportHandler, RequestDelegate requestHandler) + public LiteNetLibRequestHandler(RequestDelegate requestHandler) { - _transportHandler = transportHandler; _requestHandler = requestHandler; } public void InvokeRequest(RequestHandlerData requestHandlerData, RequestProceededDelegate responseProceedHandler) { TRequest request = new TRequest(); - string logTag = _transportHandler == null ? string.Empty : _transportHandler.LogTag; - try - { - if (requestHandlerData.Reader != null) - request.Deserialize(requestHandlerData.Reader); - if (_requestHandler != null) - _requestHandler.Invoke(requestHandlerData, request, (responseCode, response) => responseProceedHandler.Invoke(requestHandlerData.ConnectionId, requestHandlerData.RequestId, responseCode, response)); - } - catch (System.Exception ex) - { - responseProceedHandler.Invoke(requestHandlerData.ConnectionId, requestHandlerData.RequestId, AckResponseCode.Error, new TResponse()); - Logging.LogError(logTag, $"Error occuring while proceed request {requestHandlerData.RequestType}"); - Logging.LogException(logTag, ex); - } + if (requestHandlerData.Reader != null) + request.Deserialize(requestHandlerData.Reader); + if (_requestHandler != null) + _requestHandler.Invoke(requestHandlerData, request, (responseCode, response, extraResponseSerializer) => responseProceedHandler.Invoke(requestHandlerData.ConnectionId, requestHandlerData.RequestId, responseCode, response, extraResponseSerializer)); } } } diff --git a/Scripts/RequestResponse/LiteNetLibResponseHandler.cs b/Scripts/RequestResponse/LiteNetLibResponseHandler.cs index 6f745f08..3791ff4c 100644 --- a/Scripts/RequestResponse/LiteNetLibResponseHandler.cs +++ b/Scripts/RequestResponse/LiteNetLibResponseHandler.cs @@ -23,7 +23,8 @@ public LiteNetLibResponseHandler(ResponseDelegate responseHandler) public void InvokeResponse(ResponseHandlerData responseHandlerData, AckResponseCode responseCode, ResponseDelegate anotherResponseHandler) { TResponse response = new TResponse(); - if (responseCode != AckResponseCode.Timeout && + if (responseCode != AckResponseCode.Exception && + responseCode != AckResponseCode.Timeout && responseCode != AckResponseCode.Unimplemented) { if (responseHandlerData.Reader != null) diff --git a/Scripts/TransportHandler.cs b/Scripts/TransportHandler.cs index 8b50b844..00eb3387 100644 --- a/Scripts/TransportHandler.cs +++ b/Scripts/TransportHandler.cs @@ -192,12 +192,21 @@ private void ProceedRequest( if (!_requestHandlers.ContainsKey(requestType)) { // No request-response handler - RequestProceeded(connectionId, requestId, AckResponseCode.Unimplemented, EmptyMessage.Value); + RequestProceeded(connectionId, requestId, AckResponseCode.Unimplemented, EmptyMessage.Value, null); Logging.LogError(LogTag, $"Cannot proceed request {requestType} not registered."); return; } // Invoke request and create response - _requestHandlers[requestType].InvokeRequest(new RequestHandlerData(requestType, requestId, this, connectionId, reader), RequestProceeded); + try + { + _requestHandlers[requestType].InvokeRequest(new RequestHandlerData(requestType, requestId, this, connectionId, reader), RequestProceeded); + } + catch (System.Exception ex) + { + RequestProceeded(connectionId, requestId, AckResponseCode.Exception, EmptyMessage.Value, null); + Logging.LogError(LogTag, $"Error occuring while proceed request {requestType}, ID {requestId}"); + Logging.LogException(LogTag, ex); + } } /// @@ -208,7 +217,7 @@ private void ProceedRequest( /// /// /// - private void RequestProceeded(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response) + private void RequestProceeded(long connectionId, uint requestId, AckResponseCode responseCode, INetSerializable response, SerializerDelegate extraResponseSerializer) { // Write response s_Writer.Reset(); @@ -216,6 +225,8 @@ private void RequestProceeded(long connectionId, uint requestId, AckResponseCode s_Writer.PutPackedUInt(requestId); s_Writer.PutValue(responseCode); s_Writer.Put(response); + if (extraResponseSerializer != null) + extraResponseSerializer.Invoke(s_Writer); // Send response SendMessage(connectionId, 0, DeliveryMethod.ReliableUnordered, s_Writer); } @@ -249,7 +260,7 @@ public void RegisterRequestHandler( where TRequest : INetSerializable, new() where TResponse : INetSerializable, new() { - _requestHandlers[requestType] = new LiteNetLibRequestHandler(this, handlerDelegate); + _requestHandlers[requestType] = new LiteNetLibRequestHandler(handlerDelegate); } public void UnregisterRequestHandler(ushort requestType) From b22d7f6309b19d20662e1c7beefea8945216929e Mon Sep 17 00:00:00 2001 From: insthync Date: Tue, 21 May 2024 11:37:57 +0700 Subject: [PATCH 43/58] feat: improve delaying to reduce CPU usage --- Scripts/LiteNetLibClient.cs | 7 ++----- Scripts/LiteNetLibServer.cs | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Scripts/LiteNetLibClient.cs b/Scripts/LiteNetLibClient.cs index 52633d7f..8a46e2fe 100644 --- a/Scripts/LiteNetLibClient.cs +++ b/Scripts/LiteNetLibClient.cs @@ -133,12 +133,9 @@ public async UniTask> SendRequestAsync> SendRequestAsync Date: Tue, 21 May 2024 14:10:04 +0700 Subject: [PATCH 44/58] fix: no UniTask.Delay() function for .NET platform --- Scripts/LiteNetLibClient.cs | 2 +- Scripts/LiteNetLibServer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/LiteNetLibClient.cs b/Scripts/LiteNetLibClient.cs index 8a46e2fe..1f271c66 100644 --- a/Scripts/LiteNetLibClient.cs +++ b/Scripts/LiteNetLibClient.cs @@ -133,7 +133,7 @@ public async UniTask> SendRequestAsync> SendRequestAsync Date: Sat, 25 May 2024 17:46:56 +0700 Subject: [PATCH 45/58] feat: avoid null ref error --- Scripts/LiteNetLibManager.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Scripts/LiteNetLibManager.cs b/Scripts/LiteNetLibManager.cs index 99ece390..fa62b366 100644 --- a/Scripts/LiteNetLibManager.cs +++ b/Scripts/LiteNetLibManager.cs @@ -254,7 +254,8 @@ public void StopServer() if (_serverUpdater != null) _serverUpdater.Stop(); IsServer = false; - Server.StopServer(); + if (Server != null) + Server.StopServer(); OnStopServer(); if (IsOfflineConnection && IsClient) @@ -273,7 +274,8 @@ public void StopClient() if (_clientUpdater != null) _clientUpdater.Stop(); IsClient = false; - Client.StopClient(); + if (Client != null) + Client.StopClient(); OnStopClient(); if (IsOfflineConnection && IsServer) From 5d39eff59b32e528344b96ad11696d488c25a893 Mon Sep 17 00:00:00 2001 From: insthync Date: Wed, 29 May 2024 11:07:22 +0700 Subject: [PATCH 46/58] feat: avoid ambigous codes --- Scripts/Transports/WebSocket/WsTransportClient.cs | 2 ++ Scripts/Transports/WebSocket/WsTransportSession.cs | 1 + Scripts/Transports/WebSocket/WssTransportClient.cs | 2 ++ Scripts/Transports/WebSocket/WssTransportSession.cs | 1 + 4 files changed, 6 insertions(+) diff --git a/Scripts/Transports/WebSocket/WsTransportClient.cs b/Scripts/Transports/WebSocket/WsTransportClient.cs index a05b94a1..8c988d70 100644 --- a/Scripts/Transports/WebSocket/WsTransportClient.cs +++ b/Scripts/Transports/WebSocket/WsTransportClient.cs @@ -4,6 +4,8 @@ using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; +using HttpRequest = NetCoreServer.HttpRequest; +using HttpResponse = NetCoreServer.HttpResponse; namespace LiteNetLibManager { diff --git a/Scripts/Transports/WebSocket/WsTransportSession.cs b/Scripts/Transports/WebSocket/WsTransportSession.cs index 7be9f3a1..0b1875fd 100644 --- a/Scripts/Transports/WebSocket/WsTransportSession.cs +++ b/Scripts/Transports/WebSocket/WsTransportSession.cs @@ -2,6 +2,7 @@ using NetCoreServer; using System; using System.Net.Sockets; +using HttpRequest = NetCoreServer.HttpRequest; namespace LiteNetLibManager { diff --git a/Scripts/Transports/WebSocket/WssTransportClient.cs b/Scripts/Transports/WebSocket/WssTransportClient.cs index 49a165e1..eaaa34e4 100644 --- a/Scripts/Transports/WebSocket/WssTransportClient.cs +++ b/Scripts/Transports/WebSocket/WssTransportClient.cs @@ -4,6 +4,8 @@ using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; +using HttpRequest = NetCoreServer.HttpRequest; +using HttpResponse = NetCoreServer.HttpResponse; namespace LiteNetLibManager { diff --git a/Scripts/Transports/WebSocket/WssTransportSession.cs b/Scripts/Transports/WebSocket/WssTransportSession.cs index adab7f4e..b1b02ae3 100644 --- a/Scripts/Transports/WebSocket/WssTransportSession.cs +++ b/Scripts/Transports/WebSocket/WssTransportSession.cs @@ -2,6 +2,7 @@ using NetCoreServer; using System; using System.Net.Sockets; +using HttpRequest = NetCoreServer.HttpRequest; namespace LiteNetLibManager { From 432e413125211c698ed53bc2e4a66965ddd4cb7c Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 21:23:01 +0700 Subject: [PATCH 47/58] feat: delete NetCoreServer, will change to use sta-websocket-sharp for web server implementation instead --- Plugins/websocket-sharp.meta | 8 + Plugins/websocket-sharp/.gitignore | 14 + Plugins/websocket-sharp/LICENSE.txt | 21 + Plugins/websocket-sharp/LICENSE.txt.meta | 7 + Plugins/websocket-sharp/README.md | 4 + Plugins/websocket-sharp/websocket-sharp.meta | 8 + .../websocket-sharp/ByteOrder.cs | 47 + .../websocket-sharp/ByteOrder.cs.meta | 11 + .../websocket-sharp/CloseEventArgs.cs | 113 + .../websocket-sharp/CloseEventArgs.cs.meta | 11 + .../websocket-sharp/CloseStatusCode.cs | 120 + .../websocket-sharp/CloseStatusCode.cs.meta | 11 + .../websocket-sharp/CompressionMethod.cs | 52 + .../websocket-sharp/CompressionMethod.cs.meta | 11 + .../websocket-sharp/ErrorEventArgs.cs | 109 + .../websocket-sharp/ErrorEventArgs.cs.meta | 11 + .../websocket-sharp/websocket-sharp/Ext.cs | 2252 +++++++++ .../websocket-sharp/Ext.cs.meta | 11 + .../websocket-sharp/websocket-sharp/Fin.cs | 51 + .../websocket-sharp/Fin.cs.meta | 11 + .../websocket-sharp/HttpBase.cs | 208 + .../websocket-sharp/HttpBase.cs.meta | 11 + .../websocket-sharp/HttpRequest.cs | 217 + .../websocket-sharp/HttpRequest.cs.meta | 11 + .../websocket-sharp/HttpResponse.cs | 209 + .../websocket-sharp/HttpResponse.cs.meta | 11 + .../websocket-sharp/LogData.cs | 149 + .../websocket-sharp/LogData.cs.meta | 11 + .../websocket-sharp/LogLevel.cs | 63 + .../websocket-sharp/LogLevel.cs.meta | 11 + .../websocket-sharp/websocket-sharp/Logger.cs | 330 ++ .../websocket-sharp/Logger.cs.meta | 11 + .../websocket-sharp/websocket-sharp/Mask.cs | 51 + .../websocket-sharp/Mask.cs.meta | 11 + .../websocket-sharp/MessageEventArgs.cs | 183 + .../websocket-sharp/MessageEventArgs.cs.meta | 11 + .../websocket-sharp/websocket-sharp/Net.meta | 8 + .../websocket-sharp/Net/AuthenticationBase.cs | 151 + .../Net/AuthenticationBase.cs.meta | 11 + .../Net/AuthenticationChallenge.cs | 146 + .../Net/AuthenticationChallenge.cs.meta | 11 + .../Net/AuthenticationResponse.cs | 323 ++ .../Net/AuthenticationResponse.cs.meta | 11 + .../Net/AuthenticationSchemes.cs | 66 + .../Net/AuthenticationSchemes.cs.meta | 11 + .../websocket-sharp/Net/Chunk.cs | 93 + .../websocket-sharp/Net/Chunk.cs.meta | 11 + .../websocket-sharp/Net/ChunkStream.cs | 383 ++ .../websocket-sharp/Net/ChunkStream.cs.meta | 11 + .../Net/ChunkedRequestStream.cs | 249 + .../Net/ChunkedRequestStream.cs.meta | 11 + .../Net/ClientSslConfiguration.cs | 303 ++ .../Net/ClientSslConfiguration.cs.meta | 11 + .../websocket-sharp/Net/Cookie.cs | 1016 ++++ .../websocket-sharp/Net/Cookie.cs.meta | 11 + .../websocket-sharp/Net/CookieCollection.cs | 821 ++++ .../Net/CookieCollection.cs.meta | 11 + .../websocket-sharp/Net/CookieException.cs | 165 + .../Net/CookieException.cs.meta | 11 + .../websocket-sharp/Net/EndPointListener.cs | 582 +++ .../Net/EndPointListener.cs.meta | 11 + .../websocket-sharp/Net/EndPointManager.cs | 261 ++ .../Net/EndPointManager.cs.meta | 11 + .../websocket-sharp/Net/HttpBasicIdentity.cs | 82 + .../Net/HttpBasicIdentity.cs.meta | 11 + .../websocket-sharp/Net/HttpConnection.cs | 571 +++ .../Net/HttpConnection.cs.meta | 11 + .../websocket-sharp/Net/HttpDigestIdentity.cs | 187 + .../Net/HttpDigestIdentity.cs.meta | 11 + .../websocket-sharp/Net/HttpHeaderInfo.cs | 128 + .../Net/HttpHeaderInfo.cs.meta | 11 + .../websocket-sharp/Net/HttpHeaderType.cs | 44 + .../Net/HttpHeaderType.cs.meta | 11 + .../websocket-sharp/Net/HttpListener.cs | 973 ++++ .../websocket-sharp/Net/HttpListener.cs.meta | 11 + .../Net/HttpListenerAsyncResult.cs | 193 + .../Net/HttpListenerAsyncResult.cs.meta | 11 + .../Net/HttpListenerContext.cs | 311 ++ .../Net/HttpListenerContext.cs.meta | 11 + .../Net/HttpListenerException.cs | 137 + .../Net/HttpListenerException.cs.meta | 11 + .../websocket-sharp/Net/HttpListenerPrefix.cs | 273 ++ .../Net/HttpListenerPrefix.cs.meta | 11 + .../Net/HttpListenerPrefixCollection.cs | 294 ++ .../Net/HttpListenerPrefixCollection.cs.meta | 11 + .../Net/HttpListenerRequest.cs | 928 ++++ .../Net/HttpListenerRequest.cs.meta | 11 + .../Net/HttpListenerResponse.cs | 1199 +++++ .../Net/HttpListenerResponse.cs.meta | 11 + .../websocket-sharp/Net/HttpRequestHeader.cs | 233 + .../Net/HttpRequestHeader.cs.meta | 11 + .../websocket-sharp/Net/HttpResponseHeader.cs | 189 + .../Net/HttpResponseHeader.cs.meta | 11 + .../websocket-sharp/Net/HttpStatusCode.cs | 346 ++ .../Net/HttpStatusCode.cs.meta | 11 + .../Net/HttpStreamAsyncResult.cs | 201 + .../Net/HttpStreamAsyncResult.cs.meta | 11 + .../websocket-sharp/Net/HttpUtility.cs | 1150 +++++ .../websocket-sharp/Net/HttpUtility.cs.meta | 11 + .../websocket-sharp/Net/HttpVersion.cs | 73 + .../websocket-sharp/Net/HttpVersion.cs.meta | 11 + .../websocket-sharp/Net/InputChunkState.cs | 52 + .../Net/InputChunkState.cs.meta | 11 + .../websocket-sharp/Net/InputState.cs | 49 + .../websocket-sharp/Net/InputState.cs.meta | 11 + .../websocket-sharp/Net/LineState.cs | 50 + .../websocket-sharp/Net/LineState.cs.meta | 11 + .../websocket-sharp/Net/NetworkCredential.cs | 209 + .../Net/NetworkCredential.cs.meta | 11 + .../Net/QueryStringCollection.cs | 150 + .../Net/QueryStringCollection.cs.meta | 11 + .../websocket-sharp/Net/ReadBufferState.cs | 126 + .../Net/ReadBufferState.cs.meta | 11 + .../websocket-sharp/Net/RequestStream.cs | 318 ++ .../websocket-sharp/Net/RequestStream.cs.meta | 11 + .../websocket-sharp/Net/ResponseStream.cs | 403 ++ .../Net/ResponseStream.cs.meta | 11 + .../Net/ServerSslConfiguration.cs | 236 + .../Net/ServerSslConfiguration.cs.meta | 11 + .../Net/WebHeaderCollection.cs | 1889 ++++++++ .../Net/WebHeaderCollection.cs.meta | 11 + .../websocket-sharp/Net/WebSockets.meta | 8 + .../HttpListenerWebSocketContext.cs | 395 ++ .../HttpListenerWebSocketContext.cs.meta | 11 + .../WebSockets/TcpListenerWebSocketContext.cs | 518 +++ .../TcpListenerWebSocketContext.cs.meta | 11 + .../Net/WebSockets/WebSocketContext.cs | 224 + .../Net/WebSockets/WebSocketContext.cs.meta | 11 + .../websocket-sharp/websocket-sharp/Opcode.cs | 68 + .../websocket-sharp/Opcode.cs.meta | 11 + .../websocket-sharp/PayloadData.cs | 208 + .../websocket-sharp/PayloadData.cs.meta | 11 + .../websocket-sharp/websocket-sharp/Rsv.cs | 51 + .../websocket-sharp/Rsv.cs.meta | 11 + .../websocket-sharp/Server.meta | 8 + .../Server/HttpRequestEventArgs.cs | 260 ++ .../Server/HttpRequestEventArgs.cs.meta | 11 + .../websocket-sharp/Server/HttpServer.cs | 1485 ++++++ .../websocket-sharp/Server/HttpServer.cs.meta | 11 + .../Server/IWebSocketSession.cs | 91 + .../Server/IWebSocketSession.cs.meta | 11 + .../websocket-sharp/Server/ServerState.cs | 40 + .../Server/ServerState.cs.meta | 11 + .../Server/WebSocketBehavior.cs | 1204 +++++ .../Server/WebSocketBehavior.cs.meta | 11 + .../websocket-sharp/Server/WebSocketServer.cs | 1518 ++++++ .../Server/WebSocketServer.cs.meta | 11 + .../Server/WebSocketServiceHost.cs | 224 + .../Server/WebSocketServiceHost.cs.meta | 11 + .../Server/WebSocketServiceHost`1.cs | 102 + .../Server/WebSocketServiceHost`1.cs.meta | 11 + .../Server/WebSocketServiceManager.cs | 1078 +++++ .../Server/WebSocketServiceManager.cs.meta | 11 + .../Server/WebSocketSessionManager.cs | 1695 +++++++ .../Server/WebSocketSessionManager.cs.meta | 11 + .../websocket-sharp/WebSocket.cs | 4097 +++++++++++++++++ .../websocket-sharp/WebSocket.cs.meta | 11 + .../websocket-sharp/WebSocketException.cs | 109 + .../WebSocketException.cs.meta | 11 + .../websocket-sharp/WebSocketFrame.cs | 895 ++++ .../websocket-sharp/WebSocketFrame.cs.meta | 11 + .../websocket-sharp/WebSocketState.cs | 65 + .../websocket-sharp/WebSocketState.cs.meta | 11 + .../websocket-sharp/websocket-sharp.asmdef | 16 + .../websocket-sharp.asmdef.meta | 7 + .../websocket-sharp/websocket-sharp.csproj | 149 + .../websocket-sharp.csproj.meta | 7 + .../websocket-sharp/websocket-sharp.snk | Bin 0 -> 596 bytes .../websocket-sharp/websocket-sharp.snk.meta | 7 + 169 files changed, 35153 insertions(+) create mode 100644 Plugins/websocket-sharp.meta create mode 100644 Plugins/websocket-sharp/.gitignore create mode 100644 Plugins/websocket-sharp/LICENSE.txt create mode 100644 Plugins/websocket-sharp/LICENSE.txt.meta create mode 100644 Plugins/websocket-sharp/README.md create mode 100644 Plugins/websocket-sharp/websocket-sharp.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/ByteOrder.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/ByteOrder.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/CloseEventArgs.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/CloseEventArgs.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/CloseStatusCode.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/CloseStatusCode.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/CompressionMethod.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/CompressionMethod.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/ErrorEventArgs.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/ErrorEventArgs.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Ext.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Ext.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Fin.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Fin.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/HttpBase.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/HttpBase.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/HttpRequest.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/HttpRequest.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/HttpResponse.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/HttpResponse.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/LogData.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/LogData.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/LogLevel.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/LogLevel.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Logger.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Logger.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Mask.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Mask.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/MessageEventArgs.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/MessageEventArgs.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationBase.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationBase.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationChallenge.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationChallenge.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationResponse.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationResponse.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationSchemes.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationSchemes.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/Chunk.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/Chunk.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ChunkStream.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ChunkStream.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ChunkedRequestStream.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ChunkedRequestStream.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ClientSslConfiguration.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ClientSslConfiguration.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/Cookie.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/Cookie.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/CookieCollection.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/CookieCollection.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/CookieException.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/CookieException.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/EndPointListener.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/EndPointListener.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/EndPointManager.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/EndPointManager.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpBasicIdentity.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpBasicIdentity.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpConnection.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpConnection.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpDigestIdentity.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpDigestIdentity.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderInfo.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderInfo.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderType.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderType.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListener.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListener.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerAsyncResult.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerAsyncResult.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerContext.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerContext.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerException.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerException.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefix.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefix.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefixCollection.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefixCollection.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerRequest.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerRequest.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerResponse.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerResponse.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpRequestHeader.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpRequestHeader.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpResponseHeader.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpResponseHeader.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpStatusCode.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpStatusCode.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpStreamAsyncResult.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpStreamAsyncResult.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpUtility.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpUtility.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpVersion.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/HttpVersion.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/InputChunkState.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/InputChunkState.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/InputState.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/InputState.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/LineState.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/LineState.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/NetworkCredential.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/NetworkCredential.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/QueryStringCollection.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/QueryStringCollection.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ReadBufferState.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ReadBufferState.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/RequestStream.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/RequestStream.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ResponseStream.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ResponseStream.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ServerSslConfiguration.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/ServerSslConfiguration.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebHeaderCollection.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebHeaderCollection.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebSockets.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/WebSocketContext.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/WebSocketContext.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Opcode.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Opcode.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/PayloadData.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/PayloadData.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Rsv.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Rsv.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/HttpRequestEventArgs.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/HttpRequestEventArgs.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/HttpServer.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/HttpServer.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/IWebSocketSession.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/IWebSocketSession.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/ServerState.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/ServerState.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketBehavior.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketBehavior.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServer.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServer.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost`1.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost`1.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceManager.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceManager.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketSessionManager.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/Server/WebSocketSessionManager.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/WebSocket.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/WebSocket.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/WebSocketException.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/WebSocketException.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/WebSocketFrame.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/WebSocketFrame.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/WebSocketState.cs create mode 100644 Plugins/websocket-sharp/websocket-sharp/WebSocketState.cs.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/websocket-sharp.asmdef create mode 100644 Plugins/websocket-sharp/websocket-sharp/websocket-sharp.asmdef.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/websocket-sharp.csproj create mode 100644 Plugins/websocket-sharp/websocket-sharp/websocket-sharp.csproj.meta create mode 100644 Plugins/websocket-sharp/websocket-sharp/websocket-sharp.snk create mode 100644 Plugins/websocket-sharp/websocket-sharp/websocket-sharp.snk.meta diff --git a/Plugins/websocket-sharp.meta b/Plugins/websocket-sharp.meta new file mode 100644 index 00000000..c913d13d --- /dev/null +++ b/Plugins/websocket-sharp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f2b621c0e4c824392a268a32d19c8424 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/.gitignore b/Plugins/websocket-sharp/.gitignore new file mode 100644 index 00000000..376bdfd8 --- /dev/null +++ b/Plugins/websocket-sharp/.gitignore @@ -0,0 +1,14 @@ +## Ignore build results and temporary files. + +Backup* +_UpgradeReport_Files +bin +obj + +*.mdb +*.pdb +*.pidb +*.suo +*.user +*.userprefs +UpgradeLog*.* diff --git a/Plugins/websocket-sharp/LICENSE.txt b/Plugins/websocket-sharp/LICENSE.txt new file mode 100644 index 00000000..4d4e5632 --- /dev/null +++ b/Plugins/websocket-sharp/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2010-2021 sta.blockhead + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Plugins/websocket-sharp/LICENSE.txt.meta b/Plugins/websocket-sharp/LICENSE.txt.meta new file mode 100644 index 00000000..f3e70920 --- /dev/null +++ b/Plugins/websocket-sharp/LICENSE.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a4743919fec5f45189f5184def37b6c2 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/README.md b/Plugins/websocket-sharp/README.md new file mode 100644 index 00000000..1ce235b4 --- /dev/null +++ b/Plugins/websocket-sharp/README.md @@ -0,0 +1,4 @@ +# websocket-sharp +Cloned from [github.com/sta/websocket-sharp](https://github.com/sta/websocket-sharp) `master` branch. + +This contains the same files as the original repository, however `websocket-sharp/AssemblyInfo.cs` file was removed as we don't need to build the related DLL. Other files like the original `README.md` and examples were also removed. diff --git a/Plugins/websocket-sharp/websocket-sharp.meta b/Plugins/websocket-sharp/websocket-sharp.meta new file mode 100644 index 00000000..14342813 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 63e3b01c0529049988f12dd7dee508c4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/ByteOrder.cs b/Plugins/websocket-sharp/websocket-sharp/ByteOrder.cs new file mode 100644 index 00000000..317f462e --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/ByteOrder.cs @@ -0,0 +1,47 @@ +#region License +/* + * ByteOrder.cs + * + * The MIT License + * + * Copyright (c) 2012-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Specifies the byte order. + /// + public enum ByteOrder + { + /// + /// Specifies Little-endian. + /// + Little, + /// + /// Specifies Big-endian. + /// + Big + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/ByteOrder.cs.meta b/Plugins/websocket-sharp/websocket-sharp/ByteOrder.cs.meta new file mode 100644 index 00000000..1a71bfc2 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/ByteOrder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a725b78f78c144fc1861afbd7861700f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/CloseEventArgs.cs b/Plugins/websocket-sharp/websocket-sharp/CloseEventArgs.cs new file mode 100644 index 00000000..8127ce41 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/CloseEventArgs.cs @@ -0,0 +1,113 @@ +#region License +/* + * CloseEventArgs.cs + * + * The MIT License + * + * Copyright (c) 2012-2019 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Represents the event data for the event. + /// + /// + /// + /// That event occurs when the WebSocket connection has been closed. + /// + /// + /// If you would like to get the reason for the connection close, you should + /// access the or property. + /// + /// + public class CloseEventArgs : EventArgs + { + #region Private Fields + + private bool _clean; + private PayloadData _payloadData; + + #endregion + + #region Internal Constructors + + internal CloseEventArgs (PayloadData payloadData, bool clean) + { + _payloadData = payloadData; + _clean = clean; + } + + internal CloseEventArgs (ushort code, string reason, bool clean) + { + _payloadData = new PayloadData (code, reason); + _clean = clean; + } + + #endregion + + #region Public Properties + + /// + /// Gets the status code for the connection close. + /// + /// + /// A that represents the status code for + /// the connection close if present. + /// + public ushort Code { + get { + return _payloadData.Code; + } + } + + /// + /// Gets the reason for the connection close. + /// + /// + /// A that represents the reason for + /// the connection close if present. + /// + public string Reason { + get { + return _payloadData.Reason; + } + } + + /// + /// Gets a value indicating whether the connection has been closed cleanly. + /// + /// + /// true if the connection has been closed cleanly; otherwise, + /// false. + /// + public bool WasClean { + get { + return _clean; + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/CloseEventArgs.cs.meta b/Plugins/websocket-sharp/websocket-sharp/CloseEventArgs.cs.meta new file mode 100644 index 00000000..c6d61cec --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/CloseEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30d1ff7393a6945ce9ef3b5a9675c253 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/CloseStatusCode.cs b/Plugins/websocket-sharp/websocket-sharp/CloseStatusCode.cs new file mode 100644 index 00000000..81f3317a --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/CloseStatusCode.cs @@ -0,0 +1,120 @@ +#region License +/* + * CloseStatusCode.cs + * + * The MIT License + * + * Copyright (c) 2012-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Indicates the status code for the WebSocket connection close. + /// + /// + /// + /// The values of this enumeration are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// "Reserved value" cannot be sent as a status code in + /// closing handshake by an endpoint. + /// + /// + public enum CloseStatusCode : ushort + { + /// + /// Equivalent to close status 1000. Indicates normal close. + /// + Normal = 1000, + /// + /// Equivalent to close status 1001. Indicates that an endpoint is + /// going away. + /// + Away = 1001, + /// + /// Equivalent to close status 1002. Indicates that an endpoint is + /// terminating the connection due to a protocol error. + /// + ProtocolError = 1002, + /// + /// Equivalent to close status 1003. Indicates that an endpoint is + /// terminating the connection because it has received a type of + /// data that it cannot accept. + /// + UnsupportedData = 1003, + /// + /// Equivalent to close status 1004. Still undefined. A Reserved value. + /// + Undefined = 1004, + /// + /// Equivalent to close status 1005. Indicates that no status code was + /// actually present. A Reserved value. + /// + NoStatus = 1005, + /// + /// Equivalent to close status 1006. Indicates that the connection was + /// closed abnormally. A Reserved value. + /// + Abnormal = 1006, + /// + /// Equivalent to close status 1007. Indicates that an endpoint is + /// terminating the connection because it has received a message that + /// contains data that is not consistent with the type of the message. + /// + InvalidData = 1007, + /// + /// Equivalent to close status 1008. Indicates that an endpoint is + /// terminating the connection because it has received a message that + /// violates its policy. + /// + PolicyViolation = 1008, + /// + /// Equivalent to close status 1009. Indicates that an endpoint is + /// terminating the connection because it has received a message that + /// is too big to process. + /// + TooBig = 1009, + /// + /// Equivalent to close status 1010. Indicates that a client is + /// terminating the connection because it has expected the server to + /// negotiate one or more extension, but the server did not return + /// them in the handshake response. + /// + MandatoryExtension = 1010, + /// + /// Equivalent to close status 1011. Indicates that a server is + /// terminating the connection because it has encountered an unexpected + /// condition that prevented it from fulfilling the request. + /// + ServerError = 1011, + /// + /// Equivalent to close status 1015. Indicates that the connection was + /// closed due to a failure to perform a TLS handshake. A Reserved value. + /// + TlsHandshakeFailure = 1015 + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/CloseStatusCode.cs.meta b/Plugins/websocket-sharp/websocket-sharp/CloseStatusCode.cs.meta new file mode 100644 index 00000000..c89383f5 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/CloseStatusCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9267b5a40b24f4160941a8887b531cff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/CompressionMethod.cs b/Plugins/websocket-sharp/websocket-sharp/CompressionMethod.cs new file mode 100644 index 00000000..42ab230a --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/CompressionMethod.cs @@ -0,0 +1,52 @@ +#region License +/* + * CompressionMethod.cs + * + * The MIT License + * + * Copyright (c) 2013-2017 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Specifies the method for compression. + /// + /// + /// The methods are defined in + /// + /// Compression Extensions for WebSocket. + /// + public enum CompressionMethod : byte + { + /// + /// Specifies no compression. + /// + None, + /// + /// Specifies DEFLATE. + /// + Deflate + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/CompressionMethod.cs.meta b/Plugins/websocket-sharp/websocket-sharp/CompressionMethod.cs.meta new file mode 100644 index 00000000..561822f7 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/CompressionMethod.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1a224d1c619343a1b2fd02d6b4bbbec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/ErrorEventArgs.cs b/Plugins/websocket-sharp/websocket-sharp/ErrorEventArgs.cs new file mode 100644 index 00000000..41502ab0 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/ErrorEventArgs.cs @@ -0,0 +1,109 @@ +#region License +/* + * ErrorEventArgs.cs + * + * The MIT License + * + * Copyright (c) 2012-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Frank Razenberg + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Represents the event data for the event. + /// + /// + /// + /// That event occurs when the gets an error. + /// + /// + /// If you would like to get the error message, you should access + /// the property. + /// + /// + /// And if the error is due to an exception, you can get it by accessing + /// the property. + /// + /// + public class ErrorEventArgs : EventArgs + { + #region Private Fields + + private Exception _exception; + private string _message; + + #endregion + + #region Internal Constructors + + internal ErrorEventArgs (string message) + : this (message, null) + { + } + + internal ErrorEventArgs (string message, Exception exception) + { + _message = message; + _exception = exception; + } + + #endregion + + #region Public Properties + + /// + /// Gets the exception that caused the error. + /// + /// + /// An instance that represents the cause of + /// the error if it is due to an exception; otherwise, . + /// + public Exception Exception { + get { + return _exception; + } + } + + /// + /// Gets the error message. + /// + /// + /// A that represents the error message. + /// + public string Message { + get { + return _message; + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/ErrorEventArgs.cs.meta b/Plugins/websocket-sharp/websocket-sharp/ErrorEventArgs.cs.meta new file mode 100644 index 00000000..39c04889 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/ErrorEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56cf4175497f344b5854ab217026da22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Ext.cs b/Plugins/websocket-sharp/websocket-sharp/Ext.cs new file mode 100644 index 00000000..5f598e19 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Ext.cs @@ -0,0 +1,2252 @@ +#region License +/* + * Ext.cs + * + * Some parts of this code are derived from Mono (http://www.mono-project.com): + * - GetStatusDescription is derived from HttpListenerResponse.cs (System.Net) + * - IsPredefinedScheme is derived from Uri.cs (System) + * - MaybeUri is derived from Uri.cs (System) + * + * The MIT License + * + * Copyright (c) 2001 Garrett Rooney + * Copyright (c) 2003 Ian MacLean + * Copyright (c) 2003 Ben Maurer + * Copyright (c) 2003, 2005, 2009 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2009 Stephane Delcroix + * Copyright (c) 2010-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Liryna + * - Nikola Kovacevic + * - Chris Swiedler + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.IO.Compression; +using System.Net.Sockets; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using WebSocketSharp.Net; +using WebSocketSharp.Net.WebSockets; +using WebSocketSharp.Server; + +namespace WebSocketSharp +{ + /// + /// Provides a set of static methods for websocket-sharp. + /// + public static class Ext + { + #region Private Fields + + private static readonly byte[] _last = new byte[] { 0x00 }; + private static readonly int _retry = 5; + private const string _tspecials = "()<>@,;:\\\"/[]?={} \t"; + + #endregion + + #region Private Methods + + private static byte[] compress (this byte[] data) + { + if (data.LongLength == 0) + //return new byte[] { 0x00, 0x00, 0x00, 0xff, 0xff }; + return data; + + using (var input = new MemoryStream (data)) + return input.compressToArray (); + } + + private static MemoryStream compress (this Stream stream) + { + var output = new MemoryStream (); + if (stream.Length == 0) + return output; + + stream.Position = 0; + using (var ds = new DeflateStream (output, CompressionMode.Compress, true)) { + stream.CopyTo (ds, 1024); + ds.Close (); // BFINAL set to 1. + output.Write (_last, 0, 1); + output.Position = 0; + + return output; + } + } + + private static byte[] compressToArray (this Stream stream) + { + using (var output = stream.compress ()) { + output.Close (); + return output.ToArray (); + } + } + + private static byte[] decompress (this byte[] data) + { + if (data.LongLength == 0) + return data; + + using (var input = new MemoryStream (data)) + return input.decompressToArray (); + } + + private static MemoryStream decompress (this Stream stream) + { + var output = new MemoryStream (); + if (stream.Length == 0) + return output; + + stream.Position = 0; + using (var ds = new DeflateStream (stream, CompressionMode.Decompress, true)) { + ds.CopyTo (output, 1024); + output.Position = 0; + + return output; + } + } + + private static byte[] decompressToArray (this Stream stream) + { + using (var output = stream.decompress ()) { + output.Close (); + return output.ToArray (); + } + } + + private static bool isHttpMethod (this string value) + { + return value == "GET" + || value == "HEAD" + || value == "POST" + || value == "PUT" + || value == "DELETE" + || value == "CONNECT" + || value == "OPTIONS" + || value == "TRACE"; + } + + private static bool isHttpMethod10 (this string value) + { + return value == "GET" + || value == "HEAD" + || value == "POST"; + } + + #endregion + + #region Internal Methods + + internal static byte[] Append (this ushort code, string reason) + { + var bytes = code.InternalToByteArray (ByteOrder.Big); + + if (reason == null || reason.Length == 0) + return bytes; + + var buff = new List (bytes); + buff.AddRange (Encoding.UTF8.GetBytes (reason)); + + return buff.ToArray (); + } + + internal static byte[] Compress (this byte[] data, CompressionMethod method) + { + return method == CompressionMethod.Deflate + ? data.compress () + : data; + } + + internal static Stream Compress (this Stream stream, CompressionMethod method) + { + return method == CompressionMethod.Deflate + ? stream.compress () + : stream; + } + + internal static byte[] CompressToArray (this Stream stream, CompressionMethod method) + { + return method == CompressionMethod.Deflate + ? stream.compressToArray () + : stream.ToByteArray (); + } + + /// + /// Determines whether the specified string contains any of characters in + /// the specified array of . + /// + /// + /// true if contains any of characters in + /// ; otherwise, false. + /// + /// + /// A to test. + /// + /// + /// An array of that contains one or more characters to + /// seek. + /// + internal static bool Contains (this string value, params char[] anyOf) + { + return anyOf != null && anyOf.Length > 0 + ? value.IndexOfAny (anyOf) > -1 + : false; + } + + internal static bool Contains ( + this NameValueCollection collection, string name + ) + { + return collection[name] != null; + } + + internal static bool Contains ( + this NameValueCollection collection, + string name, + string value, + StringComparison comparisonTypeForValue + ) + { + var val = collection[name]; + if (val == null) + return false; + + foreach (var elm in val.Split (',')) { + if (elm.Trim ().Equals (value, comparisonTypeForValue)) + return true; + } + + return false; + } + + internal static bool Contains ( + this IEnumerable source, Func condition + ) + { + foreach (T elm in source) { + if (condition (elm)) + return true; + } + + return false; + } + + internal static bool ContainsTwice (this string[] values) + { + var len = values.Length; + var end = len - 1; + + Func seek = null; + seek = idx => { + if (idx == end) + return false; + + var val = values[idx]; + for (var i = idx + 1; i < len; i++) { + if (values[i] == val) + return true; + } + + return seek (++idx); + }; + + return seek (0); + } + + internal static T[] Copy (this T[] source, int length) + { + var dest = new T[length]; + Array.Copy (source, 0, dest, 0, length); + + return dest; + } + + internal static T[] Copy (this T[] source, long length) + { + var dest = new T[length]; + Array.Copy (source, 0, dest, 0, length); + + return dest; + } + + internal static void CopyTo ( + this Stream source, Stream destination, int bufferLength + ) + { + var buff = new byte[bufferLength]; + var nread = 0; + + while (true) { + nread = source.Read (buff, 0, bufferLength); + if (nread <= 0) + break; + + destination.Write (buff, 0, nread); + } + } + + internal static void CopyToAsync ( + this Stream source, + Stream destination, + int bufferLength, + Action completed, + Action error + ) + { + var buff = new byte[bufferLength]; + + AsyncCallback callback = null; + callback = + ar => { + try { + var nread = source.EndRead (ar); + if (nread <= 0) { + if (completed != null) + completed (); + + return; + } + + destination.Write (buff, 0, nread); + source.BeginRead (buff, 0, bufferLength, callback, null); + } + catch (Exception ex) { + if (error != null) + error (ex); + } + }; + + try { + source.BeginRead (buff, 0, bufferLength, callback, null); + } + catch (Exception ex) { + if (error != null) + error (ex); + } + } + + internal static byte[] Decompress (this byte[] data, CompressionMethod method) + { + return method == CompressionMethod.Deflate + ? data.decompress () + : data; + } + + internal static Stream Decompress (this Stream stream, CompressionMethod method) + { + return method == CompressionMethod.Deflate + ? stream.decompress () + : stream; + } + + internal static byte[] DecompressToArray (this Stream stream, CompressionMethod method) + { + return method == CompressionMethod.Deflate + ? stream.decompressToArray () + : stream.ToByteArray (); + } + + internal static void Emit ( + this EventHandler eventHandler, object sender, EventArgs e + ) + { + if (eventHandler == null) + return; + + eventHandler (sender, e); + } + + internal static void Emit ( + this EventHandler eventHandler, object sender, TEventArgs e + ) + where TEventArgs : EventArgs + { + if (eventHandler == null) + return; + + eventHandler (sender, e); + } + + /// + /// Determines whether the specified equals the specified , + /// and invokes the specified Action<int> delegate at the same time. + /// + /// + /// true if equals ; + /// otherwise, false. + /// + /// + /// An to compare. + /// + /// + /// A to compare. + /// + /// + /// An Action<int> delegate that references the method(s) called + /// at the same time as comparing. An parameter to pass to + /// the method(s) is . + /// + internal static bool EqualsWith (this int value, char c, Action action) + { + action (value); + return value == c - 0; + } + + /// + /// Gets the absolute path from the specified . + /// + /// + /// A that represents the absolute path if it's successfully found; + /// otherwise, . + /// + /// + /// A that represents the URI to get the absolute path from. + /// + internal static string GetAbsolutePath (this Uri uri) + { + if (uri.IsAbsoluteUri) + return uri.AbsolutePath; + + var original = uri.OriginalString; + if (original[0] != '/') + return null; + + var idx = original.IndexOfAny (new[] { '?', '#' }); + return idx > 0 ? original.Substring (0, idx) : original; + } + + internal static CookieCollection GetCookies ( + this NameValueCollection headers, bool response + ) + { + var val = headers[response ? "Set-Cookie" : "Cookie"]; + return val != null + ? CookieCollection.Parse (val, response) + : new CookieCollection (); + } + + internal static string GetDnsSafeHost (this Uri uri, bool bracketIPv6) + { + return bracketIPv6 && uri.HostNameType == UriHostNameType.IPv6 + ? uri.Host + : uri.DnsSafeHost; + } + + internal static string GetMessage (this CloseStatusCode code) + { + return code == CloseStatusCode.ProtocolError + ? "A WebSocket protocol error has occurred." + : code == CloseStatusCode.UnsupportedData + ? "Unsupported data has been received." + : code == CloseStatusCode.Abnormal + ? "An exception has occurred." + : code == CloseStatusCode.InvalidData + ? "Invalid data has been received." + : code == CloseStatusCode.PolicyViolation + ? "A policy violation has occurred." + : code == CloseStatusCode.TooBig + ? "A too big message has been received." + : code == CloseStatusCode.MandatoryExtension + ? "WebSocket client didn't receive expected extension(s)." + : code == CloseStatusCode.ServerError + ? "WebSocket server got an internal error." + : code == CloseStatusCode.TlsHandshakeFailure + ? "An error has occurred during a TLS handshake." + : String.Empty; + } + + /// + /// Gets the name from the specified string that contains a pair of + /// name and value separated by a character. + /// + /// + /// + /// A that represents the name. + /// + /// + /// if the name is not present. + /// + /// + /// + /// A that contains a pair of name and value. + /// + /// + /// A used to separate name and value. + /// + internal static string GetName (this string nameAndValue, char separator) + { + var idx = nameAndValue.IndexOf (separator); + return idx > 0 ? nameAndValue.Substring (0, idx).Trim () : null; + } + + internal static string GetUTF8DecodedString (this byte[] bytes) + { + return Encoding.UTF8.GetString (bytes); + } + + internal static byte[] GetUTF8EncodedBytes (this string s) + { + return Encoding.UTF8.GetBytes (s); + } + + /// + /// Gets the value from the specified string that contains a pair of + /// name and value separated by a character. + /// + /// + /// + /// A that represents the value. + /// + /// + /// if the value is not present. + /// + /// + /// + /// A that contains a pair of name and value. + /// + /// + /// A used to separate name and value. + /// + internal static string GetValue (this string nameAndValue, char separator) + { + return nameAndValue.GetValue (separator, false); + } + + /// + /// Gets the value from the specified string that contains a pair of + /// name and value separated by a character. + /// + /// + /// + /// A that represents the value. + /// + /// + /// if the value is not present. + /// + /// + /// + /// A that contains a pair of name and value. + /// + /// + /// A used to separate name and value. + /// + /// + /// A : true if unquotes the value; otherwise, + /// false. + /// + internal static string GetValue ( + this string nameAndValue, char separator, bool unquote + ) + { + var idx = nameAndValue.IndexOf (separator); + if (idx < 0 || idx == nameAndValue.Length - 1) + return null; + + var val = nameAndValue.Substring (idx + 1).Trim (); + return unquote ? val.Unquote () : val; + } + + internal static byte[] InternalToByteArray ( + this ushort value, ByteOrder order + ) + { + var ret = BitConverter.GetBytes (value); + + if (!order.IsHostOrder ()) + Array.Reverse (ret); + + return ret; + } + + internal static byte[] InternalToByteArray ( + this ulong value, ByteOrder order + ) + { + var ret = BitConverter.GetBytes (value); + + if (!order.IsHostOrder ()) + Array.Reverse (ret); + + return ret; + } + + internal static bool IsCompressionExtension ( + this string value, CompressionMethod method + ) + { + return value.StartsWith (method.ToExtensionString ()); + } + + internal static bool IsControl (this byte opcode) + { + return opcode > 0x7 && opcode < 0x10; + } + + internal static bool IsControl (this Opcode opcode) + { + return opcode >= Opcode.Close; + } + + internal static bool IsData (this byte opcode) + { + return opcode == 0x1 || opcode == 0x2; + } + + internal static bool IsData (this Opcode opcode) + { + return opcode == Opcode.Text || opcode == Opcode.Binary; + } + + internal static bool IsHttpMethod (this string value, Version version) + { + return version == HttpVersion.Version10 + ? value.isHttpMethod10 () + : value.isHttpMethod (); + } + + internal static bool IsPortNumber (this int value) + { + return value > 0 && value < 65536; + } + + internal static bool IsReserved (this ushort code) + { + return code == 1004 + || code == 1005 + || code == 1006 + || code == 1015; + } + + internal static bool IsReserved (this CloseStatusCode code) + { + return code == CloseStatusCode.Undefined + || code == CloseStatusCode.NoStatus + || code == CloseStatusCode.Abnormal + || code == CloseStatusCode.TlsHandshakeFailure; + } + + internal static bool IsSupported (this byte opcode) + { + return Enum.IsDefined (typeof (Opcode), opcode); + } + + internal static bool IsText (this string value) + { + var len = value.Length; + + for (var i = 0; i < len; i++) { + var c = value[i]; + if (c < 0x20) { + if ("\r\n\t".IndexOf (c) == -1) + return false; + + if (c == '\n') { + i++; + if (i == len) + break; + + c = value[i]; + if (" \t".IndexOf (c) == -1) + return false; + } + + continue; + } + + if (c == 0x7f) + return false; + } + + return true; + } + + internal static bool IsToken (this string value) + { + foreach (var c in value) { + if (c < 0x20) + return false; + + if (c > 0x7e) + return false; + + if (_tspecials.IndexOf (c) > -1) + return false; + } + + return true; + } + + internal static bool KeepsAlive ( + this NameValueCollection headers, Version version + ) + { + var comparison = StringComparison.OrdinalIgnoreCase; + return version < HttpVersion.Version11 + ? headers.Contains ("Connection", "keep-alive", comparison) + : !headers.Contains ("Connection", "close", comparison); + } + + internal static string Quote (this string value) + { + return String.Format ("\"{0}\"", value.Replace ("\"", "\\\"")); + } + + internal static byte[] ReadBytes (this Stream stream, int length) + { + var buff = new byte[length]; + var offset = 0; + var retry = 0; + var nread = 0; + + while (length > 0) { + nread = stream.Read (buff, offset, length); + if (nread <= 0) { + if (retry < _retry) { + retry++; + continue; + } + + return buff.SubArray (0, offset); + } + + retry = 0; + + offset += nread; + length -= nread; + } + + return buff; + } + + internal static byte[] ReadBytes ( + this Stream stream, long length, int bufferLength + ) + { + using (var dest = new MemoryStream ()) { + var buff = new byte[bufferLength]; + var retry = 0; + var nread = 0; + + while (length > 0) { + if (length < bufferLength) + bufferLength = (int) length; + + nread = stream.Read (buff, 0, bufferLength); + if (nread <= 0) { + if (retry < _retry) { + retry++; + continue; + } + + break; + } + + retry = 0; + + dest.Write (buff, 0, nread); + length -= nread; + } + + dest.Close (); + return dest.ToArray (); + } + } + + internal static void ReadBytesAsync ( + this Stream stream, + int length, + Action completed, + Action error + ) + { + var buff = new byte[length]; + var offset = 0; + var retry = 0; + + AsyncCallback callback = null; + callback = + ar => { + try { + var nread = stream.EndRead (ar); + if (nread <= 0) { + if (retry < _retry) { + retry++; + stream.BeginRead (buff, offset, length, callback, null); + + return; + } + + if (completed != null) + completed (buff.SubArray (0, offset)); + + return; + } + + if (nread == length) { + if (completed != null) + completed (buff); + + return; + } + + retry = 0; + + offset += nread; + length -= nread; + + stream.BeginRead (buff, offset, length, callback, null); + } + catch (Exception ex) { + if (error != null) + error (ex); + } + }; + + try { + stream.BeginRead (buff, offset, length, callback, null); + } + catch (Exception ex) { + if (error != null) + error (ex); + } + } + + internal static void ReadBytesAsync ( + this Stream stream, + long length, + int bufferLength, + Action completed, + Action error + ) + { + var dest = new MemoryStream (); + var buff = new byte[bufferLength]; + var retry = 0; + + Action read = null; + read = + len => { + if (len < bufferLength) + bufferLength = (int) len; + + stream.BeginRead ( + buff, + 0, + bufferLength, + ar => { + try { + var nread = stream.EndRead (ar); + if (nread <= 0) { + if (retry < _retry) { + retry++; + read (len); + + return; + } + + if (completed != null) { + dest.Close (); + completed (dest.ToArray ()); + } + + dest.Dispose (); + return; + } + + dest.Write (buff, 0, nread); + + if (nread == len) { + if (completed != null) { + dest.Close (); + completed (dest.ToArray ()); + } + + dest.Dispose (); + return; + } + + retry = 0; + + read (len - nread); + } + catch (Exception ex) { + dest.Dispose (); + if (error != null) + error (ex); + } + }, + null + ); + }; + + try { + read (length); + } + catch (Exception ex) { + dest.Dispose (); + if (error != null) + error (ex); + } + } + + internal static T[] Reverse (this T[] array) + { + var len = array.Length; + var ret = new T[len]; + + var end = len - 1; + for (var i = 0; i <= end; i++) + ret[i] = array[end - i]; + + return ret; + } + + internal static IEnumerable SplitHeaderValue ( + this string value, params char[] separators + ) + { + var len = value.Length; + var end = len - 1; + + var buff = new StringBuilder (32); + var escaped = false; + var quoted = false; + + for (var i = 0; i <= end; i++) { + var c = value[i]; + buff.Append (c); + + if (c == '"') { + if (escaped) { + escaped = false; + + continue; + } + + quoted = !quoted; + + continue; + } + + if (c == '\\') { + if (i == end) + break; + + if (value[i + 1] == '"') + escaped = true; + + continue; + } + + if (Array.IndexOf (separators, c) > -1) { + if (quoted) + continue; + + buff.Length -= 1; + + yield return buff.ToString (); + + buff.Length = 0; + + continue; + } + } + + yield return buff.ToString (); + } + + internal static byte[] ToByteArray (this Stream stream) + { + using (var output = new MemoryStream ()) { + stream.Position = 0; + stream.CopyTo (output, 1024); + output.Close (); + + return output.ToArray (); + } + } + + internal static CompressionMethod ToCompressionMethod (this string value) + { + var methods = Enum.GetValues (typeof (CompressionMethod)); + foreach (CompressionMethod method in methods) { + if (method.ToExtensionString () == value) + return method; + } + + return CompressionMethod.None; + } + + internal static string ToExtensionString ( + this CompressionMethod method, params string[] parameters + ) + { + if (method == CompressionMethod.None) + return String.Empty; + + var name = String.Format ( + "permessage-{0}", method.ToString ().ToLower () + ); + + return parameters != null && parameters.Length > 0 + ? String.Format ("{0}; {1}", name, parameters.ToString ("; ")) + : name; + } + + internal static System.Net.IPAddress ToIPAddress (this string value) + { + if (value == null || value.Length == 0) + return null; + + System.Net.IPAddress addr; + if (System.Net.IPAddress.TryParse (value, out addr)) + return addr; + + try { + var addrs = System.Net.Dns.GetHostAddresses (value); + return addrs[0]; + } + catch { + return null; + } + } + + internal static List ToList ( + this IEnumerable source + ) + { + return new List (source); + } + + internal static string ToString ( + this System.Net.IPAddress address, bool bracketIPv6 + ) + { + return bracketIPv6 + && address.AddressFamily == AddressFamily.InterNetworkV6 + ? String.Format ("[{0}]", address.ToString ()) + : address.ToString (); + } + + internal static ushort ToUInt16 (this byte[] source, ByteOrder sourceOrder) + { + return BitConverter.ToUInt16 (source.ToHostOrder (sourceOrder), 0); + } + + internal static ulong ToUInt64 (this byte[] source, ByteOrder sourceOrder) + { + return BitConverter.ToUInt64 (source.ToHostOrder (sourceOrder), 0); + } + + internal static IEnumerable TrimEach ( + this IEnumerable source + ) + { + foreach (var elm in source) + yield return elm.Trim (); + } + + internal static string TrimSlashFromEnd (this string value) + { + var ret = value.TrimEnd ('/'); + + return ret.Length > 0 ? ret : "/"; + } + + internal static string TrimSlashOrBackslashFromEnd (this string value) + { + var ret = value.TrimEnd ('/', '\\'); + + return ret.Length > 0 ? ret : value[0].ToString (); + } + + internal static bool TryCreateVersion ( + this string versionString, out Version result + ) + { + result = null; + + try { + result = new Version (versionString); + } + catch { + return false; + } + + return true; + } + + /// + /// Tries to create a new for WebSocket with + /// the specified . + /// + /// + /// true if the was successfully created; + /// otherwise, false. + /// + /// + /// A that represents a WebSocket URL to try. + /// + /// + /// When this method returns, a that + /// represents the WebSocket URL or + /// if is invalid. + /// + /// + /// When this method returns, a that + /// represents an error message or + /// if is valid. + /// + internal static bool TryCreateWebSocketUri ( + this string uriString, out Uri result, out string message + ) + { + result = null; + message = null; + + var uri = uriString.ToUri (); + if (uri == null) { + message = "An invalid URI string."; + return false; + } + + if (!uri.IsAbsoluteUri) { + message = "A relative URI."; + return false; + } + + var schm = uri.Scheme; + if (!(schm == "ws" || schm == "wss")) { + message = "The scheme part is not 'ws' or 'wss'."; + return false; + } + + var port = uri.Port; + if (port == 0) { + message = "The port part is zero."; + return false; + } + + if (uri.Fragment.Length > 0) { + message = "It includes the fragment component."; + return false; + } + + result = port != -1 + ? uri + : new Uri ( + String.Format ( + "{0}://{1}:{2}{3}", + schm, + uri.Host, + schm == "ws" ? 80 : 443, + uri.PathAndQuery + ) + ); + + return true; + } + + internal static bool TryGetUTF8DecodedString (this byte[] bytes, out string s) + { + s = null; + + try { + s = Encoding.UTF8.GetString (bytes); + } + catch { + return false; + } + + return true; + } + + internal static bool TryGetUTF8EncodedBytes (this string s, out byte[] bytes) + { + bytes = null; + + try { + bytes = Encoding.UTF8.GetBytes (s); + } + catch { + return false; + } + + return true; + } + + internal static bool TryOpenRead ( + this FileInfo fileInfo, out FileStream fileStream + ) + { + fileStream = null; + + try { + fileStream = fileInfo.OpenRead (); + } + catch { + return false; + } + + return true; + } + + internal static string Unquote (this string value) + { + var start = value.IndexOf ('"'); + if (start == -1) + return value; + + var end = value.LastIndexOf ('"'); + if (end == start) + return value; + + var len = end - start - 1; + return len > 0 + ? value.Substring (start + 1, len).Replace ("\\\"", "\"") + : String.Empty; + } + + internal static bool Upgrades ( + this NameValueCollection headers, string protocol + ) + { + var comparison = StringComparison.OrdinalIgnoreCase; + return headers.Contains ("Upgrade", protocol, comparison) + && headers.Contains ("Connection", "Upgrade", comparison); + } + + internal static string UrlDecode (this string value, Encoding encoding) + { + return HttpUtility.UrlDecode (value, encoding); + } + + internal static string UrlEncode (this string value, Encoding encoding) + { + return HttpUtility.UrlEncode (value, encoding); + } + + internal static void WriteBytes ( + this Stream stream, byte[] bytes, int bufferLength + ) + { + using (var src = new MemoryStream (bytes)) + src.CopyTo (stream, bufferLength); + } + + internal static void WriteBytesAsync ( + this Stream stream, + byte[] bytes, + int bufferLength, + Action completed, + Action error + ) + { + var src = new MemoryStream (bytes); + src.CopyToAsync ( + stream, + bufferLength, + () => { + if (completed != null) + completed (); + + src.Dispose (); + }, + ex => { + src.Dispose (); + if (error != null) + error (ex); + } + ); + } + + #endregion + + #region Public Methods + + /// + /// Gets the description of the specified HTTP status code. + /// + /// + /// A that represents the description of + /// the HTTP status code. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the HTTP status code. + /// + /// + public static string GetDescription (this HttpStatusCode code) + { + return ((int) code).GetStatusDescription (); + } + + /// + /// Gets the description of the specified HTTP status code. + /// + /// + /// + /// A that represents the description of + /// the HTTP status code. + /// + /// + /// An empty string if the description is not present. + /// + /// + /// + /// An that specifies the HTTP status code. + /// + public static string GetStatusDescription (this int code) + { + switch (code) { + case 100: return "Continue"; + case 101: return "Switching Protocols"; + case 102: return "Processing"; + case 200: return "OK"; + case 201: return "Created"; + case 202: return "Accepted"; + case 203: return "Non-Authoritative Information"; + case 204: return "No Content"; + case 205: return "Reset Content"; + case 206: return "Partial Content"; + case 207: return "Multi-Status"; + case 300: return "Multiple Choices"; + case 301: return "Moved Permanently"; + case 302: return "Found"; + case 303: return "See Other"; + case 304: return "Not Modified"; + case 305: return "Use Proxy"; + case 307: return "Temporary Redirect"; + case 400: return "Bad Request"; + case 401: return "Unauthorized"; + case 402: return "Payment Required"; + case 403: return "Forbidden"; + case 404: return "Not Found"; + case 405: return "Method Not Allowed"; + case 406: return "Not Acceptable"; + case 407: return "Proxy Authentication Required"; + case 408: return "Request Timeout"; + case 409: return "Conflict"; + case 410: return "Gone"; + case 411: return "Length Required"; + case 412: return "Precondition Failed"; + case 413: return "Request Entity Too Large"; + case 414: return "Request-Uri Too Long"; + case 415: return "Unsupported Media Type"; + case 416: return "Requested Range Not Satisfiable"; + case 417: return "Expectation Failed"; + case 422: return "Unprocessable Entity"; + case 423: return "Locked"; + case 424: return "Failed Dependency"; + case 500: return "Internal Server Error"; + case 501: return "Not Implemented"; + case 502: return "Bad Gateway"; + case 503: return "Service Unavailable"; + case 504: return "Gateway Timeout"; + case 505: return "Http Version Not Supported"; + case 507: return "Insufficient Storage"; + } + + return String.Empty; + } + + /// + /// Determines whether the specified ushort is in the range of + /// the status code for the WebSocket connection close. + /// + /// + /// + /// The ranges are the following: + /// + /// + /// + /// + /// 1000-2999: These numbers are reserved for definition by + /// the WebSocket protocol. + /// + /// + /// + /// + /// 3000-3999: These numbers are reserved for use by libraries, + /// frameworks, and applications. + /// + /// + /// + /// + /// 4000-4999: These numbers are reserved for private use. + /// + /// + /// + /// + /// + /// true if is in the range of + /// the status code for the close; otherwise, false. + /// + /// + /// A to test. + /// + public static bool IsCloseStatusCode (this ushort value) + { + return value > 999 && value < 5000; + } + + /// + /// Determines whether the specified string is enclosed in + /// the specified character. + /// + /// + /// true if is enclosed in + /// ; otherwise, false. + /// + /// + /// A to test. + /// + /// + /// A to find. + /// + public static bool IsEnclosedIn (this string value, char c) + { + if (value == null) + return false; + + var len = value.Length; + if (len < 2) + return false; + + return value[0] == c && value[len - 1] == c; + } + + /// + /// Determines whether the specified byte order is host (this computer + /// architecture) byte order. + /// + /// + /// true if is host byte order; otherwise, + /// false. + /// + /// + /// One of the enum values to test. + /// + public static bool IsHostOrder (this ByteOrder order) + { + // true: !(true ^ true) or !(false ^ false) + // false: !(true ^ false) or !(false ^ true) + return !(BitConverter.IsLittleEndian ^ (order == ByteOrder.Little)); + } + + /// + /// Determines whether the specified IP address is a local IP address. + /// + /// + /// This local means NOT REMOTE for the current host. + /// + /// + /// true if is a local IP address; + /// otherwise, false. + /// + /// + /// A to test. + /// + /// + /// is . + /// + public static bool IsLocal (this System.Net.IPAddress address) + { + if (address == null) + throw new ArgumentNullException ("address"); + + if (address.Equals (System.Net.IPAddress.Any)) + return true; + + if (address.Equals (System.Net.IPAddress.Loopback)) + return true; + + if (Socket.OSSupportsIPv6) { + if (address.Equals (System.Net.IPAddress.IPv6Any)) + return true; + + if (address.Equals (System.Net.IPAddress.IPv6Loopback)) + return true; + } + + var name = System.Net.Dns.GetHostName (); + var addrs = System.Net.Dns.GetHostAddresses (name); + + foreach (var addr in addrs) { + if (address.Equals (addr)) + return true; + } + + return false; + } + + /// + /// Determines whether the specified string is or + /// an empty string. + /// + /// + /// true if is or + /// an empty string; otherwise, false. + /// + /// + /// A to test. + /// + public static bool IsNullOrEmpty (this string value) + { + return value == null || value.Length == 0; + } + + /// + /// Determines whether the specified string is a predefined scheme. + /// + /// + /// true if is a predefined scheme; + /// otherwise, false. + /// + /// + /// A to test. + /// + public static bool IsPredefinedScheme (this string value) + { + if (value == null || value.Length < 2) + return false; + + var c = value[0]; + if (c == 'h') + return value == "http" || value == "https"; + + if (c == 'w') + return value == "ws" || value == "wss"; + + if (c == 'f') + return value == "file" || value == "ftp"; + + if (c == 'g') + return value == "gopher"; + + if (c == 'm') + return value == "mailto"; + + if (c == 'n') { + c = value[1]; + return c == 'e' + ? value == "news" || value == "net.pipe" || value == "net.tcp" + : value == "nntp"; + } + + return false; + } + + /// + /// Determines whether the specified string is a URI string. + /// + /// + /// true if may be a URI string; + /// otherwise, false. + /// + /// + /// A to test. + /// + public static bool MaybeUri (this string value) + { + if (value == null) + return false; + + if (value.Length == 0) + return false; + + var idx = value.IndexOf (':'); + if (idx == -1) + return false; + + if (idx >= 10) + return false; + + var schm = value.Substring (0, idx); + return schm.IsPredefinedScheme (); + } + + /// + /// Retrieves a sub-array from the specified array. A sub-array starts at + /// the specified index in the array. + /// + /// + /// An array of T that receives a sub-array. + /// + /// + /// An array of T from which to retrieve a sub-array. + /// + /// + /// An that represents the zero-based index in the array + /// at which retrieving starts. + /// + /// + /// An that represents the number of elements to retrieve. + /// + /// + /// The type of elements in the array. + /// + /// + /// is . + /// + /// + /// + /// is less than zero. + /// + /// + /// -or- + /// + /// + /// is greater than the end of the array. + /// + /// + /// -or- + /// + /// + /// is less than zero. + /// + /// + /// -or- + /// + /// + /// is greater than the number of elements from + /// to the end of the array. + /// + /// + public static T[] SubArray (this T[] array, int startIndex, int length) + { + if (array == null) + throw new ArgumentNullException ("array"); + + var len = array.Length; + if (len == 0) { + if (startIndex != 0) + throw new ArgumentOutOfRangeException ("startIndex"); + + if (length != 0) + throw new ArgumentOutOfRangeException ("length"); + + return array; + } + + if (startIndex < 0 || startIndex >= len) + throw new ArgumentOutOfRangeException ("startIndex"); + + if (length < 0 || length > len - startIndex) + throw new ArgumentOutOfRangeException ("length"); + + if (length == 0) + return new T[0]; + + if (length == len) + return array; + + var subArray = new T[length]; + Array.Copy (array, startIndex, subArray, 0, length); + + return subArray; + } + + /// + /// Retrieves a sub-array from the specified array. A sub-array starts at + /// the specified index in the array. + /// + /// + /// An array of T that receives a sub-array. + /// + /// + /// An array of T from which to retrieve a sub-array. + /// + /// + /// A that represents the zero-based index in the array + /// at which retrieving starts. + /// + /// + /// A that represents the number of elements to retrieve. + /// + /// + /// The type of elements in the array. + /// + /// + /// is . + /// + /// + /// + /// is less than zero. + /// + /// + /// -or- + /// + /// + /// is greater than the end of the array. + /// + /// + /// -or- + /// + /// + /// is less than zero. + /// + /// + /// -or- + /// + /// + /// is greater than the number of elements from + /// to the end of the array. + /// + /// + public static T[] SubArray (this T[] array, long startIndex, long length) + { + if (array == null) + throw new ArgumentNullException ("array"); + + var len = array.LongLength; + if (len == 0) { + if (startIndex != 0) + throw new ArgumentOutOfRangeException ("startIndex"); + + if (length != 0) + throw new ArgumentOutOfRangeException ("length"); + + return array; + } + + if (startIndex < 0 || startIndex >= len) + throw new ArgumentOutOfRangeException ("startIndex"); + + if (length < 0 || length > len - startIndex) + throw new ArgumentOutOfRangeException ("length"); + + if (length == 0) + return new T[0]; + + if (length == len) + return array; + + var subArray = new T[length]; + Array.Copy (array, startIndex, subArray, 0, length); + + return subArray; + } + + /// + /// Executes the specified delegate times. + /// + /// + /// An that specifies the number of times to execute. + /// + /// + /// An delegate to execute. + /// + public static void Times (this int n, Action action) + { + if (n <= 0) + return; + + if (action == null) + return; + + for (int i = 0; i < n; i++) + action (); + } + + /// + /// Executes the specified delegate times. + /// + /// + /// A that specifies the number of times to execute. + /// + /// + /// An delegate to execute. + /// + public static void Times (this long n, Action action) + { + if (n <= 0) + return; + + if (action == null) + return; + + for (long i = 0; i < n; i++) + action (); + } + + /// + /// Executes the specified delegate times. + /// + /// + /// A that specifies the number of times to execute. + /// + /// + /// An delegate to execute. + /// + public static void Times (this uint n, Action action) + { + if (n == 0) + return; + + if (action == null) + return; + + for (uint i = 0; i < n; i++) + action (); + } + + /// + /// Executes the specified delegate times. + /// + /// + /// A that specifies the number of times to execute. + /// + /// + /// An delegate to execute. + /// + public static void Times (this ulong n, Action action) + { + if (n == 0) + return; + + if (action == null) + return; + + for (ulong i = 0; i < n; i++) + action (); + } + + /// + /// Executes the specified delegate times. + /// + /// + /// An that specifies the number of times to execute. + /// + /// + /// + /// An Action<int> delegate to execute. + /// + /// + /// The parameter is the zero-based count of iteration. + /// + /// + public static void Times (this int n, Action action) + { + if (n <= 0) + return; + + if (action == null) + return; + + for (int i = 0; i < n; i++) + action (i); + } + + /// + /// Executes the specified delegate times. + /// + /// + /// A that specifies the number of times to execute. + /// + /// + /// + /// An Action<long> delegate to execute. + /// + /// + /// The parameter is the zero-based count of iteration. + /// + /// + public static void Times (this long n, Action action) + { + if (n <= 0) + return; + + if (action == null) + return; + + for (long i = 0; i < n; i++) + action (i); + } + + /// + /// Executes the specified delegate times. + /// + /// + /// A that specifies the number of times to execute. + /// + /// + /// + /// An Action<uint> delegate to execute. + /// + /// + /// The parameter is the zero-based count of iteration. + /// + /// + public static void Times (this uint n, Action action) + { + if (n == 0) + return; + + if (action == null) + return; + + for (uint i = 0; i < n; i++) + action (i); + } + + /// + /// Executes the specified delegate times. + /// + /// + /// A that specifies the number of times to execute. + /// + /// + /// + /// An Action<ulong> delegate to execute. + /// + /// + /// The parameter is the zero-based count of iteration. + /// + /// + public static void Times (this ulong n, Action action) + { + if (n == 0) + return; + + if (action == null) + return; + + for (ulong i = 0; i < n; i++) + action (i); + } + + /// + /// Converts the specified byte array to the specified type value. + /// + /// + /// + /// A T converted from . + /// + /// + /// The default value of T if not converted. + /// + /// + /// + /// An array of to convert. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the byte order of . + /// + /// + /// + /// + /// The type of the return. + /// + /// + /// , , , + /// , , , + /// , , , + /// or . + /// + /// + /// + /// is . + /// + [Obsolete ("This method will be removed.")] + public static T To (this byte[] source, ByteOrder sourceOrder) + where T : struct + { + if (source == null) + throw new ArgumentNullException ("source"); + + if (source.Length == 0) + return default (T); + + var type = typeof (T); + var val = source.ToHostOrder (sourceOrder); + + return type == typeof (Boolean) + ? (T)(object) BitConverter.ToBoolean (val, 0) + : type == typeof (Char) + ? (T)(object) BitConverter.ToChar (val, 0) + : type == typeof (Double) + ? (T)(object) BitConverter.ToDouble (val, 0) + : type == typeof (Int16) + ? (T)(object) BitConverter.ToInt16 (val, 0) + : type == typeof (Int32) + ? (T)(object) BitConverter.ToInt32 (val, 0) + : type == typeof (Int64) + ? (T)(object) BitConverter.ToInt64 (val, 0) + : type == typeof (Single) + ? (T)(object) BitConverter.ToSingle (val, 0) + : type == typeof (UInt16) + ? (T)(object) BitConverter.ToUInt16 (val, 0) + : type == typeof (UInt32) + ? (T)(object) BitConverter.ToUInt32 (val, 0) + : type == typeof (UInt64) + ? (T)(object) BitConverter.ToUInt64 (val, 0) + : default (T); + } + + /// + /// Converts the specified value to a byte array. + /// + /// + /// An array of converted from . + /// + /// + /// A T to convert. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the byte order of the return. + /// + /// + /// + /// + /// The type of . + /// + /// + /// , , , + /// , , , + /// , , , + /// , or . + /// + /// + [Obsolete ("This method will be removed.")] + public static byte[] ToByteArray (this T value, ByteOrder order) + where T : struct + { + var type = typeof (T); + var bytes = type == typeof (Boolean) + ? BitConverter.GetBytes ((Boolean)(object) value) + : type == typeof (Byte) + ? new byte[] { (Byte)(object) value } + : type == typeof (Char) + ? BitConverter.GetBytes ((Char)(object) value) + : type == typeof (Double) + ? BitConverter.GetBytes ((Double)(object) value) + : type == typeof (Int16) + ? BitConverter.GetBytes ((Int16)(object) value) + : type == typeof (Int32) + ? BitConverter.GetBytes ((Int32)(object) value) + : type == typeof (Int64) + ? BitConverter.GetBytes ((Int64)(object) value) + : type == typeof (Single) + ? BitConverter.GetBytes ((Single)(object) value) + : type == typeof (UInt16) + ? BitConverter.GetBytes ((UInt16)(object) value) + : type == typeof (UInt32) + ? BitConverter.GetBytes ((UInt32)(object) value) + : type == typeof (UInt64) + ? BitConverter.GetBytes ((UInt64)(object) value) + : WebSocket.EmptyBytes; + + if (bytes.Length > 1) { + if (!order.IsHostOrder ()) + Array.Reverse (bytes); + } + + return bytes; + } + + /// + /// Converts the order of elements in the specified byte array to + /// host (this computer architecture) byte order. + /// + /// + /// + /// An array of converted from + /// . + /// + /// + /// if the number of elements in + /// it is less than 2 or is + /// same as host byte order. + /// + /// + /// + /// An array of to convert. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the order of elements in . + /// + /// + /// + /// is . + /// + public static byte[] ToHostOrder (this byte[] source, ByteOrder sourceOrder) + { + if (source == null) + throw new ArgumentNullException ("source"); + + if (source.Length < 2) + return source; + + if (sourceOrder.IsHostOrder ()) + return source; + + return source.Reverse (); + } + + /// + /// Converts the specified array to a string. + /// + /// + /// + /// A converted by concatenating each element of + /// across . + /// + /// + /// An empty string if is an empty array. + /// + /// + /// + /// An array of T to convert. + /// + /// + /// A used to separate each element of + /// . + /// + /// + /// The type of elements in . + /// + /// + /// is . + /// + public static string ToString (this T[] array, string separator) + { + if (array == null) + throw new ArgumentNullException ("array"); + + var len = array.Length; + if (len == 0) + return String.Empty; + + if (separator == null) + separator = String.Empty; + + var buff = new StringBuilder (64); + var end = len - 1; + + for (var i = 0; i < end; i++) + buff.AppendFormat ("{0}{1}", array[i], separator); + + buff.Append (array[end].ToString ()); + return buff.ToString (); + } + + /// + /// Converts the specified string to a . + /// + /// + /// + /// A converted from . + /// + /// + /// if the conversion has failed. + /// + /// + /// + /// A to convert. + /// + public static Uri ToUri (this string value) + { + Uri ret; + Uri.TryCreate ( + value, value.MaybeUri () ? UriKind.Absolute : UriKind.Relative, out ret + ); + + return ret; + } + + /// + /// Sends the specified content data with the HTTP response. + /// + /// + /// A that represents the HTTP response + /// used to send the content data. + /// + /// + /// An array of that specifies the content data to send. + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + [Obsolete ("This method will be removed.")] + public static void WriteContent ( + this HttpListenerResponse response, byte[] content + ) + { + if (response == null) + throw new ArgumentNullException ("response"); + + if (content == null) + throw new ArgumentNullException ("content"); + + var len = content.LongLength; + if (len == 0) { + response.Close (); + return; + } + + response.ContentLength64 = len; + + var output = response.OutputStream; + + if (len <= Int32.MaxValue) + output.Write (content, 0, (int) len); + else + output.WriteBytes (content, 1024); + + output.Close (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Ext.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Ext.cs.meta new file mode 100644 index 00000000..00d83e4b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Ext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80614531c2687444d85d87648f4e0e7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Fin.cs b/Plugins/websocket-sharp/websocket-sharp/Fin.cs new file mode 100644 index 00000000..8965c378 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Fin.cs @@ -0,0 +1,51 @@ +#region License +/* + * Fin.cs + * + * The MIT License + * + * Copyright (c) 2012-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Indicates whether a WebSocket frame is the final frame of a message. + /// + /// + /// The values of this enumeration are defined in + /// Section 5.2 of RFC 6455. + /// + internal enum Fin : byte + { + /// + /// Equivalent to numeric value 0. Indicates more frames of a message follow. + /// + More = 0x0, + /// + /// Equivalent to numeric value 1. Indicates the final frame of a message. + /// + Final = 0x1 + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Fin.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Fin.cs.meta new file mode 100644 index 00000000..8ae0839a --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Fin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d5494ffde6508404a97a25ff82b6865e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/HttpBase.cs b/Plugins/websocket-sharp/websocket-sharp/HttpBase.cs new file mode 100644 index 00000000..a7dbd402 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/HttpBase.cs @@ -0,0 +1,208 @@ +#region License +/* + * HttpBase.cs + * + * The MIT License + * + * Copyright (c) 2012-2014 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Text; +using System.Threading; +using WebSocketSharp.Net; + +namespace WebSocketSharp +{ + internal abstract class HttpBase + { + #region Private Fields + + private NameValueCollection _headers; + private const int _headersMaxLength = 8192; + private Version _version; + + #endregion + + #region Internal Fields + + internal byte[] EntityBodyData; + + #endregion + + #region Protected Fields + + protected const string CrLf = "\r\n"; + + #endregion + + #region Protected Constructors + + protected HttpBase (Version version, NameValueCollection headers) + { + _version = version; + _headers = headers; + } + + #endregion + + #region Public Properties + + public string EntityBody { + get { + if (EntityBodyData == null || EntityBodyData.LongLength == 0) + return String.Empty; + + Encoding enc = null; + + var contentType = _headers["Content-Type"]; + if (contentType != null && contentType.Length > 0) + enc = HttpUtility.GetEncoding (contentType); + + return (enc ?? Encoding.UTF8).GetString (EntityBodyData); + } + } + + public NameValueCollection Headers { + get { + return _headers; + } + } + + public Version ProtocolVersion { + get { + return _version; + } + } + + #endregion + + #region Private Methods + + private static byte[] readEntityBody (Stream stream, string length) + { + long len; + if (!Int64.TryParse (length, out len)) + throw new ArgumentException ("Cannot be parsed.", "length"); + + if (len < 0) + throw new ArgumentOutOfRangeException ("length", "Less than zero."); + + return len > 1024 + ? stream.ReadBytes (len, 1024) + : len > 0 + ? stream.ReadBytes ((int) len) + : null; + } + + private static string[] readHeaders (Stream stream, int maxLength) + { + var buff = new List (); + var cnt = 0; + Action add = i => { + if (i == -1) + throw new EndOfStreamException ("The header cannot be read from the data source."); + + buff.Add ((byte) i); + cnt++; + }; + + var read = false; + while (cnt < maxLength) { + if (stream.ReadByte ().EqualsWith ('\r', add) && + stream.ReadByte ().EqualsWith ('\n', add) && + stream.ReadByte ().EqualsWith ('\r', add) && + stream.ReadByte ().EqualsWith ('\n', add)) { + read = true; + break; + } + } + + if (!read) + throw new WebSocketException ("The length of header part is greater than the max length."); + + return Encoding.UTF8.GetString (buff.ToArray ()) + .Replace (CrLf + " ", " ") + .Replace (CrLf + "\t", " ") + .Split (new[] { CrLf }, StringSplitOptions.RemoveEmptyEntries); + } + + #endregion + + #region Protected Methods + + protected static T Read (Stream stream, Func parser, int millisecondsTimeout) + where T : HttpBase + { + var timeout = false; + var timer = new Timer ( + state => { + timeout = true; + stream.Close (); + }, + null, + millisecondsTimeout, + -1); + + T http = null; + Exception exception = null; + try { + http = parser (readHeaders (stream, _headersMaxLength)); + var contentLen = http.Headers["Content-Length"]; + if (contentLen != null && contentLen.Length > 0) + http.EntityBodyData = readEntityBody (stream, contentLen); + } + catch (Exception ex) { + exception = ex; + } + finally { + timer.Change (-1, -1); + timer.Dispose (); + } + + var msg = timeout + ? "A timeout has occurred while reading an HTTP request/response." + : exception != null + ? "An exception has occurred while reading an HTTP request/response." + : null; + + if (msg != null) + throw new WebSocketException (msg, exception); + + return http; + } + + #endregion + + #region Public Methods + + public byte[] ToByteArray () + { + return Encoding.UTF8.GetBytes (ToString ()); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/HttpBase.cs.meta b/Plugins/websocket-sharp/websocket-sharp/HttpBase.cs.meta new file mode 100644 index 00000000..a1723ffa --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/HttpBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 799975266be9b4b4c88362bcb7ff9137 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/HttpRequest.cs b/Plugins/websocket-sharp/websocket-sharp/HttpRequest.cs new file mode 100644 index 00000000..fe74d5af --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/HttpRequest.cs @@ -0,0 +1,217 @@ +#region License +/* + * HttpRequest.cs + * + * The MIT License + * + * Copyright (c) 2012-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - David Burhans + */ +#endregion + +using System; +using System.Collections.Specialized; +using System.IO; +using System.Text; +using WebSocketSharp.Net; + +namespace WebSocketSharp +{ + internal class HttpRequest : HttpBase + { + #region Private Fields + + private CookieCollection _cookies; + private string _method; + private string _uri; + + #endregion + + #region Private Constructors + + private HttpRequest (string method, string uri, Version version, NameValueCollection headers) + : base (version, headers) + { + _method = method; + _uri = uri; + } + + #endregion + + #region Internal Constructors + + internal HttpRequest (string method, string uri) + : this (method, uri, HttpVersion.Version11, new NameValueCollection ()) + { + Headers["User-Agent"] = "websocket-sharp/1.0"; + } + + #endregion + + #region Public Properties + + public AuthenticationResponse AuthenticationResponse { + get { + var res = Headers["Authorization"]; + return res != null && res.Length > 0 + ? AuthenticationResponse.Parse (res) + : null; + } + } + + public CookieCollection Cookies { + get { + if (_cookies == null) + _cookies = Headers.GetCookies (false); + + return _cookies; + } + } + + public string HttpMethod { + get { + return _method; + } + } + + public bool IsWebSocketRequest { + get { + return _method == "GET" + && ProtocolVersion > HttpVersion.Version10 + && Headers.Upgrades ("websocket"); + } + } + + public string RequestUri { + get { + return _uri; + } + } + + #endregion + + #region Internal Methods + + internal static HttpRequest CreateConnectRequest (Uri uri) + { + var host = uri.DnsSafeHost; + var port = uri.Port; + var authority = String.Format ("{0}:{1}", host, port); + var req = new HttpRequest ("CONNECT", authority); + req.Headers["Host"] = port == 80 ? host : authority; + + return req; + } + + internal static HttpRequest CreateWebSocketRequest (Uri uri) + { + var req = new HttpRequest ("GET", uri.PathAndQuery); + var headers = req.Headers; + + // Only includes a port number in the Host header value if it's non-default. + // See: https://tools.ietf.org/html/rfc6455#page-17 + var port = uri.Port; + var schm = uri.Scheme; + headers["Host"] = (port == 80 && schm == "ws") || (port == 443 && schm == "wss") + ? uri.DnsSafeHost + : uri.Authority; + + headers["Upgrade"] = "websocket"; + headers["Connection"] = "Upgrade"; + + return req; + } + + internal HttpResponse GetResponse (Stream stream, int millisecondsTimeout) + { + var buff = ToByteArray (); + stream.Write (buff, 0, buff.Length); + + return Read (stream, HttpResponse.Parse, millisecondsTimeout); + } + + internal static HttpRequest Parse (string[] headerParts) + { + var requestLine = headerParts[0].Split (new[] { ' ' }, 3); + if (requestLine.Length != 3) + throw new ArgumentException ("Invalid request line: " + headerParts[0]); + + var headers = new WebHeaderCollection (); + for (int i = 1; i < headerParts.Length; i++) + headers.InternalSet (headerParts[i], false); + + return new HttpRequest ( + requestLine[0], requestLine[1], new Version (requestLine[2].Substring (5)), headers); + } + + internal static HttpRequest Read (Stream stream, int millisecondsTimeout) + { + return Read (stream, Parse, millisecondsTimeout); + } + + #endregion + + #region Public Methods + + public void SetCookies (CookieCollection cookies) + { + if (cookies == null || cookies.Count == 0) + return; + + var buff = new StringBuilder (64); + foreach (var cookie in cookies.Sorted) + if (!cookie.Expired) + buff.AppendFormat ("{0}; ", cookie.ToString ()); + + var len = buff.Length; + if (len > 2) { + buff.Length = len - 2; + Headers["Cookie"] = buff.ToString (); + } + } + + public override string ToString () + { + var output = new StringBuilder (64); + output.AppendFormat ("{0} {1} HTTP/{2}{3}", _method, _uri, ProtocolVersion, CrLf); + + var headers = Headers; + foreach (var key in headers.AllKeys) + output.AppendFormat ("{0}: {1}{2}", key, headers[key], CrLf); + + output.Append (CrLf); + + var entity = EntityBody; + if (entity.Length > 0) + output.Append (entity); + + return output.ToString (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/HttpRequest.cs.meta b/Plugins/websocket-sharp/websocket-sharp/HttpRequest.cs.meta new file mode 100644 index 00000000..8786a24e --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/HttpRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 437dc178142cc4967aa1cd13c31481bd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/HttpResponse.cs b/Plugins/websocket-sharp/websocket-sharp/HttpResponse.cs new file mode 100644 index 00000000..831b7278 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/HttpResponse.cs @@ -0,0 +1,209 @@ +#region License +/* + * HttpResponse.cs + * + * The MIT License + * + * Copyright (c) 2012-2014 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Specialized; +using System.IO; +using System.Text; +using WebSocketSharp.Net; + +namespace WebSocketSharp +{ + internal class HttpResponse : HttpBase + { + #region Private Fields + + private string _code; + private string _reason; + + #endregion + + #region Private Constructors + + private HttpResponse (string code, string reason, Version version, NameValueCollection headers) + : base (version, headers) + { + _code = code; + _reason = reason; + } + + #endregion + + #region Internal Constructors + + internal HttpResponse (HttpStatusCode code) + : this (code, code.GetDescription ()) + { + } + + internal HttpResponse (HttpStatusCode code, string reason) + : this (((int) code).ToString (), reason, HttpVersion.Version11, new NameValueCollection ()) + { + Headers["Server"] = "websocket-sharp/1.0"; + } + + #endregion + + #region Public Properties + + public CookieCollection Cookies { + get { + return Headers.GetCookies (true); + } + } + + public bool HasConnectionClose { + get { + var comparison = StringComparison.OrdinalIgnoreCase; + return Headers.Contains ("Connection", "close", comparison); + } + } + + public bool IsProxyAuthenticationRequired { + get { + return _code == "407"; + } + } + + public bool IsRedirect { + get { + return _code == "301" || _code == "302"; + } + } + + public bool IsUnauthorized { + get { + return _code == "401"; + } + } + + public bool IsWebSocketResponse { + get { + return ProtocolVersion > HttpVersion.Version10 + && _code == "101" + && Headers.Upgrades ("websocket"); + } + } + + public string Reason { + get { + return _reason; + } + } + + public string StatusCode { + get { + return _code; + } + } + + #endregion + + #region Internal Methods + + internal static HttpResponse CreateCloseResponse (HttpStatusCode code) + { + var res = new HttpResponse (code); + res.Headers["Connection"] = "close"; + + return res; + } + + internal static HttpResponse CreateUnauthorizedResponse (string challenge) + { + var res = new HttpResponse (HttpStatusCode.Unauthorized); + res.Headers["WWW-Authenticate"] = challenge; + + return res; + } + + internal static HttpResponse CreateWebSocketResponse () + { + var res = new HttpResponse (HttpStatusCode.SwitchingProtocols); + + var headers = res.Headers; + headers["Upgrade"] = "websocket"; + headers["Connection"] = "Upgrade"; + + return res; + } + + internal static HttpResponse Parse (string[] headerParts) + { + var statusLine = headerParts[0].Split (new[] { ' ' }, 3); + if (statusLine.Length != 3) + throw new ArgumentException ("Invalid status line: " + headerParts[0]); + + var headers = new WebHeaderCollection (); + for (int i = 1; i < headerParts.Length; i++) + headers.InternalSet (headerParts[i], true); + + return new HttpResponse ( + statusLine[1], statusLine[2], new Version (statusLine[0].Substring (5)), headers); + } + + internal static HttpResponse Read (Stream stream, int millisecondsTimeout) + { + return Read (stream, Parse, millisecondsTimeout); + } + + #endregion + + #region Public Methods + + public void SetCookies (CookieCollection cookies) + { + if (cookies == null || cookies.Count == 0) + return; + + var headers = Headers; + foreach (var cookie in cookies.Sorted) + headers.Add ("Set-Cookie", cookie.ToResponseString ()); + } + + public override string ToString () + { + var output = new StringBuilder (64); + output.AppendFormat ("HTTP/{0} {1} {2}{3}", ProtocolVersion, _code, _reason, CrLf); + + var headers = Headers; + foreach (var key in headers.AllKeys) + output.AppendFormat ("{0}: {1}{2}", key, headers[key], CrLf); + + output.Append (CrLf); + + var entity = EntityBody; + if (entity.Length > 0) + output.Append (entity); + + return output.ToString (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/HttpResponse.cs.meta b/Plugins/websocket-sharp/websocket-sharp/HttpResponse.cs.meta new file mode 100644 index 00000000..969a5888 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/HttpResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3fc5ce5d82c3c40618fc7dcde8b724f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/LogData.cs b/Plugins/websocket-sharp/websocket-sharp/LogData.cs new file mode 100644 index 00000000..9c084309 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/LogData.cs @@ -0,0 +1,149 @@ +#region License +/* + * LogData.cs + * + * The MIT License + * + * Copyright (c) 2013-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Diagnostics; +using System.Text; + +namespace WebSocketSharp +{ + /// + /// Represents a log data used by the class. + /// + public class LogData + { + #region Private Fields + + private StackFrame _caller; + private DateTime _date; + private LogLevel _level; + private string _message; + + #endregion + + #region Internal Constructors + + internal LogData (LogLevel level, StackFrame caller, string message) + { + _level = level; + _caller = caller; + _message = message ?? String.Empty; + _date = DateTime.Now; + } + + #endregion + + #region Public Properties + + /// + /// Gets the information of the logging method caller. + /// + /// + /// A that provides the information of the logging method caller. + /// + public StackFrame Caller { + get { + return _caller; + } + } + + /// + /// Gets the date and time when the log data was created. + /// + /// + /// A that represents the date and time when the log data was created. + /// + public DateTime Date { + get { + return _date; + } + } + + /// + /// Gets the logging level of the log data. + /// + /// + /// One of the enum values, indicates the logging level of the log data. + /// + public LogLevel Level { + get { + return _level; + } + } + + /// + /// Gets the message of the log data. + /// + /// + /// A that represents the message of the log data. + /// + public string Message { + get { + return _message; + } + } + + #endregion + + #region Public Methods + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString () + { + var header = String.Format ("{0}|{1,-5}|", _date, _level); + var method = _caller.GetMethod (); + var type = method.DeclaringType; +#if DEBUG + var lineNum = _caller.GetFileLineNumber (); + var headerAndCaller = + String.Format ("{0}{1}.{2}:{3}|", header, type.Name, method.Name, lineNum); +#else + var headerAndCaller = String.Format ("{0}{1}.{2}|", header, type.Name, method.Name); +#endif + var msgs = _message.Replace ("\r\n", "\n").TrimEnd ('\n').Split ('\n'); + if (msgs.Length <= 1) + return String.Format ("{0}{1}", headerAndCaller, _message); + + var buff = new StringBuilder (String.Format ("{0}{1}\n", headerAndCaller, msgs[0]), 64); + + var fmt = String.Format ("{{0,{0}}}{{1}}\n", header.Length); + for (var i = 1; i < msgs.Length; i++) + buff.AppendFormat (fmt, "", msgs[i]); + + buff.Length--; + return buff.ToString (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/LogData.cs.meta b/Plugins/websocket-sharp/websocket-sharp/LogData.cs.meta new file mode 100644 index 00000000..eb1c8b3b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/LogData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2340ae50e51984adeaac2cbe83807723 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/LogLevel.cs b/Plugins/websocket-sharp/websocket-sharp/LogLevel.cs new file mode 100644 index 00000000..ef996772 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/LogLevel.cs @@ -0,0 +1,63 @@ +#region License +/* + * LogLevel.cs + * + * The MIT License + * + * Copyright (c) 2013-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Specifies the logging level. + /// + public enum LogLevel + { + /// + /// Specifies the bottom logging level. + /// + Trace, + /// + /// Specifies the 2nd logging level from the bottom. + /// + Debug, + /// + /// Specifies the 3rd logging level from the bottom. + /// + Info, + /// + /// Specifies the 3rd logging level from the top. + /// + Warn, + /// + /// Specifies the 2nd logging level from the top. + /// + Error, + /// + /// Specifies the top logging level. + /// + Fatal + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/LogLevel.cs.meta b/Plugins/websocket-sharp/websocket-sharp/LogLevel.cs.meta new file mode 100644 index 00000000..4651be88 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/LogLevel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22aa721c595044dca8e23da4c56f2550 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Logger.cs b/Plugins/websocket-sharp/websocket-sharp/Logger.cs new file mode 100644 index 00000000..17850e67 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Logger.cs @@ -0,0 +1,330 @@ +#region License +/* + * Logger.cs + * + * The MIT License + * + * Copyright (c) 2013-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Diagnostics; +using System.IO; + +namespace WebSocketSharp +{ + /// + /// Provides a set of methods and properties for logging. + /// + /// + /// + /// If you output a log with lower than the value of the property, + /// it cannot be outputted. + /// + /// + /// The default output action writes a log to the standard output stream and the log file + /// if the property has a valid path to it. + /// + /// + /// If you would like to use the custom output action, you should set + /// the property to any Action<LogData, string> + /// delegate. + /// + /// + public class Logger + { + #region Private Fields + + private volatile string _file; + private volatile LogLevel _level; + private Action _output; + private object _sync; + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class. + /// + /// + /// This constructor initializes the current logging level with . + /// + public Logger () + : this (LogLevel.Error, null, null) + { + } + + /// + /// Initializes a new instance of the class with + /// the specified logging . + /// + /// + /// One of the enum values. + /// + public Logger (LogLevel level) + : this (level, null, null) + { + } + + /// + /// Initializes a new instance of the class with + /// the specified logging , path to the log , + /// and action. + /// + /// + /// One of the enum values. + /// + /// + /// A that represents the path to the log file. + /// + /// + /// An Action<LogData, string> delegate that references the method(s) used to + /// output a log. A parameter passed to this delegate is + /// . + /// + public Logger (LogLevel level, string file, Action output) + { + _level = level; + _file = file; + _output = output ?? defaultOutput; + _sync = new object (); + } + + #endregion + + #region Public Properties + + /// + /// Gets or sets the current path to the log file. + /// + /// + /// A that represents the current path to the log file if any. + /// + public string File { + get { + return _file; + } + + set { + lock (_sync) { + _file = value; + Warn ( + String.Format ("The current path to the log file has been changed to {0}.", _file)); + } + } + } + + /// + /// Gets or sets the current logging level. + /// + /// + /// A log with lower than the value of this property cannot be outputted. + /// + /// + /// One of the enum values, specifies the current logging level. + /// + public LogLevel Level { + get { + return _level; + } + + set { + lock (_sync) { + _level = value; + Warn (String.Format ("The current logging level has been changed to {0}.", _level)); + } + } + } + + /// + /// Gets or sets the current output action used to output a log. + /// + /// + /// + /// An Action<LogData, string> delegate that references the method(s) used to + /// output a log. A parameter passed to this delegate is the value of + /// the property. + /// + /// + /// If the value to set is , the current output action is changed to + /// the default output action. + /// + /// + public Action Output { + get { + return _output; + } + + set { + lock (_sync) { + _output = value ?? defaultOutput; + Warn ("The current output action has been changed."); + } + } + } + + #endregion + + #region Private Methods + + private static void defaultOutput (LogData data, string path) + { + var log = data.ToString (); + Console.WriteLine (log); + if (path != null && path.Length > 0) + writeToFile (log, path); + } + + private void output (string message, LogLevel level) + { + lock (_sync) { + if (_level > level) + return; + + LogData data = null; + try { + data = new LogData (level, new StackFrame (2, true), message); + _output (data, _file); + } + catch (Exception ex) { + data = new LogData (LogLevel.Fatal, new StackFrame (0, true), ex.Message); + Console.WriteLine (data.ToString ()); + } + } + } + + private static void writeToFile (string value, string path) + { + using (var writer = new StreamWriter (path, true)) + using (var syncWriter = TextWriter.Synchronized (writer)) + syncWriter.WriteLine (value); + } + + #endregion + + #region Public Methods + + /// + /// Outputs as a log with . + /// + /// + /// If the current logging level is higher than , + /// this method doesn't output as a log. + /// + /// + /// A that represents the message to output as a log. + /// + public void Debug (string message) + { + if (_level > LogLevel.Debug) + return; + + output (message, LogLevel.Debug); + } + + /// + /// Outputs as a log with . + /// + /// + /// If the current logging level is higher than , + /// this method doesn't output as a log. + /// + /// + /// A that represents the message to output as a log. + /// + public void Error (string message) + { + if (_level > LogLevel.Error) + return; + + output (message, LogLevel.Error); + } + + /// + /// Outputs as a log with . + /// + /// + /// A that represents the message to output as a log. + /// + public void Fatal (string message) + { + output (message, LogLevel.Fatal); + } + + /// + /// Outputs as a log with . + /// + /// + /// If the current logging level is higher than , + /// this method doesn't output as a log. + /// + /// + /// A that represents the message to output as a log. + /// + public void Info (string message) + { + if (_level > LogLevel.Info) + return; + + output (message, LogLevel.Info); + } + + /// + /// Outputs as a log with . + /// + /// + /// If the current logging level is higher than , + /// this method doesn't output as a log. + /// + /// + /// A that represents the message to output as a log. + /// + public void Trace (string message) + { + if (_level > LogLevel.Trace) + return; + + output (message, LogLevel.Trace); + } + + /// + /// Outputs as a log with . + /// + /// + /// If the current logging level is higher than , + /// this method doesn't output as a log. + /// + /// + /// A that represents the message to output as a log. + /// + public void Warn (string message) + { + if (_level > LogLevel.Warn) + return; + + output (message, LogLevel.Warn); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Logger.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Logger.cs.meta new file mode 100644 index 00000000..68c63286 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Logger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b87db541afe44ff2bd7a7abf5496091 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Mask.cs b/Plugins/websocket-sharp/websocket-sharp/Mask.cs new file mode 100644 index 00000000..fcafac80 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Mask.cs @@ -0,0 +1,51 @@ +#region License +/* + * Mask.cs + * + * The MIT License + * + * Copyright (c) 2012-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Indicates whether the payload data of a WebSocket frame is masked. + /// + /// + /// The values of this enumeration are defined in + /// Section 5.2 of RFC 6455. + /// + internal enum Mask : byte + { + /// + /// Equivalent to numeric value 0. Indicates not masked. + /// + Off = 0x0, + /// + /// Equivalent to numeric value 1. Indicates masked. + /// + On = 0x1 + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Mask.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Mask.cs.meta new file mode 100644 index 00000000..56feae4a --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Mask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b80c9a2981b141a9a12ee7d4629801c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/MessageEventArgs.cs b/Plugins/websocket-sharp/websocket-sharp/MessageEventArgs.cs new file mode 100644 index 00000000..7940f98b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/MessageEventArgs.cs @@ -0,0 +1,183 @@ +#region License +/* + * MessageEventArgs.cs + * + * The MIT License + * + * Copyright (c) 2012-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Represents the event data for the event. + /// + /// + /// + /// That event occurs when the receives + /// a message or a ping if the + /// property is set to true. + /// + /// + /// If you would like to get the message data, you should access + /// the or property. + /// + /// + public class MessageEventArgs : EventArgs + { + #region Private Fields + + private string _data; + private bool _dataSet; + private Opcode _opcode; + private byte[] _rawData; + + #endregion + + #region Internal Constructors + + internal MessageEventArgs (WebSocketFrame frame) + { + _opcode = frame.Opcode; + _rawData = frame.PayloadData.ApplicationData; + } + + internal MessageEventArgs (Opcode opcode, byte[] rawData) + { + if ((ulong) rawData.LongLength > PayloadData.MaxLength) + throw new WebSocketException (CloseStatusCode.TooBig); + + _opcode = opcode; + _rawData = rawData; + } + + #endregion + + #region Internal Properties + + /// + /// Gets the opcode for the message. + /// + /// + /// , , + /// or . + /// + internal Opcode Opcode { + get { + return _opcode; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the message data as a . + /// + /// + /// A that represents the message data if its type is + /// text or ping and if decoding it to a string has successfully done; + /// otherwise, . + /// + public string Data { + get { + setData (); + return _data; + } + } + + /// + /// Gets a value indicating whether the message type is binary. + /// + /// + /// true if the message type is binary; otherwise, false. + /// + public bool IsBinary { + get { + return _opcode == Opcode.Binary; + } + } + + /// + /// Gets a value indicating whether the message type is ping. + /// + /// + /// true if the message type is ping; otherwise, false. + /// + public bool IsPing { + get { + return _opcode == Opcode.Ping; + } + } + + /// + /// Gets a value indicating whether the message type is text. + /// + /// + /// true if the message type is text; otherwise, false. + /// + public bool IsText { + get { + return _opcode == Opcode.Text; + } + } + + /// + /// Gets the message data as an array of . + /// + /// + /// An array of that represents the message data. + /// + public byte[] RawData { + get { + setData (); + return _rawData; + } + } + + #endregion + + #region Private Methods + + private void setData () + { + if (_dataSet) + return; + + if (_opcode == Opcode.Binary) { + _dataSet = true; + return; + } + + string data; + if (_rawData.TryGetUTF8DecodedString (out data)) + _data = data; + + _dataSet = true; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/MessageEventArgs.cs.meta b/Plugins/websocket-sharp/websocket-sharp/MessageEventArgs.cs.meta new file mode 100644 index 00000000..613adbec --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/MessageEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4730577dd56540e2b7fe4f373756613 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net.meta b/Plugins/websocket-sharp/websocket-sharp/Net.meta new file mode 100644 index 00000000..a115e995 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: af0efd83b780d4e26ad9f604fb354c5d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationBase.cs b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationBase.cs new file mode 100644 index 00000000..10775049 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationBase.cs @@ -0,0 +1,151 @@ +#region License +/* + * AuthenticationBase.cs + * + * The MIT License + * + * Copyright (c) 2014 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Specialized; +using System.Text; + +namespace WebSocketSharp.Net +{ + internal abstract class AuthenticationBase + { + #region Private Fields + + private AuthenticationSchemes _scheme; + + #endregion + + #region Internal Fields + + internal NameValueCollection Parameters; + + #endregion + + #region Protected Constructors + + protected AuthenticationBase (AuthenticationSchemes scheme, NameValueCollection parameters) + { + _scheme = scheme; + Parameters = parameters; + } + + #endregion + + #region Public Properties + + public string Algorithm { + get { + return Parameters["algorithm"]; + } + } + + public string Nonce { + get { + return Parameters["nonce"]; + } + } + + public string Opaque { + get { + return Parameters["opaque"]; + } + } + + public string Qop { + get { + return Parameters["qop"]; + } + } + + public string Realm { + get { + return Parameters["realm"]; + } + } + + public AuthenticationSchemes Scheme { + get { + return _scheme; + } + } + + #endregion + + #region Internal Methods + + internal static string CreateNonceValue () + { + var src = new byte[16]; + var rand = new Random (); + rand.NextBytes (src); + + var res = new StringBuilder (32); + foreach (var b in src) + res.Append (b.ToString ("x2")); + + return res.ToString (); + } + + internal static NameValueCollection ParseParameters (string value) + { + var res = new NameValueCollection (); + foreach (var param in value.SplitHeaderValue (',')) { + var i = param.IndexOf ('='); + var name = i > 0 ? param.Substring (0, i).Trim () : null; + var val = i < 0 + ? param.Trim ().Trim ('"') + : i < param.Length - 1 + ? param.Substring (i + 1).Trim ().Trim ('"') + : String.Empty; + + res.Add (name, val); + } + + return res; + } + + internal abstract string ToBasicString (); + + internal abstract string ToDigestString (); + + #endregion + + #region Public Methods + + public override string ToString () + { + return _scheme == AuthenticationSchemes.Basic + ? ToBasicString () + : _scheme == AuthenticationSchemes.Digest + ? ToDigestString () + : String.Empty; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationBase.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationBase.cs.meta new file mode 100644 index 00000000..bea57170 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 964b08f2d05fa4b63adaf18d3860c7ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationChallenge.cs b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationChallenge.cs new file mode 100644 index 00000000..3472204b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationChallenge.cs @@ -0,0 +1,146 @@ +#region License +/* + * AuthenticationChallenge.cs + * + * The MIT License + * + * Copyright (c) 2013-2014 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Specialized; +using System.Text; + +namespace WebSocketSharp.Net +{ + internal class AuthenticationChallenge : AuthenticationBase + { + #region Private Constructors + + private AuthenticationChallenge (AuthenticationSchemes scheme, NameValueCollection parameters) + : base (scheme, parameters) + { + } + + #endregion + + #region Internal Constructors + + internal AuthenticationChallenge (AuthenticationSchemes scheme, string realm) + : base (scheme, new NameValueCollection ()) + { + Parameters["realm"] = realm; + if (scheme == AuthenticationSchemes.Digest) { + Parameters["nonce"] = CreateNonceValue (); + Parameters["algorithm"] = "MD5"; + Parameters["qop"] = "auth"; + } + } + + #endregion + + #region Public Properties + + public string Domain { + get { + return Parameters["domain"]; + } + } + + public string Stale { + get { + return Parameters["stale"]; + } + } + + #endregion + + #region Internal Methods + + internal static AuthenticationChallenge CreateBasicChallenge (string realm) + { + return new AuthenticationChallenge (AuthenticationSchemes.Basic, realm); + } + + internal static AuthenticationChallenge CreateDigestChallenge (string realm) + { + return new AuthenticationChallenge (AuthenticationSchemes.Digest, realm); + } + + internal static AuthenticationChallenge Parse (string value) + { + var chal = value.Split (new[] { ' ' }, 2); + if (chal.Length != 2) + return null; + + var schm = chal[0].ToLower (); + return schm == "basic" + ? new AuthenticationChallenge ( + AuthenticationSchemes.Basic, ParseParameters (chal[1])) + : schm == "digest" + ? new AuthenticationChallenge ( + AuthenticationSchemes.Digest, ParseParameters (chal[1])) + : null; + } + + internal override string ToBasicString () + { + return String.Format ("Basic realm=\"{0}\"", Parameters["realm"]); + } + + internal override string ToDigestString () + { + var output = new StringBuilder (128); + + var domain = Parameters["domain"]; + if (domain != null) + output.AppendFormat ( + "Digest realm=\"{0}\", domain=\"{1}\", nonce=\"{2}\"", + Parameters["realm"], + domain, + Parameters["nonce"]); + else + output.AppendFormat ( + "Digest realm=\"{0}\", nonce=\"{1}\"", Parameters["realm"], Parameters["nonce"]); + + var opaque = Parameters["opaque"]; + if (opaque != null) + output.AppendFormat (", opaque=\"{0}\"", opaque); + + var stale = Parameters["stale"]; + if (stale != null) + output.AppendFormat (", stale={0}", stale); + + var algo = Parameters["algorithm"]; + if (algo != null) + output.AppendFormat (", algorithm={0}", algo); + + var qop = Parameters["qop"]; + if (qop != null) + output.AppendFormat (", qop=\"{0}\"", qop); + + return output.ToString (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationChallenge.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationChallenge.cs.meta new file mode 100644 index 00000000..501d2b8b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationChallenge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 830bad6802cf1499584a7cfdb3ef2a28 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationResponse.cs b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationResponse.cs new file mode 100644 index 00000000..0257d85b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationResponse.cs @@ -0,0 +1,323 @@ +#region License +/* + * AuthenticationResponse.cs + * + * ParseBasicCredentials is derived from System.Net.HttpListenerContext.cs of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2013-2014 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Specialized; +using System.Security.Cryptography; +using System.Security.Principal; +using System.Text; + +namespace WebSocketSharp.Net +{ + internal class AuthenticationResponse : AuthenticationBase + { + #region Private Fields + + private uint _nonceCount; + + #endregion + + #region Private Constructors + + private AuthenticationResponse (AuthenticationSchemes scheme, NameValueCollection parameters) + : base (scheme, parameters) + { + } + + #endregion + + #region Internal Constructors + + internal AuthenticationResponse (NetworkCredential credentials) + : this (AuthenticationSchemes.Basic, new NameValueCollection (), credentials, 0) + { + } + + internal AuthenticationResponse ( + AuthenticationChallenge challenge, NetworkCredential credentials, uint nonceCount) + : this (challenge.Scheme, challenge.Parameters, credentials, nonceCount) + { + } + + internal AuthenticationResponse ( + AuthenticationSchemes scheme, + NameValueCollection parameters, + NetworkCredential credentials, + uint nonceCount) + : base (scheme, parameters) + { + Parameters["username"] = credentials.Username; + Parameters["password"] = credentials.Password; + Parameters["uri"] = credentials.Domain; + _nonceCount = nonceCount; + if (scheme == AuthenticationSchemes.Digest) + initAsDigest (); + } + + #endregion + + #region Internal Properties + + internal uint NonceCount { + get { + return _nonceCount < UInt32.MaxValue + ? _nonceCount + : 0; + } + } + + #endregion + + #region Public Properties + + public string Cnonce { + get { + return Parameters["cnonce"]; + } + } + + public string Nc { + get { + return Parameters["nc"]; + } + } + + public string Password { + get { + return Parameters["password"]; + } + } + + public string Response { + get { + return Parameters["response"]; + } + } + + public string Uri { + get { + return Parameters["uri"]; + } + } + + public string UserName { + get { + return Parameters["username"]; + } + } + + #endregion + + #region Private Methods + + private static string createA1 (string username, string password, string realm) + { + return String.Format ("{0}:{1}:{2}", username, realm, password); + } + + private static string createA1 ( + string username, string password, string realm, string nonce, string cnonce) + { + return String.Format ( + "{0}:{1}:{2}", hash (createA1 (username, password, realm)), nonce, cnonce); + } + + private static string createA2 (string method, string uri) + { + return String.Format ("{0}:{1}", method, uri); + } + + private static string createA2 (string method, string uri, string entity) + { + return String.Format ("{0}:{1}:{2}", method, uri, hash (entity)); + } + + private static string hash (string value) + { + var src = Encoding.UTF8.GetBytes (value); + var md5 = MD5.Create (); + var hashed = md5.ComputeHash (src); + + var res = new StringBuilder (64); + foreach (var b in hashed) + res.Append (b.ToString ("x2")); + + return res.ToString (); + } + + private void initAsDigest () + { + var qops = Parameters["qop"]; + if (qops != null) { + if (qops.Split (',').Contains (qop => qop.Trim ().ToLower () == "auth")) { + Parameters["qop"] = "auth"; + Parameters["cnonce"] = CreateNonceValue (); + Parameters["nc"] = String.Format ("{0:x8}", ++_nonceCount); + } + else { + Parameters["qop"] = null; + } + } + + Parameters["method"] = "GET"; + Parameters["response"] = CreateRequestDigest (Parameters); + } + + #endregion + + #region Internal Methods + + internal static string CreateRequestDigest (NameValueCollection parameters) + { + var user = parameters["username"]; + var pass = parameters["password"]; + var realm = parameters["realm"]; + var nonce = parameters["nonce"]; + var uri = parameters["uri"]; + var algo = parameters["algorithm"]; + var qop = parameters["qop"]; + var cnonce = parameters["cnonce"]; + var nc = parameters["nc"]; + var method = parameters["method"]; + + var a1 = algo != null && algo.ToLower () == "md5-sess" + ? createA1 (user, pass, realm, nonce, cnonce) + : createA1 (user, pass, realm); + + var a2 = qop != null && qop.ToLower () == "auth-int" + ? createA2 (method, uri, parameters["entity"]) + : createA2 (method, uri); + + var secret = hash (a1); + var data = qop != null + ? String.Format ("{0}:{1}:{2}:{3}:{4}", nonce, nc, cnonce, qop, hash (a2)) + : String.Format ("{0}:{1}", nonce, hash (a2)); + + return hash (String.Format ("{0}:{1}", secret, data)); + } + + internal static AuthenticationResponse Parse (string value) + { + try { + var cred = value.Split (new[] { ' ' }, 2); + if (cred.Length != 2) + return null; + + var schm = cred[0].ToLower (); + return schm == "basic" + ? new AuthenticationResponse ( + AuthenticationSchemes.Basic, ParseBasicCredentials (cred[1])) + : schm == "digest" + ? new AuthenticationResponse ( + AuthenticationSchemes.Digest, ParseParameters (cred[1])) + : null; + } + catch { + } + + return null; + } + + internal static NameValueCollection ParseBasicCredentials (string value) + { + // Decode the basic-credentials (a Base64 encoded string). + var userPass = Encoding.Default.GetString (Convert.FromBase64String (value)); + + // The format is [\]:. + var i = userPass.IndexOf (':'); + var user = userPass.Substring (0, i); + var pass = i < userPass.Length - 1 ? userPass.Substring (i + 1) : String.Empty; + + // Check if 'domain' exists. + i = user.IndexOf ('\\'); + if (i > -1) + user = user.Substring (i + 1); + + var res = new NameValueCollection (); + res["username"] = user; + res["password"] = pass; + + return res; + } + + internal override string ToBasicString () + { + var userPass = String.Format ("{0}:{1}", Parameters["username"], Parameters["password"]); + var cred = Convert.ToBase64String (Encoding.UTF8.GetBytes (userPass)); + + return "Basic " + cred; + } + + internal override string ToDigestString () + { + var output = new StringBuilder (256); + output.AppendFormat ( + "Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", response=\"{4}\"", + Parameters["username"], + Parameters["realm"], + Parameters["nonce"], + Parameters["uri"], + Parameters["response"]); + + var opaque = Parameters["opaque"]; + if (opaque != null) + output.AppendFormat (", opaque=\"{0}\"", opaque); + + var algo = Parameters["algorithm"]; + if (algo != null) + output.AppendFormat (", algorithm={0}", algo); + + var qop = Parameters["qop"]; + if (qop != null) + output.AppendFormat ( + ", qop={0}, cnonce=\"{1}\", nc={2}", qop, Parameters["cnonce"], Parameters["nc"]); + + return output.ToString (); + } + + #endregion + + #region Public Methods + + public IIdentity ToIdentity () + { + var schm = Scheme; + return schm == AuthenticationSchemes.Basic + ? new HttpBasicIdentity (Parameters["username"], Parameters["password"]) as IIdentity + : schm == AuthenticationSchemes.Digest + ? new HttpDigestIdentity (Parameters) + : null; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationResponse.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationResponse.cs.meta new file mode 100644 index 00000000..e749bfd6 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a33bdedb4171f4a72bb87b346f3c11e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationSchemes.cs b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationSchemes.cs new file mode 100644 index 00000000..ab7721a1 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationSchemes.cs @@ -0,0 +1,66 @@ +#region License +/* + * AuthenticationSchemes.cs + * + * This code is derived from AuthenticationSchemes.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Atsushi Enomoto + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + /// + /// Specifies the scheme for authentication. + /// + public enum AuthenticationSchemes + { + /// + /// No authentication is allowed. + /// + None, + /// + /// Specifies digest authentication. + /// + Digest = 1, + /// + /// Specifies basic authentication. + /// + Basic = 8, + /// + /// Specifies anonymous authentication. + /// + Anonymous = 0x8000 + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationSchemes.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationSchemes.cs.meta new file mode 100644 index 00000000..96621cde --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/AuthenticationSchemes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 42e611894e95847c8895dc7672c60d15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/Chunk.cs b/Plugins/websocket-sharp/websocket-sharp/Net/Chunk.cs new file mode 100644 index 00000000..9ed28f86 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/Chunk.cs @@ -0,0 +1,93 @@ +#region License +/* + * Chunk.cs + * + * This code is derived from ChunkStream.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2003 Ximian, Inc (http://www.ximian.com) + * Copyright (c) 2014-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + internal class Chunk + { + #region Private Fields + + private byte[] _data; + private int _offset; + + #endregion + + #region Public Constructors + + public Chunk (byte[] data) + { + _data = data; + } + + #endregion + + #region Public Properties + + public int ReadLeft { + get { + return _data.Length - _offset; + } + } + + #endregion + + #region Public Methods + + public int Read (byte[] buffer, int offset, int count) + { + var left = _data.Length - _offset; + + if (left == 0) + return 0; + + if (count > left) + count = left; + + Buffer.BlockCopy (_data, _offset, buffer, offset, count); + + _offset += count; + + return count; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/Chunk.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/Chunk.cs.meta new file mode 100644 index 00000000..f374b77b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/Chunk.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db88f6404ee684095ba5a0b4ab0b1b50 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ChunkStream.cs b/Plugins/websocket-sharp/websocket-sharp/Net/ChunkStream.cs new file mode 100644 index 00000000..6081113b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ChunkStream.cs @@ -0,0 +1,383 @@ +#region License +/* + * ChunkStream.cs + * + * This code is derived from ChunkStream.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2003 Ximian, Inc (http://www.ximian.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Net; +using System.Text; + +namespace WebSocketSharp.Net +{ + internal class ChunkStream + { + #region Private Fields + + private int _chunkRead; + private int _chunkSize; + private List _chunks; + private bool _gotIt; + private WebHeaderCollection _headers; + private StringBuilder _saved; + private bool _sawCr; + private InputChunkState _state; + private int _trailerState; + + #endregion + + #region Public Constructors + + public ChunkStream (WebHeaderCollection headers) + { + _headers = headers; + + _chunkSize = -1; + _chunks = new List (); + _saved = new StringBuilder (); + } + + #endregion + + #region Public Properties + + public WebHeaderCollection Headers { + get { + return _headers; + } + } + + public bool WantsMore { + get { + return _state < InputChunkState.End; + } + } + + #endregion + + #region Private Methods + + private int read (byte[] buffer, int offset, int count) + { + var nread = 0; + var cnt = _chunks.Count; + + for (var i = 0; i < cnt; i++) { + var chunk = _chunks[i]; + + if (chunk == null) + continue; + + if (chunk.ReadLeft == 0) { + _chunks[i] = null; + + continue; + } + + nread += chunk.Read (buffer, offset + nread, count - nread); + + if (nread == count) + break; + } + + return nread; + } + + private InputChunkState seekCrLf (byte[] buffer, ref int offset, int length) + { + if (!_sawCr) { + if (buffer[offset++] != 13) + throwProtocolViolation ("CR is expected."); + + _sawCr = true; + + if (offset == length) + return InputChunkState.DataEnded; + } + + if (buffer[offset++] != 10) + throwProtocolViolation ("LF is expected."); + + return InputChunkState.None; + } + + private InputChunkState setChunkSize ( + byte[] buffer, ref int offset, int length + ) + { + byte b = 0; + + while (offset < length) { + b = buffer[offset++]; + + if (_sawCr) { + if (b != 10) + throwProtocolViolation ("LF is expected."); + + break; + } + + if (b == 13) { + _sawCr = true; + + continue; + } + + if (b == 10) + throwProtocolViolation ("LF is unexpected."); + + if (_gotIt) + continue; + + if (b == 32 || b == 59) { // SP or ';' + _gotIt = true; + + continue; + } + + _saved.Append ((char) b); + } + + if (_saved.Length > 20) + throwProtocolViolation ("The chunk size is too big."); + + if (b != 10) + return InputChunkState.None; + + var s = _saved.ToString (); + + try { + _chunkSize = Int32.Parse (s, NumberStyles.HexNumber); + } + catch { + throwProtocolViolation ("The chunk size cannot be parsed."); + } + + _chunkRead = 0; + + if (_chunkSize == 0) { + _trailerState = 2; + + return InputChunkState.Trailer; + } + + return InputChunkState.Data; + } + + private InputChunkState setTrailer ( + byte[] buffer, ref int offset, int length + ) + { + while (offset < length) { + if (_trailerState == 4) // CR LF CR LF + break; + + var b = buffer[offset++]; + _saved.Append ((char) b); + + if (_trailerState == 1 || _trailerState == 3) { // CR or CR LF CR + if (b != 10) + throwProtocolViolation ("LF is expected."); + + _trailerState++; + + continue; + } + + if (b == 13) { + _trailerState++; + + continue; + } + + if (b == 10) + throwProtocolViolation ("LF is unexpected."); + + _trailerState = 0; + } + + var len = _saved.Length; + + if (len > 4196) + throwProtocolViolation ("The trailer is too long."); + + if (_trailerState < 4) + return InputChunkState.Trailer; + + if (len == 2) + return InputChunkState.End; + + _saved.Length = len - 2; + var val = _saved.ToString (); + var reader = new StringReader (val); + + while (true) { + var line = reader.ReadLine (); + + if (line == null || line.Length == 0) + break; + + _headers.Add (line); + } + + return InputChunkState.End; + } + + private static void throwProtocolViolation (string message) + { + throw new WebException ( + message, null, WebExceptionStatus.ServerProtocolViolation, null + ); + } + + private void write (byte[] buffer, int offset, int length) + { + if (_state == InputChunkState.End) + throwProtocolViolation ("The chunks were ended."); + + if (_state == InputChunkState.None) { + _state = setChunkSize (buffer, ref offset, length); + + if (_state == InputChunkState.None) + return; + + _saved.Length = 0; + _sawCr = false; + _gotIt = false; + } + + if (_state == InputChunkState.Data) { + if (offset >= length) + return; + + _state = writeData (buffer, ref offset, length); + + if (_state == InputChunkState.Data) + return; + } + + if (_state == InputChunkState.DataEnded) { + if (offset >= length) + return; + + _state = seekCrLf (buffer, ref offset, length); + + if (_state == InputChunkState.DataEnded) + return; + + _sawCr = false; + } + + if (_state == InputChunkState.Trailer) { + if (offset >= length) + return; + + _state = setTrailer (buffer, ref offset, length); + + if (_state == InputChunkState.Trailer) + return; + + _saved.Length = 0; + } + + if (offset >= length) + return; + + write (buffer, offset, length); + } + + private InputChunkState writeData ( + byte[] buffer, ref int offset, int length + ) + { + var cnt = length - offset; + var left = _chunkSize - _chunkRead; + + if (cnt > left) + cnt = left; + + var data = new byte[cnt]; + Buffer.BlockCopy (buffer, offset, data, 0, cnt); + + var chunk = new Chunk (data); + _chunks.Add (chunk); + + offset += cnt; + _chunkRead += cnt; + + return _chunkRead == _chunkSize + ? InputChunkState.DataEnded + : InputChunkState.Data; + } + + #endregion + + #region Internal Methods + + internal void ResetBuffer () + { + _chunkRead = 0; + _chunkSize = -1; + + _chunks.Clear (); + } + + #endregion + + #region Public Methods + + public int Read (byte[] buffer, int offset, int count) + { + if (count <= 0) + return 0; + + return read (buffer, offset, count); + } + + public void Write (byte[] buffer, int offset, int count) + { + if (count <= 0) + return; + + write (buffer, offset, offset + count); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ChunkStream.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/ChunkStream.cs.meta new file mode 100644 index 00000000..d0512b2a --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ChunkStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e4839a977b3874235bb57c9c4a19ecb1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ChunkedRequestStream.cs b/Plugins/websocket-sharp/websocket-sharp/Net/ChunkedRequestStream.cs new file mode 100644 index 00000000..2db4b040 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ChunkedRequestStream.cs @@ -0,0 +1,249 @@ +#region License +/* + * ChunkedRequestStream.cs + * + * This code is derived from ChunkedInputStream.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.IO; + +namespace WebSocketSharp.Net +{ + internal class ChunkedRequestStream : RequestStream + { + #region Private Fields + + private static readonly int _bufferLength; + private HttpListenerContext _context; + private ChunkStream _decoder; + private bool _disposed; + private bool _noMoreData; + + #endregion + + #region Static Constructor + + static ChunkedRequestStream () + { + _bufferLength = 8192; + } + + #endregion + + #region Internal Constructors + + internal ChunkedRequestStream ( + Stream stream, + byte[] buffer, + int offset, + int count, + HttpListenerContext context + ) + : base (stream, buffer, offset, count, -1) + { + _context = context; + + _decoder = new ChunkStream ( + (WebHeaderCollection) context.Request.Headers + ); + } + + #endregion + + #region Private Methods + + private void onRead (IAsyncResult asyncResult) + { + var rstate = (ReadBufferState) asyncResult.AsyncState; + var ares = rstate.AsyncResult; + + try { + var nread = base.EndRead (asyncResult); + + _decoder.Write (ares.Buffer, ares.Offset, nread); + nread = _decoder.Read (rstate.Buffer, rstate.Offset, rstate.Count); + + rstate.Offset += nread; + rstate.Count -= nread; + + if (rstate.Count == 0 || !_decoder.WantsMore || nread == 0) { + _noMoreData = !_decoder.WantsMore && nread == 0; + + ares.Count = rstate.InitialCount - rstate.Count; + ares.Complete (); + + return; + } + + base.BeginRead (ares.Buffer, ares.Offset, ares.Count, onRead, rstate); + } + catch (Exception ex) { + _context.ErrorMessage = "I/O operation aborted"; + _context.SendError (); + + ares.Complete (ex); + } + } + + #endregion + + #region Public Methods + + public override IAsyncResult BeginRead ( + byte[] buffer, int offset, int count, AsyncCallback callback, object state + ) + { + if (_disposed) { + var name = GetType ().ToString (); + + throw new ObjectDisposedException (name); + } + + if (buffer == null) + throw new ArgumentNullException ("buffer"); + + if (offset < 0) { + var msg = "A negative value."; + + throw new ArgumentOutOfRangeException ("offset", msg); + } + + if (count < 0) { + var msg = "A negative value."; + + throw new ArgumentOutOfRangeException ("count", msg); + } + + var len = buffer.Length; + + if (offset + count > len) { + var msg = "The sum of 'offset' and 'count' is greater than the length of 'buffer'."; + + throw new ArgumentException (msg); + } + + var ares = new HttpStreamAsyncResult (callback, state); + + if (_noMoreData) { + ares.Complete (); + + return ares; + } + + var nread = _decoder.Read (buffer, offset, count); + + offset += nread; + count -= nread; + + if (count == 0) { + ares.Count = nread; + ares.Complete (); + + return ares; + } + + if (!_decoder.WantsMore) { + _noMoreData = nread == 0; + + ares.Count = nread; + ares.Complete (); + + return ares; + } + + ares.Buffer = new byte[_bufferLength]; + ares.Offset = 0; + ares.Count = _bufferLength; + + var rstate = new ReadBufferState (buffer, offset, count, ares); + rstate.InitialCount += nread; + + base.BeginRead (ares.Buffer, ares.Offset, ares.Count, onRead, rstate); + + return ares; + } + + public override void Close () + { + if (_disposed) + return; + + _disposed = true; + + base.Close (); + } + + public override int EndRead (IAsyncResult asyncResult) + { + if (_disposed) { + var name = GetType ().ToString (); + + throw new ObjectDisposedException (name); + } + + if (asyncResult == null) + throw new ArgumentNullException ("asyncResult"); + + var ares = asyncResult as HttpStreamAsyncResult; + + if (ares == null) { + var msg = "A wrong IAsyncResult instance."; + + throw new ArgumentException (msg, "asyncResult"); + } + + if (!ares.IsCompleted) + ares.AsyncWaitHandle.WaitOne (); + + if (ares.HasException) { + var msg = "The I/O operation has been aborted."; + + throw new HttpListenerException (995, msg); + } + + return ares.Count; + } + + public override int Read (byte[] buffer, int offset, int count) + { + var ares = BeginRead (buffer, offset, count, null, null); + + return EndRead (ares); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ChunkedRequestStream.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/ChunkedRequestStream.cs.meta new file mode 100644 index 00000000..c71ffed6 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ChunkedRequestStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71bd05d76f7ff4d89a94b93d69e2a5ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ClientSslConfiguration.cs b/Plugins/websocket-sharp/websocket-sharp/Net/ClientSslConfiguration.cs new file mode 100644 index 00000000..7816e030 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ClientSslConfiguration.cs @@ -0,0 +1,303 @@ +#region License +/* + * ClientSslConfiguration.cs + * + * The MIT License + * + * Copyright (c) 2014 liryna + * Copyright (c) 2014-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Liryna + */ +#endregion + +using System; +using System.Net.Security; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; + +namespace WebSocketSharp.Net +{ + /// + /// Stores the parameters for the used by clients. + /// + public class ClientSslConfiguration + { + #region Private Fields + + private bool _checkCertRevocation; + private LocalCertificateSelectionCallback _clientCertSelectionCallback; + private X509CertificateCollection _clientCerts; + private SslProtocols _enabledSslProtocols; + private RemoteCertificateValidationCallback _serverCertValidationCallback; + private string _targetHost; + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the + /// class with the specified target host server name. + /// + /// + /// A that specifies the target host server name. + /// + /// + /// is . + /// + /// + /// is an empty string. + /// + public ClientSslConfiguration (string targetHost) + { + if (targetHost == null) + throw new ArgumentNullException ("targetHost"); + + if (targetHost.Length == 0) + throw new ArgumentException ("An empty string.", "targetHost"); + + _targetHost = targetHost; + + _enabledSslProtocols = SslProtocols.None; + } + + /// + /// Initializes a new instance of the + /// class that stores the parameters copied from the specified configuration. + /// + /// + /// A from which to copy. + /// + /// + /// is . + /// + public ClientSslConfiguration (ClientSslConfiguration configuration) + { + if (configuration == null) + throw new ArgumentNullException ("configuration"); + + _checkCertRevocation = configuration._checkCertRevocation; + _clientCertSelectionCallback = configuration._clientCertSelectionCallback; + _clientCerts = configuration._clientCerts; + _enabledSslProtocols = configuration._enabledSslProtocols; + _serverCertValidationCallback = configuration._serverCertValidationCallback; + _targetHost = configuration._targetHost; + } + + #endregion + + #region Public Properties + + /// + /// Gets or sets a value indicating whether the certificate revocation + /// list is checked during authentication. + /// + /// + /// + /// true if the certificate revocation list is checked during + /// authentication; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool CheckCertificateRevocation { + get { + return _checkCertRevocation; + } + + set { + _checkCertRevocation = value; + } + } + + /// + /// Gets or sets the collection of client certificates from which to select + /// one to supply to the server. + /// + /// + /// + /// A or . + /// + /// + /// The collection contains client certificates from which to select. + /// + /// + /// The default value is . + /// + /// + public X509CertificateCollection ClientCertificates { + get { + return _clientCerts; + } + + set { + _clientCerts = value; + } + } + + /// + /// Gets or sets the callback used to select the certificate to supply to + /// the server. + /// + /// + /// No certificate is supplied if the callback returns . + /// + /// + /// + /// A delegate that + /// invokes the method called for selecting the certificate. + /// + /// + /// The default value is a delegate that invokes a method that only + /// returns . + /// + /// + public LocalCertificateSelectionCallback ClientCertificateSelectionCallback { + get { + if (_clientCertSelectionCallback == null) + _clientCertSelectionCallback = defaultSelectClientCertificate; + + return _clientCertSelectionCallback; + } + + set { + _clientCertSelectionCallback = value; + } + } + + /// + /// Gets or sets the protocols used for authentication. + /// + /// + /// + /// Any of the enum values. + /// + /// + /// It represents the protocols used for authentication. + /// + /// + /// The default value is . + /// + /// + public SslProtocols EnabledSslProtocols { + get { + return _enabledSslProtocols; + } + + set { + _enabledSslProtocols = value; + } + } + + /// + /// Gets or sets the callback used to validate the certificate supplied by + /// the server. + /// + /// + /// The certificate is valid if the callback returns true. + /// + /// + /// + /// A delegate that + /// invokes the method called for validating the certificate. + /// + /// + /// The default value is a delegate that invokes a method that only + /// returns true. + /// + /// + public RemoteCertificateValidationCallback ServerCertificateValidationCallback { + get { + if (_serverCertValidationCallback == null) + _serverCertValidationCallback = defaultValidateServerCertificate; + + return _serverCertValidationCallback; + } + + set { + _serverCertValidationCallback = value; + } + } + + /// + /// Gets or sets the target host server name. + /// + /// + /// A that represents the name of the server that + /// will share a secure connection with a client. + /// + /// + /// The value specified for a set operation is . + /// + /// + /// The value specified for a set operation is an empty string. + /// + public string TargetHost { + get { + return _targetHost; + } + + set { + if (value == null) + throw new ArgumentNullException ("value"); + + if (value.Length == 0) + throw new ArgumentException ("An empty string.", "value"); + + _targetHost = value; + } + } + + #endregion + + #region Private Methods + + private static X509Certificate defaultSelectClientCertificate ( + object sender, + string targetHost, + X509CertificateCollection clientCertificates, + X509Certificate serverCertificate, + string[] acceptableIssuers + ) + { + return null; + } + + private static bool defaultValidateServerCertificate ( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors + ) + { + return true; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ClientSslConfiguration.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/ClientSslConfiguration.cs.meta new file mode 100644 index 00000000..eddd6bb0 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ClientSslConfiguration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91da23afcc8474a69b8e3a3105d9ca4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/Cookie.cs b/Plugins/websocket-sharp/websocket-sharp/Net/Cookie.cs new file mode 100644 index 00000000..1c5a4bf2 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/Cookie.cs @@ -0,0 +1,1016 @@ +#region License +/* + * Cookie.cs + * + * This code is derived from Cookie.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2004,2009 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2019 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Lawrence Pit + * - Gonzalo Paniagua Javier + * - Daniel Nauck + * - Sebastien Pouliot + */ +#endregion + +using System; +using System.Globalization; +using System.Text; + +namespace WebSocketSharp.Net +{ + /// + /// Provides a set of methods and properties used to manage an HTTP cookie. + /// + /// + /// + /// This class refers to the following specifications: + /// + /// + /// + /// + /// Netscape specification + /// + /// + /// + /// + /// RFC 2109 + /// + /// + /// + /// + /// RFC 2965 + /// + /// + /// + /// + /// RFC 6265 + /// + /// + /// + /// + /// This class cannot be inherited. + /// + /// + [Serializable] + public sealed class Cookie + { + #region Private Fields + + private string _comment; + private Uri _commentUri; + private bool _discard; + private string _domain; + private static readonly int[] _emptyPorts; + private DateTime _expires; + private bool _httpOnly; + private string _name; + private string _path; + private string _port; + private int[] _ports; + private static readonly char[] _reservedCharsForValue; + private string _sameSite; + private bool _secure; + private DateTime _timeStamp; + private string _value; + private int _version; + + #endregion + + #region Static Constructor + + static Cookie () + { + _emptyPorts = new int[0]; + _reservedCharsForValue = new[] { ';', ',' }; + } + + #endregion + + #region Internal Constructors + + /// + /// Initializes a new instance of the class. + /// + internal Cookie () + { + init (String.Empty, String.Empty, String.Empty, String.Empty); + } + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class with + /// the specified name and value. + /// + /// + /// + /// A that specifies the name of the cookie. + /// + /// + /// The name must be a token defined in + /// + /// RFC 2616. + /// + /// + /// + /// A that specifies the value of the cookie. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// - or - + /// + /// + /// starts with a dollar sign. + /// + /// + /// - or - + /// + /// + /// contains an invalid character. + /// + /// + /// - or - + /// + /// + /// is a string not enclosed in double quotes + /// that contains an invalid character. + /// + /// + public Cookie (string name, string value) + : this (name, value, String.Empty, String.Empty) + { + } + + /// + /// Initializes a new instance of the class with + /// the specified name, value, and path. + /// + /// + /// + /// A that specifies the name of the cookie. + /// + /// + /// The name must be a token defined in + /// + /// RFC 2616. + /// + /// + /// + /// A that specifies the value of the cookie. + /// + /// + /// A that specifies the value of the Path + /// attribute of the cookie. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// - or - + /// + /// + /// starts with a dollar sign. + /// + /// + /// - or - + /// + /// + /// contains an invalid character. + /// + /// + /// - or - + /// + /// + /// is a string not enclosed in double quotes + /// that contains an invalid character. + /// + /// + public Cookie (string name, string value, string path) + : this (name, value, path, String.Empty) + { + } + + /// + /// Initializes a new instance of the class with + /// the specified name, value, path, and domain. + /// + /// + /// + /// A that specifies the name of the cookie. + /// + /// + /// The name must be a token defined in + /// + /// RFC 2616. + /// + /// + /// + /// A that specifies the value of the cookie. + /// + /// + /// A that specifies the value of the Path + /// attribute of the cookie. + /// + /// + /// A that specifies the value of the Domain + /// attribute of the cookie. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// - or - + /// + /// + /// starts with a dollar sign. + /// + /// + /// - or - + /// + /// + /// contains an invalid character. + /// + /// + /// - or - + /// + /// + /// is a string not enclosed in double quotes + /// that contains an invalid character. + /// + /// + public Cookie (string name, string value, string path, string domain) + { + if (name == null) + throw new ArgumentNullException ("name"); + + if (name.Length == 0) + throw new ArgumentException ("An empty string.", "name"); + + if (name[0] == '$') { + var msg = "It starts with a dollar sign."; + throw new ArgumentException (msg, "name"); + } + + if (!name.IsToken ()) { + var msg = "It contains an invalid character."; + throw new ArgumentException (msg, "name"); + } + + if (value == null) + value = String.Empty; + + if (value.Contains (_reservedCharsForValue)) { + if (!value.IsEnclosedIn ('"')) { + var msg = "A string not enclosed in double quotes."; + throw new ArgumentException (msg, "value"); + } + } + + init (name, value, path ?? String.Empty, domain ?? String.Empty); + } + + #endregion + + #region Internal Properties + + internal bool ExactDomain { + get { + return _domain.Length == 0 || _domain[0] != '.'; + } + } + + internal int MaxAge { + get { + if (_expires == DateTime.MinValue) + return 0; + + var expires = _expires.Kind != DateTimeKind.Local + ? _expires.ToLocalTime () + : _expires; + + var span = expires - DateTime.Now; + return span > TimeSpan.Zero + ? (int) span.TotalSeconds + : 0; + } + + set { + _expires = value > 0 + ? DateTime.Now.AddSeconds ((double) value) + : DateTime.Now; + } + } + + internal int[] Ports { + get { + return _ports ?? _emptyPorts; + } + } + + internal string SameSite { + get { + return _sameSite; + } + + set { + _sameSite = value; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the value of the Comment attribute of the cookie. + /// + /// + /// + /// A that represents the comment to document + /// intended use of the cookie. + /// + /// + /// if not present. + /// + /// + /// The default value is . + /// + /// + public string Comment { + get { + return _comment; + } + + internal set { + _comment = value; + } + } + + /// + /// Gets the value of the CommentURL attribute of the cookie. + /// + /// + /// + /// A that represents the URI that provides + /// the comment to document intended use of the cookie. + /// + /// + /// if not present. + /// + /// + /// The default value is . + /// + /// + public Uri CommentUri { + get { + return _commentUri; + } + + internal set { + _commentUri = value; + } + } + + /// + /// Gets a value indicating whether the client discards the cookie + /// unconditionally when the client terminates. + /// + /// + /// + /// true if the client discards the cookie unconditionally + /// when the client terminates; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool Discard { + get { + return _discard; + } + + internal set { + _discard = value; + } + } + + /// + /// Gets or sets the value of the Domain attribute of the cookie. + /// + /// + /// + /// A that represents the domain name that + /// the cookie is valid for. + /// + /// + /// An empty string if this attribute is not needed. + /// + /// + public string Domain { + get { + return _domain; + } + + set { + _domain = value ?? String.Empty; + } + } + + /// + /// Gets or sets a value indicating whether the cookie has expired. + /// + /// + /// + /// true if the cookie has expired; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool Expired { + get { + return _expires != DateTime.MinValue && _expires <= DateTime.Now; + } + + set { + _expires = value ? DateTime.Now : DateTime.MinValue; + } + } + + /// + /// Gets or sets the value of the Expires attribute of the cookie. + /// + /// + /// + /// A that represents the date and time that + /// the cookie expires on. + /// + /// + /// if this attribute is not needed. + /// + /// + /// The default value is . + /// + /// + public DateTime Expires { + get { + return _expires; + } + + set { + _expires = value; + } + } + + /// + /// Gets or sets a value indicating whether non-HTTP APIs can access + /// the cookie. + /// + /// + /// + /// true if non-HTTP APIs cannot access the cookie; otherwise, + /// false. + /// + /// + /// The default value is false. + /// + /// + public bool HttpOnly { + get { + return _httpOnly; + } + + set { + _httpOnly = value; + } + } + + /// + /// Gets or sets the name of the cookie. + /// + /// + /// + /// A that represents the name of the cookie. + /// + /// + /// The name must be a token defined in + /// + /// RFC 2616. + /// + /// + /// + /// The value specified for a set operation is . + /// + /// + /// + /// The value specified for a set operation is an empty string. + /// + /// + /// - or - + /// + /// + /// The value specified for a set operation starts with a dollar sign. + /// + /// + /// - or - + /// + /// + /// The value specified for a set operation contains an invalid character. + /// + /// + public string Name { + get { + return _name; + } + + set { + if (value == null) + throw new ArgumentNullException ("value"); + + if (value.Length == 0) + throw new ArgumentException ("An empty string.", "value"); + + if (value[0] == '$') { + var msg = "It starts with a dollar sign."; + throw new ArgumentException (msg, "value"); + } + + if (!value.IsToken ()) { + var msg = "It contains an invalid character."; + throw new ArgumentException (msg, "value"); + } + + _name = value; + } + } + + /// + /// Gets or sets the value of the Path attribute of the cookie. + /// + /// + /// A that represents the subset of URI on + /// the origin server that the cookie applies to. + /// + public string Path { + get { + return _path; + } + + set { + _path = value ?? String.Empty; + } + } + + /// + /// Gets the value of the Port attribute of the cookie. + /// + /// + /// + /// A that represents the list of TCP ports + /// that the cookie applies to. + /// + /// + /// if not present. + /// + /// + /// The default value is . + /// + /// + public string Port { + get { + return _port; + } + + internal set { + int[] ports; + if (!tryCreatePorts (value, out ports)) + return; + + _port = value; + _ports = ports; + } + } + + /// + /// Gets or sets a value indicating whether the security level of + /// the cookie is secure. + /// + /// + /// When this property is true, the cookie may be included in + /// the request only if the request is transmitted over HTTPS. + /// + /// + /// + /// true if the security level of the cookie is secure; + /// otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool Secure { + get { + return _secure; + } + + set { + _secure = value; + } + } + + /// + /// Gets the time when the cookie was issued. + /// + /// + /// A that represents the time when + /// the cookie was issued. + /// + public DateTime TimeStamp { + get { + return _timeStamp; + } + } + + /// + /// Gets or sets the value of the cookie. + /// + /// + /// A that represents the value of the cookie. + /// + /// + /// The value specified for a set operation is a string not enclosed in + /// double quotes that contains an invalid character. + /// + public string Value { + get { + return _value; + } + + set { + if (value == null) + value = String.Empty; + + if (value.Contains (_reservedCharsForValue)) { + if (!value.IsEnclosedIn ('"')) { + var msg = "A string not enclosed in double quotes."; + throw new ArgumentException (msg, "value"); + } + } + + _value = value; + } + } + + /// + /// Gets the value of the Version attribute of the cookie. + /// + /// + /// + /// An that represents the version of HTTP state + /// management that the cookie conforms to. + /// + /// + /// 0 or 1. 0 if not present. + /// + /// + /// The default value is 0. + /// + /// + public int Version { + get { + return _version; + } + + internal set { + if (value < 0 || value > 1) + return; + + _version = value; + } + } + + #endregion + + #region Private Methods + + private static int hash (int i, int j, int k, int l, int m) + { + return i + ^ (j << 13 | j >> 19) + ^ (k << 26 | k >> 6) + ^ (l << 7 | l >> 25) + ^ (m << 20 | m >> 12); + } + + private void init (string name, string value, string path, string domain) + { + _name = name; + _value = value; + _path = path; + _domain = domain; + + _expires = DateTime.MinValue; + _timeStamp = DateTime.Now; + } + + private string toResponseStringVersion0 () + { + var buff = new StringBuilder (64); + + buff.AppendFormat ("{0}={1}", _name, _value); + + if (_expires != DateTime.MinValue) { + buff.AppendFormat ( + "; Expires={0}", + _expires.ToUniversalTime ().ToString ( + "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", + CultureInfo.CreateSpecificCulture ("en-US") + ) + ); + } + + if (!_path.IsNullOrEmpty ()) + buff.AppendFormat ("; Path={0}", _path); + + if (!_domain.IsNullOrEmpty ()) + buff.AppendFormat ("; Domain={0}", _domain); + + if (!_sameSite.IsNullOrEmpty ()) + buff.AppendFormat ("; SameSite={0}", _sameSite); + + if (_secure) + buff.Append ("; Secure"); + + if (_httpOnly) + buff.Append ("; HttpOnly"); + + return buff.ToString (); + } + + private string toResponseStringVersion1 () + { + var buff = new StringBuilder (64); + + buff.AppendFormat ("{0}={1}; Version={2}", _name, _value, _version); + + if (_expires != DateTime.MinValue) + buff.AppendFormat ("; Max-Age={0}", MaxAge); + + if (!_path.IsNullOrEmpty ()) + buff.AppendFormat ("; Path={0}", _path); + + if (!_domain.IsNullOrEmpty ()) + buff.AppendFormat ("; Domain={0}", _domain); + + if (_port != null) { + if (_port != "\"\"") + buff.AppendFormat ("; Port={0}", _port); + else + buff.Append ("; Port"); + } + + if (_comment != null) + buff.AppendFormat ("; Comment={0}", HttpUtility.UrlEncode (_comment)); + + if (_commentUri != null) { + var url = _commentUri.OriginalString; + buff.AppendFormat ( + "; CommentURL={0}", !url.IsToken () ? url.Quote () : url + ); + } + + if (_discard) + buff.Append ("; Discard"); + + if (_secure) + buff.Append ("; Secure"); + + return buff.ToString (); + } + + private static bool tryCreatePorts (string value, out int[] result) + { + result = null; + + var arr = value.Trim ('"').Split (','); + var len = arr.Length; + var res = new int[len]; + + for (var i = 0; i < len; i++) { + var s = arr[i].Trim (); + if (s.Length == 0) { + res[i] = Int32.MinValue; + continue; + } + + if (!Int32.TryParse (s, out res[i])) + return false; + } + + result = res; + return true; + } + + #endregion + + #region Internal Methods + + internal bool EqualsWithoutValue (Cookie cookie) + { + var caseSensitive = StringComparison.InvariantCulture; + var caseInsensitive = StringComparison.InvariantCultureIgnoreCase; + + return _name.Equals (cookie._name, caseInsensitive) + && _path.Equals (cookie._path, caseSensitive) + && _domain.Equals (cookie._domain, caseInsensitive) + && _version == cookie._version; + } + + internal bool EqualsWithoutValueAndVersion (Cookie cookie) + { + var caseSensitive = StringComparison.InvariantCulture; + var caseInsensitive = StringComparison.InvariantCultureIgnoreCase; + + return _name.Equals (cookie._name, caseInsensitive) + && _path.Equals (cookie._path, caseSensitive) + && _domain.Equals (cookie._domain, caseInsensitive); + } + + internal string ToRequestString (Uri uri) + { + if (_name.Length == 0) + return String.Empty; + + if (_version == 0) + return String.Format ("{0}={1}", _name, _value); + + var buff = new StringBuilder (64); + + buff.AppendFormat ("$Version={0}; {1}={2}", _version, _name, _value); + + if (!_path.IsNullOrEmpty ()) + buff.AppendFormat ("; $Path={0}", _path); + else if (uri != null) + buff.AppendFormat ("; $Path={0}", uri.GetAbsolutePath ()); + else + buff.Append ("; $Path=/"); + + if (!_domain.IsNullOrEmpty ()) { + if (uri == null || uri.Host != _domain) + buff.AppendFormat ("; $Domain={0}", _domain); + } + + if (_port != null) { + if (_port != "\"\"") + buff.AppendFormat ("; $Port={0}", _port); + else + buff.Append ("; $Port"); + } + + return buff.ToString (); + } + + /// + /// Returns a string that represents the current cookie instance. + /// + /// + /// A that is suitable for the Set-Cookie response + /// header. + /// + internal string ToResponseString () + { + return _name.Length == 0 + ? String.Empty + : _version == 0 + ? toResponseStringVersion0 () + : toResponseStringVersion1 (); + } + + internal static bool TryCreate ( + string name, string value, out Cookie result + ) + { + result = null; + + try { + result = new Cookie (name, value); + } + catch { + return false; + } + + return true; + } + + #endregion + + #region Public Methods + + /// + /// Determines whether the current cookie instance is equal to + /// the specified instance. + /// + /// + /// + /// An instance to compare with + /// the current cookie instance. + /// + /// + /// An reference to a instance. + /// + /// + /// + /// true if the current cookie instance is equal to + /// ; otherwise, false. + /// + public override bool Equals (object comparand) + { + var cookie = comparand as Cookie; + if (cookie == null) + return false; + + var caseSensitive = StringComparison.InvariantCulture; + var caseInsensitive = StringComparison.InvariantCultureIgnoreCase; + + return _name.Equals (cookie._name, caseInsensitive) + && _value.Equals (cookie._value, caseSensitive) + && _path.Equals (cookie._path, caseSensitive) + && _domain.Equals (cookie._domain, caseInsensitive) + && _version == cookie._version; + } + + /// + /// Gets a hash code for the current cookie instance. + /// + /// + /// An that represents the hash code. + /// + public override int GetHashCode () + { + return hash ( + StringComparer.InvariantCultureIgnoreCase.GetHashCode (_name), + _value.GetHashCode (), + _path.GetHashCode (), + StringComparer.InvariantCultureIgnoreCase.GetHashCode (_domain), + _version + ); + } + + /// + /// Returns a string that represents the current cookie instance. + /// + /// + /// A that is suitable for the Cookie request header. + /// + public override string ToString () + { + return ToRequestString (null); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/Cookie.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/Cookie.cs.meta new file mode 100644 index 00000000..69a01dae --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/Cookie.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1414df5fe386431c8c0c555bc27049b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/CookieCollection.cs b/Plugins/websocket-sharp/websocket-sharp/Net/CookieCollection.cs new file mode 100644 index 00000000..8c0322bd --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/CookieCollection.cs @@ -0,0 +1,821 @@ +#region License +/* + * CookieCollection.cs + * + * This code is derived from CookieCollection.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2004,2009 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2019 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Lawrence Pit + * - Gonzalo Paniagua Javier + * - Sebastien Pouliot + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace WebSocketSharp.Net +{ + /// + /// Provides a collection of instances of the class. + /// + [Serializable] + public class CookieCollection : ICollection + { + #region Private Fields + + private List _list; + private bool _readOnly; + private object _sync; + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class. + /// + public CookieCollection () + { + _list = new List (); + _sync = ((ICollection) _list).SyncRoot; + } + + #endregion + + #region Internal Properties + + internal IList List { + get { + return _list; + } + } + + internal IEnumerable Sorted { + get { + var list = new List (_list); + if (list.Count > 1) + list.Sort (compareForSorted); + + return list; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the number of cookies in the collection. + /// + /// + /// An that represents the number of cookies in + /// the collection. + /// + public int Count { + get { + return _list.Count; + } + } + + /// + /// Gets a value indicating whether the collection is read-only. + /// + /// + /// + /// true if the collection is read-only; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool IsReadOnly { + get { + return _readOnly; + } + + internal set { + _readOnly = value; + } + } + + /// + /// Gets a value indicating whether the access to the collection is + /// thread safe. + /// + /// + /// + /// true if the access to the collection is thread safe; + /// otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool IsSynchronized { + get { + return false; + } + } + + /// + /// Gets the cookie at the specified index from the collection. + /// + /// + /// A at the specified index in the collection. + /// + /// + /// An that specifies the zero-based index of the cookie + /// to find. + /// + /// + /// is out of allowable range for the collection. + /// + public Cookie this[int index] { + get { + if (index < 0 || index >= _list.Count) + throw new ArgumentOutOfRangeException ("index"); + + return _list[index]; + } + } + + /// + /// Gets the cookie with the specified name from the collection. + /// + /// + /// + /// A with the specified name in the collection. + /// + /// + /// if not found. + /// + /// + /// + /// A that specifies the name of the cookie to find. + /// + /// + /// is . + /// + public Cookie this[string name] { + get { + if (name == null) + throw new ArgumentNullException ("name"); + + var caseInsensitive = StringComparison.InvariantCultureIgnoreCase; + + foreach (var cookie in Sorted) { + if (cookie.Name.Equals (name, caseInsensitive)) + return cookie; + } + + return null; + } + } + + /// + /// Gets an object used to synchronize access to the collection. + /// + /// + /// An used to synchronize access to the collection. + /// + public object SyncRoot { + get { + return _sync; + } + } + + #endregion + + #region Private Methods + + private void add (Cookie cookie) + { + var idx = search (cookie); + if (idx == -1) { + _list.Add (cookie); + return; + } + + _list[idx] = cookie; + } + + private static int compareForSort (Cookie x, Cookie y) + { + return (x.Name.Length + x.Value.Length) + - (y.Name.Length + y.Value.Length); + } + + private static int compareForSorted (Cookie x, Cookie y) + { + var ret = x.Version - y.Version; + return ret != 0 + ? ret + : (ret = x.Name.CompareTo (y.Name)) != 0 + ? ret + : y.Path.Length - x.Path.Length; + } + + private static CookieCollection parseRequest (string value) + { + var ret = new CookieCollection (); + + Cookie cookie = null; + var ver = 0; + + var caseInsensitive = StringComparison.InvariantCultureIgnoreCase; + var pairs = value.SplitHeaderValue (',', ';').ToList (); + + for (var i = 0; i < pairs.Count; i++) { + var pair = pairs[i].Trim (); + if (pair.Length == 0) + continue; + + var idx = pair.IndexOf ('='); + if (idx == -1) { + if (cookie == null) + continue; + + if (pair.Equals ("$port", caseInsensitive)) { + cookie.Port = "\"\""; + continue; + } + + continue; + } + + if (idx == 0) { + if (cookie != null) { + ret.add (cookie); + cookie = null; + } + + continue; + } + + var name = pair.Substring (0, idx).TrimEnd (' '); + var val = idx < pair.Length - 1 + ? pair.Substring (idx + 1).TrimStart (' ') + : String.Empty; + + if (name.Equals ("$version", caseInsensitive)) { + if (val.Length == 0) + continue; + + int num; + if (!Int32.TryParse (val.Unquote (), out num)) + continue; + + ver = num; + continue; + } + + if (name.Equals ("$path", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.Path = val; + continue; + } + + if (name.Equals ("$domain", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.Domain = val; + continue; + } + + if (name.Equals ("$port", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.Port = val; + continue; + } + + if (cookie != null) + ret.add (cookie); + + if (!Cookie.TryCreate (name, val, out cookie)) + continue; + + if (ver != 0) + cookie.Version = ver; + } + + if (cookie != null) + ret.add (cookie); + + return ret; + } + + private static CookieCollection parseResponse (string value) + { + var ret = new CookieCollection (); + + Cookie cookie = null; + + var caseInsensitive = StringComparison.InvariantCultureIgnoreCase; + var pairs = value.SplitHeaderValue (',', ';').ToList (); + + for (var i = 0; i < pairs.Count; i++) { + var pair = pairs[i].Trim (); + if (pair.Length == 0) + continue; + + var idx = pair.IndexOf ('='); + if (idx == -1) { + if (cookie == null) + continue; + + if (pair.Equals ("port", caseInsensitive)) { + cookie.Port = "\"\""; + continue; + } + + if (pair.Equals ("discard", caseInsensitive)) { + cookie.Discard = true; + continue; + } + + if (pair.Equals ("secure", caseInsensitive)) { + cookie.Secure = true; + continue; + } + + if (pair.Equals ("httponly", caseInsensitive)) { + cookie.HttpOnly = true; + continue; + } + + continue; + } + + if (idx == 0) { + if (cookie != null) { + ret.add (cookie); + cookie = null; + } + + continue; + } + + var name = pair.Substring (0, idx).TrimEnd (' '); + var val = idx < pair.Length - 1 + ? pair.Substring (idx + 1).TrimStart (' ') + : String.Empty; + + if (name.Equals ("version", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + int num; + if (!Int32.TryParse (val.Unquote (), out num)) + continue; + + cookie.Version = num; + continue; + } + + if (name.Equals ("expires", caseInsensitive)) { + if (val.Length == 0) + continue; + + if (i == pairs.Count - 1) + break; + + i++; + + if (cookie == null) + continue; + + if (cookie.Expires != DateTime.MinValue) + continue; + + var buff = new StringBuilder (val, 32); + buff.AppendFormat (", {0}", pairs[i].Trim ()); + + DateTime expires; + if ( + !DateTime.TryParseExact ( + buff.ToString (), + new[] { "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", "r" }, + CultureInfo.CreateSpecificCulture ("en-US"), + DateTimeStyles.AdjustToUniversal + | DateTimeStyles.AssumeUniversal, + out expires + ) + ) + continue; + + cookie.Expires = expires.ToLocalTime (); + continue; + } + + if (name.Equals ("max-age", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + int num; + if (!Int32.TryParse (val.Unquote (), out num)) + continue; + + cookie.MaxAge = num; + continue; + } + + if (name.Equals ("path", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.Path = val; + continue; + } + + if (name.Equals ("domain", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.Domain = val; + continue; + } + + if (name.Equals ("port", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.Port = val; + continue; + } + + if (name.Equals ("comment", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.Comment = urlDecode (val, Encoding.UTF8); + continue; + } + + if (name.Equals ("commenturl", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.CommentUri = val.Unquote ().ToUri (); + continue; + } + + if (name.Equals ("samesite", caseInsensitive)) { + if (cookie == null) + continue; + + if (val.Length == 0) + continue; + + cookie.SameSite = val.Unquote (); + continue; + } + + if (cookie != null) + ret.add (cookie); + + Cookie.TryCreate (name, val, out cookie); + } + + if (cookie != null) + ret.add (cookie); + + return ret; + } + + private int search (Cookie cookie) + { + for (var i = _list.Count - 1; i >= 0; i--) { + if (_list[i].EqualsWithoutValue (cookie)) + return i; + } + + return -1; + } + + private static string urlDecode (string s, Encoding encoding) + { + if (s.IndexOfAny (new[] { '%', '+' }) == -1) + return s; + + try { + return HttpUtility.UrlDecode (s, encoding); + } + catch { + return null; + } + } + + #endregion + + #region Internal Methods + + internal static CookieCollection Parse (string value, bool response) + { + try { + return response + ? parseResponse (value) + : parseRequest (value); + } + catch (Exception ex) { + throw new CookieException ("It could not be parsed.", ex); + } + } + + internal void SetOrRemove (Cookie cookie) + { + var idx = search (cookie); + if (idx == -1) { + if (cookie.Expired) + return; + + _list.Add (cookie); + return; + } + + if (cookie.Expired) { + _list.RemoveAt (idx); + return; + } + + _list[idx] = cookie; + } + + internal void SetOrRemove (CookieCollection cookies) + { + foreach (var cookie in cookies._list) + SetOrRemove (cookie); + } + + internal void Sort () + { + if (_list.Count > 1) + _list.Sort (compareForSort); + } + + #endregion + + #region Public Methods + + /// + /// Adds the specified cookie to the collection. + /// + /// + /// A to add. + /// + /// + /// The collection is read-only. + /// + /// + /// is . + /// + public void Add (Cookie cookie) + { + if (_readOnly) { + var msg = "The collection is read-only."; + throw new InvalidOperationException (msg); + } + + if (cookie == null) + throw new ArgumentNullException ("cookie"); + + add (cookie); + } + + /// + /// Adds the specified cookies to the collection. + /// + /// + /// A that contains the cookies to add. + /// + /// + /// The collection is read-only. + /// + /// + /// is . + /// + public void Add (CookieCollection cookies) + { + if (_readOnly) { + var msg = "The collection is read-only."; + throw new InvalidOperationException (msg); + } + + if (cookies == null) + throw new ArgumentNullException ("cookies"); + + foreach (var cookie in cookies._list) + add (cookie); + } + + /// + /// Removes all cookies from the collection. + /// + /// + /// The collection is read-only. + /// + public void Clear () + { + if (_readOnly) { + var msg = "The collection is read-only."; + throw new InvalidOperationException (msg); + } + + _list.Clear (); + } + + /// + /// Determines whether the collection contains the specified cookie. + /// + /// + /// true if the cookie is found in the collection; otherwise, + /// false. + /// + /// + /// A to find. + /// + /// + /// is . + /// + public bool Contains (Cookie cookie) + { + if (cookie == null) + throw new ArgumentNullException ("cookie"); + + return search (cookie) > -1; + } + + /// + /// Copies the elements of the collection to the specified array, + /// starting at the specified index. + /// + /// + /// An array of that specifies the destination of + /// the elements copied from the collection. + /// + /// + /// An that specifies the zero-based index in + /// the array at which copying starts. + /// + /// + /// is . + /// + /// + /// is less than zero. + /// + /// + /// The space from to the end of + /// is not enough to copy to. + /// + public void CopyTo (Cookie[] array, int index) + { + if (array == null) + throw new ArgumentNullException ("array"); + + if (index < 0) + throw new ArgumentOutOfRangeException ("index", "Less than zero."); + + if (array.Length - index < _list.Count) { + var msg = "The available space of the array is not enough to copy to."; + throw new ArgumentException (msg); + } + + _list.CopyTo (array, index); + } + + /// + /// Gets the enumerator that iterates through the collection. + /// + /// + /// An + /// instance that can be used to iterate through the collection. + /// + public IEnumerator GetEnumerator () + { + return _list.GetEnumerator (); + } + + /// + /// Removes the specified cookie from the collection. + /// + /// + /// + /// true if the cookie is successfully removed; otherwise, + /// false. + /// + /// + /// false if the cookie is not found in the collection. + /// + /// + /// + /// A to remove. + /// + /// + /// The collection is read-only. + /// + /// + /// is . + /// + public bool Remove (Cookie cookie) + { + if (_readOnly) { + var msg = "The collection is read-only."; + throw new InvalidOperationException (msg); + } + + if (cookie == null) + throw new ArgumentNullException ("cookie"); + + var idx = search (cookie); + if (idx == -1) + return false; + + _list.RemoveAt (idx); + return true; + } + + #endregion + + #region Explicit Interface Implementations + + /// + /// Gets the enumerator that iterates through the collection. + /// + /// + /// An instance that can be used to iterate + /// through the collection. + /// + IEnumerator IEnumerable.GetEnumerator () + { + return _list.GetEnumerator (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/CookieCollection.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/CookieCollection.cs.meta new file mode 100644 index 00000000..37ec712a --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/CookieCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7b7b01a9c8124c788f268c8c869fe9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/CookieException.cs b/Plugins/websocket-sharp/websocket-sharp/Net/CookieException.cs new file mode 100644 index 00000000..2a5abe98 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/CookieException.cs @@ -0,0 +1,165 @@ +#region License +/* + * CookieException.cs + * + * This code is derived from CookieException.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2012-2019 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Lawrence Pit + */ +#endregion + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; + +namespace WebSocketSharp.Net +{ + /// + /// The exception that is thrown when a gets an error. + /// + [Serializable] + public class CookieException : FormatException, ISerializable + { + #region Internal Constructors + + internal CookieException (string message) + : base (message) + { + } + + internal CookieException (string message, Exception innerException) + : base (message, innerException) + { + } + + #endregion + + #region Protected Constructors + + /// + /// Initializes a new instance of the class + /// with the serialized data. + /// + /// + /// A that holds the serialized object data. + /// + /// + /// A that specifies the source for + /// the deserialization. + /// + /// + /// is . + /// + protected CookieException ( + SerializationInfo serializationInfo, StreamingContext streamingContext + ) + : base (serializationInfo, streamingContext) + { + } + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class. + /// + public CookieException () + : base () + { + } + + #endregion + + #region Public Methods + + /// + /// Populates the specified instance with + /// the data needed to serialize the current instance. + /// + /// + /// A that holds the serialized object data. + /// + /// + /// A that specifies the destination for + /// the serialization. + /// + /// + /// is . + /// + [ + SecurityPermission ( + SecurityAction.LinkDemand, + Flags = SecurityPermissionFlag.SerializationFormatter + ) + ] + public override void GetObjectData ( + SerializationInfo serializationInfo, StreamingContext streamingContext + ) + { + base.GetObjectData (serializationInfo, streamingContext); + } + + #endregion + + #region Explicit Interface Implementation + + /// + /// Populates the specified instance with + /// the data needed to serialize the current instance. + /// + /// + /// A that holds the serialized object data. + /// + /// + /// A that specifies the destination for + /// the serialization. + /// + /// + /// is . + /// + [ + SecurityPermission ( + SecurityAction.LinkDemand, + Flags = SecurityPermissionFlag.SerializationFormatter, + SerializationFormatter = true + ) + ] + void ISerializable.GetObjectData ( + SerializationInfo serializationInfo, StreamingContext streamingContext + ) + { + base.GetObjectData (serializationInfo, streamingContext); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/CookieException.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/CookieException.cs.meta new file mode 100644 index 00000000..2370c27f --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/CookieException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c3d26e61b20d4ac497ba1a553c6a47c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/EndPointListener.cs b/Plugins/websocket-sharp/websocket-sharp/Net/EndPointListener.cs new file mode 100644 index 00000000..b372a252 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/EndPointListener.cs @@ -0,0 +1,582 @@ +#region License +/* + * EndPointListener.cs + * + * This code is derived from EndPointListener.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Liryna + * - Nicholas Devenish + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Threading; + +namespace WebSocketSharp.Net +{ + internal sealed class EndPointListener + { + #region Private Fields + + private List _all; // host == '+' + private Dictionary _connections; + private object _connectionsSync; + private static readonly string _defaultCertFolderPath; + private IPEndPoint _endpoint; + private List _prefixes; + private bool _secure; + private Socket _socket; + private ServerSslConfiguration _sslConfig; + private List _unhandled; // host == '*' + + #endregion + + #region Static Constructor + + static EndPointListener () + { + _defaultCertFolderPath = Environment.GetFolderPath ( + Environment.SpecialFolder.ApplicationData + ); + } + + #endregion + + #region Internal Constructors + + internal EndPointListener ( + IPEndPoint endpoint, + bool secure, + string certificateFolderPath, + ServerSslConfiguration sslConfig, + bool reuseAddress + ) + { + _endpoint = endpoint; + + if (secure) { + var cert = getCertificate ( + endpoint.Port, + certificateFolderPath, + sslConfig.ServerCertificate + ); + + if (cert == null) { + var msg = "No server certificate could be found."; + + throw new ArgumentException (msg); + } + + _secure = true; + _sslConfig = new ServerSslConfiguration (sslConfig); + _sslConfig.ServerCertificate = cert; + } + + _prefixes = new List (); + _connections = new Dictionary (); + _connectionsSync = ((ICollection) _connections).SyncRoot; + + _socket = new Socket ( + endpoint.Address.AddressFamily, + SocketType.Stream, + ProtocolType.Tcp + ); + + if (reuseAddress) { + _socket.SetSocketOption ( + SocketOptionLevel.Socket, + SocketOptionName.ReuseAddress, + true + ); + } + + _socket.Bind (endpoint); + _socket.Listen (500); + _socket.BeginAccept (onAccept, this); + } + + #endregion + + #region Public Properties + + public IPAddress Address { + get { + return _endpoint.Address; + } + } + + public bool IsSecure { + get { + return _secure; + } + } + + public int Port { + get { + return _endpoint.Port; + } + } + + public ServerSslConfiguration SslConfiguration { + get { + return _sslConfig; + } + } + + #endregion + + #region Private Methods + + private static void addSpecial ( + List prefixes, HttpListenerPrefix prefix + ) + { + var path = prefix.Path; + + foreach (var pref in prefixes) { + if (pref.Path == path) { + var msg = "The prefix is already in use."; + + throw new HttpListenerException (87, msg); + } + } + + prefixes.Add (prefix); + } + + private void clearConnections () + { + HttpConnection[] conns = null; + + lock (_connectionsSync) { + var cnt = _connections.Count; + + if (cnt == 0) + return; + + conns = new HttpConnection[cnt]; + + var vals = _connections.Values; + vals.CopyTo (conns, 0); + + _connections.Clear (); + } + + foreach (var conn in conns) + conn.Close (true); + } + + private static RSACryptoServiceProvider createRSAFromFile (string path) + { + var rsa = new RSACryptoServiceProvider (); + + var key = File.ReadAllBytes (path); + rsa.ImportCspBlob (key); + + return rsa; + } + + private static X509Certificate2 getCertificate ( + int port, string folderPath, X509Certificate2 defaultCertificate + ) + { + if (folderPath == null || folderPath.Length == 0) + folderPath = _defaultCertFolderPath; + + try { + var cer = Path.Combine (folderPath, String.Format ("{0}.cer", port)); + var key = Path.Combine (folderPath, String.Format ("{0}.key", port)); + + if (File.Exists (cer) && File.Exists (key)) { + var cert = new X509Certificate2 (cer); + cert.PrivateKey = createRSAFromFile (key); + + return cert; + } + } + catch { + } + + return defaultCertificate; + } + + private void leaveIfNoPrefix () + { + if (_prefixes.Count > 0) + return; + + var prefs = _unhandled; + + if (prefs != null && prefs.Count > 0) + return; + + prefs = _all; + + if (prefs != null && prefs.Count > 0) + return; + + Close (); + } + + private static void onAccept (IAsyncResult asyncResult) + { + var lsnr = (EndPointListener) asyncResult.AsyncState; + + Socket sock = null; + + try { + sock = lsnr._socket.EndAccept (asyncResult); + } + catch (ObjectDisposedException) { + return; + } + catch (Exception) { + // TODO: Logging. + } + + try { + lsnr._socket.BeginAccept (onAccept, lsnr); + } + catch (Exception) { + // TODO: Logging. + + if (sock != null) + sock.Close (); + + return; + } + + if (sock == null) + return; + + processAccepted (sock, lsnr); + } + + private static void processAccepted ( + Socket socket, EndPointListener listener + ) + { + HttpConnection conn = null; + + try { + conn = new HttpConnection (socket, listener); + } + catch (Exception) { + // TODO: Logging. + + socket.Close (); + + return; + } + + lock (listener._connectionsSync) + listener._connections.Add (conn, conn); + + conn.BeginReadRequest (); + } + + private static bool removeSpecial ( + List prefixes, HttpListenerPrefix prefix + ) + { + var path = prefix.Path; + var cnt = prefixes.Count; + + for (var i = 0; i < cnt; i++) { + if (prefixes[i].Path == path) { + prefixes.RemoveAt (i); + + return true; + } + } + + return false; + } + + private static HttpListener searchHttpListenerFromSpecial ( + string path, List prefixes + ) + { + if (prefixes == null) + return null; + + HttpListener ret = null; + + var bestLen = -1; + + foreach (var pref in prefixes) { + var prefPath = pref.Path; + var len = prefPath.Length; + + if (len < bestLen) + continue; + + if (path.StartsWith (prefPath, StringComparison.Ordinal)) { + bestLen = len; + ret = pref.Listener; + } + } + + return ret; + } + + #endregion + + #region Internal Methods + + internal static bool CertificateExists (int port, string folderPath) + { + if (folderPath == null || folderPath.Length == 0) + folderPath = _defaultCertFolderPath; + + var cer = Path.Combine (folderPath, String.Format ("{0}.cer", port)); + var key = Path.Combine (folderPath, String.Format ("{0}.key", port)); + + return File.Exists (cer) && File.Exists (key); + } + + internal void RemoveConnection (HttpConnection connection) + { + lock (_connectionsSync) + _connections.Remove (connection); + } + + internal bool TrySearchHttpListener (Uri uri, out HttpListener listener) + { + listener = null; + + if (uri == null) + return false; + + var host = uri.Host; + var dns = Uri.CheckHostName (host) == UriHostNameType.Dns; + var port = uri.Port.ToString (); + var path = HttpUtility.UrlDecode (uri.AbsolutePath); + + if (path[path.Length - 1] != '/') + path += "/"; + + if (host != null && host.Length > 0) { + var prefs = _prefixes; + var bestLen = -1; + + foreach (var pref in prefs) { + if (dns) { + var prefHost = pref.Host; + var prefDns = Uri.CheckHostName (prefHost) == UriHostNameType.Dns; + + if (prefDns) { + if (prefHost != host) + continue; + } + } + + if (pref.Port != port) + continue; + + var prefPath = pref.Path; + var len = prefPath.Length; + + if (len < bestLen) + continue; + + if (path.StartsWith (prefPath, StringComparison.Ordinal)) { + bestLen = len; + listener = pref.Listener; + } + } + + if (bestLen != -1) + return true; + } + + listener = searchHttpListenerFromSpecial (path, _unhandled); + + if (listener != null) + return true; + + listener = searchHttpListenerFromSpecial (path, _all); + + return listener != null; + } + + #endregion + + #region Public Methods + + public void AddPrefix (HttpListenerPrefix prefix) + { + List current, future; + + if (prefix.Host == "*") { + do { + current = _unhandled; + future = current != null + ? new List (current) + : new List (); + + addSpecial (future, prefix); + } + while ( + Interlocked.CompareExchange (ref _unhandled, future, current) != current + ); + + return; + } + + if (prefix.Host == "+") { + do { + current = _all; + future = current != null + ? new List (current) + : new List (); + + addSpecial (future, prefix); + } + while ( + Interlocked.CompareExchange (ref _all, future, current) != current + ); + + return; + } + + do { + current = _prefixes; + var idx = current.IndexOf (prefix); + + if (idx > -1) { + if (current[idx].Listener != prefix.Listener) { + var msg = String.Format ( + "There is another listener for {0}.", prefix + ); + + throw new HttpListenerException (87, msg); + } + + return; + } + + future = new List (current); + future.Add (prefix); + } + while ( + Interlocked.CompareExchange (ref _prefixes, future, current) != current + ); + } + + public void Close () + { + _socket.Close (); + + clearConnections (); + EndPointManager.RemoveEndPoint (_endpoint); + } + + public void RemovePrefix (HttpListenerPrefix prefix) + { + List current, future; + + if (prefix.Host == "*") { + do { + current = _unhandled; + + if (current == null) + break; + + future = new List (current); + + if (!removeSpecial (future, prefix)) + break; + } + while ( + Interlocked.CompareExchange (ref _unhandled, future, current) != current + ); + + leaveIfNoPrefix (); + + return; + } + + if (prefix.Host == "+") { + do { + current = _all; + + if (current == null) + break; + + future = new List (current); + + if (!removeSpecial (future, prefix)) + break; + } + while ( + Interlocked.CompareExchange (ref _all, future, current) != current + ); + + leaveIfNoPrefix (); + + return; + } + + do { + current = _prefixes; + + if (!current.Contains (prefix)) + break; + + future = new List (current); + future.Remove (prefix); + } + while ( + Interlocked.CompareExchange (ref _prefixes, future, current) != current + ); + + leaveIfNoPrefix (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/EndPointListener.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/EndPointListener.cs.meta new file mode 100644 index 00000000..ac66a976 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/EndPointListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 684001ea2c1fb4201b110d24b256cfbd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/EndPointManager.cs b/Plugins/websocket-sharp/websocket-sharp/Net/EndPointManager.cs new file mode 100644 index 00000000..ac4582b2 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/EndPointManager.cs @@ -0,0 +1,261 @@ +#region License +/* + * EndPointManager.cs + * + * This code is derived from EndPointManager.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Liryna + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net; + +namespace WebSocketSharp.Net +{ + internal sealed class EndPointManager + { + #region Private Fields + + private static readonly Dictionary _endpoints; + + #endregion + + #region Static Constructor + + static EndPointManager () + { + _endpoints = new Dictionary (); + } + + #endregion + + #region Private Constructors + + private EndPointManager () + { + } + + #endregion + + #region Private Methods + + private static void addPrefix (string uriPrefix, HttpListener listener) + { + var pref = new HttpListenerPrefix (uriPrefix, listener); + + var addr = convertToIPAddress (pref.Host); + + if (addr == null) { + var msg = "The URI prefix includes an invalid host."; + + throw new HttpListenerException (87, msg); + } + + if (!addr.IsLocal ()) { + var msg = "The URI prefix includes an invalid host."; + + throw new HttpListenerException (87, msg); + } + + int port; + + if (!Int32.TryParse (pref.Port, out port)) { + var msg = "The URI prefix includes an invalid port."; + + throw new HttpListenerException (87, msg); + } + + if (!port.IsPortNumber ()) { + var msg = "The URI prefix includes an invalid port."; + + throw new HttpListenerException (87, msg); + } + + var path = pref.Path; + + if (path.IndexOf ('%') != -1) { + var msg = "The URI prefix includes an invalid path."; + + throw new HttpListenerException (87, msg); + } + + if (path.IndexOf ("//", StringComparison.Ordinal) != -1) { + var msg = "The URI prefix includes an invalid path."; + + throw new HttpListenerException (87, msg); + } + + var endpoint = new IPEndPoint (addr, port); + + EndPointListener lsnr; + + if (_endpoints.TryGetValue (endpoint, out lsnr)) { + if (lsnr.IsSecure ^ pref.IsSecure) { + var msg = "The URI prefix includes an invalid scheme."; + + throw new HttpListenerException (87, msg); + } + } + else { + lsnr = new EndPointListener ( + endpoint, + pref.IsSecure, + listener.CertificateFolderPath, + listener.SslConfiguration, + listener.ReuseAddress + ); + + _endpoints.Add (endpoint, lsnr); + } + + lsnr.AddPrefix (pref); + } + + private static IPAddress convertToIPAddress (string hostname) + { + if (hostname == "*") + return IPAddress.Any; + + if (hostname == "+") + return IPAddress.Any; + + return hostname.ToIPAddress (); + } + + private static void removePrefix (string uriPrefix, HttpListener listener) + { + var pref = new HttpListenerPrefix (uriPrefix, listener); + + var addr = convertToIPAddress (pref.Host); + + if (addr == null) + return; + + if (!addr.IsLocal ()) + return; + + int port; + + if (!Int32.TryParse (pref.Port, out port)) + return; + + if (!port.IsPortNumber ()) + return; + + var path = pref.Path; + + if (path.IndexOf ('%') != -1) + return; + + if (path.IndexOf ("//", StringComparison.Ordinal) != -1) + return; + + var endpoint = new IPEndPoint (addr, port); + + EndPointListener lsnr; + + if (!_endpoints.TryGetValue (endpoint, out lsnr)) + return; + + if (lsnr.IsSecure ^ pref.IsSecure) + return; + + lsnr.RemovePrefix (pref); + } + + #endregion + + #region Internal Methods + + internal static bool RemoveEndPoint (IPEndPoint endpoint) + { + lock (((ICollection) _endpoints).SyncRoot) + return _endpoints.Remove (endpoint); + } + + #endregion + + #region Public Methods + + public static void AddListener (HttpListener listener) + { + var added = new List (); + + lock (((ICollection) _endpoints).SyncRoot) { + try { + foreach (var pref in listener.Prefixes) { + addPrefix (pref, listener); + added.Add (pref); + } + } + catch { + foreach (var pref in added) + removePrefix (pref, listener); + + throw; + } + } + } + + public static void AddPrefix (string uriPrefix, HttpListener listener) + { + lock (((ICollection) _endpoints).SyncRoot) + addPrefix (uriPrefix, listener); + } + + public static void RemoveListener (HttpListener listener) + { + lock (((ICollection) _endpoints).SyncRoot) { + foreach (var pref in listener.Prefixes) + removePrefix (pref, listener); + } + } + + public static void RemovePrefix (string uriPrefix, HttpListener listener) + { + lock (((ICollection) _endpoints).SyncRoot) + removePrefix (uriPrefix, listener); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/EndPointManager.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/EndPointManager.cs.meta new file mode 100644 index 00000000..65a71950 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/EndPointManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 241b17e1eddde4e2886df45621e51052 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpBasicIdentity.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpBasicIdentity.cs new file mode 100644 index 00000000..d26b29f6 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpBasicIdentity.cs @@ -0,0 +1,82 @@ +#region License +/* + * HttpBasicIdentity.cs + * + * This code is derived from HttpListenerBasicIdentity.cs (System.Net) of + * Mono (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2014-2017 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.Security.Principal; + +namespace WebSocketSharp.Net +{ + /// + /// Holds the username and password from an HTTP Basic authentication attempt. + /// + public class HttpBasicIdentity : GenericIdentity + { + #region Private Fields + + private string _password; + + #endregion + + #region Internal Constructors + + internal HttpBasicIdentity (string username, string password) + : base (username, "Basic") + { + _password = password; + } + + #endregion + + #region Public Properties + + /// + /// Gets the password from a basic authentication attempt. + /// + /// + /// A that represents the password. + /// + public virtual string Password { + get { + return _password; + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpBasicIdentity.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpBasicIdentity.cs.meta new file mode 100644 index 00000000..7c7d52e4 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpBasicIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3cdcf69cbfaf74ad4978ed2a2045c3f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpConnection.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpConnection.cs new file mode 100644 index 00000000..1ae17f38 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpConnection.cs @@ -0,0 +1,571 @@ +#region License +/* + * HttpConnection.cs + * + * This code is derived from HttpConnection.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Liryna + * - Rohan Singh + */ +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Security; +using System.Net.Sockets; +using System.Text; +using System.Threading; + +namespace WebSocketSharp.Net +{ + internal sealed class HttpConnection + { + #region Private Fields + + private int _attempts; + private byte[] _buffer; + private static readonly int _bufferLength; + private HttpListenerContext _context; + private StringBuilder _currentLine; + private InputState _inputState; + private RequestStream _inputStream; + private LineState _lineState; + private EndPointListener _listener; + private EndPoint _localEndPoint; + private static readonly int _maxInputLength; + private ResponseStream _outputStream; + private int _position; + private EndPoint _remoteEndPoint; + private MemoryStream _requestBuffer; + private int _reuses; + private bool _secure; + private Socket _socket; + private Stream _stream; + private object _sync; + private int _timeout; + private Dictionary _timeoutCanceled; + private Timer _timer; + + #endregion + + #region Static Constructor + + static HttpConnection () + { + _bufferLength = 8192; + _maxInputLength = 32768; + } + + #endregion + + #region Internal Constructors + + internal HttpConnection (Socket socket, EndPointListener listener) + { + _socket = socket; + _listener = listener; + + var netStream = new NetworkStream (socket, false); + + if (listener.IsSecure) { + var sslConf = listener.SslConfiguration; + var sslStream = new SslStream ( + netStream, + false, + sslConf.ClientCertificateValidationCallback + ); + + sslStream.AuthenticateAsServer ( + sslConf.ServerCertificate, + sslConf.ClientCertificateRequired, + sslConf.EnabledSslProtocols, + sslConf.CheckCertificateRevocation + ); + + _secure = true; + _stream = sslStream; + } + else { + _stream = netStream; + } + + _buffer = new byte[_bufferLength]; + _localEndPoint = socket.LocalEndPoint; + _remoteEndPoint = socket.RemoteEndPoint; + _sync = new object (); + _timeoutCanceled = new Dictionary (); + _timer = new Timer (onTimeout, this, Timeout.Infinite, Timeout.Infinite); + + init (90000); // 90k ms for first request, 15k ms from then on. + } + + #endregion + + #region Public Properties + + public bool IsClosed { + get { + return _socket == null; + } + } + + public bool IsLocal { + get { + return ((IPEndPoint) _remoteEndPoint).Address.IsLocal (); + } + } + + public bool IsSecure { + get { + return _secure; + } + } + + public IPEndPoint LocalEndPoint { + get { + return (IPEndPoint) _localEndPoint; + } + } + + public IPEndPoint RemoteEndPoint { + get { + return (IPEndPoint) _remoteEndPoint; + } + } + + public int Reuses { + get { + return _reuses; + } + } + + public Stream Stream { + get { + return _stream; + } + } + + #endregion + + #region Private Methods + + private void close () + { + lock (_sync) { + if (_socket == null) + return; + + disposeTimer (); + disposeRequestBuffer (); + disposeStream (); + closeSocket (); + } + + _context.Unregister (); + _listener.RemoveConnection (this); + } + + private void closeSocket () + { + try { + _socket.Shutdown (SocketShutdown.Both); + } + catch { + } + + _socket.Close (); + + _socket = null; + } + + private void disposeRequestBuffer () + { + if (_requestBuffer == null) + return; + + _requestBuffer.Dispose (); + + _requestBuffer = null; + } + + private void disposeStream () + { + if (_stream == null) + return; + + _stream.Dispose (); + + _stream = null; + } + + private void disposeTimer () + { + if (_timer == null) + return; + + try { + _timer.Change (Timeout.Infinite, Timeout.Infinite); + } + catch { + } + + _timer.Dispose (); + + _timer = null; + } + + private void init (int timeout) + { + _timeout = timeout; + + _context = new HttpListenerContext (this); + _currentLine = new StringBuilder (64); + _inputState = InputState.RequestLine; + _inputStream = null; + _lineState = LineState.None; + _outputStream = null; + _position = 0; + _requestBuffer = new MemoryStream (); + } + + private static void onRead (IAsyncResult asyncResult) + { + var conn = (HttpConnection) asyncResult.AsyncState; + var current = conn._attempts; + + if (conn._socket == null) + return; + + lock (conn._sync) { + if (conn._socket == null) + return; + + conn._timer.Change (Timeout.Infinite, Timeout.Infinite); + conn._timeoutCanceled[current] = true; + + var nread = 0; + + try { + nread = conn._stream.EndRead (asyncResult); + } + catch (Exception) { + // TODO: Logging. + + conn.close (); + + return; + } + + if (nread <= 0) { + conn.close (); + + return; + } + + conn._requestBuffer.Write (conn._buffer, 0, nread); + var len = (int) conn._requestBuffer.Length; + + if (conn.processInput (conn._requestBuffer.GetBuffer (), len)) { + if (!conn._context.HasErrorMessage) + conn._context.Request.FinishInitialization (); + + if (conn._context.HasErrorMessage) { + conn._context.SendError (); + + return; + } + + var url = conn._context.Request.Url; + HttpListener lsnr; + + if (conn._listener.TrySearchHttpListener (url, out lsnr)) { + if (!lsnr.AuthenticateContext (conn._context)) + return; + + if (!lsnr.RegisterContext (conn._context)) { + conn._context.ErrorStatusCode = 503; + conn._context.SendError (); + + return; + } + + return; + } + + conn._context.ErrorStatusCode = 404; + conn._context.SendError (); + + return; + } + + conn.BeginReadRequest (); + } + } + + private static void onTimeout (object state) + { + var conn = (HttpConnection) state; + var current = conn._attempts; + + if (conn._socket == null) + return; + + lock (conn._sync) { + if (conn._socket == null) + return; + + if (conn._timeoutCanceled[current]) + return; + + conn._context.ErrorStatusCode = 408; + conn._context.SendError (); + } + } + + private bool processInput (byte[] data, int length) + { + // This method returns a bool: + // - true Done processing + // - false Need more input + + try { + while (true) { + int nread; + var line = readLineFrom (data, _position, length, out nread); + + _position += nread; + + if (line == null) + break; + + if (line.Length == 0) { + if (_inputState == InputState.RequestLine) + continue; + + if (_position > _maxInputLength) + _context.ErrorMessage = "Headers too long"; + + return true; + } + + if (_inputState == InputState.RequestLine) { + _context.Request.SetRequestLine (line); + _inputState = InputState.Headers; + } + else { + _context.Request.AddHeader (line); + } + + if (_context.HasErrorMessage) + return true; + } + } + catch (Exception ex) { + _context.ErrorMessage = ex.Message; + + return true; + } + + if (_position >= _maxInputLength) { + _context.ErrorMessage = "Headers too long"; + + return true; + } + + return false; + } + + private string readLineFrom ( + byte[] buffer, int offset, int length, out int nread + ) + { + nread = 0; + + for (var i = offset; i < length; i++) { + nread++; + + var b = buffer[i]; + + if (b == 13) { + _lineState = LineState.Cr; + + continue; + } + + if (b == 10) { + _lineState = LineState.Lf; + + break; + } + + _currentLine.Append ((char) b); + } + + if (_lineState != LineState.Lf) + return null; + + var ret = _currentLine.ToString (); + + _currentLine.Length = 0; + _lineState = LineState.None; + + return ret; + } + + #endregion + + #region Internal Methods + + internal void BeginReadRequest () + { + _attempts++; + + _timeoutCanceled.Add (_attempts, false); + _timer.Change (_timeout, Timeout.Infinite); + + try { + _stream.BeginRead (_buffer, 0, _bufferLength, onRead, this); + } + catch (Exception) { + // TODO: Logging. + + close (); + } + } + + internal void Close (bool force) + { + if (_socket == null) + return; + + lock (_sync) { + if (_socket == null) + return; + + if (force) { + if (_outputStream != null) + _outputStream.Close (true); + + close (); + + return; + } + + GetResponseStream ().Close (false); + + if (_context.Response.CloseConnection) { + close (); + + return; + } + + if (!_context.Request.FlushInput ()) { + close (); + + return; + } + + disposeRequestBuffer (); + _context.Unregister (); + + _reuses++; + + init (15000); + BeginReadRequest (); + } + } + + #endregion + + #region Public Methods + + public void Close () + { + Close (false); + } + + public RequestStream GetRequestStream (long contentLength, bool chunked) + { + lock (_sync) { + if (_socket == null) + return null; + + if (_inputStream != null) + return _inputStream; + + var buff = _requestBuffer.GetBuffer (); + var len = (int) _requestBuffer.Length; + var cnt = len - _position; + + disposeRequestBuffer (); + + _inputStream = chunked + ? new ChunkedRequestStream ( + _stream, buff, _position, cnt, _context + ) + : new RequestStream ( + _stream, buff, _position, cnt, contentLength + ); + + return _inputStream; + } + } + + public ResponseStream GetResponseStream () + { + lock (_sync) { + if (_socket == null) + return null; + + if (_outputStream != null) + return _outputStream; + + var lsnr = _context.Listener; + var ignore = lsnr != null ? lsnr.IgnoreWriteExceptions : true; + _outputStream = new ResponseStream (_stream, _context.Response, ignore); + + return _outputStream; + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpConnection.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpConnection.cs.meta new file mode 100644 index 00000000..1f02d41d --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpConnection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69ef566e951884e019553ae4b4a12c26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpDigestIdentity.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpDigestIdentity.cs new file mode 100644 index 00000000..68ec86d9 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpDigestIdentity.cs @@ -0,0 +1,187 @@ +#region License +/* + * HttpDigestIdentity.cs + * + * The MIT License + * + * Copyright (c) 2014-2017 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Specialized; +using System.Security.Principal; + +namespace WebSocketSharp.Net +{ + /// + /// Holds the username and other parameters from + /// an HTTP Digest authentication attempt. + /// + public class HttpDigestIdentity : GenericIdentity + { + #region Private Fields + + private NameValueCollection _parameters; + + #endregion + + #region Internal Constructors + + internal HttpDigestIdentity (NameValueCollection parameters) + : base (parameters["username"], "Digest") + { + _parameters = parameters; + } + + #endregion + + #region Public Properties + + /// + /// Gets the algorithm parameter from a digest authentication attempt. + /// + /// + /// A that represents the algorithm parameter. + /// + public string Algorithm { + get { + return _parameters["algorithm"]; + } + } + + /// + /// Gets the cnonce parameter from a digest authentication attempt. + /// + /// + /// A that represents the cnonce parameter. + /// + public string Cnonce { + get { + return _parameters["cnonce"]; + } + } + + /// + /// Gets the nc parameter from a digest authentication attempt. + /// + /// + /// A that represents the nc parameter. + /// + public string Nc { + get { + return _parameters["nc"]; + } + } + + /// + /// Gets the nonce parameter from a digest authentication attempt. + /// + /// + /// A that represents the nonce parameter. + /// + public string Nonce { + get { + return _parameters["nonce"]; + } + } + + /// + /// Gets the opaque parameter from a digest authentication attempt. + /// + /// + /// A that represents the opaque parameter. + /// + public string Opaque { + get { + return _parameters["opaque"]; + } + } + + /// + /// Gets the qop parameter from a digest authentication attempt. + /// + /// + /// A that represents the qop parameter. + /// + public string Qop { + get { + return _parameters["qop"]; + } + } + + /// + /// Gets the realm parameter from a digest authentication attempt. + /// + /// + /// A that represents the realm parameter. + /// + public string Realm { + get { + return _parameters["realm"]; + } + } + + /// + /// Gets the response parameter from a digest authentication attempt. + /// + /// + /// A that represents the response parameter. + /// + public string Response { + get { + return _parameters["response"]; + } + } + + /// + /// Gets the uri parameter from a digest authentication attempt. + /// + /// + /// A that represents the uri parameter. + /// + public string Uri { + get { + return _parameters["uri"]; + } + } + + #endregion + + #region Internal Methods + + internal bool IsValid ( + string password, string realm, string method, string entity + ) + { + var copied = new NameValueCollection (_parameters); + copied["password"] = password; + copied["realm"] = realm; + copied["method"] = method; + copied["entity"] = entity; + + var expected = AuthenticationResponse.CreateRequestDigest (copied); + return _parameters["response"] == expected; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpDigestIdentity.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpDigestIdentity.cs.meta new file mode 100644 index 00000000..8808deea --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpDigestIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3fdd35886466146b08c7caf3e1a8c50f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderInfo.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderInfo.cs new file mode 100644 index 00000000..2b77e3d9 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderInfo.cs @@ -0,0 +1,128 @@ +#region License +/* + * HttpHeaderInfo.cs + * + * The MIT License + * + * Copyright (c) 2013-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + internal class HttpHeaderInfo + { + #region Private Fields + + private string _headerName; + private HttpHeaderType _headerType; + + #endregion + + #region Internal Constructors + + internal HttpHeaderInfo (string headerName, HttpHeaderType headerType) + { + _headerName = headerName; + _headerType = headerType; + } + + #endregion + + #region Internal Properties + + internal bool IsMultiValueInRequest { + get { + var headerType = _headerType & HttpHeaderType.MultiValueInRequest; + + return headerType == HttpHeaderType.MultiValueInRequest; + } + } + + internal bool IsMultiValueInResponse { + get { + var headerType = _headerType & HttpHeaderType.MultiValueInResponse; + + return headerType == HttpHeaderType.MultiValueInResponse; + } + } + + #endregion + + #region Public Properties + + public string HeaderName { + get { + return _headerName; + } + } + + public HttpHeaderType HeaderType { + get { + return _headerType; + } + } + + public bool IsRequest { + get { + var headerType = _headerType & HttpHeaderType.Request; + + return headerType == HttpHeaderType.Request; + } + } + + public bool IsResponse { + get { + var headerType = _headerType & HttpHeaderType.Response; + + return headerType == HttpHeaderType.Response; + } + } + + #endregion + + #region Public Methods + + public bool IsMultiValue (bool response) + { + var headerType = _headerType & HttpHeaderType.MultiValue; + + if (headerType != HttpHeaderType.MultiValue) + return response ? IsMultiValueInResponse : IsMultiValueInRequest; + + return response ? IsResponse : IsRequest; + } + + public bool IsRestricted (bool response) + { + var headerType = _headerType & HttpHeaderType.Restricted; + + if (headerType != HttpHeaderType.Restricted) + return false; + + return response ? IsResponse : IsRequest; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderInfo.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderInfo.cs.meta new file mode 100644 index 00000000..740bd6b2 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba80abff4de434052a834b7b274396f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderType.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderType.cs new file mode 100644 index 00000000..113fb63b --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderType.cs @@ -0,0 +1,44 @@ +#region License +/* + * HttpHeaderType.cs + * + * The MIT License + * + * Copyright (c) 2013-2014 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + [Flags] + internal enum HttpHeaderType + { + Unspecified = 0, + Request = 1, + Response = 1 << 1, + Restricted = 1 << 2, + MultiValue = 1 << 3, + MultiValueInRequest = 1 << 4, + MultiValueInResponse = 1 << 5 + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderType.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderType.cs.meta new file mode 100644 index 00000000..ad12f982 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpHeaderType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb58e2a936283411aa9669237e42a463 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListener.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListener.cs new file mode 100644 index 00000000..a1a6a6ab --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListener.cs @@ -0,0 +1,973 @@ +#region License +/* + * HttpListener.cs + * + * This code is derived from HttpListener.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Liryna + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.Threading; + +// TODO: Logging. +namespace WebSocketSharp.Net +{ + /// + /// Provides a simple, programmatically controlled HTTP listener. + /// + public sealed class HttpListener : IDisposable + { + #region Private Fields + + private AuthenticationSchemes _authSchemes; + private Func _authSchemeSelector; + private string _certFolderPath; + private Queue _contextQueue; + private LinkedList _contextRegistry; + private object _contextRegistrySync; + private static readonly string _defaultRealm; + private bool _disposed; + private bool _ignoreWriteExceptions; + private volatile bool _listening; + private Logger _log; + private string _objectName; + private HttpListenerPrefixCollection _prefixes; + private string _realm; + private bool _reuseAddress; + private ServerSslConfiguration _sslConfig; + private Func _userCredFinder; + private Queue _waitQueue; + + #endregion + + #region Static Constructor + + static HttpListener () + { + _defaultRealm = "SECRET AREA"; + } + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class. + /// + public HttpListener () + { + _authSchemes = AuthenticationSchemes.Anonymous; + _contextQueue = new Queue (); + + _contextRegistry = new LinkedList (); + _contextRegistrySync = ((ICollection) _contextRegistry).SyncRoot; + + _log = new Logger (); + _objectName = GetType ().ToString (); + _prefixes = new HttpListenerPrefixCollection (this); + _waitQueue = new Queue (); + } + + #endregion + + #region Internal Properties + + internal bool ReuseAddress { + get { + return _reuseAddress; + } + + set { + _reuseAddress = value; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets or sets the scheme used to authenticate the clients. + /// + /// + /// + /// One of the + /// enum values. + /// + /// + /// It represents the scheme used to authenticate the clients. + /// + /// + /// The default value is + /// . + /// + /// + /// + /// This listener has been closed. + /// + public AuthenticationSchemes AuthenticationSchemes { + get { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + return _authSchemes; + } + + set { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + _authSchemes = value; + } + } + + /// + /// Gets or sets the delegate called to select the scheme used to + /// authenticate the clients. + /// + /// + /// + /// If this property is set, the listener uses the authentication + /// scheme selected by the delegate for each request. + /// + /// + /// Or if this property is not set, the listener uses the value of + /// the property + /// as the authentication scheme for all requests. + /// + /// + /// + /// + /// A Func<, + /// > delegate or + /// if not needed. + /// + /// + /// The delegate references the method used to select + /// an authentication scheme. + /// + /// + /// The default value is . + /// + /// + /// + /// This listener has been closed. + /// + public Func AuthenticationSchemeSelector { + get { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + return _authSchemeSelector; + } + + set { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + _authSchemeSelector = value; + } + } + + /// + /// Gets or sets the path to the folder in which stores the certificate + /// files used to authenticate the server on the secure connection. + /// + /// + /// + /// This property represents the path to the folder in which stores + /// the certificate files associated with each port number of added + /// URI prefixes. + /// + /// + /// A set of the certificate files is a pair of <port number>.cer + /// (DER) and <port number>.key (DER, RSA Private Key). + /// + /// + /// If this property is or an empty string, + /// the result of System.Environment.GetFolderPath () + /// is used as the default path. + /// + /// + /// + /// + /// A that represents the path to the folder + /// in which stores the certificate files. + /// + /// + /// The default value is . + /// + /// + /// + /// This listener has been closed. + /// + public string CertificateFolderPath { + get { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + return _certFolderPath; + } + + set { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + _certFolderPath = value; + } + } + + /// + /// Gets or sets a value indicating whether the listener returns + /// exceptions that occur when sending the response to the client. + /// + /// + /// + /// true if the listener should not return those exceptions; + /// otherwise, false. + /// + /// + /// The default value is false. + /// + /// + /// + /// This listener has been closed. + /// + public bool IgnoreWriteExceptions { + get { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + return _ignoreWriteExceptions; + } + + set { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + _ignoreWriteExceptions = value; + } + } + + /// + /// Gets a value indicating whether the listener has been started. + /// + /// + /// true if the listener has been started; otherwise, false. + /// + public bool IsListening { + get { + return _listening; + } + } + + /// + /// Gets a value indicating whether the listener can be used with + /// the current operating system. + /// + /// + /// true. + /// + public static bool IsSupported { + get { + return true; + } + } + + /// + /// Gets the logging functions. + /// + /// + /// + /// The default logging level is . + /// + /// + /// If you would like to change it, you should set the Log.Level + /// property to any of the enum values. + /// + /// + /// + /// A that provides the logging functions. + /// + public Logger Log { + get { + return _log; + } + } + + /// + /// Gets the URI prefixes handled by the listener. + /// + /// + /// A that contains the URI + /// prefixes. + /// + /// + /// This listener has been closed. + /// + public HttpListenerPrefixCollection Prefixes { + get { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + return _prefixes; + } + } + + /// + /// Gets or sets the name of the realm associated with the listener. + /// + /// + /// If this property is or an empty string, + /// "SECRET AREA" will be used as the name of the realm. + /// + /// + /// + /// A that represents the name of the realm. + /// + /// + /// The default value is . + /// + /// + /// + /// This listener has been closed. + /// + public string Realm { + get { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + return _realm; + } + + set { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + _realm = value; + } + } + + /// + /// Gets the SSL configuration used to authenticate the server and + /// optionally the client for secure connection. + /// + /// + /// A that represents the SSL + /// configuration for secure connection. + /// + /// + /// This listener has been closed. + /// + public ServerSslConfiguration SslConfiguration { + get { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + if (_sslConfig == null) + _sslConfig = new ServerSslConfiguration (); + + return _sslConfig; + } + } + + /// + /// Gets or sets a value indicating whether, when NTLM authentication is used, + /// the authentication information of first request is used to authenticate + /// additional requests on the same connection. + /// + /// + /// This property is not currently supported and always throws + /// a . + /// + /// + /// true if the authentication information of first request is used; + /// otherwise, false. + /// + /// + /// Any use of this property. + /// + public bool UnsafeConnectionNtlmAuthentication { + get { + throw new NotSupportedException (); + } + + set { + throw new NotSupportedException (); + } + } + + /// + /// Gets or sets the delegate called to find the credentials for + /// an identity used to authenticate a client. + /// + /// + /// + /// A Func<, + /// > delegate or + /// if not needed. + /// + /// + /// It references the method used to find the credentials. + /// + /// + /// The default value is . + /// + /// + /// + /// This listener has been closed. + /// + public Func UserCredentialsFinder { + get { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + return _userCredFinder; + } + + set { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + _userCredFinder = value; + } + } + + #endregion + + #region Private Methods + + private HttpListenerAsyncResult beginGetContext ( + AsyncCallback callback, object state + ) + { + lock (_contextRegistrySync) { + if (!_listening) { + var msg = _disposed + ? "The listener is closed." + : "The listener is stopped."; + + throw new HttpListenerException (995, msg); + } + + var ares = new HttpListenerAsyncResult (callback, state); + + if (_contextQueue.Count == 0) { + _waitQueue.Enqueue (ares); + } + else { + var ctx = _contextQueue.Dequeue (); + ares.Complete (ctx, true); + } + + return ares; + } + } + + private void cleanupContextQueue (bool force) + { + if (_contextQueue.Count == 0) + return; + + if (force) { + _contextQueue.Clear (); + + return; + } + + var ctxs = _contextQueue.ToArray (); + + _contextQueue.Clear (); + + foreach (var ctx in ctxs) { + ctx.ErrorStatusCode = 503; + ctx.SendError (); + } + } + + private void cleanupContextRegistry () + { + var cnt = _contextRegistry.Count; + + if (cnt == 0) + return; + + var ctxs = new HttpListenerContext[cnt]; + _contextRegistry.CopyTo (ctxs, 0); + + _contextRegistry.Clear (); + + foreach (var ctx in ctxs) + ctx.Connection.Close (true); + } + + private void cleanupWaitQueue (string message) + { + if (_waitQueue.Count == 0) + return; + + var aress = _waitQueue.ToArray (); + + _waitQueue.Clear (); + + foreach (var ares in aress) { + var ex = new HttpListenerException (995, message); + ares.Complete (ex); + } + } + + private void close (bool force) + { + if (!_listening) { + _disposed = true; + + return; + } + + _listening = false; + + cleanupContextQueue (force); + cleanupContextRegistry (); + + var msg = "The listener is closed."; + cleanupWaitQueue (msg); + + EndPointManager.RemoveListener (this); + + _disposed = true; + } + + private string getRealm () + { + var realm = _realm; + + return realm != null && realm.Length > 0 ? realm : _defaultRealm; + } + + private AuthenticationSchemes selectAuthenticationScheme ( + HttpListenerRequest request + ) + { + var selector = _authSchemeSelector; + + if (selector == null) + return _authSchemes; + + try { + return selector (request); + } + catch { + return AuthenticationSchemes.None; + } + } + + #endregion + + #region Internal Methods + + internal bool AuthenticateContext (HttpListenerContext context) + { + var req = context.Request; + var schm = selectAuthenticationScheme (req); + + if (schm == AuthenticationSchemes.Anonymous) + return true; + + if (schm == AuthenticationSchemes.None) { + context.ErrorStatusCode = 403; + context.ErrorMessage = "Authentication not allowed"; + + context.SendError (); + + return false; + } + + var realm = getRealm (); + var user = HttpUtility.CreateUser ( + req.Headers["Authorization"], + schm, + realm, + req.HttpMethod, + _userCredFinder + ); + + var authenticated = user != null && user.Identity.IsAuthenticated; + + if (!authenticated) { + context.SendAuthenticationChallenge (schm, realm); + + return false; + } + + context.User = user; + + return true; + } + + internal void CheckDisposed () + { + if (_disposed) + throw new ObjectDisposedException (_objectName); + } + + internal bool RegisterContext (HttpListenerContext context) + { + if (!_listening) + return false; + + lock (_contextRegistrySync) { + if (!_listening) + return false; + + context.Listener = this; + + _contextRegistry.AddLast (context); + + if (_waitQueue.Count == 0) { + _contextQueue.Enqueue (context); + } + else { + var ares = _waitQueue.Dequeue (); + ares.Complete (context, false); + } + + return true; + } + } + + internal void UnregisterContext (HttpListenerContext context) + { + lock (_contextRegistrySync) + _contextRegistry.Remove (context); + } + + #endregion + + #region Public Methods + + /// + /// Shuts down the listener immediately. + /// + public void Abort () + { + if (_disposed) + return; + + lock (_contextRegistrySync) { + if (_disposed) + return; + + close (true); + } + } + + /// + /// Begins getting an incoming request asynchronously. + /// + /// + /// + /// This asynchronous operation must be completed by calling + /// the EndGetContext method. + /// + /// + /// Typically, the EndGetContext method is called by + /// . + /// + /// + /// + /// An that represents the status of + /// the asynchronous operation. + /// + /// + /// An delegate that references the method to + /// invoke when the asynchronous operation completes. + /// + /// + /// An that represents a user defined object to + /// pass to . + /// + /// + /// + /// This listener has no URI prefix on which listens. + /// + /// + /// -or- + /// + /// + /// This listener has not been started or is currently stopped. + /// + /// + /// + /// This method is canceled. + /// + /// + /// This listener has been closed. + /// + public IAsyncResult BeginGetContext (AsyncCallback callback, object state) + { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + if (_prefixes.Count == 0) { + var msg = "The listener has no URI prefix on which listens."; + + throw new InvalidOperationException (msg); + } + + if (!_listening) { + var msg = "The listener has not been started."; + + throw new InvalidOperationException (msg); + } + + return beginGetContext (callback, state); + } + + /// + /// Shuts down the listener. + /// + public void Close () + { + if (_disposed) + return; + + lock (_contextRegistrySync) { + if (_disposed) + return; + + close (false); + } + } + + /// + /// Ends an asynchronous operation to get an incoming request. + /// + /// + /// This method completes an asynchronous operation started by calling + /// the BeginGetContext method. + /// + /// + /// A that represents a request. + /// + /// + /// An instance obtained by calling + /// the BeginGetContext method. + /// + /// + /// is . + /// + /// + /// was not obtained by calling + /// the BeginGetContext method. + /// + /// + /// This method was already called for . + /// + /// + /// This method is canceled. + /// + /// + /// This listener has been closed. + /// + public HttpListenerContext EndGetContext (IAsyncResult asyncResult) + { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + if (asyncResult == null) + throw new ArgumentNullException ("asyncResult"); + + var ares = asyncResult as HttpListenerAsyncResult; + + if (ares == null) { + var msg = "A wrong IAsyncResult instance."; + + throw new ArgumentException (msg, "asyncResult"); + } + + lock (ares.SyncRoot) { + if (ares.EndCalled) { + var msg = "This IAsyncResult instance cannot be reused."; + + throw new InvalidOperationException (msg); + } + + ares.EndCalled = true; + } + + if (!ares.IsCompleted) + ares.AsyncWaitHandle.WaitOne (); + + return ares.Context; + } + + /// + /// Gets an incoming request. + /// + /// + /// This method waits for an incoming request and returns when a request is + /// received. + /// + /// + /// A that represents a request. + /// + /// + /// + /// This listener has no URI prefix on which listens. + /// + /// + /// -or- + /// + /// + /// This listener has not been started or is currently stopped. + /// + /// + /// + /// This method is canceled. + /// + /// + /// This listener has been closed. + /// + public HttpListenerContext GetContext () + { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + if (_prefixes.Count == 0) { + var msg = "The listener has no URI prefix on which listens."; + + throw new InvalidOperationException (msg); + } + + if (!_listening) { + var msg = "The listener has not been started."; + + throw new InvalidOperationException (msg); + } + + var ares = beginGetContext (null, null); + ares.EndCalled = true; + + if (!ares.IsCompleted) + ares.AsyncWaitHandle.WaitOne (); + + return ares.Context; + } + + /// + /// Starts receiving incoming requests. + /// + /// + /// This listener has been closed. + /// + public void Start () + { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + lock (_contextRegistrySync) { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + if (_listening) + return; + + EndPointManager.AddListener (this); + + _listening = true; + } + } + + /// + /// Stops receiving incoming requests. + /// + /// + /// This listener has been closed. + /// + public void Stop () + { + if (_disposed) + throw new ObjectDisposedException (_objectName); + + lock (_contextRegistrySync) { + if (!_listening) + return; + + _listening = false; + + cleanupContextQueue (false); + cleanupContextRegistry (); + + var msg = "The listener is stopped."; + cleanupWaitQueue (msg); + + EndPointManager.RemoveListener (this); + } + } + + #endregion + + #region Explicit Interface Implementations + + /// + /// Releases all resources used by the listener. + /// + void IDisposable.Dispose () + { + if (_disposed) + return; + + lock (_contextRegistrySync) { + if (_disposed) + return; + + close (true); + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListener.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListener.cs.meta new file mode 100644 index 00000000..a95750db --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 965e8e05ed542436ab4e04de0d7ae923 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerAsyncResult.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerAsyncResult.cs new file mode 100644 index 00000000..abd9e1ae --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerAsyncResult.cs @@ -0,0 +1,193 @@ +#region License +/* + * HttpListenerAsyncResult.cs + * + * This code is derived from ListenerAsyncResult.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Ximian, Inc. (http://www.ximian.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Nicholas Devenish + */ +#endregion + +using System; +using System.Threading; + +namespace WebSocketSharp.Net +{ + internal class HttpListenerAsyncResult : IAsyncResult + { + #region Private Fields + + private AsyncCallback _callback; + private bool _completed; + private bool _completedSynchronously; + private HttpListenerContext _context; + private bool _endCalled; + private Exception _exception; + private object _state; + private object _sync; + private ManualResetEvent _waitHandle; + + #endregion + + #region Internal Constructors + + internal HttpListenerAsyncResult (AsyncCallback callback, object state) + { + _callback = callback; + _state = state; + + _sync = new object (); + } + + #endregion + + #region Internal Properties + + internal HttpListenerContext Context + { + get { + if (_exception != null) + throw _exception; + + return _context; + } + } + + internal bool EndCalled { + get { + return _endCalled; + } + + set { + _endCalled = value; + } + } + + internal object SyncRoot { + get { + return _sync; + } + } + + #endregion + + #region Public Properties + + public object AsyncState { + get { + return _state; + } + } + + public WaitHandle AsyncWaitHandle { + get { + lock (_sync) { + if (_waitHandle == null) + _waitHandle = new ManualResetEvent (_completed); + + return _waitHandle; + } + } + } + + public bool CompletedSynchronously { + get { + return _completedSynchronously; + } + } + + public bool IsCompleted { + get { + lock (_sync) + return _completed; + } + } + + #endregion + + #region Private Methods + + private void complete () + { + lock (_sync) { + _completed = true; + + if (_waitHandle != null) + _waitHandle.Set (); + } + + if (_callback == null) + return; + + ThreadPool.QueueUserWorkItem ( + state => { + try { + _callback (this); + } + catch { + } + }, + null + ); + } + + #endregion + + #region Internal Methods + + internal void Complete (Exception exception) + { + _exception = exception; + + complete (); + } + + internal void Complete ( + HttpListenerContext context, bool completedSynchronously + ) + { + _context = context; + _completedSynchronously = completedSynchronously; + + complete (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerAsyncResult.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerAsyncResult.cs.meta new file mode 100644 index 00000000..21a2167d --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerAsyncResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae58f14baea2e45aead7076446b071e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerContext.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerContext.cs new file mode 100644 index 00000000..6488a978 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerContext.cs @@ -0,0 +1,311 @@ +#region License +/* + * HttpListenerContext.cs + * + * This code is derived from HttpListenerContext.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.Security.Principal; +using System.Text; +using WebSocketSharp.Net.WebSockets; + +namespace WebSocketSharp.Net +{ + /// + /// Provides the access to the HTTP request and response objects used by + /// the class. + /// + /// + /// This class cannot be inherited. + /// + public sealed class HttpListenerContext + { + #region Private Fields + + private HttpConnection _connection; + private string _errorMessage; + private int _errorStatusCode; + private HttpListener _listener; + private HttpListenerRequest _request; + private HttpListenerResponse _response; + private IPrincipal _user; + private HttpListenerWebSocketContext _websocketContext; + + #endregion + + #region Internal Constructors + + internal HttpListenerContext (HttpConnection connection) + { + _connection = connection; + + _errorStatusCode = 400; + _request = new HttpListenerRequest (this); + _response = new HttpListenerResponse (this); + } + + #endregion + + #region Internal Properties + + internal HttpConnection Connection { + get { + return _connection; + } + } + + internal string ErrorMessage { + get { + return _errorMessage; + } + + set { + _errorMessage = value; + } + } + + internal int ErrorStatusCode { + get { + return _errorStatusCode; + } + + set { + _errorStatusCode = value; + } + } + + internal bool HasErrorMessage { + get { + return _errorMessage != null; + } + } + + internal HttpListener Listener { + get { + return _listener; + } + + set { + _listener = value; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the HTTP request object that represents a client request. + /// + /// + /// A that represents the client request. + /// + public HttpListenerRequest Request { + get { + return _request; + } + } + + /// + /// Gets the HTTP response object used to send a response to the client. + /// + /// + /// A that represents a response to + /// the client request. + /// + public HttpListenerResponse Response { + get { + return _response; + } + } + + /// + /// Gets the client information (identity, authentication, and security + /// roles). + /// + /// + /// + /// A instance or + /// if not authenticated. + /// + /// + /// The instance describes the client. + /// + /// + public IPrincipal User { + get { + return _user; + } + + internal set { + _user = value; + } + } + + #endregion + + #region Private Methods + + private static string createErrorContent ( + int statusCode, string statusDescription, string message + ) + { + return message != null && message.Length > 0 + ? String.Format ( + "

{0} {1} ({2})

", + statusCode, + statusDescription, + message + ) + : String.Format ( + "

{0} {1}

", + statusCode, + statusDescription + ); + } + + #endregion + + #region Internal Methods + + internal HttpListenerWebSocketContext GetWebSocketContext (string protocol) + { + _websocketContext = new HttpListenerWebSocketContext (this, protocol); + + return _websocketContext; + } + + internal void SendAuthenticationChallenge ( + AuthenticationSchemes scheme, string realm + ) + { + var chal = new AuthenticationChallenge (scheme, realm).ToString (); + + _response.StatusCode = 401; + _response.Headers.InternalSet ("WWW-Authenticate", chal, true); + + _response.Close (); + } + + internal void SendError () + { + try { + _response.StatusCode = _errorStatusCode; + _response.ContentType = "text/html"; + + var content = createErrorContent ( + _errorStatusCode, + _response.StatusDescription, + _errorMessage + ); + + var enc = Encoding.UTF8; + var entity = enc.GetBytes (content); + _response.ContentEncoding = enc; + _response.ContentLength64 = entity.LongLength; + + _response.Close (entity, true); + } + catch { + _connection.Close (true); + } + } + + internal void Unregister () + { + if (_listener == null) + return; + + _listener.UnregisterContext (this); + } + + #endregion + + #region Public Methods + + /// + /// Accepts a WebSocket handshake request. + /// + /// + /// A that represents + /// the WebSocket handshake request. + /// + /// + /// A that specifies the subprotocol supported on + /// the WebSocket connection. + /// + /// + /// + /// is empty. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// + /// This method has already been called. + /// + public HttpListenerWebSocketContext AcceptWebSocket (string protocol) + { + if (_websocketContext != null) { + var msg = "The accepting is already in progress."; + + throw new InvalidOperationException (msg); + } + + if (protocol != null) { + if (protocol.Length == 0) { + var msg = "An empty string."; + + throw new ArgumentException (msg, "protocol"); + } + + if (!protocol.IsToken ()) { + var msg = "It contains an invalid character."; + + throw new ArgumentException (msg, "protocol"); + } + } + + return GetWebSocketContext (protocol); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerContext.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerContext.cs.meta new file mode 100644 index 00000000..7bdb759c --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d3e4e208a399486a93c779183ee4660 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerException.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerException.cs new file mode 100644 index 00000000..64b7c1d8 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerException.cs @@ -0,0 +1,137 @@ +#region License +/* + * HttpListenerException.cs + * + * This code is derived from HttpListenerException.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.ComponentModel; +using System.Runtime.Serialization; + +namespace WebSocketSharp.Net +{ + /// + /// The exception that is thrown when an error occurs processing + /// an HTTP request. + /// + [Serializable] + public class HttpListenerException : Win32Exception + { + #region Protected Constructors + + /// + /// Initializes a new instance of the + /// class from the specified instances of the + /// and classes. + /// + /// + /// A that contains the serialized + /// object data. + /// + /// + /// A that specifies the source for + /// the deserialization. + /// + protected HttpListenerException ( + SerializationInfo serializationInfo, StreamingContext streamingContext + ) + : base (serializationInfo, streamingContext) + { + } + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the + /// class. + /// + public HttpListenerException () + { + } + + /// + /// Initializes a new instance of the + /// class with the specified error code. + /// + /// + /// An that specifies the error code. + /// + public HttpListenerException (int errorCode) + : base (errorCode) + { + } + + /// + /// Initializes a new instance of the + /// class with the specified error code and message. + /// + /// + /// An that specifies the error code. + /// + /// + /// A that specifies the message. + /// + public HttpListenerException (int errorCode, string message) + : base (errorCode, message) + { + } + + #endregion + + #region Public Properties + + /// + /// Gets the error code that identifies the error that occurred. + /// + /// + /// + /// An that represents the error code. + /// + /// + /// It is any of the Win32 error codes. + /// + /// + public override int ErrorCode { + get { + return NativeErrorCode; + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerException.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerException.cs.meta new file mode 100644 index 00000000..9cf6096f --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f2a0a86a16854eca85e7c70bf612815 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefix.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefix.cs new file mode 100644 index 00000000..3c9b0f8a --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefix.cs @@ -0,0 +1,273 @@ +#region License +/* + * HttpListenerPrefix.cs + * + * This code is derived from ListenerPrefix.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + * - Oleg Mihailik + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + internal sealed class HttpListenerPrefix + { + #region Private Fields + + private string _host; + private HttpListener _listener; + private string _original; + private string _path; + private string _port; + private string _prefix; + private bool _secure; + + #endregion + + #region Internal Constructors + + /// + /// Initializes a new instance of the class + /// with the specified URI prefix and HTTP listener. + /// + /// + /// This constructor must be called after calling the CheckPrefix method. + /// + /// + /// A that specifies the URI prefix. + /// + /// + /// A that specifies the HTTP listener. + /// + internal HttpListenerPrefix (string uriPrefix, HttpListener listener) + { + _original = uriPrefix; + _listener = listener; + + parse (uriPrefix); + } + + #endregion + + #region Public Properties + + public string Host { + get { + return _host; + } + } + + public bool IsSecure { + get { + return _secure; + } + } + + public HttpListener Listener { + get { + return _listener; + } + } + + public string Original { + get { + return _original; + } + } + + public string Path { + get { + return _path; + } + } + + public string Port { + get { + return _port; + } + } + + #endregion + + #region Private Methods + + private void parse (string uriPrefix) + { + if (uriPrefix.StartsWith ("https")) + _secure = true; + + var len = uriPrefix.Length; + var host = uriPrefix.IndexOf (':') + 3; + var root = uriPrefix.IndexOf ('/', host + 1, len - host - 1); + + var colon = uriPrefix.LastIndexOf (':', root - 1, root - host - 1); + + if (uriPrefix[root - 1] != ']' && colon > host) { + _host = uriPrefix.Substring (host, colon - host); + _port = uriPrefix.Substring (colon + 1, root - colon - 1); + } + else { + _host = uriPrefix.Substring (host, root - host); + _port = _secure ? "443" : "80"; + } + + _path = uriPrefix.Substring (root); + + _prefix = String.Format ( + "{0}://{1}:{2}{3}", + _secure ? "https" : "http", + _host, + _port, + _path + ); + } + + #endregion + + #region Public Methods + + public static void CheckPrefix (string uriPrefix) + { + if (uriPrefix == null) + throw new ArgumentNullException ("uriPrefix"); + + var len = uriPrefix.Length; + + if (len == 0) { + var msg = "An empty string."; + + throw new ArgumentException (msg, "uriPrefix"); + } + + var schm = uriPrefix.StartsWith ("http://") + || uriPrefix.StartsWith ("https://"); + + if (!schm) { + var msg = "The scheme is not 'http' or 'https'."; + + throw new ArgumentException (msg, "uriPrefix"); + } + + var end = len - 1; + + if (uriPrefix[end] != '/') { + var msg = "It ends without '/'."; + + throw new ArgumentException (msg, "uriPrefix"); + } + + var host = uriPrefix.IndexOf (':') + 3; + + if (host >= end) { + var msg = "No host is specified."; + + throw new ArgumentException (msg, "uriPrefix"); + } + + if (uriPrefix[host] == ':') { + var msg = "No host is specified."; + + throw new ArgumentException (msg, "uriPrefix"); + } + + var root = uriPrefix.IndexOf ('/', host, len - host); + + if (root == host) { + var msg = "No host is specified."; + + throw new ArgumentException (msg, "uriPrefix"); + } + + if (uriPrefix[root - 1] == ':') { + var msg = "No port is specified."; + + throw new ArgumentException (msg, "uriPrefix"); + } + + if (root == end - 1) { + var msg = "No path is specified."; + + throw new ArgumentException (msg, "uriPrefix"); + } + } + + /// + /// Determines whether the current instance is equal to the specified + /// instance. + /// + /// + /// This method will be required to detect duplicates in any collection. + /// + /// + /// + /// An instance to compare to the current instance. + /// + /// + /// An reference to a instance. + /// + /// + /// + /// true if the current instance and have + /// the same URI prefix; otherwise, false. + /// + public override bool Equals (object obj) + { + var pref = obj as HttpListenerPrefix; + + return pref != null && _prefix.Equals (pref._prefix); + } + + /// + /// Gets the hash code for the current instance. + /// + /// + /// This method will be required to detect duplicates in any collection. + /// + /// + /// An that represents the hash code. + /// + public override int GetHashCode () + { + return _prefix.GetHashCode (); + } + + public override string ToString () + { + return _prefix; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefix.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefix.cs.meta new file mode 100644 index 00000000..643aa333 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefix.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a9d49cda59c74bb69c94e3236e7903f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefixCollection.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefixCollection.cs new file mode 100644 index 00000000..cbe062ee --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefixCollection.cs @@ -0,0 +1,294 @@ +#region License +/* + * HttpListenerPrefixCollection.cs + * + * This code is derived from HttpListenerPrefixCollection.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace WebSocketSharp.Net +{ + /// + /// Provides a collection used to store the URI prefixes for a instance of + /// the class. + /// + /// + /// The instance responds to the request which has + /// a requested URI that the prefixes most closely match. + /// + public class HttpListenerPrefixCollection : ICollection + { + #region Private Fields + + private HttpListener _listener; + private List _prefixes; + + #endregion + + #region Internal Constructors + + internal HttpListenerPrefixCollection (HttpListener listener) + { + _listener = listener; + _prefixes = new List (); + } + + #endregion + + #region Public Properties + + /// + /// Gets the number of prefixes in the collection. + /// + /// + /// An that represents the number of prefixes. + /// + public int Count { + get { + return _prefixes.Count; + } + } + + /// + /// Gets a value indicating whether the access to the collection is + /// read-only. + /// + /// + /// Always returns false. + /// + public bool IsReadOnly { + get { + return false; + } + } + + /// + /// Gets a value indicating whether the access to the collection is + /// synchronized. + /// + /// + /// Always returns false. + /// + public bool IsSynchronized { + get { + return false; + } + } + + #endregion + + #region Public Methods + + /// + /// Adds the specified URI prefix to the collection. + /// + /// + /// + /// A that specifies the URI prefix to add. + /// + /// + /// It must be a well-formed URI prefix with http or https scheme, + /// and must end with a '/'. + /// + /// + /// + /// is . + /// + /// + /// is invalid. + /// + /// + /// The instance associated with this + /// collection is closed. + /// + public void Add (string uriPrefix) + { + _listener.CheckDisposed (); + + HttpListenerPrefix.CheckPrefix (uriPrefix); + + if (_prefixes.Contains (uriPrefix)) + return; + + if (_listener.IsListening) + EndPointManager.AddPrefix (uriPrefix, _listener); + + _prefixes.Add (uriPrefix); + } + + /// + /// Removes all URI prefixes from the collection. + /// + /// + /// The instance associated with this + /// collection is closed. + /// + public void Clear () + { + _listener.CheckDisposed (); + + if (_listener.IsListening) + EndPointManager.RemoveListener (_listener); + + _prefixes.Clear (); + } + + /// + /// Returns a value indicating whether the collection contains the + /// specified URI prefix. + /// + /// + /// true if the collection contains the URI prefix; otherwise, + /// false. + /// + /// + /// A that specifies the URI prefix to test. + /// + /// + /// is . + /// + /// + /// The instance associated with this + /// collection is closed. + /// + public bool Contains (string uriPrefix) + { + _listener.CheckDisposed (); + + if (uriPrefix == null) + throw new ArgumentNullException ("uriPrefix"); + + return _prefixes.Contains (uriPrefix); + } + + /// + /// Copies the contents of the collection to the specified array of string. + /// + /// + /// An array of that specifies the destination of + /// the URI prefix strings copied from the collection. + /// + /// + /// An that specifies the zero-based index in + /// the array at which copying begins. + /// + /// + /// is . + /// + /// + /// is less than zero. + /// + /// + /// The space from to the end of + /// is not enough to copy to. + /// + /// + /// The instance associated with this + /// collection is closed. + /// + public void CopyTo (string[] array, int offset) + { + _listener.CheckDisposed (); + + _prefixes.CopyTo (array, offset); + } + + /// + /// Gets the enumerator that iterates through the collection. + /// + /// + /// An + /// instance that can be used to iterate through the collection. + /// + public IEnumerator GetEnumerator () + { + return _prefixes.GetEnumerator (); + } + + /// + /// Removes the specified URI prefix from the collection. + /// + /// + /// true if the URI prefix is successfully removed; otherwise, + /// false. + /// + /// + /// A that specifies the URI prefix to remove. + /// + /// + /// is . + /// + /// + /// The instance associated with this + /// collection is closed. + /// + public bool Remove (string uriPrefix) + { + _listener.CheckDisposed (); + + if (uriPrefix == null) + throw new ArgumentNullException ("uriPrefix"); + + if (!_prefixes.Contains (uriPrefix)) + return false; + + if (_listener.IsListening) + EndPointManager.RemovePrefix (uriPrefix, _listener); + + return _prefixes.Remove (uriPrefix); + } + + #endregion + + #region Explicit Interface Implementations + + /// + /// Gets the enumerator that iterates through the collection. + /// + /// + /// An instance that can be used to iterate + /// through the collection. + /// + IEnumerator IEnumerable.GetEnumerator () + { + return _prefixes.GetEnumerator (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefixCollection.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefixCollection.cs.meta new file mode 100644 index 00000000..ba2d55c7 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerPrefixCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fdcaacae9f5f498b9cbf1981895f7f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerRequest.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerRequest.cs new file mode 100644 index 00000000..fec36551 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerRequest.cs @@ -0,0 +1,928 @@ +#region License +/* + * HttpListenerRequest.cs + * + * This code is derived from HttpListenerRequest.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Globalization; +using System.IO; +using System.Security.Cryptography.X509Certificates; +using System.Text; + +namespace WebSocketSharp.Net +{ + /// + /// Represents an incoming HTTP request to a + /// instance. + /// + /// + /// This class cannot be inherited. + /// + public sealed class HttpListenerRequest + { + #region Private Fields + + private static readonly byte[] _100continue; + private string[] _acceptTypes; + private bool _chunked; + private HttpConnection _connection; + private Encoding _contentEncoding; + private long _contentLength; + private HttpListenerContext _context; + private CookieCollection _cookies; + private WebHeaderCollection _headers; + private string _httpMethod; + private Stream _inputStream; + private Version _protocolVersion; + private NameValueCollection _queryString; + private string _rawUrl; + private Guid _requestTraceIdentifier; + private Uri _url; + private Uri _urlReferrer; + private bool _urlSet; + private string _userHostName; + private string[] _userLanguages; + + #endregion + + #region Static Constructor + + static HttpListenerRequest () + { + _100continue = Encoding.ASCII.GetBytes ("HTTP/1.1 100 Continue\r\n\r\n"); + } + + #endregion + + #region Internal Constructors + + internal HttpListenerRequest (HttpListenerContext context) + { + _context = context; + + _connection = context.Connection; + _contentLength = -1; + _headers = new WebHeaderCollection (); + _requestTraceIdentifier = Guid.NewGuid (); + } + + #endregion + + #region Public Properties + + /// + /// Gets the media types that are acceptable for the client. + /// + /// + /// + /// An array of that contains the names of the media + /// types specified in the value of the Accept header. + /// + /// + /// if the header is not present. + /// + /// + public string[] AcceptTypes { + get { + var val = _headers["Accept"]; + + if (val == null) + return null; + + if (_acceptTypes == null) { + _acceptTypes = val + .SplitHeaderValue (',') + .TrimEach () + .ToList () + .ToArray (); + } + + return _acceptTypes; + } + } + + /// + /// Gets an error code that identifies a problem with the certificate + /// provided by the client. + /// + /// + /// An that represents an error code. + /// + /// + /// This property is not supported. + /// + public int ClientCertificateError { + get { + throw new NotSupportedException (); + } + } + + /// + /// Gets the encoding for the entity body data included in the request. + /// + /// + /// + /// A converted from the charset value of the + /// Content-Type header. + /// + /// + /// if the charset value is not available. + /// + /// + public Encoding ContentEncoding { + get { + if (_contentEncoding == null) + _contentEncoding = getContentEncoding (); + + return _contentEncoding; + } + } + + /// + /// Gets the length in bytes of the entity body data included in the + /// request. + /// + /// + /// + /// A converted from the value of the Content-Length + /// header. + /// + /// + /// -1 if the header is not present. + /// + /// + public long ContentLength64 { + get { + return _contentLength; + } + } + + /// + /// Gets the media type of the entity body data included in the request. + /// + /// + /// + /// A that represents the value of the Content-Type + /// header. + /// + /// + /// if the header is not present. + /// + /// + public string ContentType { + get { + return _headers["Content-Type"]; + } + } + + /// + /// Gets the cookies included in the request. + /// + /// + /// + /// A that contains the cookies. + /// + /// + /// An empty collection if not included. + /// + /// + public CookieCollection Cookies { + get { + if (_cookies == null) + _cookies = _headers.GetCookies (false); + + return _cookies; + } + } + + /// + /// Gets a value indicating whether the request has the entity body data. + /// + /// + /// true if the request has the entity body data; otherwise, + /// false. + /// + public bool HasEntityBody { + get { + return _contentLength > 0 || _chunked; + } + } + + /// + /// Gets the headers included in the request. + /// + /// + /// A that contains the headers. + /// + public NameValueCollection Headers { + get { + return _headers; + } + } + + /// + /// Gets the HTTP method specified by the client. + /// + /// + /// A that represents the HTTP method specified in + /// the request line. + /// + public string HttpMethod { + get { + return _httpMethod; + } + } + + /// + /// Gets a stream that contains the entity body data included in + /// the request. + /// + /// + /// + /// A that contains the entity body data. + /// + /// + /// if the entity body data is not available. + /// + /// + public Stream InputStream { + get { + if (_inputStream == null) { + _inputStream = _contentLength > 0 || _chunked + ? _connection + .GetRequestStream (_contentLength, _chunked) + : Stream.Null; + } + + return _inputStream; + } + } + + /// + /// Gets a value indicating whether the client is authenticated. + /// + /// + /// true if the client is authenticated; otherwise, false. + /// + public bool IsAuthenticated { + get { + return _context.User != null; + } + } + + /// + /// Gets a value indicating whether the request is sent from the local + /// computer. + /// + /// + /// true if the request is sent from the same computer as the server; + /// otherwise, false. + /// + public bool IsLocal { + get { + return _connection.IsLocal; + } + } + + /// + /// Gets a value indicating whether a secure connection is used to send + /// the request. + /// + /// + /// true if the connection is secure; otherwise, false. + /// + public bool IsSecureConnection { + get { + return _connection.IsSecure; + } + } + + /// + /// Gets a value indicating whether the request is a WebSocket handshake + /// request. + /// + /// + /// true if the request is a WebSocket handshake request; otherwise, + /// false. + /// + public bool IsWebSocketRequest { + get { + return _httpMethod == "GET" && _headers.Upgrades ("websocket"); + } + } + + /// + /// Gets a value indicating whether a persistent connection is requested. + /// + /// + /// true if the request specifies that the connection is kept open; + /// otherwise, false. + /// + public bool KeepAlive { + get { + return _headers.KeepsAlive (_protocolVersion); + } + } + + /// + /// Gets the endpoint to which the request is sent. + /// + /// + /// A that represents the server IP + /// address and port number. + /// + public System.Net.IPEndPoint LocalEndPoint { + get { + return _connection.LocalEndPoint; + } + } + + /// + /// Gets the HTTP version specified by the client. + /// + /// + /// A that represents the HTTP version specified in + /// the request line. + /// + public Version ProtocolVersion { + get { + return _protocolVersion; + } + } + + /// + /// Gets the query string included in the request. + /// + /// + /// + /// A that contains the query + /// parameters. + /// + /// + /// An empty collection if not included. + /// + /// + public NameValueCollection QueryString { + get { + if (_queryString == null) { + var url = Url; + + _queryString = QueryStringCollection + .Parse ( + url != null ? url.Query : null, + Encoding.UTF8 + ); + } + + return _queryString; + } + } + + /// + /// Gets the raw URL specified by the client. + /// + /// + /// A that represents the request target specified in + /// the request line. + /// + public string RawUrl { + get { + return _rawUrl; + } + } + + /// + /// Gets the endpoint from which the request is sent. + /// + /// + /// A that represents the client IP + /// address and port number. + /// + public System.Net.IPEndPoint RemoteEndPoint { + get { + return _connection.RemoteEndPoint; + } + } + + /// + /// Gets the trace identifier of the request. + /// + /// + /// A that represents the trace identifier. + /// + public Guid RequestTraceIdentifier { + get { + return _requestTraceIdentifier; + } + } + + /// + /// Gets the URL requested by the client. + /// + /// + /// + /// A that represents the URL parsed from the request. + /// + /// + /// if the URL cannot be parsed. + /// + /// + public Uri Url { + get { + if (!_urlSet) { + _url = HttpUtility + .CreateRequestUrl ( + _rawUrl, + _userHostName ?? UserHostAddress, + IsWebSocketRequest, + IsSecureConnection + ); + + _urlSet = true; + } + + return _url; + } + } + + /// + /// Gets the URI of the resource from which the requested URL was obtained. + /// + /// + /// + /// A converted from the value of the Referer header. + /// + /// + /// if the header value is not available. + /// + /// + public Uri UrlReferrer { + get { + var val = _headers["Referer"]; + + if (val == null) + return null; + + if (_urlReferrer == null) + _urlReferrer = val.ToUri (); + + return _urlReferrer; + } + } + + /// + /// Gets the user agent from which the request is originated. + /// + /// + /// + /// A that represents the value of the User-Agent + /// header. + /// + /// + /// if the header is not present. + /// + /// + public string UserAgent { + get { + return _headers["User-Agent"]; + } + } + + /// + /// Gets the IP address and port number to which the request is sent. + /// + /// + /// A that represents the server IP address and port + /// number. + /// + public string UserHostAddress { + get { + return _connection.LocalEndPoint.ToString (); + } + } + + /// + /// Gets the server host name requested by the client. + /// + /// + /// + /// A that represents the value of the Host header. + /// + /// + /// It includes the port number if provided. + /// + /// + /// if the header is not present. + /// + /// + public string UserHostName { + get { + return _userHostName; + } + } + + /// + /// Gets the natural languages that are acceptable for the client. + /// + /// + /// + /// An array of that contains the names of the + /// natural languages specified in the value of the Accept-Language + /// header. + /// + /// + /// if the header is not present. + /// + /// + public string[] UserLanguages { + get { + var val = _headers["Accept-Language"]; + + if (val == null) + return null; + + if (_userLanguages == null) + _userLanguages = val.Split (',').TrimEach ().ToList ().ToArray (); + + return _userLanguages; + } + } + + #endregion + + #region Private Methods + + private Encoding getContentEncoding () + { + var val = _headers["Content-Type"]; + + if (val == null) + return Encoding.UTF8; + + Encoding ret; + + return HttpUtility.TryGetEncoding (val, out ret) + ? ret + : Encoding.UTF8; + } + + #endregion + + #region Internal Methods + + internal void AddHeader (string headerField) + { + var start = headerField[0]; + + if (start == ' ' || start == '\t') { + _context.ErrorMessage = "Invalid header field"; + + return; + } + + var colon = headerField.IndexOf (':'); + + if (colon < 1) { + _context.ErrorMessage = "Invalid header field"; + + return; + } + + var name = headerField.Substring (0, colon).Trim (); + + if (name.Length == 0 || !name.IsToken ()) { + _context.ErrorMessage = "Invalid header name"; + + return; + } + + var val = colon < headerField.Length - 1 + ? headerField.Substring (colon + 1).Trim () + : String.Empty; + + _headers.InternalSet (name, val, false); + + var lower = name.ToLower (CultureInfo.InvariantCulture); + + if (lower == "host") { + if (_userHostName != null) { + _context.ErrorMessage = "Invalid Host header"; + + return; + } + + if (val.Length == 0) { + _context.ErrorMessage = "Invalid Host header"; + + return; + } + + _userHostName = val; + + return; + } + + if (lower == "content-length") { + if (_contentLength > -1) { + _context.ErrorMessage = "Invalid Content-Length header"; + + return; + } + + long len; + + if (!Int64.TryParse (val, out len)) { + _context.ErrorMessage = "Invalid Content-Length header"; + + return; + } + + if (len < 0) { + _context.ErrorMessage = "Invalid Content-Length header"; + + return; + } + + _contentLength = len; + + return; + } + } + + internal void FinishInitialization () + { + if (_userHostName == null) { + _context.ErrorMessage = "Host header required"; + + return; + } + + var transferEnc = _headers["Transfer-Encoding"]; + + if (transferEnc != null) { + var comparison = StringComparison.OrdinalIgnoreCase; + + if (!transferEnc.Equals ("chunked", comparison)) { + _context.ErrorMessage = "Invalid Transfer-Encoding header"; + _context.ErrorStatusCode = 501; + + return; + } + + _chunked = true; + } + + if (_httpMethod == "POST" || _httpMethod == "PUT") { + if (_contentLength <= 0 && !_chunked) { + _context.ErrorMessage = String.Empty; + _context.ErrorStatusCode = 411; + + return; + } + } + + var expect = _headers["Expect"]; + + if (expect != null) { + var comparison = StringComparison.OrdinalIgnoreCase; + + if (!expect.Equals ("100-continue", comparison)) { + _context.ErrorMessage = "Invalid Expect header"; + + return; + } + + var output = _connection.GetResponseStream (); + output.InternalWrite (_100continue, 0, _100continue.Length); + } + } + + internal bool FlushInput () + { + var input = InputStream; + + if (input == Stream.Null) + return true; + + var len = 2048; + + if (_contentLength > 0 && _contentLength < len) + len = (int) _contentLength; + + var buff = new byte[len]; + + while (true) { + try { + var ares = input.BeginRead (buff, 0, len, null, null); + + if (!ares.IsCompleted) { + var timeout = 100; + + if (!ares.AsyncWaitHandle.WaitOne (timeout)) + return false; + } + + if (input.EndRead (ares) <= 0) + return true; + } + catch { + return false; + } + } + } + + internal bool IsUpgradeRequest (string protocol) + { + return _headers.Upgrades (protocol); + } + + internal void SetRequestLine (string requestLine) + { + var parts = requestLine.Split (new[] { ' ' }, 3); + + if (parts.Length < 3) { + _context.ErrorMessage = "Invalid request line (parts)"; + + return; + } + + var method = parts[0]; + + if (method.Length == 0) { + _context.ErrorMessage = "Invalid request line (method)"; + + return; + } + + var target = parts[1]; + + if (target.Length == 0) { + _context.ErrorMessage = "Invalid request line (target)"; + + return; + } + + var rawVer = parts[2]; + + if (rawVer.Length != 8) { + _context.ErrorMessage = "Invalid request line (version)"; + + return; + } + + if (!rawVer.StartsWith ("HTTP/", StringComparison.Ordinal)) { + _context.ErrorMessage = "Invalid request line (version)"; + + return; + } + + Version ver; + + if (!rawVer.Substring (5).TryCreateVersion (out ver)) { + _context.ErrorMessage = "Invalid request line (version)"; + + return; + } + + if (ver != HttpVersion.Version11) { + _context.ErrorMessage = "Invalid request line (version)"; + _context.ErrorStatusCode = 505; + + return; + } + + if (!method.IsHttpMethod (ver)) { + _context.ErrorMessage = "Invalid request line (method)"; + _context.ErrorStatusCode = 501; + + return; + } + + _httpMethod = method; + _rawUrl = target; + _protocolVersion = ver; + } + + #endregion + + #region Public Methods + + /// + /// Begins getting the certificate provided by the client asynchronously. + /// + /// + /// An instance that indicates the status of the + /// operation. + /// + /// + /// An delegate that invokes the method called + /// when the operation is complete. + /// + /// + /// An that represents a user defined object to pass to + /// the callback delegate. + /// + /// + /// This method is not supported. + /// + public IAsyncResult BeginGetClientCertificate ( + AsyncCallback requestCallback, object state + ) + { + throw new NotSupportedException (); + } + + /// + /// Ends an asynchronous operation to get the certificate provided by the + /// client. + /// + /// + /// A that represents an X.509 certificate + /// provided by the client. + /// + /// + /// An instance returned when the operation + /// started. + /// + /// + /// This method is not supported. + /// + public X509Certificate2 EndGetClientCertificate (IAsyncResult asyncResult) + { + throw new NotSupportedException (); + } + + /// + /// Gets the certificate provided by the client. + /// + /// + /// A that represents an X.509 certificate + /// provided by the client. + /// + /// + /// This method is not supported. + /// + public X509Certificate2 GetClientCertificate () + { + throw new NotSupportedException (); + } + + /// + /// Returns a string that represents the current instance. + /// + /// + /// A that contains the request line and headers + /// included in the request. + /// + public override string ToString () + { + var buff = new StringBuilder (64); + + buff + .AppendFormat ( + "{0} {1} HTTP/{2}\r\n", _httpMethod, _rawUrl, _protocolVersion + ) + .Append (_headers.ToString ()); + + return buff.ToString (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerRequest.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerRequest.cs.meta new file mode 100644 index 00000000..ca846299 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4152bd66109234406b2609f2ccac9c7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerResponse.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerResponse.cs new file mode 100644 index 00000000..492f5102 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerResponse.cs @@ -0,0 +1,1199 @@ +#region License +/* + * HttpListenerResponse.cs + * + * This code is derived from HttpListenerResponse.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Nicholas Devenish + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; + +namespace WebSocketSharp.Net +{ + /// + /// Represents an HTTP response to an HTTP request received by + /// a instance. + /// + /// + /// This class cannot be inherited. + /// + public sealed class HttpListenerResponse : IDisposable + { + #region Private Fields + + private bool _closeConnection; + private Encoding _contentEncoding; + private long _contentLength; + private string _contentType; + private HttpListenerContext _context; + private CookieCollection _cookies; + private bool _disposed; + private WebHeaderCollection _headers; + private bool _headersSent; + private bool _keepAlive; + private ResponseStream _outputStream; + private Uri _redirectLocation; + private bool _sendChunked; + private int _statusCode; + private string _statusDescription; + private Version _version; + + #endregion + + #region Internal Constructors + + internal HttpListenerResponse (HttpListenerContext context) + { + _context = context; + _keepAlive = true; + _statusCode = 200; + _statusDescription = "OK"; + _version = HttpVersion.Version11; + } + + #endregion + + #region Internal Properties + + internal bool CloseConnection { + get { + return _closeConnection; + } + + set { + _closeConnection = value; + } + } + + internal WebHeaderCollection FullHeaders { + get { + var headers = new WebHeaderCollection (HttpHeaderType.Response, true); + + if (_headers != null) + headers.Add (_headers); + + if (_contentType != null) { + headers.InternalSet ( + "Content-Type", + createContentTypeHeaderText (_contentType, _contentEncoding), + true + ); + } + + if (headers["Server"] == null) + headers.InternalSet ("Server", "websocket-sharp/1.0", true); + + if (headers["Date"] == null) { + headers.InternalSet ( + "Date", + DateTime.UtcNow.ToString ("r", CultureInfo.InvariantCulture), + true + ); + } + + if (_sendChunked) { + headers.InternalSet ("Transfer-Encoding", "chunked", true); + } + else { + headers.InternalSet ( + "Content-Length", + _contentLength.ToString (CultureInfo.InvariantCulture), + true + ); + } + + /* + * Apache forces closing the connection for these status codes: + * - 400 Bad Request + * - 408 Request Timeout + * - 411 Length Required + * - 413 Request Entity Too Large + * - 414 Request-Uri Too Long + * - 500 Internal Server Error + * - 503 Service Unavailable + */ + var closeConn = !_context.Request.KeepAlive + || !_keepAlive + || _statusCode == 400 + || _statusCode == 408 + || _statusCode == 411 + || _statusCode == 413 + || _statusCode == 414 + || _statusCode == 500 + || _statusCode == 503; + + var reuses = _context.Connection.Reuses; + + if (closeConn || reuses >= 100) { + headers.InternalSet ("Connection", "close", true); + } + else { + headers.InternalSet ( + "Keep-Alive", + String.Format ("timeout=15,max={0}", 100 - reuses), + true + ); + + if (_context.Request.ProtocolVersion < HttpVersion.Version11) + headers.InternalSet ("Connection", "keep-alive", true); + } + + if (_redirectLocation != null) + headers.InternalSet ("Location", _redirectLocation.AbsoluteUri, true); + + if (_cookies != null) { + foreach (var cookie in _cookies) { + headers.InternalSet ( + "Set-Cookie", + cookie.ToResponseString (), + true + ); + } + } + + return headers; + } + } + + internal bool HeadersSent { + get { + return _headersSent; + } + + set { + _headersSent = value; + } + } + + internal string StatusLine { + get { + return String.Format ( + "HTTP/{0} {1} {2}\r\n", + _version, + _statusCode, + _statusDescription + ); + } + } + + #endregion + + #region Public Properties + + /// + /// Gets or sets the encoding for the entity body data included in + /// the response. + /// + /// + /// + /// A that represents the encoding for + /// the entity body data. + /// + /// + /// if no encoding is specified. + /// + /// + /// The default value is . + /// + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + public Encoding ContentEncoding { + get { + return _contentEncoding; + } + + set { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + _contentEncoding = value; + } + } + + /// + /// Gets or sets the number of bytes in the entity body data included in + /// the response. + /// + /// + /// + /// A that represents the number of bytes in + /// the entity body data. + /// + /// + /// It is used for the value of the Content-Length header. + /// + /// + /// The default value is zero. + /// + /// + /// + /// The value specified for a set operation is less than zero. + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + public long ContentLength64 { + get { + return _contentLength; + } + + set { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + if (value < 0) { + var msg = "Less than zero."; + throw new ArgumentOutOfRangeException (msg, "value"); + } + + _contentLength = value; + } + } + + /// + /// Gets or sets the media type of the entity body included in + /// the response. + /// + /// + /// + /// A that represents the media type of + /// the entity body. + /// + /// + /// It is used for the value of the Content-Type header. + /// + /// + /// if no media type is specified. + /// + /// + /// The default value is . + /// + /// + /// + /// + /// The value specified for a set operation is an empty string. + /// + /// + /// -or- + /// + /// + /// The value specified for a set operation contains + /// an invalid character. + /// + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + public string ContentType { + get { + return _contentType; + } + + set { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + if (value == null) { + _contentType = null; + return; + } + + if (value.Length == 0) { + var msg = "An empty string."; + throw new ArgumentException (msg, "value"); + } + + if (!isValidForContentType (value)) { + var msg = "It contains an invalid character."; + throw new ArgumentException (msg, "value"); + } + + _contentType = value; + } + } + + /// + /// Gets or sets the collection of cookies sent with the response. + /// + /// + /// A that contains the cookies sent with + /// the response. + /// + public CookieCollection Cookies { + get { + if (_cookies == null) + _cookies = new CookieCollection (); + + return _cookies; + } + + set { + _cookies = value; + } + } + + /// + /// Gets or sets the collection of the HTTP headers sent to the client. + /// + /// + /// A that contains the headers sent to + /// the client. + /// + /// + /// The value specified for a set operation is not valid for a response. + /// + public WebHeaderCollection Headers { + get { + if (_headers == null) + _headers = new WebHeaderCollection (HttpHeaderType.Response, false); + + return _headers; + } + + set { + if (value == null) { + _headers = null; + return; + } + + if (value.State != HttpHeaderType.Response) { + var msg = "The value is not valid for a response."; + throw new InvalidOperationException (msg); + } + + _headers = value; + } + } + + /// + /// Gets or sets a value indicating whether the server requests + /// a persistent connection. + /// + /// + /// + /// true if the server requests a persistent connection; + /// otherwise, false. + /// + /// + /// The default value is true. + /// + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + public bool KeepAlive { + get { + return _keepAlive; + } + + set { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + _keepAlive = value; + } + } + + /// + /// Gets a stream instance to which the entity body data can be written. + /// + /// + /// A instance to which the entity body data can be + /// written. + /// + /// + /// This instance is closed. + /// + public Stream OutputStream { + get { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_outputStream == null) + _outputStream = _context.Connection.GetResponseStream (); + + return _outputStream; + } + } + + /// + /// Gets the HTTP version used for the response. + /// + /// + /// + /// A that represents the HTTP version used for + /// the response. + /// + /// + /// Always returns same as 1.1. + /// + /// + public Version ProtocolVersion { + get { + return _version; + } + } + + /// + /// Gets or sets the URL to which the client is redirected to locate + /// a requested resource. + /// + /// + /// + /// A that represents the absolute URL for + /// the redirect location. + /// + /// + /// It is used for the value of the Location header. + /// + /// + /// if no redirect location is specified. + /// + /// + /// The default value is . + /// + /// + /// + /// + /// The value specified for a set operation is an empty string. + /// + /// + /// -or- + /// + /// + /// The value specified for a set operation is not an absolute URL. + /// + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + public string RedirectLocation { + get { + return _redirectLocation != null + ? _redirectLocation.OriginalString + : null; + } + + set { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + if (value == null) { + _redirectLocation = null; + return; + } + + if (value.Length == 0) { + var msg = "An empty string."; + throw new ArgumentException (msg, "value"); + } + + Uri uri; + if (!Uri.TryCreate (value, UriKind.Absolute, out uri)) { + var msg = "Not an absolute URL."; + throw new ArgumentException (msg, "value"); + } + + _redirectLocation = uri; + } + } + + /// + /// Gets or sets a value indicating whether the response uses the chunked + /// transfer encoding. + /// + /// + /// + /// true if the response uses the chunked transfer encoding; + /// otherwise, false. + /// + /// + /// The default value is false. + /// + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + public bool SendChunked { + get { + return _sendChunked; + } + + set { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + _sendChunked = value; + } + } + + /// + /// Gets or sets the HTTP status code returned to the client. + /// + /// + /// + /// An that represents the HTTP status code for + /// the response to the request. + /// + /// + /// The default value is 200. It indicates that the request has + /// succeeded. + /// + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + /// + /// + /// The value specified for a set operation is invalid. + /// + /// + /// Valid values are between 100 and 999 inclusive. + /// + /// + public int StatusCode { + get { + return _statusCode; + } + + set { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + if (value < 100 || value > 999) { + var msg = "A value is not between 100 and 999 inclusive."; + throw new System.Net.ProtocolViolationException (msg); + } + + _statusCode = value; + _statusDescription = value.GetStatusDescription (); + } + } + + /// + /// Gets or sets the description of the HTTP status code returned to + /// the client. + /// + /// + /// + /// A that represents the description of + /// the HTTP status code for the response to the request. + /// + /// + /// The default value is + /// the + /// RFC 2616 description for the + /// property value. + /// + /// + /// An empty string if an RFC 2616 description does not exist. + /// + /// + /// + /// The value specified for a set operation is . + /// + /// + /// The value specified for a set operation contains an invalid character. + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + public string StatusDescription { + get { + return _statusDescription; + } + + set { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + if (value == null) + throw new ArgumentNullException ("value"); + + if (value.Length == 0) { + _statusDescription = _statusCode.GetStatusDescription (); + return; + } + + if (!isValidForStatusDescription (value)) { + var msg = "It contains an invalid character."; + throw new ArgumentException (msg, "value"); + } + + _statusDescription = value; + } + } + + #endregion + + #region Private Methods + + private bool canSetCookie (Cookie cookie) + { + var found = findCookie (cookie).ToList (); + + if (found.Count == 0) + return true; + + var ver = cookie.Version; + + foreach (var c in found) { + if (c.Version == ver) + return true; + } + + return false; + } + + private void close (bool force) + { + _disposed = true; + _context.Connection.Close (force); + } + + private void close (byte[] responseEntity, int bufferLength, bool willBlock) + { + var stream = OutputStream; + + if (willBlock) { + stream.WriteBytes (responseEntity, bufferLength); + close (false); + + return; + } + + stream.WriteBytesAsync ( + responseEntity, + bufferLength, + () => close (false), + null + ); + } + + private static string createContentTypeHeaderText ( + string value, Encoding encoding + ) + { + if (value.IndexOf ("charset=", StringComparison.Ordinal) > -1) + return value; + + if (encoding == null) + return value; + + return String.Format ("{0}; charset={1}", value, encoding.WebName); + } + + private IEnumerable findCookie (Cookie cookie) + { + if (_cookies == null || _cookies.Count == 0) + yield break; + + foreach (var c in _cookies) { + if (c.EqualsWithoutValueAndVersion (cookie)) + yield return c; + } + } + + private static bool isValidForContentType (string value) + { + foreach (var c in value) { + if (c < 0x20) + return false; + + if (c > 0x7e) + return false; + + if ("()<>@:\\[]?{}".IndexOf (c) > -1) + return false; + } + + return true; + } + + private static bool isValidForStatusDescription (string value) + { + foreach (var c in value) { + if (c < 0x20) + return false; + + if (c > 0x7e) + return false; + } + + return true; + } + + #endregion + + #region Public Methods + + /// + /// Closes the connection to the client without sending a response. + /// + public void Abort () + { + if (_disposed) + return; + + close (true); + } + + /// + /// Appends the specified cookie to the cookies sent with the response. + /// + /// + /// A to append. + /// + /// + /// is . + /// + public void AppendCookie (Cookie cookie) + { + Cookies.Add (cookie); + } + + /// + /// Appends an HTTP header with the specified name and value to + /// the headers for the response. + /// + /// + /// A that specifies the name of the header to + /// append. + /// + /// + /// A that specifies the value of the header to + /// append. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is a string of spaces. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header name. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// The current headers do not allow the header. + /// + public void AppendHeader (string name, string value) + { + Headers.Add (name, value); + } + + /// + /// Sends the response to the client and releases the resources used by + /// this instance. + /// + public void Close () + { + if (_disposed) + return; + + close (false); + } + + /// + /// Sends the response with the specified entity body data to the client + /// and releases the resources used by this instance. + /// + /// + /// An array of that contains the entity body data. + /// + /// + /// A : true if this method blocks execution while + /// flushing the stream to the client; otherwise, false. + /// + /// + /// is . + /// + /// + /// This instance is closed. + /// + public void Close (byte[] responseEntity, bool willBlock) + { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (responseEntity == null) + throw new ArgumentNullException ("responseEntity"); + + var len = responseEntity.LongLength; + + if (len > Int32.MaxValue) { + close (responseEntity, 1024, willBlock); + return; + } + + var stream = OutputStream; + + if (willBlock) { + stream.Write (responseEntity, 0, (int) len); + close (false); + + return; + } + + stream.BeginWrite ( + responseEntity, + 0, + (int) len, + ar => { + stream.EndWrite (ar); + close (false); + }, + null + ); + } + + /// + /// Copies some properties from the specified response instance to + /// this instance. + /// + /// + /// A to copy. + /// + /// + /// is . + /// + public void CopyFrom (HttpListenerResponse templateResponse) + { + if (templateResponse == null) + throw new ArgumentNullException ("templateResponse"); + + var headers = templateResponse._headers; + + if (headers != null) { + if (_headers != null) + _headers.Clear (); + + Headers.Add (headers); + } + else { + _headers = null; + } + + _contentLength = templateResponse._contentLength; + _statusCode = templateResponse._statusCode; + _statusDescription = templateResponse._statusDescription; + _keepAlive = templateResponse._keepAlive; + _version = templateResponse._version; + } + + /// + /// Configures the response to redirect the client's request to + /// the specified URL. + /// + /// + /// This method sets the property to + /// , the property to + /// 302, and the property to "Found". + /// + /// + /// A that specifies the absolute URL to which + /// the client is redirected to locate a requested resource. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute URL. + /// + /// + /// + /// The response is already being sent. + /// + /// + /// This instance is closed. + /// + public void Redirect (string url) + { + if (_disposed) { + var name = GetType ().ToString (); + throw new ObjectDisposedException (name); + } + + if (_headersSent) { + var msg = "The response is already being sent."; + throw new InvalidOperationException (msg); + } + + if (url == null) + throw new ArgumentNullException ("url"); + + if (url.Length == 0) { + var msg = "An empty string."; + throw new ArgumentException (msg, "url"); + } + + Uri uri; + if (!Uri.TryCreate (url, UriKind.Absolute, out uri)) { + var msg = "Not an absolute URL."; + throw new ArgumentException (msg, "url"); + } + + _redirectLocation = uri; + _statusCode = 302; + _statusDescription = "Found"; + } + + /// + /// Adds or updates a cookie in the cookies sent with the response. + /// + /// + /// A to set. + /// + /// + /// is . + /// + /// + /// already exists in the cookies but + /// it cannot be updated. + /// + public void SetCookie (Cookie cookie) + { + if (cookie == null) + throw new ArgumentNullException ("cookie"); + + if (!canSetCookie (cookie)) { + var msg = "It cannot be updated."; + throw new ArgumentException (msg, "cookie"); + } + + Cookies.Add (cookie); + } + + /// + /// Adds or updates an HTTP header with the specified name and value in + /// the headers for the response. + /// + /// + /// A that specifies the name of the header to set. + /// + /// + /// A that specifies the value of the header to set. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is a string of spaces. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header name. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// The current headers do not allow the header. + /// + public void SetHeader (string name, string value) + { + Headers.Set (name, value); + } + + #endregion + + #region Explicit Interface Implementations + + /// + /// Releases all resources used by this instance. + /// + void IDisposable.Dispose () + { + if (_disposed) + return; + + close (true); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerResponse.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerResponse.cs.meta new file mode 100644 index 00000000..fcfbe326 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpListenerResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f92744d4af4546f19f0930bb4cd38cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpRequestHeader.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpRequestHeader.cs new file mode 100644 index 00000000..aab3497f --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpRequestHeader.cs @@ -0,0 +1,233 @@ +#region License +/* + * HttpRequestHeader.cs + * + * This code is derived from HttpRequestHeader.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2014-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +namespace WebSocketSharp.Net +{ + /// + /// Indicates the HTTP header that may be specified in a client request. + /// + /// + /// The headers of this enumeration are defined in + /// RFC 2616 or + /// RFC 6455. + /// + public enum HttpRequestHeader + { + /// + /// Indicates the Cache-Control header. + /// + CacheControl, + /// + /// Indicates the Connection header. + /// + Connection, + /// + /// Indicates the Date header. + /// + Date, + /// + /// Indicates the Keep-Alive header. + /// + KeepAlive, + /// + /// Indicates the Pragma header. + /// + Pragma, + /// + /// Indicates the Trailer header. + /// + Trailer, + /// + /// Indicates the Transfer-Encoding header. + /// + TransferEncoding, + /// + /// Indicates the Upgrade header. + /// + Upgrade, + /// + /// Indicates the Via header. + /// + Via, + /// + /// Indicates the Warning header. + /// + Warning, + /// + /// Indicates the Allow header. + /// + Allow, + /// + /// Indicates the Content-Length header. + /// + ContentLength, + /// + /// Indicates the Content-Type header. + /// + ContentType, + /// + /// Indicates the Content-Encoding header. + /// + ContentEncoding, + /// + /// Indicates the Content-Language header. + /// + ContentLanguage, + /// + /// Indicates the Content-Location header. + /// + ContentLocation, + /// + /// Indicates the Content-MD5 header. + /// + ContentMd5, + /// + /// Indicates the Content-Range header. + /// + ContentRange, + /// + /// Indicates the Expires header. + /// + Expires, + /// + /// Indicates the Last-Modified header. + /// + LastModified, + /// + /// Indicates the Accept header. + /// + Accept, + /// + /// Indicates the Accept-Charset header. + /// + AcceptCharset, + /// + /// Indicates the Accept-Encoding header. + /// + AcceptEncoding, + /// + /// Indicates the Accept-Language header. + /// + AcceptLanguage, + /// + /// Indicates the Authorization header. + /// + Authorization, + /// + /// Indicates the Cookie header. + /// + Cookie, + /// + /// Indicates the Expect header. + /// + Expect, + /// + /// Indicates the From header. + /// + From, + /// + /// Indicates the Host header. + /// + Host, + /// + /// Indicates the If-Match header. + /// + IfMatch, + /// + /// Indicates the If-Modified-Since header. + /// + IfModifiedSince, + /// + /// Indicates the If-None-Match header. + /// + IfNoneMatch, + /// + /// Indicates the If-Range header. + /// + IfRange, + /// + /// Indicates the If-Unmodified-Since header. + /// + IfUnmodifiedSince, + /// + /// Indicates the Max-Forwards header. + /// + MaxForwards, + /// + /// Indicates the Proxy-Authorization header. + /// + ProxyAuthorization, + /// + /// Indicates the Referer header. + /// + Referer, + /// + /// Indicates the Range header. + /// + Range, + /// + /// Indicates the TE header. + /// + Te, + /// + /// Indicates the Translate header. + /// + Translate, + /// + /// Indicates the User-Agent header. + /// + UserAgent, + /// + /// Indicates the Sec-WebSocket-Key header. + /// + SecWebSocketKey, + /// + /// Indicates the Sec-WebSocket-Extensions header. + /// + SecWebSocketExtensions, + /// + /// Indicates the Sec-WebSocket-Protocol header. + /// + SecWebSocketProtocol, + /// + /// Indicates the Sec-WebSocket-Version header. + /// + SecWebSocketVersion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpRequestHeader.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpRequestHeader.cs.meta new file mode 100644 index 00000000..cc33b6be --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpRequestHeader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5e6d947fca244897922a2f9e20769c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpResponseHeader.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpResponseHeader.cs new file mode 100644 index 00000000..d32afe6c --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpResponseHeader.cs @@ -0,0 +1,189 @@ +#region License +/* + * HttpResponseHeader.cs + * + * This code is derived from HttpResponseHeader.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2014-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +namespace WebSocketSharp.Net +{ + /// + /// Indicates the HTTP header that can be specified in a server response. + /// + /// + /// The headers of this enumeration are defined in + /// RFC 2616 or + /// RFC 6455. + /// + public enum HttpResponseHeader + { + /// + /// Indicates the Cache-Control header. + /// + CacheControl, + /// + /// Indicates the Connection header. + /// + Connection, + /// + /// Indicates the Date header. + /// + Date, + /// + /// Indicates the Keep-Alive header. + /// + KeepAlive, + /// + /// Indicates the Pragma header. + /// + Pragma, + /// + /// Indicates the Trailer header. + /// + Trailer, + /// + /// Indicates the Transfer-Encoding header. + /// + TransferEncoding, + /// + /// Indicates the Upgrade header. + /// + Upgrade, + /// + /// Indicates the Via header. + /// + Via, + /// + /// Indicates the Warning header. + /// + Warning, + /// + /// Indicates the Allow header. + /// + Allow, + /// + /// Indicates the Content-Length header. + /// + ContentLength, + /// + /// Indicates the Content-Type header. + /// + ContentType, + /// + /// Indicates the Content-Encoding header. + /// + ContentEncoding, + /// + /// Indicates the Content-Language header. + /// + ContentLanguage, + /// + /// Indicates the Content-Location header. + /// + ContentLocation, + /// + /// Indicates the Content-MD5 header. + /// + ContentMd5, + /// + /// Indicates the Content-Range header. + /// + ContentRange, + /// + /// Indicates the Expires header. + /// + Expires, + /// + /// Indicates the Last-Modified header. + /// + LastModified, + /// + /// Indicates the Accept-Ranges header. + /// + AcceptRanges, + /// + /// Indicates the Age header. + /// + Age, + /// + /// Indicates the ETag header. + /// + ETag, + /// + /// Indicates the Location header. + /// + Location, + /// + /// Indicates the Proxy-Authenticate header. + /// + ProxyAuthenticate, + /// + /// Indicates the Retry-After header. + /// + RetryAfter, + /// + /// Indicates the Server header. + /// + Server, + /// + /// Indicates the Set-Cookie header. + /// + SetCookie, + /// + /// Indicates the Vary header. + /// + Vary, + /// + /// Indicates the WWW-Authenticate header. + /// + WwwAuthenticate, + /// + /// Indicates the Sec-WebSocket-Extensions header. + /// + SecWebSocketExtensions, + /// + /// Indicates the Sec-WebSocket-Accept header. + /// + SecWebSocketAccept, + /// + /// Indicates the Sec-WebSocket-Protocol header. + /// + SecWebSocketProtocol, + /// + /// Indicates the Sec-WebSocket-Version header. + /// + SecWebSocketVersion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpResponseHeader.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpResponseHeader.cs.meta new file mode 100644 index 00000000..3ed43bf4 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpResponseHeader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80880eb10321348be85f59660b1f8cae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpStatusCode.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpStatusCode.cs new file mode 100644 index 00000000..b773a496 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpStatusCode.cs @@ -0,0 +1,346 @@ +#region License +/* + * HttpStatusCode.cs + * + * This code is derived from HttpStatusCode.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * It was automatically generated from ECMA CLI XML Library Specification. + * Generator: libgen.xsl [1.0; (C) Sergey Chaban (serge@wildwestsoftware.com)] + * Created: Wed, 5 Sep 2001 06:32:05 UTC + * Source file: AllTypes.xml + * URL: http://msdn.microsoft.com/net/ecma/AllTypes.xml + * + * The MIT License + * + * Copyright (c) 2001 Ximian, Inc. (http://www.ximian.com) + * Copyright (c) 2012-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +namespace WebSocketSharp.Net +{ + /// + /// Indicates the HTTP status code that can be specified in a server response. + /// + /// + /// The values of this enumeration are defined in + /// RFC 2616. + /// + public enum HttpStatusCode + { + /// + /// Equivalent to status code 100. Indicates that the client should continue + /// with its request. + /// + Continue = 100, + /// + /// Equivalent to status code 101. Indicates that the server is switching + /// the HTTP version or protocol on the connection. + /// + SwitchingProtocols = 101, + /// + /// Equivalent to status code 200. Indicates that the client's request has + /// succeeded. + /// + OK = 200, + /// + /// Equivalent to status code 201. Indicates that the client's request has + /// been fulfilled and resulted in a new resource being created. + /// + Created = 201, + /// + /// Equivalent to status code 202. Indicates that the client's request has + /// been accepted for processing, but the processing has not been completed. + /// + Accepted = 202, + /// + /// Equivalent to status code 203. Indicates that the returned metainformation + /// is from a local or a third-party copy instead of the origin server. + /// + NonAuthoritativeInformation = 203, + /// + /// Equivalent to status code 204. Indicates that the server has fulfilled + /// the client's request but does not need to return an entity-body. + /// + NoContent = 204, + /// + /// Equivalent to status code 205. Indicates that the server has fulfilled + /// the client's request, and the user agent should reset the document view + /// which caused the request to be sent. + /// + ResetContent = 205, + /// + /// Equivalent to status code 206. Indicates that the server has fulfilled + /// the partial GET request for the resource. + /// + PartialContent = 206, + /// + /// + /// Equivalent to status code 300. Indicates that the requested resource + /// corresponds to any of multiple representations. + /// + /// + /// MultipleChoices is a synonym for Ambiguous. + /// + /// + MultipleChoices = 300, + /// + /// + /// Equivalent to status code 300. Indicates that the requested resource + /// corresponds to any of multiple representations. + /// + /// + /// Ambiguous is a synonym for MultipleChoices. + /// + /// + Ambiguous = 300, + /// + /// + /// Equivalent to status code 301. Indicates that the requested resource + /// has been assigned a new permanent URI and any future references to + /// this resource should use one of the returned URIs. + /// + /// + /// MovedPermanently is a synonym for Moved. + /// + /// + MovedPermanently = 301, + /// + /// + /// Equivalent to status code 301. Indicates that the requested resource + /// has been assigned a new permanent URI and any future references to + /// this resource should use one of the returned URIs. + /// + /// + /// Moved is a synonym for MovedPermanently. + /// + /// + Moved = 301, + /// + /// + /// Equivalent to status code 302. Indicates that the requested resource + /// is located temporarily under a different URI. + /// + /// + /// Found is a synonym for Redirect. + /// + /// + Found = 302, + /// + /// + /// Equivalent to status code 302. Indicates that the requested resource + /// is located temporarily under a different URI. + /// + /// + /// Redirect is a synonym for Found. + /// + /// + Redirect = 302, + /// + /// + /// Equivalent to status code 303. Indicates that the response to + /// the request can be found under a different URI and should be + /// retrieved using a GET method on that resource. + /// + /// + /// SeeOther is a synonym for RedirectMethod. + /// + /// + SeeOther = 303, + /// + /// + /// Equivalent to status code 303. Indicates that the response to + /// the request can be found under a different URI and should be + /// retrieved using a GET method on that resource. + /// + /// + /// RedirectMethod is a synonym for SeeOther. + /// + /// + RedirectMethod = 303, + /// + /// Equivalent to status code 304. Indicates that the client has performed + /// a conditional GET request and access is allowed, but the document has + /// not been modified. + /// + NotModified = 304, + /// + /// Equivalent to status code 305. Indicates that the requested resource + /// must be accessed through the proxy given by the Location field. + /// + UseProxy = 305, + /// + /// Equivalent to status code 306. This status code was used in a previous + /// version of the specification, is no longer used, and is reserved for + /// future use. + /// + Unused = 306, + /// + /// + /// Equivalent to status code 307. Indicates that the requested resource + /// is located temporarily under a different URI. + /// + /// + /// TemporaryRedirect is a synonym for RedirectKeepVerb. + /// + /// + TemporaryRedirect = 307, + /// + /// + /// Equivalent to status code 307. Indicates that the requested resource + /// is located temporarily under a different URI. + /// + /// + /// RedirectKeepVerb is a synonym for TemporaryRedirect. + /// + /// + RedirectKeepVerb = 307, + /// + /// Equivalent to status code 400. Indicates that the client's request could + /// not be understood by the server due to malformed syntax. + /// + BadRequest = 400, + /// + /// Equivalent to status code 401. Indicates that the client's request + /// requires user authentication. + /// + Unauthorized = 401, + /// + /// Equivalent to status code 402. This status code is reserved for future + /// use. + /// + PaymentRequired = 402, + /// + /// Equivalent to status code 403. Indicates that the server understood + /// the client's request but is refusing to fulfill it. + /// + Forbidden = 403, + /// + /// Equivalent to status code 404. Indicates that the server has not found + /// anything matching the request URI. + /// + NotFound = 404, + /// + /// Equivalent to status code 405. Indicates that the method specified + /// in the request line is not allowed for the resource identified by + /// the request URI. + /// + MethodNotAllowed = 405, + /// + /// Equivalent to status code 406. Indicates that the server does not + /// have the appropriate resource to respond to the Accept headers in + /// the client's request. + /// + NotAcceptable = 406, + /// + /// Equivalent to status code 407. Indicates that the client must first + /// authenticate itself with the proxy. + /// + ProxyAuthenticationRequired = 407, + /// + /// Equivalent to status code 408. Indicates that the client did not produce + /// a request within the time that the server was prepared to wait. + /// + RequestTimeout = 408, + /// + /// Equivalent to status code 409. Indicates that the client's request could + /// not be completed due to a conflict on the server. + /// + Conflict = 409, + /// + /// Equivalent to status code 410. Indicates that the requested resource is + /// no longer available at the server and no forwarding address is known. + /// + Gone = 410, + /// + /// Equivalent to status code 411. Indicates that the server refuses to + /// accept the client's request without a defined Content-Length. + /// + LengthRequired = 411, + /// + /// Equivalent to status code 412. Indicates that the precondition given in + /// one or more of the request headers evaluated to false when it was tested + /// on the server. + /// + PreconditionFailed = 412, + /// + /// Equivalent to status code 413. Indicates that the entity of the client's + /// request is larger than the server is willing or able to process. + /// + RequestEntityTooLarge = 413, + /// + /// Equivalent to status code 414. Indicates that the request URI is longer + /// than the server is willing to interpret. + /// + RequestUriTooLong = 414, + /// + /// Equivalent to status code 415. Indicates that the entity of the client's + /// request is in a format not supported by the requested resource for the + /// requested method. + /// + UnsupportedMediaType = 415, + /// + /// Equivalent to status code 416. Indicates that none of the range + /// specifier values in a Range request header overlap the current + /// extent of the selected resource. + /// + RequestedRangeNotSatisfiable = 416, + /// + /// Equivalent to status code 417. Indicates that the expectation given in + /// an Expect request header could not be met by the server. + /// + ExpectationFailed = 417, + /// + /// Equivalent to status code 500. Indicates that the server encountered + /// an unexpected condition which prevented it from fulfilling the client's + /// request. + /// + InternalServerError = 500, + /// + /// Equivalent to status code 501. Indicates that the server does not + /// support the functionality required to fulfill the client's request. + /// + NotImplemented = 501, + /// + /// Equivalent to status code 502. Indicates that a gateway or proxy server + /// received an invalid response from the upstream server. + /// + BadGateway = 502, + /// + /// Equivalent to status code 503. Indicates that the server is currently + /// unable to handle the client's request due to a temporary overloading + /// or maintenance of the server. + /// + ServiceUnavailable = 503, + /// + /// Equivalent to status code 504. Indicates that a gateway or proxy server + /// did not receive a timely response from the upstream server or some other + /// auxiliary server. + /// + GatewayTimeout = 504, + /// + /// Equivalent to status code 505. Indicates that the server does not + /// support the HTTP version used in the client's request. + /// + HttpVersionNotSupported = 505, + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpStatusCode.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpStatusCode.cs.meta new file mode 100644 index 00000000..5788dcb4 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpStatusCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 807d106f14d25495e8435fae31adc34c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpStreamAsyncResult.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpStreamAsyncResult.cs new file mode 100644 index 00000000..09447ea2 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpStreamAsyncResult.cs @@ -0,0 +1,201 @@ +#region License +/* + * HttpStreamAsyncResult.cs + * + * This code is derived from HttpStreamAsyncResult.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.Threading; + +namespace WebSocketSharp.Net +{ + internal class HttpStreamAsyncResult : IAsyncResult + { + #region Private Fields + + private byte[] _buffer; + private AsyncCallback _callback; + private bool _completed; + private int _count; + private Exception _exception; + private int _offset; + private object _state; + private object _sync; + private int _syncRead; + private ManualResetEvent _waitHandle; + + #endregion + + #region Internal Constructors + + internal HttpStreamAsyncResult (AsyncCallback callback, object state) + { + _callback = callback; + _state = state; + + _sync = new object (); + } + + #endregion + + #region Internal Properties + + internal byte[] Buffer { + get { + return _buffer; + } + + set { + _buffer = value; + } + } + + internal int Count { + get { + return _count; + } + + set { + _count = value; + } + } + + internal Exception Exception { + get { + return _exception; + } + } + + internal bool HasException { + get { + return _exception != null; + } + } + + internal int Offset { + get { + return _offset; + } + + set { + _offset = value; + } + } + + internal int SyncRead { + get { + return _syncRead; + } + + set { + _syncRead = value; + } + } + + #endregion + + #region Public Properties + + public object AsyncState { + get { + return _state; + } + } + + public WaitHandle AsyncWaitHandle { + get { + lock (_sync) { + if (_waitHandle == null) + _waitHandle = new ManualResetEvent (_completed); + + return _waitHandle; + } + } + } + + public bool CompletedSynchronously { + get { + return _syncRead == _count; + } + } + + public bool IsCompleted { + get { + lock (_sync) + return _completed; + } + } + + #endregion + + #region Internal Methods + + internal void Complete () + { + lock (_sync) { + if (_completed) + return; + + _completed = true; + + if (_waitHandle != null) + _waitHandle.Set (); + + if (_callback != null) + _callback.BeginInvoke (this, ar => _callback.EndInvoke (ar), null); + } + } + + internal void Complete (Exception exception) + { + lock (_sync) { + if (_completed) + return; + + _completed = true; + _exception = exception; + + if (_waitHandle != null) + _waitHandle.Set (); + + if (_callback != null) + _callback.BeginInvoke (this, ar => _callback.EndInvoke (ar), null); + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpStreamAsyncResult.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpStreamAsyncResult.cs.meta new file mode 100644 index 00000000..8d4d8cf5 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpStreamAsyncResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d22b06da3fa4a40b8af0d32f74787e5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpUtility.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpUtility.cs new file mode 100644 index 00000000..90461d07 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpUtility.cs @@ -0,0 +1,1150 @@ +#region License +/* + * HttpUtility.cs + * + * This code is derived from HttpUtility.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005-2009 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2019 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Patrik Torstensson + * - Wictor Wilén (decode/encode functions) + * - Tim Coleman + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Globalization; +using System.IO; +using System.Security.Principal; +using System.Text; + +namespace WebSocketSharp.Net +{ + internal static class HttpUtility + { + #region Private Fields + + private static Dictionary _entities; + private static char[] _hexChars; + private static object _sync; + + #endregion + + #region Static Constructor + + static HttpUtility () + { + _hexChars = "0123456789ABCDEF".ToCharArray (); + _sync = new object (); + } + + #endregion + + #region Private Methods + + private static Dictionary getEntities () + { + lock (_sync) { + if (_entities == null) + initEntities (); + + return _entities; + } + } + + private static int getNumber (char c) + { + return c >= '0' && c <= '9' + ? c - '0' + : c >= 'A' && c <= 'F' + ? c - 'A' + 10 + : c >= 'a' && c <= 'f' + ? c - 'a' + 10 + : -1; + } + + private static int getNumber (byte[] bytes, int offset, int count) + { + var ret = 0; + + var end = offset + count - 1; + for (var i = offset; i <= end; i++) { + var num = getNumber ((char) bytes[i]); + if (num == -1) + return -1; + + ret = (ret << 4) + num; + } + + return ret; + } + + private static int getNumber (string s, int offset, int count) + { + var ret = 0; + + var end = offset + count - 1; + for (var i = offset; i <= end; i++) { + var num = getNumber (s[i]); + if (num == -1) + return -1; + + ret = (ret << 4) + num; + } + + return ret; + } + + private static string htmlDecode (string s) + { + var buff = new StringBuilder (); + + // 0: None + // 1: Right after '&' + // 2: Between '&' and ';' but no NCR + // 3: '#' found after '&' and getting numbers + // 4: 'x' found after '#' and getting numbers + var state = 0; + + var reference = new StringBuilder (); + var num = 0; + + foreach (var c in s) { + if (state == 0) { + if (c == '&') { + reference.Append ('&'); + state = 1; + + continue; + } + + buff.Append (c); + continue; + } + + if (c == '&') { + buff.Append (reference.ToString ()); + + reference.Length = 0; + reference.Append ('&'); + state = 1; + + continue; + } + + reference.Append (c); + + if (state == 1) { + if (c == ';') { + buff.Append (reference.ToString ()); + + reference.Length = 0; + state = 0; + + continue; + } + + num = 0; + state = c == '#' ? 3 : 2; + + continue; + } + + if (state == 2) { + if (c == ';') { + var entity = reference.ToString (); + var name = entity.Substring (1, entity.Length - 2); + + var entities = getEntities (); + if (entities.ContainsKey (name)) + buff.Append (entities[name]); + else + buff.Append (entity); + + reference.Length = 0; + state = 0; + + continue; + } + + continue; + } + + if (state == 3) { + if (c == ';') { + if (reference.Length > 3 && num < 65536) + buff.Append ((char) num); + else + buff.Append (reference.ToString ()); + + reference.Length = 0; + state = 0; + + continue; + } + + if (c == 'x') { + state = reference.Length == 3 ? 4 : 2; + continue; + } + + if (!isNumeric (c)) { + state = 2; + continue; + } + + num = num * 10 + (c - '0'); + continue; + } + + if (state == 4) { + if (c == ';') { + if (reference.Length > 4 && num < 65536) + buff.Append ((char) num); + else + buff.Append (reference.ToString ()); + + reference.Length = 0; + state = 0; + + continue; + } + + var n = getNumber (c); + if (n == -1) { + state = 2; + continue; + } + + num = (num << 4) + n; + } + } + + if (reference.Length > 0) + buff.Append (reference.ToString ()); + + return buff.ToString (); + } + + /// + /// Converts the specified string to an HTML-encoded string. + /// + /// + /// + /// This method starts encoding with a NCR from the character code 160 + /// but does not stop at the character code 255. + /// + /// + /// One reason is the unicode characters < and > that + /// look like < and >. + /// + /// + /// + /// A that represents an encoded string. + /// + /// + /// A to encode. + /// + /// + /// A : true if encodes without a NCR; + /// otherwise, false. + /// + private static string htmlEncode (string s, bool minimal) + { + var buff = new StringBuilder (); + + foreach (var c in s) { + buff.Append ( + c == '"' + ? """ + : c == '&' + ? "&" + : c == '<' + ? "<" + : c == '>' + ? ">" + : !minimal && c > 159 + ? String.Format ("&#{0};", (int) c) + : c.ToString () + ); + } + + return buff.ToString (); + } + + /// + /// Initializes the _entities field. + /// + /// + /// This method builds a dictionary of HTML character entity references. + /// This dictionary comes from the HTML 4.01 W3C recommendation. + /// + private static void initEntities () + { + _entities = new Dictionary (); + _entities.Add ("nbsp", '\u00A0'); + _entities.Add ("iexcl", '\u00A1'); + _entities.Add ("cent", '\u00A2'); + _entities.Add ("pound", '\u00A3'); + _entities.Add ("curren", '\u00A4'); + _entities.Add ("yen", '\u00A5'); + _entities.Add ("brvbar", '\u00A6'); + _entities.Add ("sect", '\u00A7'); + _entities.Add ("uml", '\u00A8'); + _entities.Add ("copy", '\u00A9'); + _entities.Add ("ordf", '\u00AA'); + _entities.Add ("laquo", '\u00AB'); + _entities.Add ("not", '\u00AC'); + _entities.Add ("shy", '\u00AD'); + _entities.Add ("reg", '\u00AE'); + _entities.Add ("macr", '\u00AF'); + _entities.Add ("deg", '\u00B0'); + _entities.Add ("plusmn", '\u00B1'); + _entities.Add ("sup2", '\u00B2'); + _entities.Add ("sup3", '\u00B3'); + _entities.Add ("acute", '\u00B4'); + _entities.Add ("micro", '\u00B5'); + _entities.Add ("para", '\u00B6'); + _entities.Add ("middot", '\u00B7'); + _entities.Add ("cedil", '\u00B8'); + _entities.Add ("sup1", '\u00B9'); + _entities.Add ("ordm", '\u00BA'); + _entities.Add ("raquo", '\u00BB'); + _entities.Add ("frac14", '\u00BC'); + _entities.Add ("frac12", '\u00BD'); + _entities.Add ("frac34", '\u00BE'); + _entities.Add ("iquest", '\u00BF'); + _entities.Add ("Agrave", '\u00C0'); + _entities.Add ("Aacute", '\u00C1'); + _entities.Add ("Acirc", '\u00C2'); + _entities.Add ("Atilde", '\u00C3'); + _entities.Add ("Auml", '\u00C4'); + _entities.Add ("Aring", '\u00C5'); + _entities.Add ("AElig", '\u00C6'); + _entities.Add ("Ccedil", '\u00C7'); + _entities.Add ("Egrave", '\u00C8'); + _entities.Add ("Eacute", '\u00C9'); + _entities.Add ("Ecirc", '\u00CA'); + _entities.Add ("Euml", '\u00CB'); + _entities.Add ("Igrave", '\u00CC'); + _entities.Add ("Iacute", '\u00CD'); + _entities.Add ("Icirc", '\u00CE'); + _entities.Add ("Iuml", '\u00CF'); + _entities.Add ("ETH", '\u00D0'); + _entities.Add ("Ntilde", '\u00D1'); + _entities.Add ("Ograve", '\u00D2'); + _entities.Add ("Oacute", '\u00D3'); + _entities.Add ("Ocirc", '\u00D4'); + _entities.Add ("Otilde", '\u00D5'); + _entities.Add ("Ouml", '\u00D6'); + _entities.Add ("times", '\u00D7'); + _entities.Add ("Oslash", '\u00D8'); + _entities.Add ("Ugrave", '\u00D9'); + _entities.Add ("Uacute", '\u00DA'); + _entities.Add ("Ucirc", '\u00DB'); + _entities.Add ("Uuml", '\u00DC'); + _entities.Add ("Yacute", '\u00DD'); + _entities.Add ("THORN", '\u00DE'); + _entities.Add ("szlig", '\u00DF'); + _entities.Add ("agrave", '\u00E0'); + _entities.Add ("aacute", '\u00E1'); + _entities.Add ("acirc", '\u00E2'); + _entities.Add ("atilde", '\u00E3'); + _entities.Add ("auml", '\u00E4'); + _entities.Add ("aring", '\u00E5'); + _entities.Add ("aelig", '\u00E6'); + _entities.Add ("ccedil", '\u00E7'); + _entities.Add ("egrave", '\u00E8'); + _entities.Add ("eacute", '\u00E9'); + _entities.Add ("ecirc", '\u00EA'); + _entities.Add ("euml", '\u00EB'); + _entities.Add ("igrave", '\u00EC'); + _entities.Add ("iacute", '\u00ED'); + _entities.Add ("icirc", '\u00EE'); + _entities.Add ("iuml", '\u00EF'); + _entities.Add ("eth", '\u00F0'); + _entities.Add ("ntilde", '\u00F1'); + _entities.Add ("ograve", '\u00F2'); + _entities.Add ("oacute", '\u00F3'); + _entities.Add ("ocirc", '\u00F4'); + _entities.Add ("otilde", '\u00F5'); + _entities.Add ("ouml", '\u00F6'); + _entities.Add ("divide", '\u00F7'); + _entities.Add ("oslash", '\u00F8'); + _entities.Add ("ugrave", '\u00F9'); + _entities.Add ("uacute", '\u00FA'); + _entities.Add ("ucirc", '\u00FB'); + _entities.Add ("uuml", '\u00FC'); + _entities.Add ("yacute", '\u00FD'); + _entities.Add ("thorn", '\u00FE'); + _entities.Add ("yuml", '\u00FF'); + _entities.Add ("fnof", '\u0192'); + _entities.Add ("Alpha", '\u0391'); + _entities.Add ("Beta", '\u0392'); + _entities.Add ("Gamma", '\u0393'); + _entities.Add ("Delta", '\u0394'); + _entities.Add ("Epsilon", '\u0395'); + _entities.Add ("Zeta", '\u0396'); + _entities.Add ("Eta", '\u0397'); + _entities.Add ("Theta", '\u0398'); + _entities.Add ("Iota", '\u0399'); + _entities.Add ("Kappa", '\u039A'); + _entities.Add ("Lambda", '\u039B'); + _entities.Add ("Mu", '\u039C'); + _entities.Add ("Nu", '\u039D'); + _entities.Add ("Xi", '\u039E'); + _entities.Add ("Omicron", '\u039F'); + _entities.Add ("Pi", '\u03A0'); + _entities.Add ("Rho", '\u03A1'); + _entities.Add ("Sigma", '\u03A3'); + _entities.Add ("Tau", '\u03A4'); + _entities.Add ("Upsilon", '\u03A5'); + _entities.Add ("Phi", '\u03A6'); + _entities.Add ("Chi", '\u03A7'); + _entities.Add ("Psi", '\u03A8'); + _entities.Add ("Omega", '\u03A9'); + _entities.Add ("alpha", '\u03B1'); + _entities.Add ("beta", '\u03B2'); + _entities.Add ("gamma", '\u03B3'); + _entities.Add ("delta", '\u03B4'); + _entities.Add ("epsilon", '\u03B5'); + _entities.Add ("zeta", '\u03B6'); + _entities.Add ("eta", '\u03B7'); + _entities.Add ("theta", '\u03B8'); + _entities.Add ("iota", '\u03B9'); + _entities.Add ("kappa", '\u03BA'); + _entities.Add ("lambda", '\u03BB'); + _entities.Add ("mu", '\u03BC'); + _entities.Add ("nu", '\u03BD'); + _entities.Add ("xi", '\u03BE'); + _entities.Add ("omicron", '\u03BF'); + _entities.Add ("pi", '\u03C0'); + _entities.Add ("rho", '\u03C1'); + _entities.Add ("sigmaf", '\u03C2'); + _entities.Add ("sigma", '\u03C3'); + _entities.Add ("tau", '\u03C4'); + _entities.Add ("upsilon", '\u03C5'); + _entities.Add ("phi", '\u03C6'); + _entities.Add ("chi", '\u03C7'); + _entities.Add ("psi", '\u03C8'); + _entities.Add ("omega", '\u03C9'); + _entities.Add ("thetasym", '\u03D1'); + _entities.Add ("upsih", '\u03D2'); + _entities.Add ("piv", '\u03D6'); + _entities.Add ("bull", '\u2022'); + _entities.Add ("hellip", '\u2026'); + _entities.Add ("prime", '\u2032'); + _entities.Add ("Prime", '\u2033'); + _entities.Add ("oline", '\u203E'); + _entities.Add ("frasl", '\u2044'); + _entities.Add ("weierp", '\u2118'); + _entities.Add ("image", '\u2111'); + _entities.Add ("real", '\u211C'); + _entities.Add ("trade", '\u2122'); + _entities.Add ("alefsym", '\u2135'); + _entities.Add ("larr", '\u2190'); + _entities.Add ("uarr", '\u2191'); + _entities.Add ("rarr", '\u2192'); + _entities.Add ("darr", '\u2193'); + _entities.Add ("harr", '\u2194'); + _entities.Add ("crarr", '\u21B5'); + _entities.Add ("lArr", '\u21D0'); + _entities.Add ("uArr", '\u21D1'); + _entities.Add ("rArr", '\u21D2'); + _entities.Add ("dArr", '\u21D3'); + _entities.Add ("hArr", '\u21D4'); + _entities.Add ("forall", '\u2200'); + _entities.Add ("part", '\u2202'); + _entities.Add ("exist", '\u2203'); + _entities.Add ("empty", '\u2205'); + _entities.Add ("nabla", '\u2207'); + _entities.Add ("isin", '\u2208'); + _entities.Add ("notin", '\u2209'); + _entities.Add ("ni", '\u220B'); + _entities.Add ("prod", '\u220F'); + _entities.Add ("sum", '\u2211'); + _entities.Add ("minus", '\u2212'); + _entities.Add ("lowast", '\u2217'); + _entities.Add ("radic", '\u221A'); + _entities.Add ("prop", '\u221D'); + _entities.Add ("infin", '\u221E'); + _entities.Add ("ang", '\u2220'); + _entities.Add ("and", '\u2227'); + _entities.Add ("or", '\u2228'); + _entities.Add ("cap", '\u2229'); + _entities.Add ("cup", '\u222A'); + _entities.Add ("int", '\u222B'); + _entities.Add ("there4", '\u2234'); + _entities.Add ("sim", '\u223C'); + _entities.Add ("cong", '\u2245'); + _entities.Add ("asymp", '\u2248'); + _entities.Add ("ne", '\u2260'); + _entities.Add ("equiv", '\u2261'); + _entities.Add ("le", '\u2264'); + _entities.Add ("ge", '\u2265'); + _entities.Add ("sub", '\u2282'); + _entities.Add ("sup", '\u2283'); + _entities.Add ("nsub", '\u2284'); + _entities.Add ("sube", '\u2286'); + _entities.Add ("supe", '\u2287'); + _entities.Add ("oplus", '\u2295'); + _entities.Add ("otimes", '\u2297'); + _entities.Add ("perp", '\u22A5'); + _entities.Add ("sdot", '\u22C5'); + _entities.Add ("lceil", '\u2308'); + _entities.Add ("rceil", '\u2309'); + _entities.Add ("lfloor", '\u230A'); + _entities.Add ("rfloor", '\u230B'); + _entities.Add ("lang", '\u2329'); + _entities.Add ("rang", '\u232A'); + _entities.Add ("loz", '\u25CA'); + _entities.Add ("spades", '\u2660'); + _entities.Add ("clubs", '\u2663'); + _entities.Add ("hearts", '\u2665'); + _entities.Add ("diams", '\u2666'); + _entities.Add ("quot", '\u0022'); + _entities.Add ("amp", '\u0026'); + _entities.Add ("lt", '\u003C'); + _entities.Add ("gt", '\u003E'); + _entities.Add ("OElig", '\u0152'); + _entities.Add ("oelig", '\u0153'); + _entities.Add ("Scaron", '\u0160'); + _entities.Add ("scaron", '\u0161'); + _entities.Add ("Yuml", '\u0178'); + _entities.Add ("circ", '\u02C6'); + _entities.Add ("tilde", '\u02DC'); + _entities.Add ("ensp", '\u2002'); + _entities.Add ("emsp", '\u2003'); + _entities.Add ("thinsp", '\u2009'); + _entities.Add ("zwnj", '\u200C'); + _entities.Add ("zwj", '\u200D'); + _entities.Add ("lrm", '\u200E'); + _entities.Add ("rlm", '\u200F'); + _entities.Add ("ndash", '\u2013'); + _entities.Add ("mdash", '\u2014'); + _entities.Add ("lsquo", '\u2018'); + _entities.Add ("rsquo", '\u2019'); + _entities.Add ("sbquo", '\u201A'); + _entities.Add ("ldquo", '\u201C'); + _entities.Add ("rdquo", '\u201D'); + _entities.Add ("bdquo", '\u201E'); + _entities.Add ("dagger", '\u2020'); + _entities.Add ("Dagger", '\u2021'); + _entities.Add ("permil", '\u2030'); + _entities.Add ("lsaquo", '\u2039'); + _entities.Add ("rsaquo", '\u203A'); + _entities.Add ("euro", '\u20AC'); + } + + private static bool isAlphabet (char c) + { + return (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z'); + } + + private static bool isNumeric (char c) + { + return c >= '0' && c <= '9'; + } + + private static bool isUnreserved (char c) + { + return c == '*' + || c == '-' + || c == '.' + || c == '_'; + } + + private static bool isUnreservedInRfc2396 (char c) + { + return c == '!' + || c == '\'' + || c == '(' + || c == ')' + || c == '*' + || c == '-' + || c == '.' + || c == '_' + || c == '~'; + } + + private static bool isUnreservedInRfc3986 (char c) + { + return c == '-' + || c == '.' + || c == '_' + || c == '~'; + } + + private static byte[] urlDecodeToBytes (byte[] bytes, int offset, int count) + { + using (var buff = new MemoryStream ()) { + var end = offset + count - 1; + for (var i = offset; i <= end; i++) { + var b = bytes[i]; + + var c = (char) b; + if (c == '%') { + if (i > end - 2) + break; + + var num = getNumber (bytes, i + 1, 2); + if (num == -1) + break; + + buff.WriteByte ((byte) num); + i += 2; + + continue; + } + + if (c == '+') { + buff.WriteByte ((byte) ' '); + continue; + } + + buff.WriteByte (b); + } + + buff.Close (); + return buff.ToArray (); + } + } + + private static void urlEncode (byte b, Stream output) + { + if (b > 31 && b < 127) { + var c = (char) b; + if (c == ' ') { + output.WriteByte ((byte) '+'); + return; + } + + if (isNumeric (c)) { + output.WriteByte (b); + return; + } + + if (isAlphabet (c)) { + output.WriteByte (b); + return; + } + + if (isUnreserved (c)) { + output.WriteByte (b); + return; + } + } + + var i = (int) b; + var bytes = new byte[] { + (byte) '%', + (byte) _hexChars[i >> 4], + (byte) _hexChars[i & 0x0F] + }; + + output.Write (bytes, 0, 3); + } + + private static byte[] urlEncodeToBytes (byte[] bytes, int offset, int count) + { + using (var buff = new MemoryStream ()) { + var end = offset + count - 1; + for (var i = offset; i <= end; i++) + urlEncode (bytes[i], buff); + + buff.Close (); + return buff.ToArray (); + } + } + + #endregion + + #region Internal Methods + + internal static Uri CreateRequestUrl ( + string requestUri, string host, bool websocketRequest, bool secure + ) + { + if (requestUri == null || requestUri.Length == 0) + return null; + + if (host == null || host.Length == 0) + return null; + + string schm = null; + string path = null; + + if (requestUri.IndexOf ('/') == 0) { + path = requestUri; + } + else if (requestUri.MaybeUri ()) { + Uri uri; + + if (!Uri.TryCreate (requestUri, UriKind.Absolute, out uri)) + return null; + + schm = uri.Scheme; + var valid = websocketRequest + ? schm == "ws" || schm == "wss" + : schm == "http" || schm == "https"; + + if (!valid) + return null; + + host = uri.Authority; + path = uri.PathAndQuery; + } + else if (requestUri == "*") { + } + else { + // As the authority form. + + host = requestUri; + } + + if (schm == null) { + schm = websocketRequest + ? (secure ? "wss" : "ws") + : (secure ? "https" : "http"); + } + + if (host.IndexOf (':') == -1) + host = String.Format ("{0}:{1}", host, secure ? 443 : 80); + + var url = String.Format ("{0}://{1}{2}", schm, host, path); + Uri ret; + + return Uri.TryCreate (url, UriKind.Absolute, out ret) ? ret : null; + } + + internal static IPrincipal CreateUser ( + string response, + AuthenticationSchemes scheme, + string realm, + string method, + Func credentialsFinder + ) + { + if (response == null || response.Length == 0) + return null; + + if (scheme == AuthenticationSchemes.Digest) { + if (realm == null || realm.Length == 0) + return null; + + if (method == null || method.Length == 0) + return null; + } + else { + if (scheme != AuthenticationSchemes.Basic) + return null; + } + + if (credentialsFinder == null) + return null; + + var compType = StringComparison.OrdinalIgnoreCase; + if (response.IndexOf (scheme.ToString (), compType) != 0) + return null; + + var res = AuthenticationResponse.Parse (response); + if (res == null) + return null; + + var id = res.ToIdentity (); + if (id == null) + return null; + + NetworkCredential cred = null; + try { + cred = credentialsFinder (id); + } + catch { + } + + if (cred == null) + return null; + + if (scheme == AuthenticationSchemes.Basic) { + var basicId = (HttpBasicIdentity) id; + return basicId.Password == cred.Password + ? new GenericPrincipal (id, cred.Roles) + : null; + } + + var digestId = (HttpDigestIdentity) id; + return digestId.IsValid (cred.Password, realm, method, null) + ? new GenericPrincipal (id, cred.Roles) + : null; + } + + internal static Encoding GetEncoding (string contentType) + { + var name = "charset="; + var compType = StringComparison.OrdinalIgnoreCase; + + foreach (var elm in contentType.SplitHeaderValue (';')) { + var part = elm.Trim (); + + if (!part.StartsWith (name, compType)) + continue; + + var val = part.GetValue ('=', true); + + if (val == null || val.Length == 0) + return null; + + return Encoding.GetEncoding (val); + } + + return null; + } + + internal static bool TryGetEncoding ( + string contentType, out Encoding result + ) + { + result = null; + + try { + result = GetEncoding (contentType); + } + catch { + return false; + } + + return result != null; + } + + #endregion + + #region Public Methods + + public static string HtmlAttributeEncode (string s) + { + if (s == null) + throw new ArgumentNullException ("s"); + + return s.Length > 0 ? htmlEncode (s, true) : s; + } + + public static void HtmlAttributeEncode (string s, TextWriter output) + { + if (s == null) + throw new ArgumentNullException ("s"); + + if (output == null) + throw new ArgumentNullException ("output"); + + if (s.Length == 0) + return; + + output.Write (htmlEncode (s, true)); + } + + public static string HtmlDecode (string s) + { + if (s == null) + throw new ArgumentNullException ("s"); + + return s.Length > 0 ? htmlDecode (s) : s; + } + + public static void HtmlDecode (string s, TextWriter output) + { + if (s == null) + throw new ArgumentNullException ("s"); + + if (output == null) + throw new ArgumentNullException ("output"); + + if (s.Length == 0) + return; + + output.Write (htmlDecode (s)); + } + + public static string HtmlEncode (string s) + { + if (s == null) + throw new ArgumentNullException ("s"); + + return s.Length > 0 ? htmlEncode (s, false) : s; + } + + public static void HtmlEncode (string s, TextWriter output) + { + if (s == null) + throw new ArgumentNullException ("s"); + + if (output == null) + throw new ArgumentNullException ("output"); + + if (s.Length == 0) + return; + + output.Write (htmlEncode (s, false)); + } + + public static string UrlDecode (string s) + { + return UrlDecode (s, Encoding.UTF8); + } + + public static string UrlDecode (byte[] bytes, Encoding encoding) + { + if (bytes == null) + throw new ArgumentNullException ("bytes"); + + var len = bytes.Length; + return len > 0 + ? (encoding ?? Encoding.UTF8).GetString ( + urlDecodeToBytes (bytes, 0, len) + ) + : String.Empty; + } + + public static string UrlDecode (string s, Encoding encoding) + { + if (s == null) + throw new ArgumentNullException ("s"); + + if (s.Length == 0) + return s; + + var bytes = Encoding.ASCII.GetBytes (s); + return (encoding ?? Encoding.UTF8).GetString ( + urlDecodeToBytes (bytes, 0, bytes.Length) + ); + } + + public static string UrlDecode ( + byte[] bytes, int offset, int count, Encoding encoding + ) + { + if (bytes == null) + throw new ArgumentNullException ("bytes"); + + var len = bytes.Length; + if (len == 0) { + if (offset != 0) + throw new ArgumentOutOfRangeException ("offset"); + + if (count != 0) + throw new ArgumentOutOfRangeException ("count"); + + return String.Empty; + } + + if (offset < 0 || offset >= len) + throw new ArgumentOutOfRangeException ("offset"); + + if (count < 0 || count > len - offset) + throw new ArgumentOutOfRangeException ("count"); + + return count > 0 + ? (encoding ?? Encoding.UTF8).GetString ( + urlDecodeToBytes (bytes, offset, count) + ) + : String.Empty; + } + + public static byte[] UrlDecodeToBytes (byte[] bytes) + { + if (bytes == null) + throw new ArgumentNullException ("bytes"); + + var len = bytes.Length; + return len > 0 + ? urlDecodeToBytes (bytes, 0, len) + : bytes; + } + + public static byte[] UrlDecodeToBytes (string s) + { + if (s == null) + throw new ArgumentNullException ("s"); + + if (s.Length == 0) + return new byte[0]; + + var bytes = Encoding.ASCII.GetBytes (s); + return urlDecodeToBytes (bytes, 0, bytes.Length); + } + + public static byte[] UrlDecodeToBytes (byte[] bytes, int offset, int count) + { + if (bytes == null) + throw new ArgumentNullException ("bytes"); + + var len = bytes.Length; + if (len == 0) { + if (offset != 0) + throw new ArgumentOutOfRangeException ("offset"); + + if (count != 0) + throw new ArgumentOutOfRangeException ("count"); + + return bytes; + } + + if (offset < 0 || offset >= len) + throw new ArgumentOutOfRangeException ("offset"); + + if (count < 0 || count > len - offset) + throw new ArgumentOutOfRangeException ("count"); + + return count > 0 + ? urlDecodeToBytes (bytes, offset, count) + : new byte[0]; + } + + public static string UrlEncode (byte[] bytes) + { + if (bytes == null) + throw new ArgumentNullException ("bytes"); + + var len = bytes.Length; + return len > 0 + ? Encoding.ASCII.GetString (urlEncodeToBytes (bytes, 0, len)) + : String.Empty; + } + + public static string UrlEncode (string s) + { + return UrlEncode (s, Encoding.UTF8); + } + + public static string UrlEncode (string s, Encoding encoding) + { + if (s == null) + throw new ArgumentNullException ("s"); + + var len = s.Length; + if (len == 0) + return s; + + if (encoding == null) + encoding = Encoding.UTF8; + + var bytes = new byte[encoding.GetMaxByteCount (len)]; + var realLen = encoding.GetBytes (s, 0, len, bytes, 0); + + return Encoding.ASCII.GetString (urlEncodeToBytes (bytes, 0, realLen)); + } + + public static string UrlEncode (byte[] bytes, int offset, int count) + { + if (bytes == null) + throw new ArgumentNullException ("bytes"); + + var len = bytes.Length; + if (len == 0) { + if (offset != 0) + throw new ArgumentOutOfRangeException ("offset"); + + if (count != 0) + throw new ArgumentOutOfRangeException ("count"); + + return String.Empty; + } + + if (offset < 0 || offset >= len) + throw new ArgumentOutOfRangeException ("offset"); + + if (count < 0 || count > len - offset) + throw new ArgumentOutOfRangeException ("count"); + + return count > 0 + ? Encoding.ASCII.GetString ( + urlEncodeToBytes (bytes, offset, count) + ) + : String.Empty; + } + + public static byte[] UrlEncodeToBytes (byte[] bytes) + { + if (bytes == null) + throw new ArgumentNullException ("bytes"); + + var len = bytes.Length; + return len > 0 ? urlEncodeToBytes (bytes, 0, len) : bytes; + } + + public static byte[] UrlEncodeToBytes (string s) + { + return UrlEncodeToBytes (s, Encoding.UTF8); + } + + public static byte[] UrlEncodeToBytes (string s, Encoding encoding) + { + if (s == null) + throw new ArgumentNullException ("s"); + + if (s.Length == 0) + return new byte[0]; + + var bytes = (encoding ?? Encoding.UTF8).GetBytes (s); + return urlEncodeToBytes (bytes, 0, bytes.Length); + } + + public static byte[] UrlEncodeToBytes (byte[] bytes, int offset, int count) + { + if (bytes == null) + throw new ArgumentNullException ("bytes"); + + var len = bytes.Length; + if (len == 0) { + if (offset != 0) + throw new ArgumentOutOfRangeException ("offset"); + + if (count != 0) + throw new ArgumentOutOfRangeException ("count"); + + return bytes; + } + + if (offset < 0 || offset >= len) + throw new ArgumentOutOfRangeException ("offset"); + + if (count < 0 || count > len - offset) + throw new ArgumentOutOfRangeException ("count"); + + return count > 0 ? urlEncodeToBytes (bytes, offset, count) : new byte[0]; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpUtility.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpUtility.cs.meta new file mode 100644 index 00000000..3701da17 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73561cfb76c5945c082fec6f70d9936f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpVersion.cs b/Plugins/websocket-sharp/websocket-sharp/Net/HttpVersion.cs new file mode 100644 index 00000000..d20061e0 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpVersion.cs @@ -0,0 +1,73 @@ +#region License +/* + * HttpVersion.cs + * + * This code is derived from System.Net.HttpVersion.cs of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2012-2014 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Lawrence Pit + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + /// + /// Provides the HTTP version numbers. + /// + public class HttpVersion + { + #region Public Fields + + /// + /// Provides a instance for the HTTP/1.0. + /// + public static readonly Version Version10 = new Version (1, 0); + + /// + /// Provides a instance for the HTTP/1.1. + /// + public static readonly Version Version11 = new Version (1, 1); + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class. + /// + public HttpVersion () + { + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/HttpVersion.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/HttpVersion.cs.meta new file mode 100644 index 00000000..1a2f9839 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/HttpVersion.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36d2d6c42f2b3480f8115125d2661c14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/InputChunkState.cs b/Plugins/websocket-sharp/websocket-sharp/Net/InputChunkState.cs new file mode 100644 index 00000000..f50ad6b7 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/InputChunkState.cs @@ -0,0 +1,52 @@ +#region License +/* + * InputChunkState.cs + * + * This code is derived from ChunkStream.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2003 Ximian, Inc (http://www.ximian.com) + * Copyright (c) 2014-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + internal enum InputChunkState + { + None, + Data, + DataEnded, + Trailer, + End + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/InputChunkState.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/InputChunkState.cs.meta new file mode 100644 index 00000000..45374d65 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/InputChunkState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f36d2b77dafaa43f9a9e64e09ab9d6a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/InputState.cs b/Plugins/websocket-sharp/websocket-sharp/Net/InputState.cs new file mode 100644 index 00000000..9f566d24 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/InputState.cs @@ -0,0 +1,49 @@ +#region License +/* + * InputState.cs + * + * This code is derived from HttpConnection.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2014-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + internal enum InputState + { + RequestLine, + Headers + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/InputState.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/InputState.cs.meta new file mode 100644 index 00000000..1ceee781 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/InputState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36eadda9a88394df3bd7d2fed4e4933b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/LineState.cs b/Plugins/websocket-sharp/websocket-sharp/Net/LineState.cs new file mode 100644 index 00000000..84e271a7 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/LineState.cs @@ -0,0 +1,50 @@ +#region License +/* + * LineState.cs + * + * This code is derived from HttpConnection.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2014-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + internal enum LineState + { + None, + Cr, + Lf + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/LineState.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/LineState.cs.meta new file mode 100644 index 00000000..e2ca5198 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/LineState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 792b8c6be26a74b5cbc389817956dcd2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/NetworkCredential.cs b/Plugins/websocket-sharp/websocket-sharp/Net/NetworkCredential.cs new file mode 100644 index 00000000..3ee52f40 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/NetworkCredential.cs @@ -0,0 +1,209 @@ +#region License +/* + * NetworkCredential.cs + * + * The MIT License + * + * Copyright (c) 2014-2017 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + /// + /// Provides the credentials for the password-based authentication. + /// + public class NetworkCredential + { + #region Private Fields + + private string _domain; + private static readonly string[] _noRoles; + private string _password; + private string[] _roles; + private string _username; + + #endregion + + #region Static Constructor + + static NetworkCredential () + { + _noRoles = new string[0]; + } + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class with + /// the specified and . + /// + /// + /// A that represents the username associated with + /// the credentials. + /// + /// + /// A that represents the password for the username + /// associated with the credentials. + /// + /// + /// is . + /// + /// + /// is empty. + /// + public NetworkCredential (string username, string password) + : this (username, password, null, null) + { + } + + /// + /// Initializes a new instance of the class with + /// the specified , , + /// and . + /// + /// + /// A that represents the username associated with + /// the credentials. + /// + /// + /// A that represents the password for the username + /// associated with the credentials. + /// + /// + /// A that represents the domain associated with + /// the credentials. + /// + /// + /// An array of that represents the roles + /// associated with the credentials if any. + /// + /// + /// is . + /// + /// + /// is empty. + /// + public NetworkCredential ( + string username, string password, string domain, params string[] roles + ) + { + if (username == null) + throw new ArgumentNullException ("username"); + + if (username.Length == 0) + throw new ArgumentException ("An empty string.", "username"); + + _username = username; + _password = password; + _domain = domain; + _roles = roles; + } + + #endregion + + #region Public Properties + + /// + /// Gets the domain associated with the credentials. + /// + /// + /// This property returns an empty string if the domain was + /// initialized with . + /// + /// + /// A that represents the domain name + /// to which the username belongs. + /// + public string Domain { + get { + return _domain ?? String.Empty; + } + + internal set { + _domain = value; + } + } + + /// + /// Gets the password for the username associated with the credentials. + /// + /// + /// This property returns an empty string if the password was + /// initialized with . + /// + /// + /// A that represents the password. + /// + public string Password { + get { + return _password ?? String.Empty; + } + + internal set { + _password = value; + } + } + + /// + /// Gets the roles associated with the credentials. + /// + /// + /// This property returns an empty array if the roles were + /// initialized with . + /// + /// + /// An array of that represents the role names + /// to which the username belongs. + /// + public string[] Roles { + get { + return _roles ?? _noRoles; + } + + internal set { + _roles = value; + } + } + + /// + /// Gets the username associated with the credentials. + /// + /// + /// A that represents the username. + /// + public string Username { + get { + return _username; + } + + internal set { + _username = value; + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/NetworkCredential.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/NetworkCredential.cs.meta new file mode 100644 index 00000000..38b5c80c --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/NetworkCredential.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07d26162677f44ceb9f3033d8da17222 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/QueryStringCollection.cs b/Plugins/websocket-sharp/websocket-sharp/Net/QueryStringCollection.cs new file mode 100644 index 00000000..2e925e2d --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/QueryStringCollection.cs @@ -0,0 +1,150 @@ +#region License +/* + * QueryStringCollection.cs + * + * This code is derived from HttpUtility.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005-2009 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2018 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Patrik Torstensson + * - Wictor Wilén (decode/encode functions) + * - Tim Coleman + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.Collections.Specialized; +using System.Text; + +namespace WebSocketSharp.Net +{ + internal sealed class QueryStringCollection : NameValueCollection + { + #region Public Constructors + + public QueryStringCollection () + { + } + + public QueryStringCollection (int capacity) + : base (capacity) + { + } + + #endregion + + #region Private Methods + + private static string urlDecode (string s, Encoding encoding) + { + return s.IndexOfAny (new[] { '%', '+' }) > -1 + ? HttpUtility.UrlDecode (s, encoding) + : s; + } + + #endregion + + #region Public Methods + + public static QueryStringCollection Parse (string query) + { + return Parse (query, Encoding.UTF8); + } + + public static QueryStringCollection Parse (string query, Encoding encoding) + { + if (query == null) + return new QueryStringCollection (1); + + var len = query.Length; + if (len == 0) + return new QueryStringCollection (1); + + if (query == "?") + return new QueryStringCollection (1); + + if (query[0] == '?') + query = query.Substring (1); + + if (encoding == null) + encoding = Encoding.UTF8; + + var ret = new QueryStringCollection (); + + var components = query.Split ('&'); + foreach (var component in components) { + len = component.Length; + if (len == 0) + continue; + + if (component == "=") + continue; + + var i = component.IndexOf ('='); + if (i < 0) { + ret.Add (null, urlDecode (component, encoding)); + continue; + } + + if (i == 0) { + ret.Add (null, urlDecode (component.Substring (1), encoding)); + continue; + } + + var name = urlDecode (component.Substring (0, i), encoding); + + var start = i + 1; + var val = start < len + ? urlDecode (component.Substring (start), encoding) + : String.Empty; + + ret.Add (name, val); + } + + return ret; + } + + public override string ToString () + { + var buff = new StringBuilder (); + + foreach (var key in AllKeys) + buff.AppendFormat ("{0}={1}&", key, this[key]); + + if (buff.Length > 0) + buff.Length--; + + return buff.ToString (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/QueryStringCollection.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/QueryStringCollection.cs.meta new file mode 100644 index 00000000..8d0eafd2 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/QueryStringCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0f4bd09b1c758475f9e3650e09c5be2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ReadBufferState.cs b/Plugins/websocket-sharp/websocket-sharp/Net/ReadBufferState.cs new file mode 100644 index 00000000..1d8280f0 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ReadBufferState.cs @@ -0,0 +1,126 @@ +#region License +/* + * ReadBufferState.cs + * + * This code is derived from ChunkedInputStream.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2014-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; + +namespace WebSocketSharp.Net +{ + internal class ReadBufferState + { + #region Private Fields + + private HttpStreamAsyncResult _asyncResult; + private byte[] _buffer; + private int _count; + private int _initialCount; + private int _offset; + + #endregion + + #region Public Constructors + + public ReadBufferState ( + byte[] buffer, int offset, int count, HttpStreamAsyncResult asyncResult + ) + { + _buffer = buffer; + _offset = offset; + _count = count; + _asyncResult = asyncResult; + + _initialCount = count; + } + + #endregion + + #region Public Properties + + public HttpStreamAsyncResult AsyncResult { + get { + return _asyncResult; + } + + set { + _asyncResult = value; + } + } + + public byte[] Buffer { + get { + return _buffer; + } + + set { + _buffer = value; + } + } + + public int Count { + get { + return _count; + } + + set { + _count = value; + } + } + + public int InitialCount { + get { + return _initialCount; + } + + set { + _initialCount = value; + } + } + + public int Offset { + get { + return _offset; + } + + set { + _offset = value; + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ReadBufferState.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/ReadBufferState.cs.meta new file mode 100644 index 00000000..d0b72d11 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ReadBufferState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e742ab99989634093b0dd0df8f4b9cd0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/RequestStream.cs b/Plugins/websocket-sharp/websocket-sharp/Net/RequestStream.cs new file mode 100644 index 00000000..a8d9eaba --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/RequestStream.cs @@ -0,0 +1,318 @@ +#region License +/* + * RequestStream.cs + * + * This code is derived from RequestStream.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.IO; + +namespace WebSocketSharp.Net +{ + internal class RequestStream : Stream + { + #region Private Fields + + private long _bodyLeft; + private byte[] _buffer; + private int _count; + private bool _disposed; + private int _offset; + private Stream _stream; + + #endregion + + #region Internal Constructors + + internal RequestStream ( + Stream stream, byte[] buffer, int offset, int count, long contentLength + ) + { + _stream = stream; + _buffer = buffer; + _offset = offset; + _count = count; + _bodyLeft = contentLength; + } + + #endregion + + #region Public Properties + + public override bool CanRead { + get { + return true; + } + } + + public override bool CanSeek { + get { + return false; + } + } + + public override bool CanWrite { + get { + return false; + } + } + + public override long Length { + get { + throw new NotSupportedException (); + } + } + + public override long Position { + get { + throw new NotSupportedException (); + } + + set { + throw new NotSupportedException (); + } + } + + #endregion + + #region Private Methods + + private int fillFromBuffer (byte[] buffer, int offset, int count) + { + // This method returns a int: + // - > 0 The number of bytes read from the internal buffer + // - 0 No more bytes read from the internal buffer + // - -1 No more content data + + if (_bodyLeft == 0) + return -1; + + if (_count == 0) + return 0; + + if (count > _count) + count = _count; + + if (_bodyLeft > 0 && _bodyLeft < count) + count = (int) _bodyLeft; + + Buffer.BlockCopy (_buffer, _offset, buffer, offset, count); + + _offset += count; + _count -= count; + + if (_bodyLeft > 0) + _bodyLeft -= count; + + return count; + } + + #endregion + + #region Public Methods + + public override IAsyncResult BeginRead ( + byte[] buffer, int offset, int count, AsyncCallback callback, object state + ) + { + if (_disposed) { + var name = GetType ().ToString (); + + throw new ObjectDisposedException (name); + } + + if (buffer == null) + throw new ArgumentNullException ("buffer"); + + if (offset < 0) { + var msg = "A negative value."; + + throw new ArgumentOutOfRangeException ("offset", msg); + } + + if (count < 0) { + var msg = "A negative value."; + + throw new ArgumentOutOfRangeException ("count", msg); + } + + var len = buffer.Length; + + if (offset + count > len) { + var msg = "The sum of 'offset' and 'count' is greater than the length of 'buffer'."; + + throw new ArgumentException (msg); + } + + if (count == 0) + return _stream.BeginRead (buffer, offset, 0, callback, state); + + var nread = fillFromBuffer (buffer, offset, count); + + if (nread != 0) { + var ares = new HttpStreamAsyncResult (callback, state); + ares.Buffer = buffer; + ares.Offset = offset; + ares.Count = count; + ares.SyncRead = nread > 0 ? nread : 0; + ares.Complete (); + + return ares; + } + + if (_bodyLeft >= 0 && _bodyLeft < count) + count = (int) _bodyLeft; + + return _stream.BeginRead (buffer, offset, count, callback, state); + } + + public override IAsyncResult BeginWrite ( + byte[] buffer, int offset, int count, AsyncCallback callback, object state + ) + { + throw new NotSupportedException (); + } + + public override void Close () + { + _disposed = true; + } + + public override int EndRead (IAsyncResult asyncResult) + { + if (_disposed) { + var name = GetType ().ToString (); + + throw new ObjectDisposedException (name); + } + + if (asyncResult == null) + throw new ArgumentNullException ("asyncResult"); + + if (asyncResult is HttpStreamAsyncResult) { + var ares = (HttpStreamAsyncResult) asyncResult; + + if (!ares.IsCompleted) + ares.AsyncWaitHandle.WaitOne (); + + return ares.SyncRead; + } + + var nread = _stream.EndRead (asyncResult); + + if (nread > 0 && _bodyLeft > 0) + _bodyLeft -= nread; + + return nread; + } + + public override void EndWrite (IAsyncResult asyncResult) + { + throw new NotSupportedException (); + } + + public override void Flush () + { + } + + public override int Read (byte[] buffer, int offset, int count) + { + if (_disposed) { + var name = GetType ().ToString (); + + throw new ObjectDisposedException (name); + } + + if (buffer == null) + throw new ArgumentNullException ("buffer"); + + if (offset < 0) { + var msg = "A negative value."; + + throw new ArgumentOutOfRangeException ("offset", msg); + } + + if (count < 0) { + var msg = "A negative value."; + + throw new ArgumentOutOfRangeException ("count", msg); + } + + var len = buffer.Length; + + if (offset + count > len) { + var msg = "The sum of 'offset' and 'count' is greater than the length of 'buffer'."; + + throw new ArgumentException (msg); + } + + if (count == 0) + return 0; + + var nread = fillFromBuffer (buffer, offset, count); + + if (nread == -1) + return 0; + + if (nread > 0) + return nread; + + nread = _stream.Read (buffer, offset, count); + + if (nread > 0 && _bodyLeft > 0) + _bodyLeft -= nread; + + return nread; + } + + public override long Seek (long offset, SeekOrigin origin) + { + throw new NotSupportedException (); + } + + public override void SetLength (long value) + { + throw new NotSupportedException (); + } + + public override void Write (byte[] buffer, int offset, int count) + { + throw new NotSupportedException (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/RequestStream.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/RequestStream.cs.meta new file mode 100644 index 00000000..7a8b9f7d --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/RequestStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 837b9e902bd774d548cb37a56e422d4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ResponseStream.cs b/Plugins/websocket-sharp/websocket-sharp/Net/ResponseStream.cs new file mode 100644 index 00000000..c91b6e29 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ResponseStream.cs @@ -0,0 +1,403 @@ +#region License +/* + * ResponseStream.cs + * + * This code is derived from ResponseStream.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Gonzalo Paniagua Javier + */ +#endregion + +using System; +using System.IO; +using System.Text; + +namespace WebSocketSharp.Net +{ + internal class ResponseStream : Stream + { + #region Private Fields + + private MemoryStream _bodyBuffer; + private static readonly byte[] _crlf; + private bool _disposed; + private Stream _innerStream; + private static readonly byte[] _lastChunk; + private static readonly int _maxHeadersLength; + private HttpListenerResponse _response; + private bool _sendChunked; + private Action _write; + private Action _writeBody; + private Action _writeChunked; + + #endregion + + #region Static Constructor + + static ResponseStream () + { + _crlf = new byte[] { 13, 10 }; // "\r\n" + _lastChunk = new byte[] { 48, 13, 10, 13, 10 }; // "0\r\n\r\n" + _maxHeadersLength = 32768; + } + + #endregion + + #region Internal Constructors + + internal ResponseStream ( + Stream innerStream, + HttpListenerResponse response, + bool ignoreWriteExceptions + ) + { + _innerStream = innerStream; + _response = response; + + if (ignoreWriteExceptions) { + _write = writeWithoutThrowingException; + _writeChunked = writeChunkedWithoutThrowingException; + } + else { + _write = innerStream.Write; + _writeChunked = writeChunked; + } + + _bodyBuffer = new MemoryStream (); + } + + #endregion + + #region Public Properties + + public override bool CanRead { + get { + return false; + } + } + + public override bool CanSeek { + get { + return false; + } + } + + public override bool CanWrite { + get { + return !_disposed; + } + } + + public override long Length { + get { + throw new NotSupportedException (); + } + } + + public override long Position { + get { + throw new NotSupportedException (); + } + + set { + throw new NotSupportedException (); + } + } + + #endregion + + #region Private Methods + + private bool flush (bool closing) + { + if (!_response.HeadersSent) { + if (!flushHeaders ()) + return false; + + _response.HeadersSent = true; + + _sendChunked = _response.SendChunked; + _writeBody = _sendChunked ? _writeChunked : _write; + } + + flushBody (closing); + + return true; + } + + private void flushBody (bool closing) + { + using (_bodyBuffer) { + var len = _bodyBuffer.Length; + + if (len > Int32.MaxValue) { + _bodyBuffer.Position = 0; + + var buffLen = 1024; + var buff = new byte[buffLen]; + var nread = 0; + + while (true) { + nread = _bodyBuffer.Read (buff, 0, buffLen); + + if (nread <= 0) + break; + + _writeBody (buff, 0, nread); + } + } + else if (len > 0) { + _writeBody (_bodyBuffer.GetBuffer (), 0, (int) len); + } + } + + if (!closing) { + _bodyBuffer = new MemoryStream (); + return; + } + + if (_sendChunked) + _write (_lastChunk, 0, 5); + + _bodyBuffer = null; + } + + private bool flushHeaders () + { + if (!_response.SendChunked) { + if (_response.ContentLength64 != _bodyBuffer.Length) + return false; + } + + var statusLine = _response.StatusLine; + var headers = _response.FullHeaders; + + var buff = new MemoryStream (); + var enc = Encoding.UTF8; + + using (var writer = new StreamWriter (buff, enc, 256)) { + writer.Write (statusLine); + writer.Write (headers.ToStringMultiValue (true)); + writer.Flush (); + + var start = enc.GetPreamble ().Length; + var len = buff.Length - start; + + if (len > _maxHeadersLength) + return false; + + _write (buff.GetBuffer (), start, (int) len); + } + + _response.CloseConnection = headers["Connection"] == "close"; + + return true; + } + + private static byte[] getChunkSizeBytes (int size) + { + var chunkSize = String.Format ("{0:x}\r\n", size); + + return Encoding.ASCII.GetBytes (chunkSize); + } + + private void writeChunked (byte[] buffer, int offset, int count) + { + var size = getChunkSizeBytes (count); + + _innerStream.Write (size, 0, size.Length); + _innerStream.Write (buffer, offset, count); + _innerStream.Write (_crlf, 0, 2); + } + + private void writeChunkedWithoutThrowingException ( + byte[] buffer, int offset, int count + ) + { + try { + writeChunked (buffer, offset, count); + } + catch { + } + } + + private void writeWithoutThrowingException ( + byte[] buffer, int offset, int count + ) + { + try { + _innerStream.Write (buffer, offset, count); + } + catch { + } + } + + #endregion + + #region Internal Methods + + internal void Close (bool force) + { + if (_disposed) + return; + + _disposed = true; + + if (!force) { + if (flush (true)) { + _response.Close (); + + _response = null; + _innerStream = null; + + return; + } + + _response.CloseConnection = true; + } + + if (_sendChunked) + _write (_lastChunk, 0, 5); + + _bodyBuffer.Dispose (); + _response.Abort (); + + _bodyBuffer = null; + _response = null; + _innerStream = null; + } + + internal void InternalWrite (byte[] buffer, int offset, int count) + { + _write (buffer, offset, count); + } + + #endregion + + #region Public Methods + + public override IAsyncResult BeginRead ( + byte[] buffer, + int offset, + int count, + AsyncCallback callback, + object state + ) + { + throw new NotSupportedException (); + } + + public override IAsyncResult BeginWrite ( + byte[] buffer, + int offset, + int count, + AsyncCallback callback, + object state + ) + { + if (_disposed) { + var name = GetType ().ToString (); + + throw new ObjectDisposedException (name); + } + + return _bodyBuffer.BeginWrite (buffer, offset, count, callback, state); + } + + public override void Close () + { + Close (false); + } + + protected override void Dispose (bool disposing) + { + Close (!disposing); + } + + public override int EndRead (IAsyncResult asyncResult) + { + throw new NotSupportedException (); + } + + public override void EndWrite (IAsyncResult asyncResult) + { + if (_disposed) { + var name = GetType ().ToString (); + + throw new ObjectDisposedException (name); + } + + _bodyBuffer.EndWrite (asyncResult); + } + + public override void Flush () + { + if (_disposed) + return; + + var sendChunked = _sendChunked || _response.SendChunked; + + if (!sendChunked) + return; + + flush (false); + } + + public override int Read (byte[] buffer, int offset, int count) + { + throw new NotSupportedException (); + } + + public override long Seek (long offset, SeekOrigin origin) + { + throw new NotSupportedException (); + } + + public override void SetLength (long value) + { + throw new NotSupportedException (); + } + + public override void Write (byte[] buffer, int offset, int count) + { + if (_disposed) { + var name = GetType ().ToString (); + + throw new ObjectDisposedException (name); + } + + _bodyBuffer.Write (buffer, offset, count); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ResponseStream.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/ResponseStream.cs.meta new file mode 100644 index 00000000..18598851 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ResponseStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be642d9e6412844cfab92f1d4b465cc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ServerSslConfiguration.cs b/Plugins/websocket-sharp/websocket-sharp/Net/ServerSslConfiguration.cs new file mode 100644 index 00000000..47541f43 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ServerSslConfiguration.cs @@ -0,0 +1,236 @@ +#region License +/* + * ServerSslConfiguration.cs + * + * The MIT License + * + * Copyright (c) 2014 liryna + * Copyright (c) 2014-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Liryna + */ +#endregion + +using System; +using System.Net.Security; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; + +namespace WebSocketSharp.Net +{ + /// + /// Stores the parameters for the used by servers. + /// + public class ServerSslConfiguration + { + #region Private Fields + + private bool _checkCertRevocation; + private bool _clientCertRequired; + private RemoteCertificateValidationCallback _clientCertValidationCallback; + private SslProtocols _enabledSslProtocols; + private X509Certificate2 _serverCert; + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the + /// class. + /// + public ServerSslConfiguration () + { + _enabledSslProtocols = SslProtocols.None; + } + + /// + /// Initializes a new instance of the + /// class that stores the parameters copied from the specified configuration. + /// + /// + /// A from which to copy. + /// + /// + /// is . + /// + public ServerSslConfiguration (ServerSslConfiguration configuration) + { + if (configuration == null) + throw new ArgumentNullException ("configuration"); + + _checkCertRevocation = configuration._checkCertRevocation; + _clientCertRequired = configuration._clientCertRequired; + _clientCertValidationCallback = configuration._clientCertValidationCallback; + _enabledSslProtocols = configuration._enabledSslProtocols; + _serverCert = configuration._serverCert; + } + + #endregion + + #region Public Properties + + /// + /// Gets or sets a value indicating whether the certificate revocation + /// list is checked during authentication. + /// + /// + /// + /// true if the certificate revocation list is checked during + /// authentication; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool CheckCertificateRevocation { + get { + return _checkCertRevocation; + } + + set { + _checkCertRevocation = value; + } + } + + /// + /// Gets or sets a value indicating whether the client is asked for + /// a certificate for authentication. + /// + /// + /// + /// true if the client is asked for a certificate for + /// authentication; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool ClientCertificateRequired { + get { + return _clientCertRequired; + } + + set { + _clientCertRequired = value; + } + } + + /// + /// Gets or sets the callback used to validate the certificate supplied by + /// the client. + /// + /// + /// The certificate is valid if the callback returns true. + /// + /// + /// + /// A delegate that + /// invokes the method called for validating the certificate. + /// + /// + /// The default value is a delegate that invokes a method that only + /// returns true. + /// + /// + public RemoteCertificateValidationCallback ClientCertificateValidationCallback { + get { + if (_clientCertValidationCallback == null) + _clientCertValidationCallback = defaultValidateClientCertificate; + + return _clientCertValidationCallback; + } + + set { + _clientCertValidationCallback = value; + } + } + + /// + /// Gets or sets the protocols used for authentication. + /// + /// + /// + /// Any of the enum values. + /// + /// + /// It represents the protocols used for authentication. + /// + /// + /// The default value is . + /// + /// + public SslProtocols EnabledSslProtocols { + get { + return _enabledSslProtocols; + } + + set { + _enabledSslProtocols = value; + } + } + + /// + /// Gets or sets the certificate used to authenticate the server. + /// + /// + /// + /// A or . + /// + /// + /// The certificate represents an X.509 certificate. + /// + /// + /// The default value is . + /// + /// + public X509Certificate2 ServerCertificate { + get { + return _serverCert; + } + + set { + _serverCert = value; + } + } + + #endregion + + #region Private Methods + + private static bool defaultValidateClientCertificate ( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors + ) + { + return true; + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/ServerSslConfiguration.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/ServerSslConfiguration.cs.meta new file mode 100644 index 00000000..697abb5e --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/ServerSslConfiguration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67a3610e219e8491da36a4d59add3d7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebHeaderCollection.cs b/Plugins/websocket-sharp/websocket-sharp/Net/WebHeaderCollection.cs new file mode 100644 index 00000000..f92fc291 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebHeaderCollection.cs @@ -0,0 +1,1889 @@ +#region License +/* + * WebHeaderCollection.cs + * + * This code is derived from WebHeaderCollection.cs (System.Net) of Mono + * (http://www.mono-project.com). + * + * The MIT License + * + * Copyright (c) 2003 Ximian, Inc. (http://www.ximian.com) + * Copyright (c) 2007 Novell, Inc. (http://www.novell.com) + * Copyright (c) 2012-2020 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Authors +/* + * Authors: + * - Lawrence Pit + * - Gonzalo Paniagua Javier + * - Miguel de Icaza + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Security.Permissions; +using System.Text; + +namespace WebSocketSharp.Net +{ + /// + /// Provides a collection of the HTTP headers associated with a request or + /// response. + /// + [Serializable] + [ComVisible (true)] + public class WebHeaderCollection : NameValueCollection, ISerializable + { + #region Private Fields + + private static readonly Dictionary _headers; + private bool _internallyUsed; + private HttpHeaderType _state; + + #endregion + + #region Static Constructor + + static WebHeaderCollection () + { + _headers = + new Dictionary ( + StringComparer.InvariantCultureIgnoreCase + ) + { + { + "Accept", + new HttpHeaderInfo ( + "Accept", + HttpHeaderType.Request + | HttpHeaderType.Restricted + | HttpHeaderType.MultiValue + ) + }, + { + "AcceptCharset", + new HttpHeaderInfo ( + "Accept-Charset", + HttpHeaderType.Request | HttpHeaderType.MultiValue + ) + }, + { + "AcceptEncoding", + new HttpHeaderInfo ( + "Accept-Encoding", + HttpHeaderType.Request | HttpHeaderType.MultiValue + ) + }, + { + "AcceptLanguage", + new HttpHeaderInfo ( + "Accept-Language", + HttpHeaderType.Request | HttpHeaderType.MultiValue + ) + }, + { + "AcceptRanges", + new HttpHeaderInfo ( + "Accept-Ranges", + HttpHeaderType.Response | HttpHeaderType.MultiValue + ) + }, + { + "Age", + new HttpHeaderInfo ( + "Age", + HttpHeaderType.Response + ) + }, + { + "Allow", + new HttpHeaderInfo ( + "Allow", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValue + ) + }, + { + "Authorization", + new HttpHeaderInfo ( + "Authorization", + HttpHeaderType.Request | HttpHeaderType.MultiValue + ) + }, + { + "CacheControl", + new HttpHeaderInfo ( + "Cache-Control", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValue + ) + }, + { + "Connection", + new HttpHeaderInfo ( + "Connection", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.Restricted + | HttpHeaderType.MultiValue + ) + }, + { + "ContentEncoding", + new HttpHeaderInfo ( + "Content-Encoding", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValue + ) + }, + { + "ContentLanguage", + new HttpHeaderInfo ( + "Content-Language", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValue + ) + }, + { + "ContentLength", + new HttpHeaderInfo ( + "Content-Length", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.Restricted + ) + }, + { + "ContentLocation", + new HttpHeaderInfo ( + "Content-Location", + HttpHeaderType.Request | HttpHeaderType.Response + ) + }, + { + "ContentMd5", + new HttpHeaderInfo ( + "Content-MD5", + HttpHeaderType.Request | HttpHeaderType.Response + ) + }, + { + "ContentRange", + new HttpHeaderInfo ( + "Content-Range", + HttpHeaderType.Request | HttpHeaderType.Response + ) + }, + { + "ContentType", + new HttpHeaderInfo ( + "Content-Type", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.Restricted + ) + }, + { + "Cookie", + new HttpHeaderInfo ( + "Cookie", + HttpHeaderType.Request + ) + }, + { + "Cookie2", + new HttpHeaderInfo ( + "Cookie2", + HttpHeaderType.Request + ) + }, + { + "Date", + new HttpHeaderInfo ( + "Date", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.Restricted + ) + }, + { + "Expect", + new HttpHeaderInfo ( + "Expect", + HttpHeaderType.Request + | HttpHeaderType.Restricted + | HttpHeaderType.MultiValue + ) + }, + { + "Expires", + new HttpHeaderInfo ( + "Expires", + HttpHeaderType.Request | HttpHeaderType.Response + ) + }, + { + "ETag", + new HttpHeaderInfo ( + "ETag", + HttpHeaderType.Response + ) + }, + { + "From", + new HttpHeaderInfo ( + "From", + HttpHeaderType.Request + ) + }, + { + "Host", + new HttpHeaderInfo ( + "Host", + HttpHeaderType.Request | HttpHeaderType.Restricted + ) + }, + { + "IfMatch", + new HttpHeaderInfo ( + "If-Match", + HttpHeaderType.Request | HttpHeaderType.MultiValue + ) + }, + { + "IfModifiedSince", + new HttpHeaderInfo ( + "If-Modified-Since", + HttpHeaderType.Request | HttpHeaderType.Restricted + ) + }, + { + "IfNoneMatch", + new HttpHeaderInfo ( + "If-None-Match", + HttpHeaderType.Request | HttpHeaderType.MultiValue + ) + }, + { + "IfRange", + new HttpHeaderInfo ( + "If-Range", + HttpHeaderType.Request + ) + }, + { + "IfUnmodifiedSince", + new HttpHeaderInfo ( + "If-Unmodified-Since", + HttpHeaderType.Request + ) + }, + { + "KeepAlive", + new HttpHeaderInfo ( + "Keep-Alive", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValue + ) + }, + { + "LastModified", + new HttpHeaderInfo ( + "Last-Modified", + HttpHeaderType.Request | HttpHeaderType.Response + ) + }, + { + "Location", + new HttpHeaderInfo ( + "Location", + HttpHeaderType.Response + ) + }, + { + "MaxForwards", + new HttpHeaderInfo ( + "Max-Forwards", + HttpHeaderType.Request + ) + }, + { + "Pragma", + new HttpHeaderInfo ( + "Pragma", + HttpHeaderType.Request | HttpHeaderType.Response + ) + }, + { + "ProxyAuthenticate", + new HttpHeaderInfo ( + "Proxy-Authenticate", + HttpHeaderType.Response | HttpHeaderType.MultiValue + ) + }, + { + "ProxyAuthorization", + new HttpHeaderInfo ( + "Proxy-Authorization", + HttpHeaderType.Request + ) + }, + { + "ProxyConnection", + new HttpHeaderInfo ( + "Proxy-Connection", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.Restricted + ) + }, + { + "Public", + new HttpHeaderInfo ( + "Public", + HttpHeaderType.Response | HttpHeaderType.MultiValue + ) + }, + { + "Range", + new HttpHeaderInfo ( + "Range", + HttpHeaderType.Request + | HttpHeaderType.Restricted + | HttpHeaderType.MultiValue + ) + }, + { + "Referer", + new HttpHeaderInfo ( + "Referer", + HttpHeaderType.Request | HttpHeaderType.Restricted + ) + }, + { + "RetryAfter", + new HttpHeaderInfo ( + "Retry-After", + HttpHeaderType.Response + ) + }, + { + "SecWebSocketAccept", + new HttpHeaderInfo ( + "Sec-WebSocket-Accept", + HttpHeaderType.Response | HttpHeaderType.Restricted + ) + }, + { + "SecWebSocketExtensions", + new HttpHeaderInfo ( + "Sec-WebSocket-Extensions", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.Restricted + | HttpHeaderType.MultiValueInRequest + ) + }, + { + "SecWebSocketKey", + new HttpHeaderInfo ( + "Sec-WebSocket-Key", + HttpHeaderType.Request | HttpHeaderType.Restricted + ) + }, + { + "SecWebSocketProtocol", + new HttpHeaderInfo ( + "Sec-WebSocket-Protocol", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValueInRequest + ) + }, + { + "SecWebSocketVersion", + new HttpHeaderInfo ( + "Sec-WebSocket-Version", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.Restricted + | HttpHeaderType.MultiValueInResponse + ) + }, + { + "Server", + new HttpHeaderInfo ( + "Server", + HttpHeaderType.Response + ) + }, + { + "SetCookie", + new HttpHeaderInfo ( + "Set-Cookie", + HttpHeaderType.Response | HttpHeaderType.MultiValue + ) + }, + { + "SetCookie2", + new HttpHeaderInfo ( + "Set-Cookie2", + HttpHeaderType.Response | HttpHeaderType.MultiValue + ) + }, + { + "Te", + new HttpHeaderInfo ( + "TE", + HttpHeaderType.Request + ) + }, + { + "Trailer", + new HttpHeaderInfo ( + "Trailer", + HttpHeaderType.Request | HttpHeaderType.Response + ) + }, + { + "TransferEncoding", + new HttpHeaderInfo ( + "Transfer-Encoding", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.Restricted + | HttpHeaderType.MultiValue + ) + }, + { + "Translate", + new HttpHeaderInfo ( + "Translate", + HttpHeaderType.Request + ) + }, + { + "Upgrade", + new HttpHeaderInfo ( + "Upgrade", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValue + ) + }, + { + "UserAgent", + new HttpHeaderInfo ( + "User-Agent", + HttpHeaderType.Request | HttpHeaderType.Restricted + ) + }, + { + "Vary", + new HttpHeaderInfo ( + "Vary", + HttpHeaderType.Response | HttpHeaderType.MultiValue + ) + }, + { + "Via", + new HttpHeaderInfo ( + "Via", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValue + ) + }, + { + "Warning", + new HttpHeaderInfo ( + "Warning", + HttpHeaderType.Request + | HttpHeaderType.Response + | HttpHeaderType.MultiValue + ) + }, + { + "WwwAuthenticate", + new HttpHeaderInfo ( + "WWW-Authenticate", + HttpHeaderType.Response + | HttpHeaderType.Restricted + | HttpHeaderType.MultiValue + ) + } + }; + } + + #endregion + + #region Internal Constructors + + internal WebHeaderCollection (HttpHeaderType state, bool internallyUsed) + { + _state = state; + _internallyUsed = internallyUsed; + } + + #endregion + + #region Protected Constructors + + /// + /// Initializes a new instance of the class + /// from the specified instances of the and + /// classes. + /// + /// + /// A that contains the serialized + /// object data. + /// + /// + /// A that specifies the source for + /// the deserialization. + /// + /// + /// is . + /// + /// + /// An element with the specified name is not found in + /// . + /// + protected WebHeaderCollection ( + SerializationInfo serializationInfo, StreamingContext streamingContext + ) + { + if (serializationInfo == null) + throw new ArgumentNullException ("serializationInfo"); + + try { + _internallyUsed = serializationInfo.GetBoolean ("InternallyUsed"); + _state = (HttpHeaderType) serializationInfo.GetInt32 ("State"); + + var cnt = serializationInfo.GetInt32 ("Count"); + + for (var i = 0; i < cnt; i++) { + base.Add ( + serializationInfo.GetString (i.ToString ()), + serializationInfo.GetString ((cnt + i).ToString ()) + ); + } + } + catch (SerializationException ex) { + throw new ArgumentException (ex.Message, "serializationInfo", ex); + } + } + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the + /// class. + /// + public WebHeaderCollection () + { + } + + #endregion + + #region Internal Properties + + internal HttpHeaderType State { + get { + return _state; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets all header names in the collection. + /// + /// + /// An array of that contains all header names in + /// the collection. + /// + public override string[] AllKeys { + get { + return base.AllKeys; + } + } + + /// + /// Gets the number of headers in the collection. + /// + /// + /// An that represents the number of headers in + /// the collection. + /// + public override int Count { + get { + return base.Count; + } + } + + /// + /// Gets or sets the specified request header. + /// + /// + /// A that represents the value of the request header. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the request header to get or set. + /// + /// + /// + /// + /// is a restricted header. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the request header. + /// + public string this[HttpRequestHeader header] { + get { + var key = header.ToString (); + var name = getHeaderName (key); + + return Get (name); + } + + set { + Add (header, value); + } + } + + /// + /// Gets or sets the specified response header. + /// + /// + /// A that represents the value of the response header. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the response header to get or set. + /// + /// + /// + /// + /// is a restricted header. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the response header. + /// + public string this[HttpResponseHeader header] { + get { + var key = header.ToString (); + var name = getHeaderName (key); + + return Get (name); + } + + set { + Add (header, value); + } + } + + /// + /// Gets a collection of header names in the collection. + /// + /// + /// A that contains + /// all header names in the collection. + /// + public override NameObjectCollectionBase.KeysCollection Keys { + get { + return base.Keys; + } + } + + #endregion + + #region Private Methods + + private void add (string name, string value, HttpHeaderType headerType) + { + base.Add (name, value); + + if (_state != HttpHeaderType.Unspecified) + return; + + if (headerType == HttpHeaderType.Unspecified) + return; + + _state = headerType; + } + + private void checkAllowed (HttpHeaderType headerType) + { + if (_state == HttpHeaderType.Unspecified) + return; + + if (headerType == HttpHeaderType.Unspecified) + return; + + if (headerType != _state) { + var msg = "This instance does not allow the header."; + + throw new InvalidOperationException (msg); + } + } + + private static string checkName (string name, string paramName) + { + if (name == null) { + var msg = "The name is null."; + + throw new ArgumentNullException (paramName, msg); + } + + if (name.Length == 0) { + var msg = "The name is an empty string."; + + throw new ArgumentException (msg, paramName); + } + + name = name.Trim (); + + if (name.Length == 0) { + var msg = "The name is a string of spaces."; + + throw new ArgumentException (msg, paramName); + } + + if (!name.IsToken ()) { + var msg = "The name contains an invalid character."; + + throw new ArgumentException (msg, paramName); + } + + return name; + } + + private void checkRestricted (string name, HttpHeaderType headerType) + { + if (_internallyUsed) + return; + + var res = headerType == HttpHeaderType.Response; + + if (isRestricted (name, res)) { + var msg = "The header is a restricted header."; + + throw new ArgumentException (msg); + } + } + + private static string checkValue (string value, string paramName) + { + if (value == null) + return String.Empty; + + value = value.Trim (); + + var len = value.Length; + + if (len == 0) + return value; + + if (len > 65535) { + var msg = "The length of the value is greater than 65,535 characters."; + + throw new ArgumentOutOfRangeException (paramName, msg); + } + + if (!value.IsText ()) { + var msg = "The value contains an invalid character."; + + throw new ArgumentException (msg, paramName); + } + + return value; + } + + private static HttpHeaderInfo getHeaderInfo (string name) + { + var comparison = StringComparison.InvariantCultureIgnoreCase; + + foreach (var headerInfo in _headers.Values) { + if (headerInfo.HeaderName.Equals (name, comparison)) + return headerInfo; + } + + return null; + } + + private static string getHeaderName (string key) + { + HttpHeaderInfo headerInfo; + + return _headers.TryGetValue (key, out headerInfo) + ? headerInfo.HeaderName + : null; + } + + private static HttpHeaderType getHeaderType (string name) + { + var headerInfo = getHeaderInfo (name); + + if (headerInfo == null) + return HttpHeaderType.Unspecified; + + if (headerInfo.IsRequest) { + return !headerInfo.IsResponse + ? HttpHeaderType.Request + : HttpHeaderType.Unspecified; + } + + return headerInfo.IsResponse + ? HttpHeaderType.Response + : HttpHeaderType.Unspecified; + } + + private static bool isMultiValue (string name, bool response) + { + var headerInfo = getHeaderInfo (name); + + return headerInfo != null && headerInfo.IsMultiValue (response); + } + + private static bool isRestricted (string name, bool response) + { + var headerInfo = getHeaderInfo (name); + + return headerInfo != null && headerInfo.IsRestricted (response); + } + + private void set (string name, string value, HttpHeaderType headerType) + { + base.Set (name, value); + + if (_state != HttpHeaderType.Unspecified) + return; + + if (headerType == HttpHeaderType.Unspecified) + return; + + _state = headerType; + } + + #endregion + + #region Internal Methods + + internal void InternalRemove (string name) + { + base.Remove (name); + } + + internal void InternalSet (string header, bool response) + { + var idx = header.IndexOf (':'); + + if (idx == -1) { + var msg = "It does not contain a colon character."; + + throw new ArgumentException (msg, "header"); + } + + var name = header.Substring (0, idx); + var val = idx < header.Length - 1 + ? header.Substring (idx + 1) + : String.Empty; + + name = checkName (name, "header"); + val = checkValue (val, "header"); + + if (isMultiValue (name, response)) { + base.Add (name, val); + + return; + } + + base.Set (name, val); + } + + internal void InternalSet (string name, string value, bool response) + { + value = checkValue (value, "value"); + + if (isMultiValue (name, response)) { + base.Add (name, value); + + return; + } + + base.Set (name, value); + } + + internal string ToStringMultiValue (bool response) + { + var cnt = Count; + + if (cnt == 0) + return "\r\n"; + + var buff = new StringBuilder (); + + for (var i = 0; i < cnt; i++) { + var name = GetKey (i); + + if (isMultiValue (name, response)) { + foreach (var val in GetValues (i)) + buff.AppendFormat ("{0}: {1}\r\n", name, val); + + continue; + } + + buff.AppendFormat ("{0}: {1}\r\n", name, Get (i)); + } + + buff.Append ("\r\n"); + + return buff.ToString (); + } + + #endregion + + #region Protected Methods + + /// + /// Adds a header to the collection without checking if the header is on + /// the restricted header list. + /// + /// + /// A that specifies the name of the header to add. + /// + /// + /// A that specifies the value of the header to add. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is a string of spaces. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the header. + /// + protected void AddWithoutValidate (string headerName, string headerValue) + { + headerName = checkName (headerName, "headerName"); + headerValue = checkValue (headerValue, "headerValue"); + + var headerType = getHeaderType (headerName); + + checkAllowed (headerType); + add (headerName, headerValue, headerType); + } + + #endregion + + #region Public Methods + + /// + /// Adds the specified header to the collection. + /// + /// + /// A that specifies the header to add, + /// with the name and value separated by a colon character (':'). + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// does not contain a colon character. + /// + /// + /// -or- + /// + /// + /// The name part of is an empty string. + /// + /// + /// -or- + /// + /// + /// The name part of is a string of spaces. + /// + /// + /// -or- + /// + /// + /// The name part of contains an invalid + /// character. + /// + /// + /// -or- + /// + /// + /// The value part of contains an invalid + /// character. + /// + /// + /// -or- + /// + /// + /// is a restricted header. + /// + /// + /// + /// The length of the value part of is greater + /// than 65,535 characters. + /// + /// + /// This instance does not allow the header. + /// + public void Add (string header) + { + if (header == null) + throw new ArgumentNullException ("header"); + + var len = header.Length; + + if (len == 0) { + var msg = "An empty string."; + + throw new ArgumentException (msg, "header"); + } + + var idx = header.IndexOf (':'); + + if (idx == -1) { + var msg = "It does not contain a colon character."; + + throw new ArgumentException (msg, "header"); + } + + var name = header.Substring (0, idx); + var val = idx < len - 1 + ? header.Substring (idx + 1) + : String.Empty; + + name = checkName (name, "header"); + val = checkValue (val, "header"); + + var headerType = getHeaderType (name); + + checkRestricted (name, headerType); + checkAllowed (headerType); + add (name, val, headerType); + } + + /// + /// Adds the specified request header with the specified value to + /// the collection. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the request header to add. + /// + /// + /// + /// A that specifies the value of the header to add. + /// + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the request header. + /// + public void Add (HttpRequestHeader header, string value) + { + value = checkValue (value, "value"); + + var key = header.ToString (); + var name = getHeaderName (key); + + checkRestricted (name, HttpHeaderType.Request); + checkAllowed (HttpHeaderType.Request); + add (name, value, HttpHeaderType.Request); + } + + /// + /// Adds the specified response header with the specified value to + /// the collection. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the response header to add. + /// + /// + /// + /// A that specifies the value of the header to add. + /// + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the response header. + /// + public void Add (HttpResponseHeader header, string value) + { + value = checkValue (value, "value"); + + var key = header.ToString (); + var name = getHeaderName (key); + + checkRestricted (name, HttpHeaderType.Response); + checkAllowed (HttpHeaderType.Response); + add (name, value, HttpHeaderType.Response); + } + + /// + /// Adds a header with the specified name and value to the collection. + /// + /// + /// A that specifies the name of the header to add. + /// + /// + /// A that specifies the value of the header to add. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is a string of spaces. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header name. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the header. + /// + public override void Add (string name, string value) + { + name = checkName (name, "name"); + value = checkValue (value, "value"); + + var headerType = getHeaderType (name); + + checkRestricted (name, headerType); + checkAllowed (headerType); + add (name, value, headerType); + } + + /// + /// Removes all headers from the collection. + /// + public override void Clear () + { + base.Clear (); + _state = HttpHeaderType.Unspecified; + } + + /// + /// Get the value of the header at the specified index in the collection. + /// + /// + /// A that receives the value of the header. + /// + /// + /// An that specifies the zero-based index of the header + /// to find. + /// + /// + /// is out of allowable range of indexes for + /// the collection. + /// + public override string Get (int index) + { + return base.Get (index); + } + + /// + /// Get the value of the header with the specified name in the collection. + /// + /// + /// + /// A that receives the value of the header. + /// + /// + /// if not found. + /// + /// + /// + /// A that specifies the name of the header to find. + /// + public override string Get (string name) + { + return base.Get (name); + } + + /// + /// Gets the enumerator used to iterate through the collection. + /// + /// + /// An instance used to iterate through + /// the collection. + /// + public override IEnumerator GetEnumerator () + { + return base.GetEnumerator (); + } + + /// + /// Get the name of the header at the specified index in the collection. + /// + /// + /// A that receives the name of the header. + /// + /// + /// An that specifies the zero-based index of the header + /// to find. + /// + /// + /// is out of allowable range of indexes for + /// the collection. + /// + public override string GetKey (int index) + { + return base.GetKey (index); + } + + /// + /// Get the values of the header at the specified index in the collection. + /// + /// + /// + /// An array of that receives the values of + /// the header. + /// + /// + /// if not present. + /// + /// + /// + /// An that specifies the zero-based index of the header + /// to find. + /// + /// + /// is out of allowable range of indexes for + /// the collection. + /// + public override string[] GetValues (int index) + { + var vals = base.GetValues (index); + + return vals != null && vals.Length > 0 ? vals : null; + } + + /// + /// Get the values of the header with the specified name in the collection. + /// + /// + /// + /// An array of that receives the values of + /// the header. + /// + /// + /// if not present. + /// + /// + /// + /// A that specifies the name of the header to find. + /// + public override string[] GetValues (string name) + { + var vals = base.GetValues (name); + + return vals != null && vals.Length > 0 ? vals : null; + } + + /// + /// Populates a instance with the data + /// needed to serialize this instance. + /// + /// + /// A to populate with the data. + /// + /// + /// A that specifies the destination for + /// the serialization. + /// + /// + /// is . + /// + [ + SecurityPermission ( + SecurityAction.LinkDemand, + Flags = SecurityPermissionFlag.SerializationFormatter + ) + ] + public override void GetObjectData ( + SerializationInfo serializationInfo, StreamingContext streamingContext + ) + { + if (serializationInfo == null) + throw new ArgumentNullException ("serializationInfo"); + + serializationInfo.AddValue ("InternallyUsed", _internallyUsed); + serializationInfo.AddValue ("State", (int) _state); + + var cnt = Count; + + serializationInfo.AddValue ("Count", cnt); + + for (var i = 0; i < cnt; i++) { + serializationInfo.AddValue (i.ToString (), GetKey (i)); + serializationInfo.AddValue ((cnt + i).ToString (), Get (i)); + } + } + + /// + /// Determines whether the specified HTTP header can be set for the request. + /// + /// + /// true if the header cannot be set; otherwise, false. + /// + /// + /// A that specifies the name of the header to test. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is a string of spaces. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + public static bool IsRestricted (string headerName) + { + return IsRestricted (headerName, false); + } + + /// + /// Determines whether the specified HTTP header can be set for the request + /// or the response. + /// + /// + /// true if the header cannot be set; otherwise, false. + /// + /// + /// A that specifies the name of the header to test. + /// + /// + /// A : true if the test is for the response; + /// otherwise, false. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is a string of spaces. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + public static bool IsRestricted (string headerName, bool response) + { + headerName = checkName (headerName, "headerName"); + + return isRestricted (headerName, response); + } + + /// + /// Implements the interface and raises + /// the deserialization event when the deserialization is complete. + /// + /// + /// An instance that represents the source of + /// the deserialization event. + /// + public override void OnDeserialization (object sender) + { + } + + /// + /// Removes the specified request header from the collection. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the request header to remove. + /// + /// + /// + /// is a restricted header. + /// + /// + /// This instance does not allow the request header. + /// + public void Remove (HttpRequestHeader header) + { + var key = header.ToString (); + var name = getHeaderName (key); + + checkRestricted (name, HttpHeaderType.Request); + checkAllowed (HttpHeaderType.Request); + base.Remove (name); + } + + /// + /// Removes the specified response header from the collection. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the response header to remove. + /// + /// + /// + /// is a restricted header. + /// + /// + /// This instance does not allow the response header. + /// + public void Remove (HttpResponseHeader header) + { + var key = header.ToString (); + var name = getHeaderName (key); + + checkRestricted (name, HttpHeaderType.Response); + checkAllowed (HttpHeaderType.Response); + base.Remove (name); + } + + /// + /// Removes the specified header from the collection. + /// + /// + /// A that specifies the name of the header to remove. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is a string of spaces. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header name. + /// + /// + /// + /// This instance does not allow the header. + /// + public override void Remove (string name) + { + name = checkName (name, "name"); + + var headerType = getHeaderType (name); + + checkRestricted (name, headerType); + checkAllowed (headerType); + base.Remove (name); + } + + /// + /// Sets the specified request header to the specified value. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the request header to set. + /// + /// + /// + /// A that specifies the value of the request header + /// to set. + /// + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the request header. + /// + public void Set (HttpRequestHeader header, string value) + { + value = checkValue (value, "value"); + + var key = header.ToString (); + var name = getHeaderName (key); + + checkRestricted (name, HttpHeaderType.Request); + checkAllowed (HttpHeaderType.Request); + set (name, value, HttpHeaderType.Request); + } + + /// + /// Sets the specified response header to the specified value. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the response header to set. + /// + /// + /// + /// A that specifies the value of the response header + /// to set. + /// + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the response header. + /// + public void Set (HttpResponseHeader header, string value) + { + value = checkValue (value, "value"); + + var key = header.ToString (); + var name = getHeaderName (key); + + checkRestricted (name, HttpHeaderType.Response); + checkAllowed (HttpHeaderType.Response); + set (name, value, HttpHeaderType.Response); + } + + /// + /// Sets the specified header to the specified value. + /// + /// + /// A that specifies the name of the header to set. + /// + /// + /// A that specifies the value of the header to set. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is a string of spaces. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// is a restricted header name. + /// + /// + /// + /// The length of is greater than 65,535 + /// characters. + /// + /// + /// This instance does not allow the header. + /// + public override void Set (string name, string value) + { + name = checkName (name, "name"); + value = checkValue (value, "value"); + + var headerType = getHeaderType (name); + + checkRestricted (name, headerType); + checkAllowed (headerType); + set (name, value, headerType); + } + + /// + /// Converts the current instance to an array of byte. + /// + /// + /// An array of converted from a string that represents + /// the current instance. + /// + public byte[] ToByteArray () + { + return Encoding.UTF8.GetBytes (ToString ()); + } + + /// + /// Returns a string that represents the current instance. + /// + /// + /// A that represents all headers in the collection. + /// + public override string ToString () + { + var cnt = Count; + + if (cnt == 0) + return "\r\n"; + + var buff = new StringBuilder (); + + for (var i = 0; i < cnt; i++) + buff.AppendFormat ("{0}: {1}\r\n", GetKey (i), Get (i)); + + buff.Append ("\r\n"); + + return buff.ToString (); + } + + #endregion + + #region Explicit Interface Implementations + + /// + /// Populates a instance with the data + /// needed to serialize this instance. + /// + /// + /// A to populate with the data. + /// + /// + /// A that specifies the destination for + /// the serialization. + /// + /// + /// is . + /// + [ + SecurityPermission ( + SecurityAction.LinkDemand, + Flags = SecurityPermissionFlag.SerializationFormatter, + SerializationFormatter = true + ) + ] + void ISerializable.GetObjectData ( + SerializationInfo serializationInfo, StreamingContext streamingContext + ) + { + GetObjectData (serializationInfo, streamingContext); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebHeaderCollection.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/WebHeaderCollection.cs.meta new file mode 100644 index 00000000..52738a4e --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebHeaderCollection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02443bde705304e9d99c4055aad740c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets.meta b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets.meta new file mode 100644 index 00000000..236d6410 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 39ffe4f806e964f03ab31380829cf028 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs new file mode 100644 index 00000000..ac963c78 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs @@ -0,0 +1,395 @@ +#region License +/* + * HttpListenerWebSocketContext.cs + * + * The MIT License + * + * Copyright (c) 2012-2018 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Security.Principal; + +namespace WebSocketSharp.Net.WebSockets +{ + /// + /// Provides the access to the information in a WebSocket handshake request to + /// a instance. + /// + public class HttpListenerWebSocketContext : WebSocketContext + { + #region Private Fields + + private HttpListenerContext _context; + private WebSocket _websocket; + + #endregion + + #region Internal Constructors + + internal HttpListenerWebSocketContext ( + HttpListenerContext context, string protocol + ) + { + _context = context; + _websocket = new WebSocket (this, protocol); + } + + #endregion + + #region Internal Properties + + internal Logger Log { + get { + return _context.Listener.Log; + } + } + + internal Stream Stream { + get { + return _context.Connection.Stream; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the HTTP cookies included in the handshake request. + /// + /// + /// + /// A that contains + /// the cookies. + /// + /// + /// An empty collection if not included. + /// + /// + public override CookieCollection CookieCollection { + get { + return _context.Request.Cookies; + } + } + + /// + /// Gets the HTTP headers included in the handshake request. + /// + /// + /// A that contains the headers. + /// + public override NameValueCollection Headers { + get { + return _context.Request.Headers; + } + } + + /// + /// Gets the value of the Host header included in the handshake request. + /// + /// + /// + /// A that represents the server host name requested + /// by the client. + /// + /// + /// It includes the port number if provided. + /// + /// + public override string Host { + get { + return _context.Request.UserHostName; + } + } + + /// + /// Gets a value indicating whether the client is authenticated. + /// + /// + /// true if the client is authenticated; otherwise, false. + /// + public override bool IsAuthenticated { + get { + return _context.Request.IsAuthenticated; + } + } + + /// + /// Gets a value indicating whether the handshake request is sent from + /// the local computer. + /// + /// + /// true if the handshake request is sent from the same computer + /// as the server; otherwise, false. + /// + public override bool IsLocal { + get { + return _context.Request.IsLocal; + } + } + + /// + /// Gets a value indicating whether a secure connection is used to send + /// the handshake request. + /// + /// + /// true if the connection is secure; otherwise, false. + /// + public override bool IsSecureConnection { + get { + return _context.Request.IsSecureConnection; + } + } + + /// + /// Gets a value indicating whether the request is a WebSocket handshake + /// request. + /// + /// + /// true if the request is a WebSocket handshake request; otherwise, + /// false. + /// + public override bool IsWebSocketRequest { + get { + return _context.Request.IsWebSocketRequest; + } + } + + /// + /// Gets the value of the Origin header included in the handshake request. + /// + /// + /// + /// A that represents the value of the Origin header. + /// + /// + /// if the header is not present. + /// + /// + public override string Origin { + get { + return _context.Request.Headers["Origin"]; + } + } + + /// + /// Gets the query string included in the handshake request. + /// + /// + /// + /// A that contains the query + /// parameters. + /// + /// + /// An empty collection if not included. + /// + /// + public override NameValueCollection QueryString { + get { + return _context.Request.QueryString; + } + } + + /// + /// Gets the URI requested by the client. + /// + /// + /// + /// A that represents the URI parsed from the request. + /// + /// + /// if the URI cannot be parsed. + /// + /// + public override Uri RequestUri { + get { + return _context.Request.Url; + } + } + + /// + /// Gets the value of the Sec-WebSocket-Key header included in + /// the handshake request. + /// + /// + /// + /// A that represents the value of + /// the Sec-WebSocket-Key header. + /// + /// + /// The value is used to prove that the server received + /// a valid WebSocket handshake request. + /// + /// + /// if the header is not present. + /// + /// + public override string SecWebSocketKey { + get { + return _context.Request.Headers["Sec-WebSocket-Key"]; + } + } + + /// + /// Gets the names of the subprotocols from the Sec-WebSocket-Protocol + /// header included in the handshake request. + /// + /// + /// + /// An + /// instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the names of the subprotocols. + /// + /// + public override IEnumerable SecWebSocketProtocols { + get { + var val = _context.Request.Headers["Sec-WebSocket-Protocol"]; + if (val == null || val.Length == 0) + yield break; + + foreach (var elm in val.Split (',')) { + var protocol = elm.Trim (); + if (protocol.Length == 0) + continue; + + yield return protocol; + } + } + } + + /// + /// Gets the value of the Sec-WebSocket-Version header included in + /// the handshake request. + /// + /// + /// + /// A that represents the WebSocket protocol + /// version specified by the client. + /// + /// + /// if the header is not present. + /// + /// + public override string SecWebSocketVersion { + get { + return _context.Request.Headers["Sec-WebSocket-Version"]; + } + } + + /// + /// Gets the endpoint to which the handshake request is sent. + /// + /// + /// A that represents the server IP + /// address and port number. + /// + public override System.Net.IPEndPoint ServerEndPoint { + get { + return _context.Request.LocalEndPoint; + } + } + + /// + /// Gets the client information. + /// + /// + /// + /// A instance that represents identity, + /// authentication, and security roles for the client. + /// + /// + /// if the client is not authenticated. + /// + /// + public override IPrincipal User { + get { + return _context.User; + } + } + + /// + /// Gets the endpoint from which the handshake request is sent. + /// + /// + /// A that represents the client IP + /// address and port number. + /// + public override System.Net.IPEndPoint UserEndPoint { + get { + return _context.Request.RemoteEndPoint; + } + } + + /// + /// Gets the WebSocket instance used for two-way communication between + /// the client and server. + /// + /// + /// A . + /// + public override WebSocket WebSocket { + get { + return _websocket; + } + } + + #endregion + + #region Internal Methods + + internal void Close () + { + _context.Connection.Close (true); + } + + internal void Close (HttpStatusCode code) + { + _context.Response.StatusCode = (int) code; + _context.Response.Close (); + } + + #endregion + + #region Public Methods + + /// + /// Returns a string that represents the current instance. + /// + /// + /// A that contains the request line and headers + /// included in the handshake request. + /// + public override string ToString () + { + return _context.Request.ToString (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs.meta new file mode 100644 index 00000000..8595e686 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad4bcec9c7dfe491cb8be048f59fab2b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs new file mode 100644 index 00000000..519da789 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs @@ -0,0 +1,518 @@ +#region License +/* + * TcpListenerWebSocketContext.cs + * + * The MIT License + * + * Copyright (c) 2012-2018 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Liryna + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Net.Security; +using System.Net.Sockets; +using System.Security.Principal; +using System.Text; + +namespace WebSocketSharp.Net.WebSockets +{ + /// + /// Provides the access to the information in a WebSocket handshake request to + /// a instance. + /// + internal class TcpListenerWebSocketContext : WebSocketContext + { + #region Private Fields + + private Logger _log; + private NameValueCollection _queryString; + private HttpRequest _request; + private Uri _requestUri; + private bool _secure; + private System.Net.EndPoint _serverEndPoint; + private Stream _stream; + private TcpClient _tcpClient; + private IPrincipal _user; + private System.Net.EndPoint _userEndPoint; + private WebSocket _websocket; + + #endregion + + #region Internal Constructors + + internal TcpListenerWebSocketContext ( + TcpClient tcpClient, + string protocol, + bool secure, + ServerSslConfiguration sslConfig, + Logger log + ) + { + _tcpClient = tcpClient; + _secure = secure; + _log = log; + + var netStream = tcpClient.GetStream (); + if (secure) { + var sslStream = new SslStream ( + netStream, + false, + sslConfig.ClientCertificateValidationCallback + ); + + sslStream.AuthenticateAsServer ( + sslConfig.ServerCertificate, + sslConfig.ClientCertificateRequired, + sslConfig.EnabledSslProtocols, + sslConfig.CheckCertificateRevocation + ); + + _stream = sslStream; + } + else { + _stream = netStream; + } + + var sock = tcpClient.Client; + _serverEndPoint = sock.LocalEndPoint; + _userEndPoint = sock.RemoteEndPoint; + + _request = HttpRequest.Read (_stream, 90000); + _websocket = new WebSocket (this, protocol); + } + + #endregion + + #region Internal Properties + + internal Logger Log { + get { + return _log; + } + } + + internal Stream Stream { + get { + return _stream; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the HTTP cookies included in the handshake request. + /// + /// + /// + /// A that contains + /// the cookies. + /// + /// + /// An empty collection if not included. + /// + /// + public override CookieCollection CookieCollection { + get { + return _request.Cookies; + } + } + + /// + /// Gets the HTTP headers included in the handshake request. + /// + /// + /// A that contains the headers. + /// + public override NameValueCollection Headers { + get { + return _request.Headers; + } + } + + /// + /// Gets the value of the Host header included in the handshake request. + /// + /// + /// + /// A that represents the server host name requested + /// by the client. + /// + /// + /// It includes the port number if provided. + /// + /// + public override string Host { + get { + return _request.Headers["Host"]; + } + } + + /// + /// Gets a value indicating whether the client is authenticated. + /// + /// + /// true if the client is authenticated; otherwise, false. + /// + public override bool IsAuthenticated { + get { + return _user != null; + } + } + + /// + /// Gets a value indicating whether the handshake request is sent from + /// the local computer. + /// + /// + /// true if the handshake request is sent from the same computer + /// as the server; otherwise, false. + /// + public override bool IsLocal { + get { + return UserEndPoint.Address.IsLocal (); + } + } + + /// + /// Gets a value indicating whether a secure connection is used to send + /// the handshake request. + /// + /// + /// true if the connection is secure; otherwise, false. + /// + public override bool IsSecureConnection { + get { + return _secure; + } + } + + /// + /// Gets a value indicating whether the request is a WebSocket handshake + /// request. + /// + /// + /// true if the request is a WebSocket handshake request; otherwise, + /// false. + /// + public override bool IsWebSocketRequest { + get { + return _request.IsWebSocketRequest; + } + } + + /// + /// Gets the value of the Origin header included in the handshake request. + /// + /// + /// + /// A that represents the value of the Origin header. + /// + /// + /// if the header is not present. + /// + /// + public override string Origin { + get { + return _request.Headers["Origin"]; + } + } + + /// + /// Gets the query string included in the handshake request. + /// + /// + /// + /// A that contains the query + /// parameters. + /// + /// + /// An empty collection if not included. + /// + /// + public override NameValueCollection QueryString { + get { + if (_queryString == null) { + var uri = RequestUri; + _queryString = QueryStringCollection.Parse ( + uri != null ? uri.Query : null, + Encoding.UTF8 + ); + } + + return _queryString; + } + } + + /// + /// Gets the URI requested by the client. + /// + /// + /// + /// A that represents the URI parsed from the request. + /// + /// + /// if the URI cannot be parsed. + /// + /// + public override Uri RequestUri { + get { + if (_requestUri == null) { + _requestUri = HttpUtility.CreateRequestUrl ( + _request.RequestUri, + _request.Headers["Host"], + _request.IsWebSocketRequest, + _secure + ); + } + + return _requestUri; + } + } + + /// + /// Gets the value of the Sec-WebSocket-Key header included in + /// the handshake request. + /// + /// + /// + /// A that represents the value of + /// the Sec-WebSocket-Key header. + /// + /// + /// The value is used to prove that the server received + /// a valid WebSocket handshake request. + /// + /// + /// if the header is not present. + /// + /// + public override string SecWebSocketKey { + get { + return _request.Headers["Sec-WebSocket-Key"]; + } + } + + /// + /// Gets the names of the subprotocols from the Sec-WebSocket-Protocol + /// header included in the handshake request. + /// + /// + /// + /// An + /// instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the names of the subprotocols. + /// + /// + public override IEnumerable SecWebSocketProtocols { + get { + var val = _request.Headers["Sec-WebSocket-Protocol"]; + if (val == null || val.Length == 0) + yield break; + + foreach (var elm in val.Split (',')) { + var protocol = elm.Trim (); + if (protocol.Length == 0) + continue; + + yield return protocol; + } + } + } + + /// + /// Gets the value of the Sec-WebSocket-Version header included in + /// the handshake request. + /// + /// + /// + /// A that represents the WebSocket protocol + /// version specified by the client. + /// + /// + /// if the header is not present. + /// + /// + public override string SecWebSocketVersion { + get { + return _request.Headers["Sec-WebSocket-Version"]; + } + } + + /// + /// Gets the endpoint to which the handshake request is sent. + /// + /// + /// A that represents the server IP + /// address and port number. + /// + public override System.Net.IPEndPoint ServerEndPoint { + get { + return (System.Net.IPEndPoint) _serverEndPoint; + } + } + + /// + /// Gets the client information. + /// + /// + /// + /// A instance that represents identity, + /// authentication, and security roles for the client. + /// + /// + /// if the client is not authenticated. + /// + /// + public override IPrincipal User { + get { + return _user; + } + } + + /// + /// Gets the endpoint from which the handshake request is sent. + /// + /// + /// A that represents the client IP + /// address and port number. + /// + public override System.Net.IPEndPoint UserEndPoint { + get { + return (System.Net.IPEndPoint) _userEndPoint; + } + } + + /// + /// Gets the WebSocket instance used for two-way communication between + /// the client and server. + /// + /// + /// A . + /// + public override WebSocket WebSocket { + get { + return _websocket; + } + } + + #endregion + + #region Private Methods + + private HttpRequest sendAuthenticationChallenge (string challenge) + { + var res = HttpResponse.CreateUnauthorizedResponse (challenge); + var bytes = res.ToByteArray (); + _stream.Write (bytes, 0, bytes.Length); + + return HttpRequest.Read (_stream, 15000); + } + + #endregion + + #region Internal Methods + + internal bool Authenticate ( + AuthenticationSchemes scheme, + string realm, + Func credentialsFinder + ) + { + var chal = new AuthenticationChallenge (scheme, realm).ToString (); + + var retry = -1; + Func auth = null; + auth = + () => { + retry++; + if (retry > 99) + return false; + + var user = HttpUtility.CreateUser ( + _request.Headers["Authorization"], + scheme, + realm, + _request.HttpMethod, + credentialsFinder + ); + + if (user != null && user.Identity.IsAuthenticated) { + _user = user; + return true; + } + + _request = sendAuthenticationChallenge (chal); + return auth (); + }; + + return auth (); + } + + internal void Close () + { + _stream.Close (); + _tcpClient.Close (); + } + + internal void Close (HttpStatusCode code) + { + var res = HttpResponse.CreateCloseResponse (code); + var bytes = res.ToByteArray (); + _stream.Write (bytes, 0, bytes.Length); + + _stream.Close (); + _tcpClient.Close (); + } + + #endregion + + #region Public Methods + + /// + /// Returns a string that represents the current instance. + /// + /// + /// A that contains the request line and headers + /// included in the handshake request. + /// + public override string ToString () + { + return _request.ToString (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs.meta new file mode 100644 index 00000000..ad258abd --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e4f3583ce398946c5924d84b9c37949a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/WebSocketContext.cs b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/WebSocketContext.cs new file mode 100644 index 00000000..6921891f --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/WebSocketContext.cs @@ -0,0 +1,224 @@ +#region License +/* + * WebSocketContext.cs + * + * The MIT License + * + * Copyright (c) 2012-2018 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Security.Principal; + +namespace WebSocketSharp.Net.WebSockets +{ + /// + /// Exposes the access to the information in a WebSocket handshake request. + /// + /// + /// This class is an abstract class. + /// + public abstract class WebSocketContext + { + #region Protected Constructors + + /// + /// Initializes a new instance of the class. + /// + protected WebSocketContext () + { + } + + #endregion + + #region Public Properties + + /// + /// Gets the HTTP cookies included in the handshake request. + /// + /// + /// A that contains + /// the cookies. + /// + public abstract CookieCollection CookieCollection { get; } + + /// + /// Gets the HTTP headers included in the handshake request. + /// + /// + /// A that contains the headers. + /// + public abstract NameValueCollection Headers { get; } + + /// + /// Gets the value of the Host header included in the handshake request. + /// + /// + /// A that represents the server host name requested + /// by the client. + /// + public abstract string Host { get; } + + /// + /// Gets a value indicating whether the client is authenticated. + /// + /// + /// true if the client is authenticated; otherwise, false. + /// + public abstract bool IsAuthenticated { get; } + + /// + /// Gets a value indicating whether the handshake request is sent from + /// the local computer. + /// + /// + /// true if the handshake request is sent from the same computer + /// as the server; otherwise, false. + /// + public abstract bool IsLocal { get; } + + /// + /// Gets a value indicating whether a secure connection is used to send + /// the handshake request. + /// + /// + /// true if the connection is secure; otherwise, false. + /// + public abstract bool IsSecureConnection { get; } + + /// + /// Gets a value indicating whether the request is a WebSocket handshake + /// request. + /// + /// + /// true if the request is a WebSocket handshake request; otherwise, + /// false. + /// + public abstract bool IsWebSocketRequest { get; } + + /// + /// Gets the value of the Origin header included in the handshake request. + /// + /// + /// A that represents the value of the Origin header. + /// + public abstract string Origin { get; } + + /// + /// Gets the query string included in the handshake request. + /// + /// + /// A that contains the query parameters. + /// + public abstract NameValueCollection QueryString { get; } + + /// + /// Gets the URI requested by the client. + /// + /// + /// A that represents the URI parsed from the request. + /// + public abstract Uri RequestUri { get; } + + /// + /// Gets the value of the Sec-WebSocket-Key header included in + /// the handshake request. + /// + /// + /// + /// A that represents the value of + /// the Sec-WebSocket-Key header. + /// + /// + /// The value is used to prove that the server received + /// a valid WebSocket handshake request. + /// + /// + public abstract string SecWebSocketKey { get; } + + /// + /// Gets the names of the subprotocols from the Sec-WebSocket-Protocol + /// header included in the handshake request. + /// + /// + /// + /// An + /// instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the names of the subprotocols. + /// + /// + public abstract IEnumerable SecWebSocketProtocols { get; } + + /// + /// Gets the value of the Sec-WebSocket-Version header included in + /// the handshake request. + /// + /// + /// A that represents the WebSocket protocol + /// version specified by the client. + /// + public abstract string SecWebSocketVersion { get; } + + /// + /// Gets the endpoint to which the handshake request is sent. + /// + /// + /// A that represents the server IP + /// address and port number. + /// + public abstract System.Net.IPEndPoint ServerEndPoint { get; } + + /// + /// Gets the client information. + /// + /// + /// A instance that represents identity, + /// authentication, and security roles for the client. + /// + public abstract IPrincipal User { get; } + + /// + /// Gets the endpoint from which the handshake request is sent. + /// + /// + /// A that represents the client IP + /// address and port number. + /// + public abstract System.Net.IPEndPoint UserEndPoint { get; } + + /// + /// Gets the WebSocket instance used for two-way communication between + /// the client and server. + /// + /// + /// A . + /// + public abstract WebSocket WebSocket { get; } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/WebSocketContext.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/WebSocketContext.cs.meta new file mode 100644 index 00000000..e34e3f0d --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Net/WebSockets/WebSocketContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe3ff51618e8f41dd9344b6ac5dfcc76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Opcode.cs b/Plugins/websocket-sharp/websocket-sharp/Opcode.cs new file mode 100644 index 00000000..5a8c632e --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Opcode.cs @@ -0,0 +1,68 @@ +#region License +/* + * Opcode.cs + * + * The MIT License + * + * Copyright (c) 2012-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Indicates the WebSocket frame type. + /// + /// + /// The values of this enumeration are defined in + /// + /// Section 5.2 of RFC 6455. + /// + internal enum Opcode : byte + { + /// + /// Equivalent to numeric value 0. Indicates continuation frame. + /// + Cont = 0x0, + /// + /// Equivalent to numeric value 1. Indicates text frame. + /// + Text = 0x1, + /// + /// Equivalent to numeric value 2. Indicates binary frame. + /// + Binary = 0x2, + /// + /// Equivalent to numeric value 8. Indicates connection close frame. + /// + Close = 0x8, + /// + /// Equivalent to numeric value 9. Indicates ping frame. + /// + Ping = 0x9, + /// + /// Equivalent to numeric value 10. Indicates pong frame. + /// + Pong = 0xa + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Opcode.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Opcode.cs.meta new file mode 100644 index 00000000..1e6372b3 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Opcode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 92d1b2b8ce5f34b3ca6bb830e5a3c37a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/PayloadData.cs b/Plugins/websocket-sharp/websocket-sharp/PayloadData.cs new file mode 100644 index 00000000..9e40b940 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/PayloadData.cs @@ -0,0 +1,208 @@ +#region License +/* + * PayloadData.cs + * + * The MIT License + * + * Copyright (c) 2012-2019 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace WebSocketSharp +{ + internal class PayloadData : IEnumerable + { + #region Private Fields + + private byte[] _data; + private long _extDataLength; + private long _length; + + #endregion + + #region Public Fields + + /// + /// Represents the empty payload data. + /// + public static readonly PayloadData Empty; + + /// + /// Represents the allowable max length of payload data. + /// + /// + /// + /// A will occur when the length of + /// incoming payload data is greater than the value of this field. + /// + /// + /// If you would like to change the value of this field, it must be + /// a number between and + /// inclusive. + /// + /// + public static readonly ulong MaxLength; + + #endregion + + #region Static Constructor + + static PayloadData () + { + Empty = new PayloadData (WebSocket.EmptyBytes, 0); + MaxLength = Int64.MaxValue; + } + + #endregion + + #region Internal Constructors + + internal PayloadData (byte[] data) + : this (data, data.LongLength) + { + } + + internal PayloadData (byte[] data, long length) + { + _data = data; + _length = length; + } + + internal PayloadData (ushort code, string reason) + { + _data = code.Append (reason); + _length = _data.LongLength; + } + + #endregion + + #region Internal Properties + + internal ushort Code { + get { + return _length >= 2 + ? _data.SubArray (0, 2).ToUInt16 (ByteOrder.Big) + : (ushort) 1005; + } + } + + internal long ExtensionDataLength { + get { + return _extDataLength; + } + + set { + _extDataLength = value; + } + } + + internal bool HasReservedCode { + get { + return _length >= 2 && Code.IsReserved (); + } + } + + internal string Reason { + get { + if (_length <= 2) + return String.Empty; + + var raw = _data.SubArray (2, _length - 2); + + string reason; + return raw.TryGetUTF8DecodedString (out reason) + ? reason + : String.Empty; + } + } + + #endregion + + #region Public Properties + + public byte[] ApplicationData { + get { + return _extDataLength > 0 + ? _data.SubArray (_extDataLength, _length - _extDataLength) + : _data; + } + } + + public byte[] ExtensionData { + get { + return _extDataLength > 0 + ? _data.SubArray (0, _extDataLength) + : WebSocket.EmptyBytes; + } + } + + public ulong Length { + get { + return (ulong) _length; + } + } + + #endregion + + #region Internal Methods + + internal void Mask (byte[] key) + { + for (long i = 0; i < _length; i++) + _data[i] = (byte) (_data[i] ^ key[i % 4]); + } + + #endregion + + #region Public Methods + + public IEnumerator GetEnumerator () + { + foreach (var b in _data) + yield return b; + } + + public byte[] ToArray () + { + return _data; + } + + public override string ToString () + { + return BitConverter.ToString (_data); + } + + #endregion + + #region Explicit Interface Implementations + + IEnumerator IEnumerable.GetEnumerator () + { + return GetEnumerator (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/PayloadData.cs.meta b/Plugins/websocket-sharp/websocket-sharp/PayloadData.cs.meta new file mode 100644 index 00000000..7a9e1428 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/PayloadData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fd26df4d7aac427294cc0ac713fa9e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Rsv.cs b/Plugins/websocket-sharp/websocket-sharp/Rsv.cs new file mode 100644 index 00000000..8a10567c --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Rsv.cs @@ -0,0 +1,51 @@ +#region License +/* + * Rsv.cs + * + * The MIT License + * + * Copyright (c) 2012-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Indicates whether each RSV (RSV1, RSV2, and RSV3) of a WebSocket frame is non-zero. + /// + /// + /// The values of this enumeration are defined in + /// Section 5.2 of RFC 6455. + /// + internal enum Rsv : byte + { + /// + /// Equivalent to numeric value 0. Indicates zero. + /// + Off = 0x0, + /// + /// Equivalent to numeric value 1. Indicates non-zero. + /// + On = 0x1 + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Rsv.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Rsv.cs.meta new file mode 100644 index 00000000..db1717b2 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Rsv.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49ca9b2d695d243e897a231b672e842f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server.meta b/Plugins/websocket-sharp/websocket-sharp/Server.meta new file mode 100644 index 00000000..9566b239 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cb1916257deec45c68fe1eeb3b406bb1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/HttpRequestEventArgs.cs b/Plugins/websocket-sharp/websocket-sharp/Server/HttpRequestEventArgs.cs new file mode 100644 index 00000000..722fe8b9 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/HttpRequestEventArgs.cs @@ -0,0 +1,260 @@ +#region License +/* + * HttpRequestEventArgs.cs + * + * The MIT License + * + * Copyright (c) 2012-2021 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.IO; +using System.Security.Principal; +using System.Text; +using WebSocketSharp.Net; + +namespace WebSocketSharp.Server +{ + /// + /// Represents the event data for the HTTP request events of the + /// class. + /// + /// + /// + /// An HTTP request event occurs when the + /// instance receives an HTTP request. + /// + /// + /// You should access the property if you would + /// like to get the request data sent from a client. + /// + /// + /// And you should access the property if you + /// would like to get the response data to return to the client. + /// + /// + public class HttpRequestEventArgs : EventArgs + { + #region Private Fields + + private HttpListenerContext _context; + private string _docRootPath; + + #endregion + + #region Internal Constructors + + internal HttpRequestEventArgs ( + HttpListenerContext context, string documentRootPath + ) + { + _context = context; + _docRootPath = documentRootPath; + } + + #endregion + + #region Public Properties + + /// + /// Gets the request data sent from a client. + /// + /// + /// A that provides the methods and + /// properties for the request data. + /// + public HttpListenerRequest Request { + get { + return _context.Request; + } + } + + /// + /// Gets the response data to return to the client. + /// + /// + /// A that provides the methods and + /// properties for the response data. + /// + public HttpListenerResponse Response { + get { + return _context.Response; + } + } + + /// + /// Gets the information for the client. + /// + /// + /// + /// A instance or + /// if not authenticated. + /// + /// + /// That instance describes the identity, authentication scheme, + /// and security roles for the client. + /// + /// + public IPrincipal User { + get { + return _context.User; + } + } + + #endregion + + #region Private Methods + + private string createFilePath (string childPath) + { + childPath = childPath.TrimStart ('/', '\\'); + + return new StringBuilder (_docRootPath, 32) + .AppendFormat ("/{0}", childPath) + .ToString () + .Replace ('\\', '/'); + } + + private static bool tryReadFile (string path, out byte[] contents) + { + contents = null; + + if (!File.Exists (path)) + return false; + + try { + contents = File.ReadAllBytes (path); + } + catch { + return false; + } + + return true; + } + + #endregion + + #region Public Methods + + /// + /// Reads the specified file from the document folder of the + /// class. + /// + /// + /// + /// An array of or + /// if it fails. + /// + /// + /// That array receives the contents of the file. + /// + /// + /// + /// A that specifies a virtual path to + /// find the file from the document folder. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// contains "..". + /// + /// + public byte[] ReadFile (string path) + { + if (path == null) + throw new ArgumentNullException ("path"); + + if (path.Length == 0) + throw new ArgumentException ("An empty string.", "path"); + + if (path.IndexOf ("..") > -1) + throw new ArgumentException ("It contains '..'.", "path"); + + path = createFilePath (path); + byte[] contents; + + tryReadFile (path, out contents); + + return contents; + } + + /// + /// Tries to read the specified file from the document folder of + /// the class. + /// + /// + /// true if it succeeds to read; otherwise, false. + /// + /// + /// A that specifies a virtual path to find + /// the file from the document folder. + /// + /// + /// + /// When this method returns, an array of or + /// if it fails. + /// + /// + /// That array receives the contents of the file. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// contains "..". + /// + /// + public bool TryReadFile (string path, out byte[] contents) + { + if (path == null) + throw new ArgumentNullException ("path"); + + if (path.Length == 0) + throw new ArgumentException ("An empty string.", "path"); + + if (path.IndexOf ("..") > -1) + throw new ArgumentException ("It contains '..'.", "path"); + + path = createFilePath (path); + + return tryReadFile (path, out contents); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/HttpRequestEventArgs.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/HttpRequestEventArgs.cs.meta new file mode 100644 index 00000000..fbb1496c --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/HttpRequestEventArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e411a70bf8664d01babb8c782da79fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/HttpServer.cs b/Plugins/websocket-sharp/websocket-sharp/Server/HttpServer.cs new file mode 100644 index 00000000..71bb52bf --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/HttpServer.cs @@ -0,0 +1,1485 @@ +#region License +/* + * HttpServer.cs + * + * The MIT License + * + * Copyright (c) 2012-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Juan Manuel Lallana + * - Liryna + * - Rohan Singh + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net.Sockets; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.Text; +using System.Threading; +using WebSocketSharp.Net; +using WebSocketSharp.Net.WebSockets; + +namespace WebSocketSharp.Server +{ + /// + /// Provides a simple HTTP server. + /// + /// + /// + /// The server supports HTTP/1.1 version request and response. + /// + /// + /// And the server allows to accept WebSocket handshake requests. + /// + /// + /// This class can provide multiple WebSocket services. + /// + /// + public class HttpServer + { + #region Private Fields + + private System.Net.IPAddress _address; + private string _docRootPath; + private string _hostname; + private HttpListener _listener; + private Logger _log; + private int _port; + private Thread _receiveThread; + private bool _secure; + private WebSocketServiceManager _services; + private volatile ServerState _state; + private object _sync; + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class. + /// + /// + /// The new instance listens for incoming requests on + /// and port 80. + /// + public HttpServer () + { + init ("*", System.Net.IPAddress.Any, 80, false); + } + + /// + /// Initializes a new instance of the class with + /// the specified port. + /// + /// + /// + /// The new instance listens for incoming requests on + /// and . + /// + /// + /// It provides secure connections if is 443. + /// + /// + /// + /// An that specifies the number of the port on which + /// to listen. + /// + /// + /// is less than 1 or greater than 65535. + /// + public HttpServer (int port) + : this (port, port == 443) + { + } + + /// + /// Initializes a new instance of the class with + /// the specified URL. + /// + /// + /// + /// The new instance listens for incoming requests on the IP address and + /// port of . + /// + /// + /// Either port 80 or 443 is used if includes + /// no port. Port 443 is used if the scheme of + /// is https; otherwise, port 80 is used. + /// + /// + /// The new instance provides secure connections if the scheme of + /// is https. + /// + /// + /// + /// A that specifies the HTTP URL of the server. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is invalid. + /// + /// + public HttpServer (string url) + { + if (url == null) + throw new ArgumentNullException ("url"); + + if (url.Length == 0) + throw new ArgumentException ("An empty string.", "url"); + + Uri uri; + string msg; + + if (!tryCreateUri (url, out uri, out msg)) + throw new ArgumentException (msg, "url"); + + var host = uri.GetDnsSafeHost (true); + var addr = host.ToIPAddress (); + + if (addr == null) { + msg = "The host part could not be converted to an IP address."; + + throw new ArgumentException (msg, "url"); + } + + if (!addr.IsLocal ()) { + msg = "The IP address of the host is not a local IP address."; + + throw new ArgumentException (msg, "url"); + } + + init (host, addr, uri.Port, uri.Scheme == "https"); + } + + /// + /// Initializes a new instance of the class with + /// the specified port and boolean if secure or not. + /// + /// + /// The new instance listens for incoming requests on + /// and . + /// + /// + /// An that specifies the number of the port on which + /// to listen. + /// + /// + /// A : true if the new instance provides + /// secure connections; otherwise, false. + /// + /// + /// is less than 1 or greater than 65535. + /// + public HttpServer (int port, bool secure) + { + if (!port.IsPortNumber ()) { + var msg = "It is less than 1 or greater than 65535."; + + throw new ArgumentOutOfRangeException ("port", msg); + } + + init ("*", System.Net.IPAddress.Any, port, secure); + } + + /// + /// Initializes a new instance of the class with + /// the specified IP address and port. + /// + /// + /// + /// The new instance listens for incoming requests on + /// and . + /// + /// + /// It provides secure connections if is 443. + /// + /// + /// + /// A that specifies the local IP + /// address on which to listen. + /// + /// + /// An that specifies the number of the port on which + /// to listen. + /// + /// + /// is . + /// + /// + /// is not a local IP address. + /// + /// + /// is less than 1 or greater than 65535. + /// + public HttpServer (System.Net.IPAddress address, int port) + : this (address, port, port == 443) + { + } + + /// + /// Initializes a new instance of the class with + /// the specified IP address, port, and boolean if secure or not. + /// + /// + /// The new instance listens for incoming requests on + /// and . + /// + /// + /// A that specifies the local IP + /// address on which to listen. + /// + /// + /// An that specifies the number of the port on which + /// to listen. + /// + /// + /// A : true if the new instance provides + /// secure connections; otherwise, false. + /// + /// + /// is . + /// + /// + /// is not a local IP address. + /// + /// + /// is less than 1 or greater than 65535. + /// + public HttpServer (System.Net.IPAddress address, int port, bool secure) + { + if (address == null) + throw new ArgumentNullException ("address"); + + if (!address.IsLocal ()) { + var msg = "It is not a local IP address."; + + throw new ArgumentException (msg, "address"); + } + + if (!port.IsPortNumber ()) { + var msg = "It is less than 1 or greater than 65535."; + + throw new ArgumentOutOfRangeException ("port", msg); + } + + init (address.ToString (true), address, port, secure); + } + + #endregion + + #region Public Properties + + /// + /// Gets the IP address of the server. + /// + /// + /// A that represents the local + /// IP address on which to listen for incoming requests. + /// + public System.Net.IPAddress Address { + get { + return _address; + } + } + + /// + /// Gets or sets the scheme used to authenticate the clients. + /// + /// + /// The set operation does nothing if the server has already + /// started or it is shutting down. + /// + /// + /// + /// One of the + /// enum values. + /// + /// + /// It represents the scheme used to authenticate the clients. + /// + /// + /// The default value is + /// . + /// + /// + public AuthenticationSchemes AuthenticationSchemes { + get { + return _listener.AuthenticationSchemes; + } + + set { + lock (_sync) { + string msg; + + if (!canSet (out msg)) { + _log.Warn (msg); + + return; + } + + _listener.AuthenticationSchemes = value; + } + } + } + + /// + /// Gets or sets the path to the document folder of the server. + /// + /// + /// + /// '/' or '\' is trimmed from the end of the value if any. + /// + /// + /// The set operation does nothing if the server has already + /// started or it is shutting down. + /// + /// + /// + /// + /// A that represents a path to the folder + /// from which to find the requested file. + /// + /// + /// The default value is "./Public". + /// + /// + /// + /// The value specified for a set operation is . + /// + /// + /// + /// The value specified for a set operation is an empty string. + /// + /// + /// -or- + /// + /// + /// The value specified for a set operation is an absolute root. + /// + /// + /// -or- + /// + /// + /// The value specified for a set operation is an invalid path string. + /// + /// + public string DocumentRootPath { + get { + return _docRootPath; + } + + set { + if (value == null) + throw new ArgumentNullException ("value"); + + if (value.Length == 0) + throw new ArgumentException ("An empty string.", "value"); + + value = value.TrimSlashOrBackslashFromEnd (); + + if (value == "/") + throw new ArgumentException ("An absolute root.", "value"); + + if (value == "\\") + throw new ArgumentException ("An absolute root.", "value"); + + if (value.Length == 2 && value[1] == ':') + throw new ArgumentException ("An absolute root.", "value"); + + string full = null; + + try { + full = Path.GetFullPath (value); + } + catch (Exception ex) { + throw new ArgumentException ("An invalid path string.", "value", ex); + } + + if (full == "/") + throw new ArgumentException ("An absolute root.", "value"); + + full = full.TrimSlashOrBackslashFromEnd (); + + if (full.Length == 2 && full[1] == ':') + throw new ArgumentException ("An absolute root.", "value"); + + lock (_sync) { + string msg; + + if (!canSet (out msg)) { + _log.Warn (msg); + + return; + } + + _docRootPath = value; + } + } + } + + /// + /// Gets a value indicating whether the server has started. + /// + /// + /// true if the server has started; otherwise, false. + /// + public bool IsListening { + get { + return _state == ServerState.Start; + } + } + + /// + /// Gets a value indicating whether secure connections are provided. + /// + /// + /// true if this instance provides secure connections; otherwise, + /// false. + /// + public bool IsSecure { + get { + return _secure; + } + } + + /// + /// Gets or sets a value indicating whether the server cleans up + /// the inactive sessions periodically. + /// + /// + /// The set operation does nothing if the server has already + /// started or it is shutting down. + /// + /// + /// + /// true if the server cleans up the inactive sessions + /// every 60 seconds; otherwise, false. + /// + /// + /// The default value is true. + /// + /// + public bool KeepClean { + get { + return _services.KeepClean; + } + + set { + _services.KeepClean = value; + } + } + + /// + /// Gets the logging function for the server. + /// + /// + /// The default logging level is . + /// + /// + /// A that provides the logging function. + /// + public Logger Log { + get { + return _log; + } + } + + /// + /// Gets the port of the server. + /// + /// + /// An that represents the number of the port + /// on which to listen for incoming requests. + /// + public int Port { + get { + return _port; + } + } + + /// + /// Gets or sets the realm used for authentication. + /// + /// + /// + /// "SECRET AREA" is used as the realm if the value is + /// or an empty string. + /// + /// + /// The set operation does nothing if the server has + /// already started or it is shutting down. + /// + /// + /// + /// + /// A that represents the name of + /// the realm or . + /// + /// + /// The default value is . + /// + /// + public string Realm { + get { + return _listener.Realm; + } + + set { + lock (_sync) { + string msg; + + if (!canSet (out msg)) { + _log.Warn (msg); + + return; + } + + _listener.Realm = value; + } + } + } + + /// + /// Gets or sets a value indicating whether the server is allowed to + /// be bound to an address that is already in use. + /// + /// + /// + /// You should set this property to true if you would + /// like to resolve to wait for socket in TIME_WAIT state. + /// + /// + /// The set operation does nothing if the server has already + /// started or it is shutting down. + /// + /// + /// + /// + /// true if the server is allowed to be bound to an address + /// that is already in use; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool ReuseAddress { + get { + return _listener.ReuseAddress; + } + + set { + lock (_sync) { + string msg; + + if (!canSet (out msg)) { + _log.Warn (msg); + + return; + } + + _listener.ReuseAddress = value; + } + } + } + + /// + /// Gets the configuration for secure connection. + /// + /// + /// The configuration will be referenced when attempts to start, + /// so it must be configured before the start method is called. + /// + /// + /// A that represents + /// the configuration used to provide secure connections. + /// + /// + /// This server does not provide secure connections. + /// + public ServerSslConfiguration SslConfiguration { + get { + if (!_secure) { + var msg = "The server does not provide secure connections."; + + throw new InvalidOperationException (msg); + } + + return _listener.SslConfiguration; + } + } + + /// + /// Gets or sets the delegate used to find the credentials + /// for an identity. + /// + /// + /// + /// No credentials are found if the method invoked by + /// the delegate returns or + /// the value is . + /// + /// + /// The set operation does nothing if the server has + /// already started or it is shutting down. + /// + /// + /// + /// + /// A Func<, + /// > delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called for finding + /// the credentials used to authenticate a client. + /// + /// + /// The default value is . + /// + /// + public Func UserCredentialsFinder { + get { + return _listener.UserCredentialsFinder; + } + + set { + lock (_sync) { + string msg; + + if (!canSet (out msg)) { + _log.Warn (msg); + + return; + } + + _listener.UserCredentialsFinder = value; + } + } + } + + /// + /// Gets or sets the time to wait for the response to the WebSocket + /// Ping or Close. + /// + /// + /// The set operation does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// + /// A to wait for the response. + /// + /// + /// The default value is the same as 1 second. + /// + /// + /// + /// The value specified for a set operation is zero or less. + /// + public TimeSpan WaitTime { + get { + return _services.WaitTime; + } + + set { + _services.WaitTime = value; + } + } + + /// + /// Gets the management function for the WebSocket services + /// provided by the server. + /// + /// + /// A that manages + /// the WebSocket services provided by the server. + /// + public WebSocketServiceManager WebSocketServices { + get { + return _services; + } + } + + #endregion + + #region Public Events + + /// + /// Occurs when the server receives an HTTP CONNECT request. + /// + public event EventHandler OnConnect; + + /// + /// Occurs when the server receives an HTTP DELETE request. + /// + public event EventHandler OnDelete; + + /// + /// Occurs when the server receives an HTTP GET request. + /// + public event EventHandler OnGet; + + /// + /// Occurs when the server receives an HTTP HEAD request. + /// + public event EventHandler OnHead; + + /// + /// Occurs when the server receives an HTTP OPTIONS request. + /// + public event EventHandler OnOptions; + + /// + /// Occurs when the server receives an HTTP POST request. + /// + public event EventHandler OnPost; + + /// + /// Occurs when the server receives an HTTP PUT request. + /// + public event EventHandler OnPut; + + /// + /// Occurs when the server receives an HTTP TRACE request. + /// + public event EventHandler OnTrace; + + #endregion + + #region Private Methods + + private void abort () + { + lock (_sync) { + if (_state != ServerState.Start) + return; + + _state = ServerState.ShuttingDown; + } + + try { + try { + _services.Stop (1006, String.Empty); + } + finally { + _listener.Abort (); + } + } + catch { + } + + _state = ServerState.Stop; + } + + private bool canSet (out string message) + { + message = null; + + if (_state == ServerState.Start) { + message = "The server has already started."; + + return false; + } + + if (_state == ServerState.ShuttingDown) { + message = "The server is shutting down."; + + return false; + } + + return true; + } + + private bool checkCertificate (out string message) + { + message = null; + + var byUser = _listener.SslConfiguration.ServerCertificate != null; + + var path = _listener.CertificateFolderPath; + var withPort = EndPointListener.CertificateExists (_port, path); + + var either = byUser || withPort; + + if (!either) { + message = "There is no server certificate for secure connection."; + + return false; + } + + var both = byUser && withPort; + + if (both) { + var msg = "The server certificate associated with the port is used."; + + _log.Warn (msg); + } + + return true; + } + + private static HttpListener createListener ( + string hostname, int port, bool secure + ) + { + var lsnr = new HttpListener (); + + var schm = secure ? "https" : "http"; + var pref = String.Format ("{0}://{1}:{2}/", schm, hostname, port); + lsnr.Prefixes.Add (pref); + + return lsnr; + } + + private void init ( + string hostname, System.Net.IPAddress address, int port, bool secure + ) + { + _hostname = hostname; + _address = address; + _port = port; + _secure = secure; + + _docRootPath = "./Public"; + _listener = createListener (_hostname, _port, _secure); + _log = _listener.Log; + _services = new WebSocketServiceManager (_log); + _sync = new object (); + } + + private void processRequest (HttpListenerContext context) + { + var method = context.Request.HttpMethod; + var evt = method == "GET" + ? OnGet + : method == "HEAD" + ? OnHead + : method == "POST" + ? OnPost + : method == "PUT" + ? OnPut + : method == "DELETE" + ? OnDelete + : method == "CONNECT" + ? OnConnect + : method == "OPTIONS" + ? OnOptions + : method == "TRACE" + ? OnTrace + : null; + + if (evt != null) + evt (this, new HttpRequestEventArgs (context, _docRootPath)); + else + context.Response.StatusCode = 501; // Not Implemented + + context.Response.Close (); + } + + private void processRequest (HttpListenerWebSocketContext context) + { + var uri = context.RequestUri; + + if (uri == null) { + context.Close (HttpStatusCode.BadRequest); + + return; + } + + var path = uri.AbsolutePath; + + if (path.IndexOfAny (new[] { '%', '+' }) > -1) + path = HttpUtility.UrlDecode (path, Encoding.UTF8); + + WebSocketServiceHost host; + + if (!_services.InternalTryGetServiceHost (path, out host)) { + context.Close (HttpStatusCode.NotImplemented); + + return; + } + + host.StartSession (context); + } + + private void receiveRequest () + { + while (true) { + HttpListenerContext ctx = null; + + try { + ctx = _listener.GetContext (); + + ThreadPool.QueueUserWorkItem ( + state => { + try { + if (ctx.Request.IsUpgradeRequest ("websocket")) { + processRequest (ctx.GetWebSocketContext (null)); + + return; + } + + processRequest (ctx); + } + catch (Exception ex) { + _log.Fatal (ex.Message); + _log.Debug (ex.ToString ()); + + ctx.Connection.Close (true); + } + } + ); + } + catch (HttpListenerException) { + _log.Info ("The underlying listener is stopped."); + + break; + } + catch (InvalidOperationException) { + _log.Info ("The underlying listener is stopped."); + + break; + } + catch (Exception ex) { + _log.Fatal (ex.Message); + _log.Debug (ex.ToString ()); + + if (ctx != null) + ctx.Connection.Close (true); + + break; + } + } + + if (_state != ServerState.ShuttingDown) + abort (); + } + + private void start () + { + if (_state == ServerState.Start) { + _log.Info ("The server has already started."); + + return; + } + + if (_state == ServerState.ShuttingDown) { + _log.Warn ("The server is shutting down."); + + return; + } + + lock (_sync) { + if (_state == ServerState.Start) { + _log.Info ("The server has already started."); + + return; + } + + if (_state == ServerState.ShuttingDown) { + _log.Warn ("The server is shutting down."); + + return; + } + + _services.Start (); + + try { + startReceiving (); + } + catch { + _services.Stop (1011, String.Empty); + + throw; + } + + _state = ServerState.Start; + } + } + + private void startReceiving () + { + try { + _listener.Start (); + } + catch (Exception ex) { + var msg = "The underlying listener has failed to start."; + + throw new InvalidOperationException (msg, ex); + } + + _receiveThread = new Thread (new ThreadStart (receiveRequest)); + _receiveThread.IsBackground = true; + + _receiveThread.Start (); + } + + private void stop (ushort code, string reason) + { + if (_state == ServerState.Ready) { + _log.Info ("The server is not started."); + + return; + } + + if (_state == ServerState.ShuttingDown) { + _log.Info ("The server is shutting down."); + + return; + } + + if (_state == ServerState.Stop) { + _log.Info ("The server has already stopped."); + + return; + } + + lock (_sync) { + if (_state == ServerState.ShuttingDown) { + _log.Info ("The server is shutting down."); + + return; + } + + if (_state == ServerState.Stop) { + _log.Info ("The server has already stopped."); + + return; + } + + _state = ServerState.ShuttingDown; + } + + try { + var threw = false; + + try { + _services.Stop (code, reason); + } + catch { + threw = true; + + throw; + } + finally { + try { + stopReceiving (5000); + } + catch { + if (!threw) + throw; + } + } + } + finally { + _state = ServerState.Stop; + } + } + + private void stopReceiving (int millisecondsTimeout) + { + _listener.Stop (); + _receiveThread.Join (millisecondsTimeout); + } + + private static bool tryCreateUri ( + string uriString, out Uri result, out string message + ) + { + result = null; + message = null; + + var uri = uriString.ToUri (); + + if (uri == null) { + message = "An invalid URI string."; + + return false; + } + + if (!uri.IsAbsoluteUri) { + message = "A relative URI."; + + return false; + } + + var schm = uri.Scheme; + var http = schm == "http" || schm == "https"; + + if (!http) { + message = "The scheme part is not 'http' or 'https'."; + + return false; + } + + if (uri.PathAndQuery != "/") { + message = "It includes either or both path and query components."; + + return false; + } + + if (uri.Fragment.Length > 0) { + message = "It includes the fragment component."; + + return false; + } + + if (uri.Port == 0) { + message = "The port part is zero."; + + return false; + } + + result = uri; + + return true; + } + + #endregion + + #region Public Methods + + /// + /// Adds a WebSocket service with the specified behavior, path, + /// and delegate. + /// + /// + /// + /// A that represents an absolute path to + /// the service to add. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// + /// A Func<TBehavior> delegate. + /// + /// + /// It invokes the method called when creating a new session + /// instance for the service. + /// + /// + /// The method must create a new instance of the specified + /// behavior class and return it. + /// + /// + /// + /// + /// The type of the behavior for the service. + /// + /// + /// It must inherit the class. + /// + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + /// -or- + /// + /// + /// is already in use. + /// + /// + [Obsolete ("This method will be removed. Use added one instead.")] + public void AddWebSocketService ( + string path, Func creator + ) + where TBehavior : WebSocketBehavior + { + if (path == null) + throw new ArgumentNullException ("path"); + + if (creator == null) + throw new ArgumentNullException ("creator"); + + if (path.Length == 0) + throw new ArgumentException ("An empty string.", "path"); + + if (path[0] != '/') + throw new ArgumentException ("Not an absolute path.", "path"); + + if (path.IndexOfAny (new[] { '?', '#' }) > -1) { + var msg = "It includes either or both query and fragment components."; + throw new ArgumentException (msg, "path"); + } + + _services.Add (path, creator); + } + + /// + /// Adds a WebSocket service with the specified behavior and path. + /// + /// + /// + /// A that represents an absolute path to + /// the service to add. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// + /// The type of the behavior for the service. + /// + /// + /// It must inherit the class. + /// + /// + /// And also, it must have a public parameterless constructor. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + /// -or- + /// + /// + /// is already in use. + /// + /// + public void AddWebSocketService (string path) + where TBehaviorWithNew : WebSocketBehavior, new () + { + _services.AddService (path, null); + } + + /// + /// Adds a WebSocket service with the specified behavior, path, + /// and delegate. + /// + /// + /// + /// A that represents an absolute path to + /// the service to add. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// + /// An Action<TBehaviorWithNew> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when initializing + /// a new session instance for the service. + /// + /// + /// + /// + /// The type of the behavior for the service. + /// + /// + /// It must inherit the class. + /// + /// + /// And also, it must have a public parameterless constructor. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + /// -or- + /// + /// + /// is already in use. + /// + /// + public void AddWebSocketService ( + string path, Action initializer + ) + where TBehaviorWithNew : WebSocketBehavior, new () + { + _services.AddService (path, initializer); + } + + /// + /// Removes a WebSocket service with the specified path. + /// + /// + /// The service is stopped with close status 1001 (going away) + /// if it has already started. + /// + /// + /// true if the service is successfully found and removed; + /// otherwise, false. + /// + /// + /// + /// A that represents an absolute path to + /// the service to remove. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + public bool RemoveWebSocketService (string path) + { + return _services.RemoveService (path); + } + + /// + /// Starts receiving incoming requests. + /// + /// + /// This method does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// + /// There is no server certificate for secure connection. + /// + /// + /// -or- + /// + /// + /// The underlying has failed to start. + /// + /// + public void Start () + { + if (_secure) { + string msg; + + if (!checkCertificate (out msg)) + throw new InvalidOperationException (msg); + } + + start (); + } + + /// + /// Stops receiving incoming requests. + /// + public void Stop () + { + stop (1001, String.Empty); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/HttpServer.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/HttpServer.cs.meta new file mode 100644 index 00000000..3ca296b9 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/HttpServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a05017ff27abd423ab3f2366bcc4154c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/IWebSocketSession.cs b/Plugins/websocket-sharp/websocket-sharp/Server/IWebSocketSession.cs new file mode 100644 index 00000000..296b5bf5 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/IWebSocketSession.cs @@ -0,0 +1,91 @@ +#region License +/* + * IWebSocketSession.cs + * + * The MIT License + * + * Copyright (c) 2013-2018 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using WebSocketSharp.Net.WebSockets; + +namespace WebSocketSharp.Server +{ + /// + /// Exposes the access to the information in a WebSocket session. + /// + public interface IWebSocketSession + { + #region Properties + + /// + /// Gets the current state of the WebSocket connection for the session. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It indicates the current state of the connection. + /// + /// + WebSocketState ConnectionState { get; } + + /// + /// Gets the information in the WebSocket handshake request. + /// + /// + /// A instance that provides the access to + /// the information in the handshake request. + /// + WebSocketContext Context { get; } + + /// + /// Gets the unique ID of the session. + /// + /// + /// A that represents the unique ID of the session. + /// + string ID { get; } + + /// + /// Gets the name of the WebSocket subprotocol for the session. + /// + /// + /// A that represents the name of the subprotocol + /// if present. + /// + string Protocol { get; } + + /// + /// Gets the time that the session has started. + /// + /// + /// A that represents the time that the session + /// has started. + /// + DateTime StartTime { get; } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/IWebSocketSession.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/IWebSocketSession.cs.meta new file mode 100644 index 00000000..04ea7c94 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/IWebSocketSession.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2bed1b7656ba5446ebea9b98b554234c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/ServerState.cs b/Plugins/websocket-sharp/websocket-sharp/Server/ServerState.cs new file mode 100644 index 00000000..2d758292 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/ServerState.cs @@ -0,0 +1,40 @@ +#region License +/* + * ServerState.cs + * + * The MIT License + * + * Copyright (c) 2013-2014 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Server +{ + internal enum ServerState + { + Ready, + Start, + ShuttingDown, + Stop + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/ServerState.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/ServerState.cs.meta new file mode 100644 index 00000000..07ecf35f --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/ServerState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f6b932a1a2044bd7a8de911c85abd80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketBehavior.cs b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketBehavior.cs new file mode 100644 index 00000000..b5e8ffeb --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketBehavior.cs @@ -0,0 +1,1204 @@ +#region License +/* + * WebSocketBehavior.cs + * + * The MIT License + * + * Copyright (c) 2012-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections.Specialized; +using System.IO; +using WebSocketSharp.Net; +using WebSocketSharp.Net.WebSockets; + +namespace WebSocketSharp.Server +{ + /// + /// Exposes a set of methods and properties used to define the behavior of + /// a WebSocket service provided by the or + /// . + /// + /// + /// This class is an abstract class. + /// + public abstract class WebSocketBehavior : IWebSocketSession + { + #region Private Fields + + private WebSocketContext _context; + private Func _cookiesValidator; + private bool _emitOnPing; + private string _id; + private bool _ignoreExtensions; + private Func _originValidator; + private string _protocol; + private WebSocketSessionManager _sessions; + private DateTime _startTime; + private WebSocket _websocket; + + #endregion + + #region Protected Constructors + + /// + /// Initializes a new instance of the class. + /// + protected WebSocketBehavior () + { + _startTime = DateTime.MaxValue; + } + + #endregion + + #region Protected Properties + + /// + /// Gets the HTTP headers included in a WebSocket handshake request. + /// + /// + /// + /// A that contains the headers. + /// + /// + /// if the session has not started yet. + /// + /// + protected NameValueCollection Headers { + get { + return _context != null ? _context.Headers : null; + } + } + + /// + /// Gets the logging function. + /// + /// + /// + /// A that provides the logging function. + /// + /// + /// if the session has not started yet. + /// + /// + [Obsolete ("This property will be removed.")] + protected Logger Log { + get { + return _websocket != null ? _websocket.Log : null; + } + } + + /// + /// Gets the query string included in a WebSocket handshake request. + /// + /// + /// + /// A that contains the query + /// parameters. + /// + /// + /// An empty collection if not included. + /// + /// + /// if the session has not started yet. + /// + /// + protected NameValueCollection QueryString { + get { + return _context != null ? _context.QueryString : null; + } + } + + /// + /// Gets the management function for the sessions in the service. + /// + /// + /// + /// A that manages the sessions in + /// the service. + /// + /// + /// if the session has not started yet. + /// + /// + protected WebSocketSessionManager Sessions { + get { + return _sessions; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the current state of the WebSocket connection for a session. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It indicates the current state of the connection. + /// + /// + /// if the session has not + /// started yet. + /// + /// + public WebSocketState ConnectionState { + get { + return _websocket != null + ? _websocket.ReadyState + : WebSocketState.Connecting; + } + } + + /// + /// Gets the information in a WebSocket handshake request to the service. + /// + /// + /// + /// A instance that provides the access to + /// the information in the handshake request. + /// + /// + /// if the session has not started yet. + /// + /// + public WebSocketContext Context { + get { + return _context; + } + } + + /// + /// Gets or sets the delegate used to validate the HTTP cookies included in + /// a WebSocket handshake request to the service. + /// + /// + /// + /// A Func<CookieCollection, CookieCollection, bool> delegate + /// or if not needed. + /// + /// + /// The delegate invokes the method called when the WebSocket instance + /// for a session validates the handshake request. + /// + /// + /// 1st parameter passed to the method + /// contains the cookies to validate if present. + /// + /// + /// 2nd parameter passed to the method + /// receives the cookies to send to the client. + /// + /// + /// The method must return true if the cookies are valid. + /// + /// + /// The default value is . + /// + /// + public Func CookiesValidator { + get { + return _cookiesValidator; + } + + set { + _cookiesValidator = value; + } + } + + /// + /// Gets or sets a value indicating whether the WebSocket instance for + /// a session emits the message event when receives a ping. + /// + /// + /// + /// true if the WebSocket instance emits the message event + /// when receives a ping; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool EmitOnPing { + get { + return _websocket != null ? _websocket.EmitOnPing : _emitOnPing; + } + + set { + if (_websocket != null) { + _websocket.EmitOnPing = value; + return; + } + + _emitOnPing = value; + } + } + + /// + /// Gets the unique ID of a session. + /// + /// + /// + /// A that represents the unique ID of the session. + /// + /// + /// if the session has not started yet. + /// + /// + public string ID { + get { + return _id; + } + } + + /// + /// Gets or sets a value indicating whether the service ignores + /// the Sec-WebSocket-Extensions header included in a WebSocket + /// handshake request. + /// + /// + /// + /// true if the service ignores the extensions requested + /// from a client; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool IgnoreExtensions { + get { + return _ignoreExtensions; + } + + set { + _ignoreExtensions = value; + } + } + + /// + /// Gets or sets the delegate used to validate the Origin header included in + /// a WebSocket handshake request to the service. + /// + /// + /// + /// A Func<string, bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the WebSocket instance + /// for a session validates the handshake request. + /// + /// + /// The parameter passed to the method is the value + /// of the Origin header or if the header is not + /// present. + /// + /// + /// The method must return true if the header value is valid. + /// + /// + /// The default value is . + /// + /// + public Func OriginValidator { + get { + return _originValidator; + } + + set { + _originValidator = value; + } + } + + /// + /// Gets or sets the name of the WebSocket subprotocol for the service. + /// + /// + /// + /// A that represents the name of the subprotocol. + /// + /// + /// The value specified for a set must be a token defined in + /// + /// RFC 2616. + /// + /// + /// The default value is an empty string. + /// + /// + /// + /// The set operation is not available if the session has already started. + /// + /// + /// The value specified for a set operation is not a token. + /// + public string Protocol { + get { + return _websocket != null + ? _websocket.Protocol + : (_protocol ?? String.Empty); + } + + set { + if (ConnectionState != WebSocketState.Connecting) { + var msg = "The session has already started."; + throw new InvalidOperationException (msg); + } + + if (value == null || value.Length == 0) { + _protocol = null; + return; + } + + if (!value.IsToken ()) + throw new ArgumentException ("Not a token.", "value"); + + _protocol = value; + } + } + + /// + /// Gets the time that a session has started. + /// + /// + /// + /// A that represents the time that the session + /// has started. + /// + /// + /// if the session has not started yet. + /// + /// + public DateTime StartTime { + get { + return _startTime; + } + } + + #endregion + + #region Private Methods + + private string checkHandshakeRequest (WebSocketContext context) + { + if (_originValidator != null) { + if (!_originValidator (context.Origin)) + return "It includes no Origin header or an invalid one."; + } + + if (_cookiesValidator != null) { + var req = context.CookieCollection; + var res = context.WebSocket.CookieCollection; + if (!_cookiesValidator (req, res)) + return "It includes no cookie or an invalid one."; + } + + return null; + } + + private void onClose (object sender, CloseEventArgs e) + { + if (_id == null) + return; + + _sessions.Remove (_id); + OnClose (e); + } + + private void onError (object sender, ErrorEventArgs e) + { + OnError (e); + } + + private void onMessage (object sender, MessageEventArgs e) + { + OnMessage (e); + } + + private void onOpen (object sender, EventArgs e) + { + _id = _sessions.Add (this); + if (_id == null) { + _websocket.Close (CloseStatusCode.Away); + return; + } + + _startTime = DateTime.Now; + OnOpen (); + } + + #endregion + + #region Internal Methods + + internal void Start (WebSocketContext context, WebSocketSessionManager sessions) + { + if (_websocket != null) { + _websocket.Log.Error ("A session instance cannot be reused."); + context.WebSocket.Close (HttpStatusCode.ServiceUnavailable); + + return; + } + + _context = context; + _sessions = sessions; + + _websocket = context.WebSocket; + _websocket.CustomHandshakeRequestChecker = checkHandshakeRequest; + _websocket.EmitOnPing = _emitOnPing; + _websocket.IgnoreExtensions = _ignoreExtensions; + _websocket.Protocol = _protocol; + + var waitTime = sessions.WaitTime; + if (waitTime != _websocket.WaitTime) + _websocket.WaitTime = waitTime; + + _websocket.OnOpen += onOpen; + _websocket.OnMessage += onMessage; + _websocket.OnError += onError; + _websocket.OnClose += onClose; + + _websocket.InternalAccept (); + } + + #endregion + + #region Protected Methods + + /// + /// Closes the WebSocket connection for a session. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// The session has not started yet. + /// + protected void Close () + { + if (_websocket == null) { + var msg = "The session has not started yet."; + throw new InvalidOperationException (msg); + } + + _websocket.Close (); + } + + /// + /// Closes the WebSocket connection for a session with the specified + /// code and reason. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// A that represents the status code indicating + /// the reason for the close. + /// + /// + /// The status codes are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// The session has not started yet. + /// + /// + /// + /// is less than 1000 or greater than 4999. + /// + /// + /// -or- + /// + /// + /// The size of is greater than 123 bytes. + /// + /// + /// + /// + /// is 1010 (mandatory extension). + /// + /// + /// -or- + /// + /// + /// is 1005 (no status) and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + protected void Close (ushort code, string reason) + { + if (_websocket == null) { + var msg = "The session has not started yet."; + throw new InvalidOperationException (msg); + } + + _websocket.Close (code, reason); + } + + /// + /// Closes the WebSocket connection for a session with the specified + /// code and reason. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It represents the status code indicating the reason for the close. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// The session has not started yet. + /// + /// + /// The size of is greater than 123 bytes. + /// + /// + /// + /// is + /// . + /// + /// + /// -or- + /// + /// + /// is + /// and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + protected void Close (CloseStatusCode code, string reason) + { + if (_websocket == null) { + var msg = "The session has not started yet."; + throw new InvalidOperationException (msg); + } + + _websocket.Close (code, reason); + } + + /// + /// Closes the WebSocket connection for a session asynchronously. + /// + /// + /// + /// This method does not wait for the close to be complete. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// The session has not started yet. + /// + protected void CloseAsync () + { + if (_websocket == null) { + var msg = "The session has not started yet."; + throw new InvalidOperationException (msg); + } + + _websocket.CloseAsync (); + } + + /// + /// Closes the WebSocket connection for a session asynchronously with + /// the specified code and reason. + /// + /// + /// + /// This method does not wait for the close to be complete. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// + /// A that represents the status code indicating + /// the reason for the close. + /// + /// + /// The status codes are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// The session has not started yet. + /// + /// + /// + /// is less than 1000 or greater than 4999. + /// + /// + /// -or- + /// + /// + /// The size of is greater than 123 bytes. + /// + /// + /// + /// + /// is 1010 (mandatory extension). + /// + /// + /// -or- + /// + /// + /// is 1005 (no status) and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + protected void CloseAsync (ushort code, string reason) + { + if (_websocket == null) { + var msg = "The session has not started yet."; + throw new InvalidOperationException (msg); + } + + _websocket.CloseAsync (code, reason); + } + + /// + /// Closes the WebSocket connection for a session asynchronously with + /// the specified code and reason. + /// + /// + /// + /// This method does not wait for the close to be complete. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// + /// One of the enum values. + /// + /// + /// It represents the status code indicating the reason for the close. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// The session has not started yet. + /// + /// + /// + /// is + /// . + /// + /// + /// -or- + /// + /// + /// is + /// and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// The size of is greater than 123 bytes. + /// + protected void CloseAsync (CloseStatusCode code, string reason) + { + if (_websocket == null) { + var msg = "The session has not started yet."; + throw new InvalidOperationException (msg); + } + + _websocket.CloseAsync (code, reason); + } + + /// + /// Calls the method with the specified message. + /// + /// + /// A that represents the error message. + /// + /// + /// An instance that represents the cause of + /// the error if present. + /// + /// + /// is . + /// + /// + /// is an empty string. + /// + [Obsolete ("This method will be removed.")] + protected void Error (string message, Exception exception) + { + if (message == null) + throw new ArgumentNullException ("message"); + + if (message.Length == 0) + throw new ArgumentException ("An empty string.", "message"); + + OnError (new ErrorEventArgs (message, exception)); + } + + /// + /// Called when the WebSocket connection for a session has been closed. + /// + /// + /// A that represents the event data passed + /// from a event. + /// + protected virtual void OnClose (CloseEventArgs e) + { + } + + /// + /// Called when the WebSocket instance for a session gets an error. + /// + /// + /// A that represents the event data passed + /// from a event. + /// + protected virtual void OnError (ErrorEventArgs e) + { + } + + /// + /// Called when the WebSocket instance for a session receives a message. + /// + /// + /// A that represents the event data passed + /// from a event. + /// + protected virtual void OnMessage (MessageEventArgs e) + { + } + + /// + /// Called when the WebSocket connection for a session has been established. + /// + protected virtual void OnOpen () + { + } + + /// + /// Sends the specified data to a client using the WebSocket connection. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + protected void Send (byte[] data) + { + if (_websocket == null) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + _websocket.Send (data); + } + + /// + /// Sends the specified file to a client using the WebSocket connection. + /// + /// + /// + /// A that specifies the file to send. + /// + /// + /// The file is sent as the binary data. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// + /// The file does not exist. + /// + /// + /// -or- + /// + /// + /// The file could not be opened. + /// + /// + protected void Send (FileInfo fileInfo) + { + if (_websocket == null) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + _websocket.Send (fileInfo); + } + + /// + /// Sends the specified data to a client using the WebSocket connection. + /// + /// + /// A that represents the text data to send. + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// could not be UTF-8-encoded. + /// + protected void Send (string data) + { + if (_websocket == null) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + _websocket.Send (data); + } + + /// + /// Sends the data from the specified stream to a client using + /// the WebSocket connection. + /// + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// The data is sent as the binary data. + /// + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + protected void Send (Stream stream, int length) + { + if (_websocket == null) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + _websocket.Send (stream, length); + } + + /// + /// Sends the specified data to a client asynchronously using + /// the WebSocket connection. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + protected void SendAsync (byte[] data, Action completed) + { + if (_websocket == null) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + _websocket.SendAsync (data, completed); + } + + /// + /// Sends the specified file to a client asynchronously using + /// the WebSocket connection. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// + /// A that specifies the file to send. + /// + /// + /// The file is sent as the binary data. + /// + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// + /// The file does not exist. + /// + /// + /// -or- + /// + /// + /// The file could not be opened. + /// + /// + protected void SendAsync (FileInfo fileInfo, Action completed) + { + if (_websocket == null) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + _websocket.SendAsync (fileInfo, completed); + } + + /// + /// Sends the specified data to a client asynchronously using + /// the WebSocket connection. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// A that represents the text data to send. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// could not be UTF-8-encoded. + /// + protected void SendAsync (string data, Action completed) + { + if (_websocket == null) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + _websocket.SendAsync (data, completed); + } + + /// + /// Sends the data from the specified stream to a client asynchronously + /// using the WebSocket connection. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// The data is sent as the binary data. + /// + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + protected void SendAsync (Stream stream, int length, Action completed) + { + if (_websocket == null) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + _websocket.SendAsync (stream, length, completed); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketBehavior.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketBehavior.cs.meta new file mode 100644 index 00000000..ec84b577 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketBehavior.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c1725e48e79543a893c4c301568e3c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServer.cs b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServer.cs new file mode 100644 index 00000000..be7bca76 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServer.cs @@ -0,0 +1,1518 @@ +#region License +/* + * WebSocketServer.cs + * + * The MIT License + * + * Copyright (c) 2012-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Juan Manuel Lallana + * - Jonas Hovgaard + * - Liryna + * - Rohan Singh + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.Text; +using System.Threading; +using WebSocketSharp.Net; +using WebSocketSharp.Net.WebSockets; + +namespace WebSocketSharp.Server +{ + /// + /// Provides a WebSocket protocol server. + /// + /// + /// This class can provide multiple WebSocket services. + /// + public class WebSocketServer + { + #region Private Fields + + private System.Net.IPAddress _address; + private bool _allowForwardedRequest; + private AuthenticationSchemes _authSchemes; + private static readonly string _defaultRealm; + private bool _dnsStyle; + private string _hostname; + private TcpListener _listener; + private Logger _log; + private int _port; + private string _realm; + private string _realmInUse; + private Thread _receiveThread; + private bool _reuseAddress; + private bool _secure; + private WebSocketServiceManager _services; + private ServerSslConfiguration _sslConfig; + private ServerSslConfiguration _sslConfigInUse; + private volatile ServerState _state; + private object _sync; + private Func _userCredFinder; + + #endregion + + #region Static Constructor + + static WebSocketServer () + { + _defaultRealm = "SECRET AREA"; + } + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class. + /// + /// + /// The new instance listens for incoming handshake requests on + /// and port 80. + /// + public WebSocketServer () + { + var addr = System.Net.IPAddress.Any; + init (addr.ToString (), addr, 80, false); + } + + /// + /// Initializes a new instance of the class + /// with the specified . + /// + /// + /// + /// The new instance listens for incoming handshake requests on + /// and . + /// + /// + /// It provides secure connections if is 443. + /// + /// + /// + /// An that represents the number of the port + /// on which to listen. + /// + /// + /// is less than 1 or greater than 65535. + /// + public WebSocketServer (int port) + : this (port, port == 443) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified . + /// + /// + /// + /// The new instance listens for incoming handshake requests on + /// the IP address of the host of and + /// the port of . + /// + /// + /// Either port 80 or 443 is used if includes + /// no port. Port 443 is used if the scheme of + /// is wss; otherwise, port 80 is used. + /// + /// + /// The new instance provides secure connections if the scheme of + /// is wss. + /// + /// + /// + /// A that represents the WebSocket URL of the server. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is invalid. + /// + /// + public WebSocketServer (string url) + { + if (url == null) + throw new ArgumentNullException ("url"); + + if (url.Length == 0) + throw new ArgumentException ("An empty string.", "url"); + + Uri uri; + string msg; + if (!tryCreateUri (url, out uri, out msg)) + throw new ArgumentException (msg, "url"); + + var host = uri.DnsSafeHost; + + var addr = host.ToIPAddress (); + if (addr == null) { + msg = "The host part could not be converted to an IP address."; + throw new ArgumentException (msg, "url"); + } + + if (!addr.IsLocal ()) { + msg = "The IP address of the host is not a local IP address."; + throw new ArgumentException (msg, "url"); + } + + init (host, addr, uri.Port, uri.Scheme == "wss"); + } + + /// + /// Initializes a new instance of the class + /// with the specified and . + /// + /// + /// The new instance listens for incoming handshake requests on + /// and . + /// + /// + /// An that represents the number of the port + /// on which to listen. + /// + /// + /// A : true if the new instance provides + /// secure connections; otherwise, false. + /// + /// + /// is less than 1 or greater than 65535. + /// + public WebSocketServer (int port, bool secure) + { + if (!port.IsPortNumber ()) { + var msg = "Less than 1 or greater than 65535."; + throw new ArgumentOutOfRangeException ("port", msg); + } + + var addr = System.Net.IPAddress.Any; + init (addr.ToString (), addr, port, secure); + } + + /// + /// Initializes a new instance of the class + /// with the specified and . + /// + /// + /// + /// The new instance listens for incoming handshake requests on + /// and . + /// + /// + /// It provides secure connections if is 443. + /// + /// + /// + /// A that represents the local + /// IP address on which to listen. + /// + /// + /// An that represents the number of the port + /// on which to listen. + /// + /// + /// is . + /// + /// + /// is not a local IP address. + /// + /// + /// is less than 1 or greater than 65535. + /// + public WebSocketServer (System.Net.IPAddress address, int port) + : this (address, port, port == 443) + { + } + + /// + /// Initializes a new instance of the class + /// with the specified , , + /// and . + /// + /// + /// The new instance listens for incoming handshake requests on + /// and . + /// + /// + /// A that represents the local + /// IP address on which to listen. + /// + /// + /// An that represents the number of the port + /// on which to listen. + /// + /// + /// A : true if the new instance provides + /// secure connections; otherwise, false. + /// + /// + /// is . + /// + /// + /// is not a local IP address. + /// + /// + /// is less than 1 or greater than 65535. + /// + public WebSocketServer (System.Net.IPAddress address, int port, bool secure) + { + if (address == null) + throw new ArgumentNullException ("address"); + + if (!address.IsLocal ()) + throw new ArgumentException ("Not a local IP address.", "address"); + + if (!port.IsPortNumber ()) { + var msg = "Less than 1 or greater than 65535."; + throw new ArgumentOutOfRangeException ("port", msg); + } + + init (address.ToString (), address, port, secure); + } + + #endregion + + #region Public Properties + + /// + /// Gets the IP address of the server. + /// + /// + /// A that represents the local + /// IP address on which to listen for incoming handshake requests. + /// + public System.Net.IPAddress Address { + get { + return _address; + } + } + + /// + /// Gets or sets a value indicating whether the server accepts every + /// handshake request without checking the request URI. + /// + /// + /// The set operation does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// + /// true if the server accepts every handshake request without + /// checking the request URI; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool AllowForwardedRequest { + get { + return _allowForwardedRequest; + } + + set { + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + _allowForwardedRequest = value; + } + } + } + + /// + /// Gets or sets the scheme used to authenticate the clients. + /// + /// + /// The set operation does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// + /// One of the + /// enum values. + /// + /// + /// It represents the scheme used to authenticate the clients. + /// + /// + /// The default value is + /// . + /// + /// + public AuthenticationSchemes AuthenticationSchemes { + get { + return _authSchemes; + } + + set { + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + _authSchemes = value; + } + } + } + + /// + /// Gets a value indicating whether the server has started. + /// + /// + /// true if the server has started; otherwise, false. + /// + public bool IsListening { + get { + return _state == ServerState.Start; + } + } + + /// + /// Gets a value indicating whether secure connections are provided. + /// + /// + /// true if this instance provides secure connections; otherwise, + /// false. + /// + public bool IsSecure { + get { + return _secure; + } + } + + /// + /// Gets or sets a value indicating whether the server cleans up + /// the inactive sessions periodically. + /// + /// + /// The set operation does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// + /// true if the server cleans up the inactive sessions every + /// 60 seconds; otherwise, false. + /// + /// + /// The default value is true. + /// + /// + public bool KeepClean { + get { + return _services.KeepClean; + } + + set { + _services.KeepClean = value; + } + } + + /// + /// Gets the logging function for the server. + /// + /// + /// The default logging level is . + /// + /// + /// A that provides the logging function. + /// + public Logger Log { + get { + return _log; + } + } + + /// + /// Gets the port of the server. + /// + /// + /// An that represents the number of the port + /// on which to listen for incoming handshake requests. + /// + public int Port { + get { + return _port; + } + } + + /// + /// Gets or sets the realm used for authentication. + /// + /// + /// + /// "SECRET AREA" is used as the realm if the value is + /// or an empty string. + /// + /// + /// The set operation does nothing if the server has + /// already started or it is shutting down. + /// + /// + /// + /// + /// A or by default. + /// + /// + /// That string represents the name of the realm. + /// + /// + public string Realm { + get { + return _realm; + } + + set { + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + _realm = value; + } + } + } + + /// + /// Gets or sets a value indicating whether the server is allowed to + /// be bound to an address that is already in use. + /// + /// + /// + /// You should set this property to true if you would + /// like to resolve to wait for socket in TIME_WAIT state. + /// + /// + /// The set operation does nothing if the server has already + /// started or it is shutting down. + /// + /// + /// + /// + /// true if the server is allowed to be bound to an address + /// that is already in use; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool ReuseAddress { + get { + return _reuseAddress; + } + + set { + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + _reuseAddress = value; + } + } + } + + /// + /// Gets the configuration for secure connection. + /// + /// + /// This configuration will be referenced when attempts to start, + /// so it must be configured before the start method is called. + /// + /// + /// A that represents + /// the configuration used to provide secure connections. + /// + /// + /// This instance does not provide secure connections. + /// + public ServerSslConfiguration SslConfiguration { + get { + if (!_secure) { + var msg = "This instance does not provide secure connections."; + throw new InvalidOperationException (msg); + } + + return getSslConfiguration (); + } + } + + /// + /// Gets or sets the delegate used to find the credentials + /// for an identity. + /// + /// + /// + /// No credentials are found if the method invoked by + /// the delegate returns or + /// the value is . + /// + /// + /// The set operation does nothing if the server has + /// already started or it is shutting down. + /// + /// + /// + /// + /// A Func<, + /// > delegate or + /// if not needed. + /// + /// + /// That delegate invokes the method called for finding + /// the credentials used to authenticate a client. + /// + /// + /// The default value is . + /// + /// + public Func UserCredentialsFinder { + get { + return _userCredFinder; + } + + set { + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + _userCredFinder = value; + } + } + } + + /// + /// Gets or sets the time to wait for the response to the WebSocket Ping or + /// Close. + /// + /// + /// The set operation does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// + /// A to wait for the response. + /// + /// + /// The default value is the same as 1 second. + /// + /// + /// + /// The value specified for a set operation is zero or less. + /// + public TimeSpan WaitTime { + get { + return _services.WaitTime; + } + + set { + _services.WaitTime = value; + } + } + + /// + /// Gets the management function for the WebSocket services + /// provided by the server. + /// + /// + /// A that manages + /// the WebSocket services provided by the server. + /// + public WebSocketServiceManager WebSocketServices { + get { + return _services; + } + } + + #endregion + + #region Private Methods + + private void abort () + { + lock (_sync) { + if (_state != ServerState.Start) + return; + + _state = ServerState.ShuttingDown; + } + + try { + try { + _listener.Stop (); + } + finally { + _services.Stop (1006, String.Empty); + } + } + catch { + } + + _state = ServerState.Stop; + } + + private bool authenticateClient (TcpListenerWebSocketContext context) + { + if (_authSchemes == AuthenticationSchemes.Anonymous) + return true; + + if (_authSchemes == AuthenticationSchemes.None) + return false; + + return context.Authenticate (_authSchemes, _realmInUse, _userCredFinder); + } + + private bool canSet (out string message) + { + message = null; + + if (_state == ServerState.Start) { + message = "The server has already started."; + return false; + } + + if (_state == ServerState.ShuttingDown) { + message = "The server is shutting down."; + return false; + } + + return true; + } + + private bool checkHostNameForRequest (string name) + { + return !_dnsStyle + || Uri.CheckHostName (name) != UriHostNameType.Dns + || name == _hostname; + } + + private static bool checkSslConfiguration ( + ServerSslConfiguration configuration, out string message + ) + { + message = null; + + if (configuration.ServerCertificate == null) { + message = "There is no server certificate for secure connection."; + return false; + } + + return true; + } + + private string getRealm () + { + var realm = _realm; + return realm != null && realm.Length > 0 ? realm : _defaultRealm; + } + + private ServerSslConfiguration getSslConfiguration () + { + if (_sslConfig == null) + _sslConfig = new ServerSslConfiguration (); + + return _sslConfig; + } + + private void init ( + string hostname, System.Net.IPAddress address, int port, bool secure + ) + { + _hostname = hostname; + _address = address; + _port = port; + _secure = secure; + + _authSchemes = AuthenticationSchemes.Anonymous; + _dnsStyle = Uri.CheckHostName (hostname) == UriHostNameType.Dns; + _listener = new TcpListener (address, port); + _log = new Logger (); + _services = new WebSocketServiceManager (_log); + _sync = new object (); + } + + private void processRequest (TcpListenerWebSocketContext context) + { + if (!authenticateClient (context)) { + context.Close (HttpStatusCode.Forbidden); + return; + } + + var uri = context.RequestUri; + if (uri == null) { + context.Close (HttpStatusCode.BadRequest); + return; + } + + if (!_allowForwardedRequest) { + if (uri.Port != _port) { + context.Close (HttpStatusCode.BadRequest); + return; + } + + if (!checkHostNameForRequest (uri.DnsSafeHost)) { + context.Close (HttpStatusCode.NotFound); + return; + } + } + + var path = uri.AbsolutePath; + if (path.IndexOfAny (new[] { '%', '+' }) > -1) + path = HttpUtility.UrlDecode (path, Encoding.UTF8); + + WebSocketServiceHost host; + if (!_services.InternalTryGetServiceHost (path, out host)) { + context.Close (HttpStatusCode.NotImplemented); + return; + } + + host.StartSession (context); + } + + private void receiveRequest () + { + while (true) { + TcpClient cl = null; + try { + cl = _listener.AcceptTcpClient (); + ThreadPool.QueueUserWorkItem ( + state => { + try { + var ctx = new TcpListenerWebSocketContext ( + cl, null, _secure, _sslConfigInUse, _log + ); + + processRequest (ctx); + } + catch (Exception ex) { + _log.Error (ex.Message); + _log.Debug (ex.ToString ()); + + cl.Close (); + } + } + ); + } + catch (SocketException ex) { + if (_state == ServerState.ShuttingDown) { + _log.Info ("The underlying listener is stopped."); + break; + } + + _log.Fatal (ex.Message); + _log.Debug (ex.ToString ()); + + break; + } + catch (Exception ex) { + _log.Fatal (ex.Message); + _log.Debug (ex.ToString ()); + + if (cl != null) + cl.Close (); + + break; + } + } + + if (_state != ServerState.ShuttingDown) + abort (); + } + + private void start (ServerSslConfiguration sslConfig) + { + if (_state == ServerState.Start) { + _log.Info ("The server has already started."); + return; + } + + if (_state == ServerState.ShuttingDown) { + _log.Warn ("The server is shutting down."); + return; + } + + lock (_sync) { + if (_state == ServerState.Start) { + _log.Info ("The server has already started."); + return; + } + + if (_state == ServerState.ShuttingDown) { + _log.Warn ("The server is shutting down."); + return; + } + + _sslConfigInUse = sslConfig; + _realmInUse = getRealm (); + + _services.Start (); + try { + startReceiving (); + } + catch { + _services.Stop (1011, String.Empty); + throw; + } + + _state = ServerState.Start; + } + } + + private void startReceiving () + { + if (_reuseAddress) { + _listener.Server.SetSocketOption ( + SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true + ); + } + + try { + _listener.Start (); + } + catch (Exception ex) { + var msg = "The underlying listener has failed to start."; + throw new InvalidOperationException (msg, ex); + } + + _receiveThread = new Thread (new ThreadStart (receiveRequest)); + _receiveThread.IsBackground = true; + _receiveThread.Start (); + } + + private void stop (ushort code, string reason) + { + if (_state == ServerState.Ready) { + _log.Info ("The server is not started."); + return; + } + + if (_state == ServerState.ShuttingDown) { + _log.Info ("The server is shutting down."); + return; + } + + if (_state == ServerState.Stop) { + _log.Info ("The server has already stopped."); + return; + } + + lock (_sync) { + if (_state == ServerState.ShuttingDown) { + _log.Info ("The server is shutting down."); + return; + } + + if (_state == ServerState.Stop) { + _log.Info ("The server has already stopped."); + return; + } + + _state = ServerState.ShuttingDown; + } + + try { + var threw = false; + try { + stopReceiving (5000); + } + catch { + threw = true; + throw; + } + finally { + try { + _services.Stop (code, reason); + } + catch { + if (!threw) + throw; + } + } + } + finally { + _state = ServerState.Stop; + } + } + + private void stopReceiving (int millisecondsTimeout) + { + try { + _listener.Stop (); + } + catch (Exception ex) { + var msg = "The underlying listener has failed to stop."; + throw new InvalidOperationException (msg, ex); + } + + _receiveThread.Join (millisecondsTimeout); + } + + private static bool tryCreateUri ( + string uriString, out Uri result, out string message + ) + { + if (!uriString.TryCreateWebSocketUri (out result, out message)) + return false; + + if (result.PathAndQuery != "/") { + result = null; + message = "It includes either or both path and query components."; + + return false; + } + + return true; + } + + #endregion + + #region Public Methods + + /// + /// Adds a WebSocket service with the specified behavior, path, + /// and delegate. + /// + /// + /// + /// A that represents an absolute path to + /// the service to add. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// + /// A Func<TBehavior> delegate. + /// + /// + /// It invokes the method called when creating a new session + /// instance for the service. + /// + /// + /// The method must create a new instance of the specified + /// behavior class and return it. + /// + /// + /// + /// + /// The type of the behavior for the service. + /// + /// + /// It must inherit the class. + /// + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + /// -or- + /// + /// + /// is already in use. + /// + /// + [Obsolete ("This method will be removed. Use added one instead.")] + public void AddWebSocketService ( + string path, Func creator + ) + where TBehavior : WebSocketBehavior + { + if (path == null) + throw new ArgumentNullException ("path"); + + if (creator == null) + throw new ArgumentNullException ("creator"); + + if (path.Length == 0) + throw new ArgumentException ("An empty string.", "path"); + + if (path[0] != '/') + throw new ArgumentException ("Not an absolute path.", "path"); + + if (path.IndexOfAny (new[] { '?', '#' }) > -1) { + var msg = "It includes either or both query and fragment components."; + throw new ArgumentException (msg, "path"); + } + + _services.Add (path, creator); + } + + /// + /// Adds a WebSocket service with the specified behavior and path. + /// + /// + /// + /// A that represents an absolute path to + /// the service to add. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// + /// The type of the behavior for the service. + /// + /// + /// It must inherit the class. + /// + /// + /// And also, it must have a public parameterless constructor. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + /// -or- + /// + /// + /// is already in use. + /// + /// + public void AddWebSocketService (string path) + where TBehaviorWithNew : WebSocketBehavior, new () + { + _services.AddService (path, null); + } + + /// + /// Adds a WebSocket service with the specified behavior, path, + /// and delegate. + /// + /// + /// + /// A that represents an absolute path to + /// the service to add. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// + /// An Action<TBehaviorWithNew> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when initializing + /// a new session instance for the service. + /// + /// + /// + /// + /// The type of the behavior for the service. + /// + /// + /// It must inherit the class. + /// + /// + /// And also, it must have a public parameterless constructor. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + /// -or- + /// + /// + /// is already in use. + /// + /// + public void AddWebSocketService ( + string path, Action initializer + ) + where TBehaviorWithNew : WebSocketBehavior, new () + { + _services.AddService (path, initializer); + } + + /// + /// Removes a WebSocket service with the specified path. + /// + /// + /// The service is stopped with close status 1001 (going away) + /// if it has already started. + /// + /// + /// true if the service is successfully found and removed; + /// otherwise, false. + /// + /// + /// + /// A that represents an absolute path to + /// the service to remove. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + public bool RemoveWebSocketService (string path) + { + return _services.RemoveService (path); + } + + /// + /// Starts receiving incoming handshake requests. + /// + /// + /// This method does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// + /// There is no server certificate for secure connection. + /// + /// + /// -or- + /// + /// + /// The underlying has failed to start. + /// + /// + public void Start () + { + ServerSslConfiguration sslConfig = null; + + if (_secure) { + sslConfig = new ServerSslConfiguration (getSslConfiguration ()); + + string msg; + if (!checkSslConfiguration (sslConfig, out msg)) + throw new InvalidOperationException (msg); + } + + start (sslConfig); + } + + /// + /// Stops receiving incoming handshake requests. + /// + /// + /// The underlying has failed to stop. + /// + public void Stop () + { + stop (1001, String.Empty); + } + + /// + /// Stops receiving incoming handshake requests and closes each connection + /// with the specified code and reason. + /// + /// + /// + /// A that represents the status code indicating + /// the reason for the close. + /// + /// + /// The status codes are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// + /// is less than 1000 or greater than 4999. + /// + /// + /// -or- + /// + /// + /// The size of is greater than 123 bytes. + /// + /// + /// + /// + /// is 1010 (mandatory extension). + /// + /// + /// -or- + /// + /// + /// is 1005 (no status) and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// The underlying has failed to stop. + /// + [Obsolete ("This method will be removed.")] + public void Stop (ushort code, string reason) + { + if (!code.IsCloseStatusCode ()) { + var msg = "Less than 1000 or greater than 4999."; + throw new ArgumentOutOfRangeException ("code", msg); + } + + if (code == 1010) { + var msg = "1010 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!reason.IsNullOrEmpty ()) { + if (code == 1005) { + var msg = "1005 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + byte[] bytes; + if (!reason.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "reason"); + } + + if (bytes.Length > 123) { + var msg = "Its size is greater than 123 bytes."; + throw new ArgumentOutOfRangeException ("reason", msg); + } + } + + stop (code, reason); + } + + /// + /// Stops receiving incoming handshake requests and closes each connection + /// with the specified code and reason. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It represents the status code indicating the reason for the close. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// + /// is + /// . + /// + /// + /// -or- + /// + /// + /// is + /// and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// The size of is greater than 123 bytes. + /// + /// + /// The underlying has failed to stop. + /// + [Obsolete ("This method will be removed.")] + public void Stop (CloseStatusCode code, string reason) + { + if (code == CloseStatusCode.MandatoryExtension) { + var msg = "MandatoryExtension cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!reason.IsNullOrEmpty ()) { + if (code == CloseStatusCode.NoStatus) { + var msg = "NoStatus cannot be used."; + throw new ArgumentException (msg, "code"); + } + + byte[] bytes; + if (!reason.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "reason"); + } + + if (bytes.Length > 123) { + var msg = "Its size is greater than 123 bytes."; + throw new ArgumentOutOfRangeException ("reason", msg); + } + } + + stop ((ushort) code, reason); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServer.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServer.cs.meta new file mode 100644 index 00000000..361009d7 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ac21975e0a0942e7b5039017ce625c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost.cs b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost.cs new file mode 100644 index 00000000..1da76427 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost.cs @@ -0,0 +1,224 @@ +#region License +/* + * WebSocketServiceHost.cs + * + * The MIT License + * + * Copyright (c) 2012-2017 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Juan Manuel Lallana + */ +#endregion + +using System; +using WebSocketSharp.Net.WebSockets; + +namespace WebSocketSharp.Server +{ + /// + /// Exposes the methods and properties used to access the information in + /// a WebSocket service provided by the or + /// . + /// + /// + /// This class is an abstract class. + /// + public abstract class WebSocketServiceHost + { + #region Private Fields + + private Logger _log; + private string _path; + private WebSocketSessionManager _sessions; + + #endregion + + #region Protected Constructors + + /// + /// Initializes a new instance of the class + /// with the specified and . + /// + /// + /// A that represents the absolute path to the service. + /// + /// + /// A that represents the logging function for the service. + /// + protected WebSocketServiceHost (string path, Logger log) + { + _path = path; + _log = log; + + _sessions = new WebSocketSessionManager (log); + } + + #endregion + + #region Internal Properties + + internal ServerState State { + get { + return _sessions.State; + } + } + + #endregion + + #region Protected Properties + + /// + /// Gets the logging function for the service. + /// + /// + /// A that provides the logging function. + /// + protected Logger Log { + get { + return _log; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets or sets a value indicating whether the service cleans up + /// the inactive sessions periodically. + /// + /// + /// The set operation does nothing if the service has already started or + /// it is shutting down. + /// + /// + /// true if the service cleans up the inactive sessions every + /// 60 seconds; otherwise, false. + /// + public bool KeepClean { + get { + return _sessions.KeepClean; + } + + set { + _sessions.KeepClean = value; + } + } + + /// + /// Gets the path to the service. + /// + /// + /// A that represents the absolute path to + /// the service. + /// + public string Path { + get { + return _path; + } + } + + /// + /// Gets the management function for the sessions in the service. + /// + /// + /// A that manages the sessions in + /// the service. + /// + public WebSocketSessionManager Sessions { + get { + return _sessions; + } + } + + /// + /// Gets the of the behavior of the service. + /// + /// + /// A that represents the type of the behavior of + /// the service. + /// + public abstract Type BehaviorType { get; } + + /// + /// Gets or sets the time to wait for the response to the WebSocket Ping or + /// Close. + /// + /// + /// The set operation does nothing if the service has already started or + /// it is shutting down. + /// + /// + /// A to wait for the response. + /// + /// + /// The value specified for a set operation is zero or less. + /// + public TimeSpan WaitTime { + get { + return _sessions.WaitTime; + } + + set { + _sessions.WaitTime = value; + } + } + + #endregion + + #region Internal Methods + + internal void Start () + { + _sessions.Start (); + } + + internal void StartSession (WebSocketContext context) + { + CreateSession ().Start (context, _sessions); + } + + internal void Stop (ushort code, string reason) + { + _sessions.Stop (code, reason); + } + + #endregion + + #region Protected Methods + + /// + /// Creates a new session for the service. + /// + /// + /// A instance that represents + /// the new session. + /// + protected abstract WebSocketBehavior CreateSession (); + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost.cs.meta new file mode 100644 index 00000000..4a16c926 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b54355bc04fdf4ec18d52fda9670098d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost`1.cs b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost`1.cs new file mode 100644 index 00000000..d4ca6a2d --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost`1.cs @@ -0,0 +1,102 @@ +#region License +/* + * WebSocketServiceHost`1.cs + * + * The MIT License + * + * Copyright (c) 2015-2017 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Server +{ + internal class WebSocketServiceHost : WebSocketServiceHost + where TBehavior : WebSocketBehavior + { + #region Private Fields + + private Func _creator; + + #endregion + + #region Internal Constructors + + internal WebSocketServiceHost ( + string path, Func creator, Logger log + ) + : this (path, creator, null, log) + { + } + + internal WebSocketServiceHost ( + string path, + Func creator, + Action initializer, + Logger log + ) + : base (path, log) + { + _creator = createCreator (creator, initializer); + } + + #endregion + + #region Public Properties + + public override Type BehaviorType { + get { + return typeof (TBehavior); + } + } + + #endregion + + #region Private Methods + + private Func createCreator ( + Func creator, Action initializer + ) + { + if (initializer == null) + return creator; + + return () => { + var ret = creator (); + initializer (ret); + + return ret; + }; + } + + #endregion + + #region Protected Methods + + protected override WebSocketBehavior CreateSession () + { + return _creator (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost`1.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost`1.cs.meta new file mode 100644 index 00000000..daceb767 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceHost`1.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bac2d7c79b1db44a39304dbe37fceb24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceManager.cs b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceManager.cs new file mode 100644 index 00000000..ee1256fc --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceManager.cs @@ -0,0 +1,1078 @@ +#region License +/* + * WebSocketServiceManager.cs + * + * The MIT License + * + * Copyright (c) 2012-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using WebSocketSharp.Net; + +namespace WebSocketSharp.Server +{ + /// + /// Provides the management function for the WebSocket services. + /// + /// + /// This class manages the WebSocket services provided by + /// the or . + /// + public class WebSocketServiceManager + { + #region Private Fields + + private volatile bool _clean; + private Dictionary _hosts; + private Logger _log; + private volatile ServerState _state; + private object _sync; + private TimeSpan _waitTime; + + #endregion + + #region Internal Constructors + + internal WebSocketServiceManager (Logger log) + { + _log = log; + + _clean = true; + _hosts = new Dictionary (); + _state = ServerState.Ready; + _sync = ((ICollection) _hosts).SyncRoot; + _waitTime = TimeSpan.FromSeconds (1); + } + + #endregion + + #region Public Properties + + /// + /// Gets the number of the WebSocket services. + /// + /// + /// An that represents the number of the services. + /// + public int Count { + get { + lock (_sync) + return _hosts.Count; + } + } + + /// + /// Gets the host instances for the WebSocket services. + /// + /// + /// + /// An IEnumerable<WebSocketServiceHost> instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the host instances. + /// + /// + public IEnumerable Hosts { + get { + lock (_sync) + return _hosts.Values.ToList (); + } + } + + /// + /// Gets the host instance for a WebSocket service with the specified path. + /// + /// + /// + /// A instance or + /// if not found. + /// + /// + /// The host instance provides the function to access + /// the information in the service. + /// + /// + /// + /// + /// A that represents an absolute path to + /// the service to find. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// is . + /// + /// + /// + /// is empty. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + public WebSocketServiceHost this[string path] { + get { + if (path == null) + throw new ArgumentNullException ("path"); + + if (path.Length == 0) + throw new ArgumentException ("An empty string.", "path"); + + if (path[0] != '/') + throw new ArgumentException ("Not an absolute path.", "path"); + + if (path.IndexOfAny (new[] { '?', '#' }) > -1) { + var msg = "It includes either or both query and fragment components."; + throw new ArgumentException (msg, "path"); + } + + WebSocketServiceHost host; + InternalTryGetServiceHost (path, out host); + + return host; + } + } + + /// + /// Gets or sets a value indicating whether the inactive sessions in + /// the WebSocket services are cleaned up periodically. + /// + /// + /// The set operation does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// true if the inactive sessions are cleaned up every 60 seconds; + /// otherwise, false. + /// + public bool KeepClean { + get { + return _clean; + } + + set { + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + foreach (var host in _hosts.Values) + host.KeepClean = value; + + _clean = value; + } + } + } + + /// + /// Gets the paths for the WebSocket services. + /// + /// + /// + /// An IEnumerable<string> instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the paths. + /// + /// + public IEnumerable Paths { + get { + lock (_sync) + return _hosts.Keys.ToList (); + } + } + + /// + /// Gets the total number of the sessions in the WebSocket services. + /// + /// + /// An that represents the total number of + /// the sessions in the services. + /// + [Obsolete ("This property will be removed.")] + public int SessionCount { + get { + var cnt = 0; + foreach (var host in Hosts) { + if (_state != ServerState.Start) + break; + + cnt += host.Sessions.Count; + } + + return cnt; + } + } + + /// + /// Gets or sets the time to wait for the response to the WebSocket Ping or + /// Close. + /// + /// + /// The set operation does nothing if the server has already started or + /// it is shutting down. + /// + /// + /// A to wait for the response. + /// + /// + /// The value specified for a set operation is zero or less. + /// + public TimeSpan WaitTime { + get { + return _waitTime; + } + + set { + if (value <= TimeSpan.Zero) + throw new ArgumentOutOfRangeException ("value", "Zero or less."); + + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + foreach (var host in _hosts.Values) + host.WaitTime = value; + + _waitTime = value; + } + } + } + + #endregion + + #region Private Methods + + private void broadcast (Opcode opcode, byte[] data, Action completed) + { + var cache = new Dictionary (); + + try { + foreach (var host in Hosts) { + if (_state != ServerState.Start) { + _log.Error ("The server is shutting down."); + break; + } + + host.Sessions.Broadcast (opcode, data, cache); + } + + if (completed != null) + completed (); + } + catch (Exception ex) { + _log.Error (ex.Message); + _log.Debug (ex.ToString ()); + } + finally { + cache.Clear (); + } + } + + private void broadcast (Opcode opcode, Stream stream, Action completed) + { + var cache = new Dictionary (); + + try { + foreach (var host in Hosts) { + if (_state != ServerState.Start) { + _log.Error ("The server is shutting down."); + break; + } + + host.Sessions.Broadcast (opcode, stream, cache); + } + + if (completed != null) + completed (); + } + catch (Exception ex) { + _log.Error (ex.Message); + _log.Debug (ex.ToString ()); + } + finally { + foreach (var cached in cache.Values) + cached.Dispose (); + + cache.Clear (); + } + } + + private void broadcastAsync (Opcode opcode, byte[] data, Action completed) + { + ThreadPool.QueueUserWorkItem ( + state => broadcast (opcode, data, completed) + ); + } + + private void broadcastAsync (Opcode opcode, Stream stream, Action completed) + { + ThreadPool.QueueUserWorkItem ( + state => broadcast (opcode, stream, completed) + ); + } + + private Dictionary> broadping ( + byte[] frameAsBytes, TimeSpan timeout + ) + { + var ret = new Dictionary> (); + + foreach (var host in Hosts) { + if (_state != ServerState.Start) { + _log.Error ("The server is shutting down."); + break; + } + + var res = host.Sessions.Broadping (frameAsBytes, timeout); + ret.Add (host.Path, res); + } + + return ret; + } + + private bool canSet (out string message) + { + message = null; + + if (_state == ServerState.Start) { + message = "The server has already started."; + return false; + } + + if (_state == ServerState.ShuttingDown) { + message = "The server is shutting down."; + return false; + } + + return true; + } + + #endregion + + #region Internal Methods + + internal void Add (string path, Func creator) + where TBehavior : WebSocketBehavior + { + path = path.TrimSlashFromEnd (); + + lock (_sync) { + WebSocketServiceHost host; + if (_hosts.TryGetValue (path, out host)) + throw new ArgumentException ("Already in use.", "path"); + + host = new WebSocketServiceHost ( + path, creator, null, _log + ); + + if (!_clean) + host.KeepClean = false; + + if (_waitTime != host.WaitTime) + host.WaitTime = _waitTime; + + if (_state == ServerState.Start) + host.Start (); + + _hosts.Add (path, host); + } + } + + internal bool InternalTryGetServiceHost ( + string path, out WebSocketServiceHost host + ) + { + path = path.TrimSlashFromEnd (); + + lock (_sync) + return _hosts.TryGetValue (path, out host); + } + + internal void Start () + { + lock (_sync) { + foreach (var host in _hosts.Values) + host.Start (); + + _state = ServerState.Start; + } + } + + internal void Stop (ushort code, string reason) + { + lock (_sync) { + _state = ServerState.ShuttingDown; + + foreach (var host in _hosts.Values) + host.Stop (code, reason); + + _state = ServerState.Stop; + } + } + + #endregion + + #region Public Methods + + /// + /// Adds a WebSocket service with the specified behavior, path, + /// and delegate. + /// + /// + /// + /// A that represents an absolute path to + /// the service to add. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// + /// An Action<TBehavior> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when initializing + /// a new session instance for the service. + /// + /// + /// + /// + /// The type of the behavior for the service. + /// + /// + /// It must inherit the class. + /// + /// + /// And also, it must have a public parameterless constructor. + /// + /// + /// + /// is . + /// + /// + /// + /// is empty. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + /// -or- + /// + /// + /// is already in use. + /// + /// + public void AddService ( + string path, Action initializer + ) + where TBehavior : WebSocketBehavior, new () + { + if (path == null) + throw new ArgumentNullException ("path"); + + if (path.Length == 0) + throw new ArgumentException ("An empty string.", "path"); + + if (path[0] != '/') + throw new ArgumentException ("Not an absolute path.", "path"); + + if (path.IndexOfAny (new[] { '?', '#' }) > -1) { + var msg = "It includes either or both query and fragment components."; + throw new ArgumentException (msg, "path"); + } + + path = path.TrimSlashFromEnd (); + + lock (_sync) { + WebSocketServiceHost host; + if (_hosts.TryGetValue (path, out host)) + throw new ArgumentException ("Already in use.", "path"); + + host = new WebSocketServiceHost ( + path, () => new TBehavior (), initializer, _log + ); + + if (!_clean) + host.KeepClean = false; + + if (_waitTime != host.WaitTime) + host.WaitTime = _waitTime; + + if (_state == ServerState.Start) + host.Start (); + + _hosts.Add (path, host); + } + } + + /// + /// Sends to every client in the WebSocket services. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + [Obsolete ("This method will be removed.")] + public void Broadcast (byte[] data) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + if (data.LongLength <= WebSocket.FragmentLength) + broadcast (Opcode.Binary, data, null); + else + broadcast (Opcode.Binary, new MemoryStream (data), null); + } + + /// + /// Sends to every client in the WebSocket services. + /// + /// + /// A that represents the text data to send. + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + /// + /// could not be UTF-8-encoded. + /// + [Obsolete ("This method will be removed.")] + public void Broadcast (string data) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + byte[] bytes; + if (!data.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "data"); + } + + if (bytes.LongLength <= WebSocket.FragmentLength) + broadcast (Opcode.Text, bytes, null); + else + broadcast (Opcode.Text, new MemoryStream (bytes), null); + } + + /// + /// Sends asynchronously to every client in + /// the WebSocket services. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// + /// An delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + [Obsolete ("This method will be removed.")] + public void BroadcastAsync (byte[] data, Action completed) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + if (data.LongLength <= WebSocket.FragmentLength) + broadcastAsync (Opcode.Binary, data, completed); + else + broadcastAsync (Opcode.Binary, new MemoryStream (data), completed); + } + + /// + /// Sends asynchronously to every client in + /// the WebSocket services. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// A that represents the text data to send. + /// + /// + /// + /// An delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + /// + /// could not be UTF-8-encoded. + /// + [Obsolete ("This method will be removed.")] + public void BroadcastAsync (string data, Action completed) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + byte[] bytes; + if (!data.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "data"); + } + + if (bytes.LongLength <= WebSocket.FragmentLength) + broadcastAsync (Opcode.Text, bytes, completed); + else + broadcastAsync (Opcode.Text, new MemoryStream (bytes), completed); + } + + /// + /// Sends the data from asynchronously to + /// every client in the WebSocket services. + /// + /// + /// + /// The data is sent as the binary data. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// + /// An delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + [Obsolete ("This method will be removed.")] + public void BroadcastAsync (Stream stream, int length, Action completed) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (stream == null) + throw new ArgumentNullException ("stream"); + + if (!stream.CanRead) { + var msg = "It cannot be read."; + throw new ArgumentException (msg, "stream"); + } + + if (length < 1) { + var msg = "Less than 1."; + throw new ArgumentException (msg, "length"); + } + + var bytes = stream.ReadBytes (length); + + var len = bytes.Length; + if (len == 0) { + var msg = "No data could be read from it."; + throw new ArgumentException (msg, "stream"); + } + + if (len < length) { + _log.Warn ( + String.Format ( + "Only {0} byte(s) of data could be read from the stream.", + len + ) + ); + } + + if (len <= WebSocket.FragmentLength) + broadcastAsync (Opcode.Binary, bytes, completed); + else + broadcastAsync (Opcode.Binary, new MemoryStream (bytes), completed); + } + + /// + /// Sends a ping to every client in the WebSocket services. + /// + /// + /// + /// A Dictionary<string, Dictionary<string, bool>>. + /// + /// + /// It represents a collection of pairs of a service path and another + /// collection of pairs of a session ID and a value indicating whether + /// a pong has been received from the client within a time. + /// + /// + /// + /// The current state of the manager is not Start. + /// + [Obsolete ("This method will be removed.")] + public Dictionary> Broadping () + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + return broadping (WebSocketFrame.EmptyPingBytes, _waitTime); + } + + /// + /// Sends a ping with to every client in + /// the WebSocket services. + /// + /// + /// + /// A Dictionary<string, Dictionary<string, bool>>. + /// + /// + /// It represents a collection of pairs of a service path and another + /// collection of pairs of a session ID and a value indicating whether + /// a pong has been received from the client within a time. + /// + /// + /// + /// + /// A that represents the message to send. + /// + /// + /// The size must be 125 bytes or less in UTF-8. + /// + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// The size of is greater than 125 bytes. + /// + [Obsolete ("This method will be removed.")] + public Dictionary> Broadping (string message) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (message.IsNullOrEmpty ()) + return broadping (WebSocketFrame.EmptyPingBytes, _waitTime); + + byte[] bytes; + if (!message.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "message"); + } + + if (bytes.Length > 125) { + var msg = "Its size is greater than 125 bytes."; + throw new ArgumentOutOfRangeException ("message", msg); + } + + var frame = WebSocketFrame.CreatePingFrame (bytes, false); + return broadping (frame.ToArray (), _waitTime); + } + + /// + /// Removes all WebSocket services managed by the manager. + /// + /// + /// A service is stopped with close status 1001 (going away) + /// if it has already started. + /// + public void Clear () + { + List hosts = null; + + lock (_sync) { + hosts = _hosts.Values.ToList (); + _hosts.Clear (); + } + + foreach (var host in hosts) { + if (host.State == ServerState.Start) + host.Stop (1001, String.Empty); + } + } + + /// + /// Removes a WebSocket service with the specified path. + /// + /// + /// The service is stopped with close status 1001 (going away) + /// if it has already started. + /// + /// + /// true if the service is successfully found and removed; + /// otherwise, false. + /// + /// + /// + /// A that represents an absolute path to + /// the service to remove. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// is . + /// + /// + /// + /// is empty. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + public bool RemoveService (string path) + { + if (path == null) + throw new ArgumentNullException ("path"); + + if (path.Length == 0) + throw new ArgumentException ("An empty string.", "path"); + + if (path[0] != '/') + throw new ArgumentException ("Not an absolute path.", "path"); + + if (path.IndexOfAny (new[] { '?', '#' }) > -1) { + var msg = "It includes either or both query and fragment components."; + throw new ArgumentException (msg, "path"); + } + + path = path.TrimSlashFromEnd (); + + WebSocketServiceHost host; + lock (_sync) { + if (!_hosts.TryGetValue (path, out host)) + return false; + + _hosts.Remove (path); + } + + if (host.State == ServerState.Start) + host.Stop (1001, String.Empty); + + return true; + } + + /// + /// Tries to get the host instance for a WebSocket service with + /// the specified path. + /// + /// + /// true if the service is successfully found; otherwise, + /// false. + /// + /// + /// + /// A that represents an absolute path to + /// the service to find. + /// + /// + /// / is trimmed from the end of the string if present. + /// + /// + /// + /// + /// When this method returns, a + /// instance or if not found. + /// + /// + /// The host instance provides the function to access + /// the information in the service. + /// + /// + /// + /// is . + /// + /// + /// + /// is empty. + /// + /// + /// -or- + /// + /// + /// is not an absolute path. + /// + /// + /// -or- + /// + /// + /// includes either or both + /// query and fragment components. + /// + /// + public bool TryGetServiceHost (string path, out WebSocketServiceHost host) + { + if (path == null) + throw new ArgumentNullException ("path"); + + if (path.Length == 0) + throw new ArgumentException ("An empty string.", "path"); + + if (path[0] != '/') + throw new ArgumentException ("Not an absolute path.", "path"); + + if (path.IndexOfAny (new[] { '?', '#' }) > -1) { + var msg = "It includes either or both query and fragment components."; + throw new ArgumentException (msg, "path"); + } + + return InternalTryGetServiceHost (path, out host); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceManager.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceManager.cs.meta new file mode 100644 index 00000000..07b88887 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketServiceManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3338682d74e7f41f7b849bcb38718d8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketSessionManager.cs b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketSessionManager.cs new file mode 100644 index 00000000..f7144b0c --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketSessionManager.cs @@ -0,0 +1,1695 @@ +#region License +/* + * WebSocketSessionManager.cs + * + * The MIT License + * + * Copyright (c) 2012-2015 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Timers; + +namespace WebSocketSharp.Server +{ + /// + /// Provides the management function for the sessions in a WebSocket service. + /// + /// + /// This class manages the sessions in a WebSocket service provided by + /// the or . + /// + public class WebSocketSessionManager + { + #region Private Fields + + private volatile bool _clean; + private object _forSweep; + private Logger _log; + private Dictionary _sessions; + private volatile ServerState _state; + private volatile bool _sweeping; + private System.Timers.Timer _sweepTimer; + private object _sync; + private TimeSpan _waitTime; + + #endregion + + #region Internal Constructors + + internal WebSocketSessionManager (Logger log) + { + _log = log; + + _clean = true; + _forSweep = new object (); + _sessions = new Dictionary (); + _state = ServerState.Ready; + _sync = ((ICollection) _sessions).SyncRoot; + _waitTime = TimeSpan.FromSeconds (1); + + setSweepTimer (60000); + } + + #endregion + + #region Internal Properties + + internal ServerState State { + get { + return _state; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the IDs for the active sessions in the WebSocket service. + /// + /// + /// + /// An IEnumerable<string> instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the IDs for the active sessions. + /// + /// + public IEnumerable ActiveIDs { + get { + foreach (var res in broadping (WebSocketFrame.EmptyPingBytes)) { + if (res.Value) + yield return res.Key; + } + } + } + + /// + /// Gets the number of the sessions in the WebSocket service. + /// + /// + /// An that represents the number of the sessions. + /// + public int Count { + get { + lock (_sync) + return _sessions.Count; + } + } + + /// + /// Gets the IDs for the sessions in the WebSocket service. + /// + /// + /// + /// An IEnumerable<string> instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the IDs for the sessions. + /// + /// + public IEnumerable IDs { + get { + if (_state != ServerState.Start) + return Enumerable.Empty (); + + lock (_sync) { + if (_state != ServerState.Start) + return Enumerable.Empty (); + + return _sessions.Keys.ToList (); + } + } + } + + /// + /// Gets the IDs for the inactive sessions in the WebSocket service. + /// + /// + /// + /// An IEnumerable<string> instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the IDs for the inactive sessions. + /// + /// + public IEnumerable InactiveIDs { + get { + foreach (var res in broadping (WebSocketFrame.EmptyPingBytes)) { + if (!res.Value) + yield return res.Key; + } + } + } + + /// + /// Gets the session instance with . + /// + /// + /// + /// A instance or + /// if not found. + /// + /// + /// The session instance provides the function to access the information + /// in the session. + /// + /// + /// + /// A that represents the ID of the session to find. + /// + /// + /// is . + /// + /// + /// is an empty string. + /// + public IWebSocketSession this[string id] { + get { + if (id == null) + throw new ArgumentNullException ("id"); + + if (id.Length == 0) + throw new ArgumentException ("An empty string.", "id"); + + IWebSocketSession session; + tryGetSession (id, out session); + + return session; + } + } + + /// + /// Gets or sets a value indicating whether the inactive sessions in + /// the WebSocket service are cleaned up periodically. + /// + /// + /// The set operation does nothing if the service has already started or + /// it is shutting down. + /// + /// + /// true if the inactive sessions are cleaned up every 60 seconds; + /// otherwise, false. + /// + public bool KeepClean { + get { + return _clean; + } + + set { + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + _clean = value; + } + } + } + + /// + /// Gets the session instances in the WebSocket service. + /// + /// + /// + /// An IEnumerable<IWebSocketSession> instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the session instances. + /// + /// + public IEnumerable Sessions { + get { + if (_state != ServerState.Start) + return Enumerable.Empty (); + + lock (_sync) { + if (_state != ServerState.Start) + return Enumerable.Empty (); + + return _sessions.Values.ToList (); + } + } + } + + /// + /// Gets or sets the time to wait for the response to the WebSocket Ping or + /// Close. + /// + /// + /// The set operation does nothing if the service has already started or + /// it is shutting down. + /// + /// + /// A to wait for the response. + /// + /// + /// The value specified for a set operation is zero or less. + /// + public TimeSpan WaitTime { + get { + return _waitTime; + } + + set { + if (value <= TimeSpan.Zero) + throw new ArgumentOutOfRangeException ("value", "Zero or less."); + + string msg; + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + lock (_sync) { + if (!canSet (out msg)) { + _log.Warn (msg); + return; + } + + _waitTime = value; + } + } + } + + #endregion + + #region Private Methods + + private void broadcast (Opcode opcode, byte[] data, Action completed) + { + var cache = new Dictionary (); + + try { + foreach (var session in Sessions) { + if (_state != ServerState.Start) { + _log.Error ("The service is shutting down."); + break; + } + + session.Context.WebSocket.Send (opcode, data, cache); + } + + if (completed != null) + completed (); + } + catch (Exception ex) { + _log.Error (ex.Message); + _log.Debug (ex.ToString ()); + } + finally { + cache.Clear (); + } + } + + private void broadcast (Opcode opcode, Stream stream, Action completed) + { + var cache = new Dictionary (); + + try { + foreach (var session in Sessions) { + if (_state != ServerState.Start) { + _log.Error ("The service is shutting down."); + break; + } + + session.Context.WebSocket.Send (opcode, stream, cache); + } + + if (completed != null) + completed (); + } + catch (Exception ex) { + _log.Error (ex.Message); + _log.Debug (ex.ToString ()); + } + finally { + foreach (var cached in cache.Values) + cached.Dispose (); + + cache.Clear (); + } + } + + private void broadcastAsync (Opcode opcode, byte[] data, Action completed) + { + ThreadPool.QueueUserWorkItem ( + state => broadcast (opcode, data, completed) + ); + } + + private void broadcastAsync (Opcode opcode, Stream stream, Action completed) + { + ThreadPool.QueueUserWorkItem ( + state => broadcast (opcode, stream, completed) + ); + } + + private Dictionary broadping (byte[] frameAsBytes) + { + var ret = new Dictionary (); + + foreach (var session in Sessions) { + if (_state != ServerState.Start) { + _log.Error ("The service is shutting down."); + break; + } + + var res = session.Context.WebSocket.Ping (frameAsBytes, _waitTime); + ret.Add (session.ID, res); + } + + return ret; + } + + private bool canSet (out string message) + { + message = null; + + if (_state == ServerState.Start) { + message = "The service has already started."; + return false; + } + + if (_state == ServerState.ShuttingDown) { + message = "The service is shutting down."; + return false; + } + + return true; + } + + private static string createID () + { + return Guid.NewGuid ().ToString ("N"); + } + + private void setSweepTimer (double interval) + { + _sweepTimer = new System.Timers.Timer (interval); + _sweepTimer.Elapsed += (sender, e) => Sweep (); + } + + private void stop (PayloadData payloadData, bool send) + { + var bytes = send + ? WebSocketFrame.CreateCloseFrame (payloadData, false).ToArray () + : null; + + lock (_sync) { + _state = ServerState.ShuttingDown; + + _sweepTimer.Enabled = false; + foreach (var session in _sessions.Values.ToList ()) + session.Context.WebSocket.Close (payloadData, bytes); + + _state = ServerState.Stop; + } + } + + private bool tryGetSession (string id, out IWebSocketSession session) + { + session = null; + + if (_state != ServerState.Start) + return false; + + lock (_sync) { + if (_state != ServerState.Start) + return false; + + return _sessions.TryGetValue (id, out session); + } + } + + #endregion + + #region Internal Methods + + internal string Add (IWebSocketSession session) + { + lock (_sync) { + if (_state != ServerState.Start) + return null; + + var id = createID (); + _sessions.Add (id, session); + + return id; + } + } + + internal void Broadcast ( + Opcode opcode, byte[] data, Dictionary cache + ) + { + foreach (var session in Sessions) { + if (_state != ServerState.Start) { + _log.Error ("The service is shutting down."); + break; + } + + session.Context.WebSocket.Send (opcode, data, cache); + } + } + + internal void Broadcast ( + Opcode opcode, Stream stream, Dictionary cache + ) + { + foreach (var session in Sessions) { + if (_state != ServerState.Start) { + _log.Error ("The service is shutting down."); + break; + } + + session.Context.WebSocket.Send (opcode, stream, cache); + } + } + + internal Dictionary Broadping ( + byte[] frameAsBytes, TimeSpan timeout + ) + { + var ret = new Dictionary (); + + foreach (var session in Sessions) { + if (_state != ServerState.Start) { + _log.Error ("The service is shutting down."); + break; + } + + var res = session.Context.WebSocket.Ping (frameAsBytes, timeout); + ret.Add (session.ID, res); + } + + return ret; + } + + internal bool Remove (string id) + { + lock (_sync) + return _sessions.Remove (id); + } + + internal void Start () + { + lock (_sync) { + _sweepTimer.Enabled = _clean; + _state = ServerState.Start; + } + } + + internal void Stop (ushort code, string reason) + { + if (code == 1005) { // == no status + stop (PayloadData.Empty, true); + return; + } + + stop (new PayloadData (code, reason), !code.IsReserved ()); + } + + #endregion + + #region Public Methods + + /// + /// Sends to every client in the WebSocket service. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + public void Broadcast (byte[] data) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + if (data.LongLength <= WebSocket.FragmentLength) + broadcast (Opcode.Binary, data, null); + else + broadcast (Opcode.Binary, new MemoryStream (data), null); + } + + /// + /// Sends to every client in the WebSocket service. + /// + /// + /// A that represents the text data to send. + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + /// + /// could not be UTF-8-encoded. + /// + public void Broadcast (string data) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + byte[] bytes; + if (!data.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "data"); + } + + if (bytes.LongLength <= WebSocket.FragmentLength) + broadcast (Opcode.Text, bytes, null); + else + broadcast (Opcode.Text, new MemoryStream (bytes), null); + } + + /// + /// Sends the data from to every client in + /// the WebSocket service. + /// + /// + /// The data is sent as the binary data. + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + public void Broadcast (Stream stream, int length) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (stream == null) + throw new ArgumentNullException ("stream"); + + if (!stream.CanRead) { + var msg = "It cannot be read."; + throw new ArgumentException (msg, "stream"); + } + + if (length < 1) { + var msg = "Less than 1."; + throw new ArgumentException (msg, "length"); + } + + var bytes = stream.ReadBytes (length); + + var len = bytes.Length; + if (len == 0) { + var msg = "No data could be read from it."; + throw new ArgumentException (msg, "stream"); + } + + if (len < length) { + _log.Warn ( + String.Format ( + "Only {0} byte(s) of data could be read from the stream.", + len + ) + ); + } + + if (len <= WebSocket.FragmentLength) + broadcast (Opcode.Binary, bytes, null); + else + broadcast (Opcode.Binary, new MemoryStream (bytes), null); + } + + /// + /// Sends asynchronously to every client in + /// the WebSocket service. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// + /// An delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + public void BroadcastAsync (byte[] data, Action completed) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + if (data.LongLength <= WebSocket.FragmentLength) + broadcastAsync (Opcode.Binary, data, completed); + else + broadcastAsync (Opcode.Binary, new MemoryStream (data), completed); + } + + /// + /// Sends asynchronously to every client in + /// the WebSocket service. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// A that represents the text data to send. + /// + /// + /// + /// An delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + /// + /// could not be UTF-8-encoded. + /// + public void BroadcastAsync (string data, Action completed) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + byte[] bytes; + if (!data.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "data"); + } + + if (bytes.LongLength <= WebSocket.FragmentLength) + broadcastAsync (Opcode.Text, bytes, completed); + else + broadcastAsync (Opcode.Text, new MemoryStream (bytes), completed); + } + + /// + /// Sends the data from asynchronously to + /// every client in the WebSocket service. + /// + /// + /// + /// The data is sent as the binary data. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// + /// An delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// is . + /// + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + public void BroadcastAsync (Stream stream, int length, Action completed) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (stream == null) + throw new ArgumentNullException ("stream"); + + if (!stream.CanRead) { + var msg = "It cannot be read."; + throw new ArgumentException (msg, "stream"); + } + + if (length < 1) { + var msg = "Less than 1."; + throw new ArgumentException (msg, "length"); + } + + var bytes = stream.ReadBytes (length); + + var len = bytes.Length; + if (len == 0) { + var msg = "No data could be read from it."; + throw new ArgumentException (msg, "stream"); + } + + if (len < length) { + _log.Warn ( + String.Format ( + "Only {0} byte(s) of data could be read from the stream.", + len + ) + ); + } + + if (len <= WebSocket.FragmentLength) + broadcastAsync (Opcode.Binary, bytes, completed); + else + broadcastAsync (Opcode.Binary, new MemoryStream (bytes), completed); + } + + /// + /// Sends a ping to every client in the WebSocket service. + /// + /// + /// + /// A Dictionary<string, bool>. + /// + /// + /// It represents a collection of pairs of a session ID and + /// a value indicating whether a pong has been received from + /// the client within a time. + /// + /// + /// + /// The current state of the manager is not Start. + /// + [Obsolete ("This method will be removed.")] + public Dictionary Broadping () + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + return Broadping (WebSocketFrame.EmptyPingBytes, _waitTime); + } + + /// + /// Sends a ping with to every client in + /// the WebSocket service. + /// + /// + /// + /// A Dictionary<string, bool>. + /// + /// + /// It represents a collection of pairs of a session ID and + /// a value indicating whether a pong has been received from + /// the client within a time. + /// + /// + /// + /// + /// A that represents the message to send. + /// + /// + /// The size must be 125 bytes or less in UTF-8. + /// + /// + /// + /// The current state of the manager is not Start. + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// The size of is greater than 125 bytes. + /// + [Obsolete ("This method will be removed.")] + public Dictionary Broadping (string message) + { + if (_state != ServerState.Start) { + var msg = "The current state of the manager is not Start."; + throw new InvalidOperationException (msg); + } + + if (message.IsNullOrEmpty ()) + return Broadping (WebSocketFrame.EmptyPingBytes, _waitTime); + + byte[] bytes; + if (!message.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "message"); + } + + if (bytes.Length > 125) { + var msg = "Its size is greater than 125 bytes."; + throw new ArgumentOutOfRangeException ("message", msg); + } + + var frame = WebSocketFrame.CreatePingFrame (bytes, false); + return Broadping (frame.ToArray (), _waitTime); + } + + /// + /// Closes the specified session. + /// + /// + /// A that represents the ID of the session to close. + /// + /// + /// is . + /// + /// + /// is an empty string. + /// + /// + /// The session could not be found. + /// + public void CloseSession (string id) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.Close (); + } + + /// + /// Closes the specified session with and + /// . + /// + /// + /// A that represents the ID of the session to close. + /// + /// + /// + /// A that represents the status code indicating + /// the reason for the close. + /// + /// + /// The status codes are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is 1010 (mandatory extension). + /// + /// + /// -or- + /// + /// + /// is 1005 (no status) and there is + /// . + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// The session could not be found. + /// + /// + /// + /// is less than 1000 or greater than 4999. + /// + /// + /// -or- + /// + /// + /// The size of is greater than 123 bytes. + /// + /// + public void CloseSession (string id, ushort code, string reason) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.Close (code, reason); + } + + /// + /// Closes the specified session with and + /// . + /// + /// + /// A that represents the ID of the session to close. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It represents the status code indicating the reason for the close. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is + /// . + /// + /// + /// -or- + /// + /// + /// is + /// and there is + /// . + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// The session could not be found. + /// + /// + /// The size of is greater than 123 bytes. + /// + public void CloseSession (string id, CloseStatusCode code, string reason) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.Close (code, reason); + } + + /// + /// Sends a ping to the client using the specified session. + /// + /// + /// true if the send has done with no error and a pong has been + /// received from the client within a time; otherwise, false. + /// + /// + /// A that represents the ID of the session. + /// + /// + /// is . + /// + /// + /// is an empty string. + /// + /// + /// The session could not be found. + /// + public bool PingTo (string id) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + return session.Context.WebSocket.Ping (); + } + + /// + /// Sends a ping with to the client using + /// the specified session. + /// + /// + /// true if the send has done with no error and a pong has been + /// received from the client within a time; otherwise, false. + /// + /// + /// + /// A that represents the message to send. + /// + /// + /// The size must be 125 bytes or less in UTF-8. + /// + /// + /// + /// A that represents the ID of the session. + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// The session could not be found. + /// + /// + /// The size of is greater than 125 bytes. + /// + public bool PingTo (string message, string id) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + return session.Context.WebSocket.Ping (message); + } + + /// + /// Sends to the client using the specified session. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// A that represents the ID of the session. + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// + /// The session could not be found. + /// + /// + /// -or- + /// + /// + /// The current state of the WebSocket connection is not Open. + /// + /// + public void SendTo (byte[] data, string id) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.Send (data); + } + + /// + /// Sends to the client using the specified session. + /// + /// + /// A that represents the text data to send. + /// + /// + /// A that represents the ID of the session. + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// + /// The session could not be found. + /// + /// + /// -or- + /// + /// + /// The current state of the WebSocket connection is not Open. + /// + /// + public void SendTo (string data, string id) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.Send (data); + } + + /// + /// Sends the data from to the client using + /// the specified session. + /// + /// + /// The data is sent as the binary data. + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// A that represents the ID of the session. + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + /// + /// + /// The session could not be found. + /// + /// + /// -or- + /// + /// + /// The current state of the WebSocket connection is not Open. + /// + /// + public void SendTo (Stream stream, int length, string id) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.Send (stream, length); + } + + /// + /// Sends asynchronously to the client using + /// the specified session. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// A that represents the ID of the session. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// + /// The session could not be found. + /// + /// + /// -or- + /// + /// + /// The current state of the WebSocket connection is not Open. + /// + /// + public void SendToAsync (byte[] data, string id, Action completed) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.SendAsync (data, completed); + } + + /// + /// Sends asynchronously to the client using + /// the specified session. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// A that represents the text data to send. + /// + /// + /// A that represents the ID of the session. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// + /// The session could not be found. + /// + /// + /// -or- + /// + /// + /// The current state of the WebSocket connection is not Open. + /// + /// + public void SendToAsync (string data, string id, Action completed) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.SendAsync (data, completed); + } + + /// + /// Sends the data from asynchronously to + /// the client using the specified session. + /// + /// + /// + /// The data is sent as the binary data. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// A that represents the ID of the session. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// + /// is . + /// + /// + /// -or- + /// + /// + /// is . + /// + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + /// + /// + /// The session could not be found. + /// + /// + /// -or- + /// + /// + /// The current state of the WebSocket connection is not Open. + /// + /// + public void SendToAsync ( + Stream stream, int length, string id, Action completed + ) + { + IWebSocketSession session; + if (!TryGetSession (id, out session)) { + var msg = "The session could not be found."; + throw new InvalidOperationException (msg); + } + + session.Context.WebSocket.SendAsync (stream, length, completed); + } + + /// + /// Cleans up the inactive sessions in the WebSocket service. + /// + public void Sweep () + { + if (_sweeping) { + _log.Info ("The sweeping is already in progress."); + return; + } + + lock (_forSweep) { + if (_sweeping) { + _log.Info ("The sweeping is already in progress."); + return; + } + + _sweeping = true; + } + + foreach (var id in InactiveIDs) { + if (_state != ServerState.Start) + break; + + lock (_sync) { + if (_state != ServerState.Start) + break; + + IWebSocketSession session; + if (_sessions.TryGetValue (id, out session)) { + var state = session.ConnectionState; + if (state == WebSocketState.Open) + session.Context.WebSocket.Close (CloseStatusCode.Abnormal); + else if (state == WebSocketState.Closing) + continue; + else + _sessions.Remove (id); + } + } + } + + _sweeping = false; + } + + /// + /// Tries to get the session instance with . + /// + /// + /// true if the session is successfully found; otherwise, + /// false. + /// + /// + /// A that represents the ID of the session to find. + /// + /// + /// + /// When this method returns, a + /// instance or if not found. + /// + /// + /// The session instance provides the function to access + /// the information in the session. + /// + /// + /// + /// is . + /// + /// + /// is an empty string. + /// + public bool TryGetSession (string id, out IWebSocketSession session) + { + if (id == null) + throw new ArgumentNullException ("id"); + + if (id.Length == 0) + throw new ArgumentException ("An empty string.", "id"); + + return tryGetSession (id, out session); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketSessionManager.cs.meta b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketSessionManager.cs.meta new file mode 100644 index 00000000..722f2fa6 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/Server/WebSocketSessionManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3562b4fae16a349c59c6372a511d049f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/WebSocket.cs b/Plugins/websocket-sharp/websocket-sharp/WebSocket.cs new file mode 100644 index 00000000..4c1c88ba --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/WebSocket.cs @@ -0,0 +1,4097 @@ +#region License +/* + * WebSocket.cs + * + * This code is derived from WebSocket.java + * (http://github.com/adamac/Java-WebSocket-client). + * + * The MIT License + * + * Copyright (c) 2009 Adam MacBeth + * Copyright (c) 2010-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Frank Razenberg + * - David Wood + * - Liryna + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; +using System.IO; +using System.Net.Security; +using System.Net.Sockets; +using System.Security.Cryptography; +using System.Text; +using System.Threading; +using WebSocketSharp.Net; +using WebSocketSharp.Net.WebSockets; + +namespace WebSocketSharp +{ + /// + /// Implements the WebSocket interface. + /// + /// + /// + /// This class provides a set of methods and properties for two-way + /// communication using the WebSocket protocol. + /// + /// + /// The WebSocket protocol is defined in + /// RFC 6455. + /// + /// + public class WebSocket : IDisposable + { + #region Private Fields + + private AuthenticationChallenge _authChallenge; + private string _base64Key; + private bool _client; + private Action _closeContext; + private CompressionMethod _compression; + private WebSocketContext _context; + private CookieCollection _cookies; + private NetworkCredential _credentials; + private bool _emitOnPing; + private bool _enableRedirection; + private string _extensions; + private bool _extensionsRequested; + private object _forMessageEventQueue; + private object _forPing; + private object _forSend; + private object _forState; + private MemoryStream _fragmentsBuffer; + private bool _fragmentsCompressed; + private Opcode _fragmentsOpcode; + private const string _guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + private Func _handshakeRequestChecker; + private bool _ignoreExtensions; + private bool _inContinuation; + private volatile bool _inMessage; + private volatile Logger _logger; + private static readonly int _maxRetryCountForConnect; + private Action _message; + private Queue _messageEventQueue; + private uint _nonceCount; + private string _origin; + private ManualResetEvent _pongReceived; + private bool _preAuth; + private string _protocol; + private string[] _protocols; + private bool _protocolsRequested; + private NetworkCredential _proxyCredentials; + private Uri _proxyUri; + private volatile WebSocketState _readyState; + private ManualResetEvent _receivingExited; + private int _retryCountForConnect; + private bool _secure; + private ClientSslConfiguration _sslConfig; + private Stream _stream; + private TcpClient _tcpClient; + private Uri _uri; + private const string _version = "13"; + private TimeSpan _waitTime; + + #endregion + + #region Internal Fields + + /// + /// Represents the empty array of used internally. + /// + internal static readonly byte[] EmptyBytes; + + /// + /// Represents the length used to determine whether the data should be fragmented in sending. + /// + /// + /// + /// The data will be fragmented if that length is greater than the value of this field. + /// + /// + /// If you would like to change the value, you must set it to a value between 125 and + /// Int32.MaxValue - 14 inclusive. + /// + /// + internal static readonly int FragmentLength; + + /// + /// Represents the random number generator used internally. + /// + internal static readonly RandomNumberGenerator RandomNumber; + + #endregion + + #region Static Constructor + + static WebSocket () + { + _maxRetryCountForConnect = 10; + EmptyBytes = new byte[0]; + FragmentLength = 1016; + RandomNumber = new RNGCryptoServiceProvider (); + } + + #endregion + + #region Internal Constructors + + // As server + internal WebSocket (HttpListenerWebSocketContext context, string protocol) + { + _context = context; + _protocol = protocol; + + _closeContext = context.Close; + _logger = context.Log; + _message = messages; + _secure = context.IsSecureConnection; + _stream = context.Stream; + _waitTime = TimeSpan.FromSeconds (1); + + init (); + } + + // As server + internal WebSocket (TcpListenerWebSocketContext context, string protocol) + { + _context = context; + _protocol = protocol; + + _closeContext = context.Close; + _logger = context.Log; + _message = messages; + _secure = context.IsSecureConnection; + _stream = context.Stream; + _waitTime = TimeSpan.FromSeconds (1); + + init (); + } + + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the class with + /// and optionally . + /// + /// + /// + /// A that specifies the URL to which to connect. + /// + /// + /// The scheme of the URL must be ws or wss. + /// + /// + /// The new instance uses a secure connection if the scheme is wss. + /// + /// + /// + /// + /// An array of that specifies the names of + /// the subprotocols if necessary. + /// + /// + /// Each value of the array must be a token defined in + /// + /// RFC 2616. + /// + /// + /// + /// is . + /// + /// + /// + /// is an empty string. + /// + /// + /// -or- + /// + /// + /// is an invalid WebSocket URL string. + /// + /// + /// -or- + /// + /// + /// contains a value that is not a token. + /// + /// + /// -or- + /// + /// + /// contains a value twice. + /// + /// + public WebSocket (string url, params string[] protocols) + { + if (url == null) + throw new ArgumentNullException ("url"); + + if (url.Length == 0) + throw new ArgumentException ("An empty string.", "url"); + + string msg; + if (!url.TryCreateWebSocketUri (out _uri, out msg)) + throw new ArgumentException (msg, "url"); + + if (protocols != null && protocols.Length > 0) { + if (!checkProtocols (protocols, out msg)) + throw new ArgumentException (msg, "protocols"); + + _protocols = protocols; + } + + _base64Key = CreateBase64Key (); + _client = true; + _logger = new Logger (); + _message = messagec; + _secure = _uri.Scheme == "wss"; + _waitTime = TimeSpan.FromSeconds (5); + + init (); + } + + #endregion + + #region Internal Properties + + internal CookieCollection CookieCollection { + get { + return _cookies; + } + } + + // As server + internal Func CustomHandshakeRequestChecker { + get { + return _handshakeRequestChecker; + } + + set { + _handshakeRequestChecker = value; + } + } + + internal bool HasMessage { + get { + lock (_forMessageEventQueue) + return _messageEventQueue.Count > 0; + } + } + + // As server + internal bool IgnoreExtensions { + get { + return _ignoreExtensions; + } + + set { + _ignoreExtensions = value; + } + } + + internal bool IsConnected { + get { + return _readyState == WebSocketState.Open || _readyState == WebSocketState.Closing; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets or sets the compression method used to compress a message. + /// + /// + /// The set operation does nothing if the connection has already been + /// established or it is closing. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It specifies the compression method used to compress a message. + /// + /// + /// The default value is . + /// + /// + /// + /// The set operation is not available if this instance is not a client. + /// + public CompressionMethod Compression { + get { + return _compression; + } + + set { + string msg = null; + + if (!_client) { + msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + lock (_forState) { + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + _compression = value; + } + } + } + + /// + /// Gets the HTTP cookies included in the handshake request/response. + /// + /// + /// + /// An + /// instance. + /// + /// + /// It provides an enumerator which supports the iteration over + /// the collection of the cookies. + /// + /// + public IEnumerable Cookies { + get { + lock (_cookies.SyncRoot) { + foreach (Cookie cookie in _cookies) + yield return cookie; + } + } + } + + /// + /// Gets the credentials for the HTTP authentication (Basic/Digest). + /// + /// + /// + /// A that represents the credentials + /// used to authenticate the client. + /// + /// + /// The default value is . + /// + /// + public NetworkCredential Credentials { + get { + return _credentials; + } + } + + /// + /// Gets or sets a value indicating whether a event + /// is emitted when a ping is received. + /// + /// + /// + /// true if this instance emits a event + /// when receives a ping; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + public bool EmitOnPing { + get { + return _emitOnPing; + } + + set { + _emitOnPing = value; + } + } + + /// + /// Gets or sets a value indicating whether the URL redirection for + /// the handshake request is allowed. + /// + /// + /// The set operation does nothing if the connection has already been + /// established or it is closing. + /// + /// + /// + /// true if this instance allows the URL redirection for + /// the handshake request; otherwise, false. + /// + /// + /// The default value is false. + /// + /// + /// + /// The set operation is not available if this instance is not a client. + /// + public bool EnableRedirection { + get { + return _enableRedirection; + } + + set { + string msg = null; + + if (!_client) { + msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + lock (_forState) { + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + _enableRedirection = value; + } + } + } + + /// + /// Gets the extensions selected by server. + /// + /// + /// A that will be a list of the extensions + /// negotiated between client and server, or an empty string if + /// not specified or selected. + /// + public string Extensions { + get { + return _extensions ?? String.Empty; + } + } + + /// + /// Gets a value indicating whether the connection is alive. + /// + /// + /// The get operation returns the value by using a ping/pong + /// if the current state of the connection is Open. + /// + /// + /// true if the connection is alive; otherwise, false. + /// + public bool IsAlive { + get { + return ping (EmptyBytes); + } + } + + /// + /// Gets a value indicating whether a secure connection is used. + /// + /// + /// true if this instance uses a secure connection; otherwise, + /// false. + /// + public bool IsSecure { + get { + return _secure; + } + } + + /// + /// Gets the logging function. + /// + /// + /// The default logging level is . + /// + /// + /// A that provides the logging function. + /// + public Logger Log { + get { + return _logger; + } + + internal set { + _logger = value; + } + } + + /// + /// Gets or sets the value of the HTTP Origin header to send with + /// the handshake request. + /// + /// + /// + /// The HTTP Origin header is defined in + /// + /// Section 7 of RFC 6454. + /// + /// + /// This instance sends the Origin header if this property has any. + /// + /// + /// The set operation does nothing if the connection has already been + /// established or it is closing. + /// + /// + /// + /// + /// A that represents the value of the Origin + /// header to send. + /// + /// + /// The syntax is <scheme>://<host>[:<port>]. + /// + /// + /// The default value is . + /// + /// + /// + /// The set operation is not available if this instance is not a client. + /// + /// + /// + /// The value specified for a set operation is not an absolute URI string. + /// + /// + /// -or- + /// + /// + /// The value specified for a set operation includes the path segments. + /// + /// + public string Origin { + get { + return _origin; + } + + set { + string msg = null; + + if (!_client) { + msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + if (!value.IsNullOrEmpty ()) { + Uri uri; + if (!Uri.TryCreate (value, UriKind.Absolute, out uri)) { + msg = "Not an absolute URI string."; + throw new ArgumentException (msg, "value"); + } + + if (uri.Segments.Length > 1) { + msg = "It includes the path segments."; + throw new ArgumentException (msg, "value"); + } + } + + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + lock (_forState) { + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + _origin = !value.IsNullOrEmpty () ? value.TrimEnd ('/') : value; + } + } + } + + /// + /// Gets the name of subprotocol selected by the server. + /// + /// + /// + /// A that will be one of the names of + /// subprotocols specified by client. + /// + /// + /// An empty string if not specified or selected. + /// + /// + public string Protocol { + get { + return _protocol ?? String.Empty; + } + + internal set { + _protocol = value; + } + } + + /// + /// Gets the current state of the connection. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It indicates the current state of the connection. + /// + /// + /// The default value is . + /// + /// + public WebSocketState ReadyState { + get { + return _readyState; + } + } + + /// + /// Gets the configuration for secure connection. + /// + /// + /// This configuration will be referenced when attempts to connect, + /// so it must be configured before any connect method is called. + /// + /// + /// A that represents + /// the configuration used to establish a secure connection. + /// + /// + /// + /// This instance is not a client. + /// + /// + /// This instance does not use a secure connection. + /// + /// + public ClientSslConfiguration SslConfiguration { + get { + if (!_client) { + var msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + if (!_secure) { + var msg = "This instance does not use a secure connection."; + throw new InvalidOperationException (msg); + } + + return getSslConfiguration (); + } + } + + /// + /// Gets the URL to which to connect. + /// + /// + /// A that represents the URL to which to connect. + /// + public Uri Url { + get { + return _client ? _uri : _context.RequestUri; + } + } + + /// + /// Gets or sets the time to wait for the response to the ping or close. + /// + /// + /// The set operation does nothing if the connection has already been + /// established or it is closing. + /// + /// + /// + /// A to wait for the response. + /// + /// + /// The default value is the same as 5 seconds if this instance is + /// a client. + /// + /// + /// + /// The value specified for a set operation is zero or less. + /// + public TimeSpan WaitTime { + get { + return _waitTime; + } + + set { + if (value <= TimeSpan.Zero) + throw new ArgumentOutOfRangeException ("value", "Zero or less."); + + string msg; + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + lock (_forState) { + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + _waitTime = value; + } + } + } + + #endregion + + #region Public Events + + /// + /// Occurs when the WebSocket connection has been closed. + /// + public event EventHandler OnClose; + + /// + /// Occurs when the gets an error. + /// + public event EventHandler OnError; + + /// + /// Occurs when the receives a message. + /// + public event EventHandler OnMessage; + + /// + /// Occurs when the WebSocket connection has been established. + /// + public event EventHandler OnOpen; + + #endregion + + #region Private Methods + + // As server + private bool accept () + { + if (_readyState == WebSocketState.Open) { + var msg = "The handshake request has already been accepted."; + _logger.Warn (msg); + + return false; + } + + lock (_forState) { + if (_readyState == WebSocketState.Open) { + var msg = "The handshake request has already been accepted."; + _logger.Warn (msg); + + return false; + } + + if (_readyState == WebSocketState.Closing) { + var msg = "The close process has set in."; + _logger.Error (msg); + + msg = "An interruption has occurred while attempting to accept."; + error (msg, null); + + return false; + } + + if (_readyState == WebSocketState.Closed) { + var msg = "The connection has been closed."; + _logger.Error (msg); + + msg = "An interruption has occurred while attempting to accept."; + error (msg, null); + + return false; + } + + try { + if (!acceptHandshake ()) + return false; + } + catch (Exception ex) { + _logger.Fatal (ex.Message); + _logger.Debug (ex.ToString ()); + + var msg = "An exception has occurred while attempting to accept."; + fatal (msg, ex); + + return false; + } + + _readyState = WebSocketState.Open; + return true; + } + } + + // As server + private bool acceptHandshake () + { + _logger.Debug ( + String.Format ( + "A handshake request from {0}:\n{1}", _context.UserEndPoint, _context + ) + ); + + string msg; + if (!checkHandshakeRequest (_context, out msg)) { + _logger.Error (msg); + + refuseHandshake ( + CloseStatusCode.ProtocolError, + "A handshake error has occurred while attempting to accept." + ); + + return false; + } + + if (!customCheckHandshakeRequest (_context, out msg)) { + _logger.Error (msg); + + refuseHandshake ( + CloseStatusCode.PolicyViolation, + "A handshake error has occurred while attempting to accept." + ); + + return false; + } + + _base64Key = _context.Headers["Sec-WebSocket-Key"]; + + if (_protocol != null) { + var vals = _context.SecWebSocketProtocols; + processSecWebSocketProtocolClientHeader (vals); + } + + if (!_ignoreExtensions) { + var val = _context.Headers["Sec-WebSocket-Extensions"]; + processSecWebSocketExtensionsClientHeader (val); + } + + return sendHttpResponse (createHandshakeResponse ()); + } + + private bool canSet (out string message) + { + message = null; + + if (_readyState == WebSocketState.Open) { + message = "The connection has already been established."; + return false; + } + + if (_readyState == WebSocketState.Closing) { + message = "The connection is closing."; + return false; + } + + return true; + } + + // As server + private bool checkHandshakeRequest ( + WebSocketContext context, out string message + ) + { + message = null; + + if (!context.IsWebSocketRequest) { + message = "Not a handshake request."; + return false; + } + + if (context.RequestUri == null) { + message = "It specifies an invalid Request-URI."; + return false; + } + + var headers = context.Headers; + + var key = headers["Sec-WebSocket-Key"]; + if (key == null) { + message = "It includes no Sec-WebSocket-Key header."; + return false; + } + + if (key.Length == 0) { + message = "It includes an invalid Sec-WebSocket-Key header."; + return false; + } + + var version = headers["Sec-WebSocket-Version"]; + if (version == null) { + message = "It includes no Sec-WebSocket-Version header."; + return false; + } + + if (version != _version) { + message = "It includes an invalid Sec-WebSocket-Version header."; + return false; + } + + var protocol = headers["Sec-WebSocket-Protocol"]; + if (protocol != null && protocol.Length == 0) { + message = "It includes an invalid Sec-WebSocket-Protocol header."; + return false; + } + + if (!_ignoreExtensions) { + var extensions = headers["Sec-WebSocket-Extensions"]; + if (extensions != null && extensions.Length == 0) { + message = "It includes an invalid Sec-WebSocket-Extensions header."; + return false; + } + } + + return true; + } + + // As client + private bool checkHandshakeResponse (HttpResponse response, out string message) + { + message = null; + + if (response.IsRedirect) { + message = "Indicates the redirection."; + return false; + } + + if (response.IsUnauthorized) { + message = "Requires the authentication."; + return false; + } + + if (!response.IsWebSocketResponse) { + message = "Not a WebSocket handshake response."; + return false; + } + + var headers = response.Headers; + if (!validateSecWebSocketAcceptHeader (headers["Sec-WebSocket-Accept"])) { + message = "Includes no Sec-WebSocket-Accept header, or it has an invalid value."; + return false; + } + + if (!validateSecWebSocketProtocolServerHeader (headers["Sec-WebSocket-Protocol"])) { + message = "Includes no Sec-WebSocket-Protocol header, or it has an invalid value."; + return false; + } + + if (!validateSecWebSocketExtensionsServerHeader (headers["Sec-WebSocket-Extensions"])) { + message = "Includes an invalid Sec-WebSocket-Extensions header."; + return false; + } + + if (!validateSecWebSocketVersionServerHeader (headers["Sec-WebSocket-Version"])) { + message = "Includes an invalid Sec-WebSocket-Version header."; + return false; + } + + return true; + } + + private static bool checkProtocols (string[] protocols, out string message) + { + message = null; + + Func cond = protocol => protocol.IsNullOrEmpty () + || !protocol.IsToken (); + + if (protocols.Contains (cond)) { + message = "It contains a value that is not a token."; + return false; + } + + if (protocols.ContainsTwice ()) { + message = "It contains a value twice."; + return false; + } + + return true; + } + + private bool checkReceivedFrame (WebSocketFrame frame, out string message) + { + message = null; + + var masked = frame.IsMasked; + if (_client && masked) { + message = "A frame from the server is masked."; + return false; + } + + if (!_client && !masked) { + message = "A frame from a client is not masked."; + return false; + } + + if (_inContinuation && frame.IsData) { + message = "A data frame has been received while receiving continuation frames."; + return false; + } + + if (frame.IsCompressed && _compression == CompressionMethod.None) { + message = "A compressed frame has been received without any agreement for it."; + return false; + } + + if (frame.Rsv2 == Rsv.On) { + message = "The RSV2 of a frame is non-zero without any negotiation for it."; + return false; + } + + if (frame.Rsv3 == Rsv.On) { + message = "The RSV3 of a frame is non-zero without any negotiation for it."; + return false; + } + + return true; + } + + private void close (ushort code, string reason) + { + if (_readyState == WebSocketState.Closing) { + _logger.Info ("The closing is already in progress."); + return; + } + + if (_readyState == WebSocketState.Closed) { + _logger.Info ("The connection has already been closed."); + return; + } + + if (code == 1005) { // == no status + close (PayloadData.Empty, true, true, false); + return; + } + + var send = !code.IsReserved (); + close (new PayloadData (code, reason), send, send, false); + } + + private void close ( + PayloadData payloadData, bool send, bool receive, bool received + ) + { + lock (_forState) { + if (_readyState == WebSocketState.Closing) { + _logger.Info ("The closing is already in progress."); + return; + } + + if (_readyState == WebSocketState.Closed) { + _logger.Info ("The connection has already been closed."); + return; + } + + send = send && _readyState == WebSocketState.Open; + receive = send && receive; + + _readyState = WebSocketState.Closing; + } + + _logger.Trace ("Begin closing the connection."); + + var res = closeHandshake (payloadData, send, receive, received); + releaseResources (); + + _logger.Trace ("End closing the connection."); + + _readyState = WebSocketState.Closed; + + var e = new CloseEventArgs (payloadData, res); + + try { + OnClose.Emit (this, e); + } + catch (Exception ex) { + _logger.Error (ex.Message); + _logger.Debug (ex.ToString ()); + } + } + + private void closeAsync (ushort code, string reason) + { + if (_readyState == WebSocketState.Closing) { + _logger.Info ("The closing is already in progress."); + return; + } + + if (_readyState == WebSocketState.Closed) { + _logger.Info ("The connection has already been closed."); + return; + } + + if (code == 1005) { // == no status + closeAsync (PayloadData.Empty, true, true, false); + return; + } + + var send = !code.IsReserved (); + closeAsync (new PayloadData (code, reason), send, send, false); + } + + private void closeAsync ( + PayloadData payloadData, bool send, bool receive, bool received + ) + { + Action closer = close; + closer.BeginInvoke ( + payloadData, send, receive, received, ar => closer.EndInvoke (ar), null + ); + } + + private bool closeHandshake (byte[] frameAsBytes, bool receive, bool received) + { + var sent = frameAsBytes != null && sendBytes (frameAsBytes); + + var wait = !received && sent && receive && _receivingExited != null; + if (wait) + received = _receivingExited.WaitOne (_waitTime); + + var ret = sent && received; + + _logger.Debug ( + String.Format ( + "Was clean?: {0}\n sent: {1}\n received: {2}", ret, sent, received + ) + ); + + return ret; + } + + private bool closeHandshake ( + PayloadData payloadData, bool send, bool receive, bool received + ) + { + var sent = false; + if (send) { + var frame = WebSocketFrame.CreateCloseFrame (payloadData, _client); + sent = sendBytes (frame.ToArray ()); + + if (_client) + frame.Unmask (); + } + + var wait = !received && sent && receive && _receivingExited != null; + if (wait) + received = _receivingExited.WaitOne (_waitTime); + + var ret = sent && received; + + _logger.Debug ( + String.Format ( + "Was clean?: {0}\n sent: {1}\n received: {2}", ret, sent, received + ) + ); + + return ret; + } + + // As client + private bool connect () + { + if (_readyState == WebSocketState.Open) { + var msg = "The connection has already been established."; + _logger.Warn (msg); + + return false; + } + + lock (_forState) { + if (_readyState == WebSocketState.Open) { + var msg = "The connection has already been established."; + _logger.Warn (msg); + + return false; + } + + if (_readyState == WebSocketState.Closing) { + var msg = "The close process has set in."; + _logger.Error (msg); + + msg = "An interruption has occurred while attempting to connect."; + error (msg, null); + + return false; + } + + if (_retryCountForConnect > _maxRetryCountForConnect) { + var msg = "An opportunity for reconnecting has been lost."; + _logger.Error (msg); + + msg = "An interruption has occurred while attempting to connect."; + error (msg, null); + + return false; + } + + _readyState = WebSocketState.Connecting; + + try { + doHandshake (); + } + catch (Exception ex) { + _retryCountForConnect++; + + _logger.Fatal (ex.Message); + _logger.Debug (ex.ToString ()); + + var msg = "An exception has occurred while attempting to connect."; + fatal (msg, ex); + + return false; + } + + _retryCountForConnect = 1; + _readyState = WebSocketState.Open; + + return true; + } + } + + // As client + private string createExtensions () + { + var buff = new StringBuilder (80); + + if (_compression != CompressionMethod.None) { + var str = _compression.ToExtensionString ( + "server_no_context_takeover", "client_no_context_takeover"); + + buff.AppendFormat ("{0}, ", str); + } + + var len = buff.Length; + if (len > 2) { + buff.Length = len - 2; + return buff.ToString (); + } + + return null; + } + + // As server + private HttpResponse createHandshakeFailureResponse (HttpStatusCode code) + { + var ret = HttpResponse.CreateCloseResponse (code); + ret.Headers["Sec-WebSocket-Version"] = _version; + + return ret; + } + + // As client + private HttpRequest createHandshakeRequest () + { + var ret = HttpRequest.CreateWebSocketRequest (_uri); + + var headers = ret.Headers; + if (!_origin.IsNullOrEmpty ()) + headers["Origin"] = _origin; + + headers["Sec-WebSocket-Key"] = _base64Key; + + _protocolsRequested = _protocols != null; + if (_protocolsRequested) + headers["Sec-WebSocket-Protocol"] = _protocols.ToString (", "); + + _extensionsRequested = _compression != CompressionMethod.None; + if (_extensionsRequested) + headers["Sec-WebSocket-Extensions"] = createExtensions (); + + headers["Sec-WebSocket-Version"] = _version; + + AuthenticationResponse authRes = null; + if (_authChallenge != null && _credentials != null) { + authRes = new AuthenticationResponse (_authChallenge, _credentials, _nonceCount); + _nonceCount = authRes.NonceCount; + } + else if (_preAuth) { + authRes = new AuthenticationResponse (_credentials); + } + + if (authRes != null) + headers["Authorization"] = authRes.ToString (); + + if (_cookies.Count > 0) + ret.SetCookies (_cookies); + + return ret; + } + + // As server + private HttpResponse createHandshakeResponse () + { + var ret = HttpResponse.CreateWebSocketResponse (); + + var headers = ret.Headers; + headers["Sec-WebSocket-Accept"] = CreateResponseKey (_base64Key); + + if (_protocol != null) + headers["Sec-WebSocket-Protocol"] = _protocol; + + if (_extensions != null) + headers["Sec-WebSocket-Extensions"] = _extensions; + + if (_cookies.Count > 0) + ret.SetCookies (_cookies); + + return ret; + } + + // As server + private bool customCheckHandshakeRequest ( + WebSocketContext context, out string message + ) + { + message = null; + + if (_handshakeRequestChecker == null) + return true; + + message = _handshakeRequestChecker (context); + return message == null; + } + + private MessageEventArgs dequeueFromMessageEventQueue () + { + lock (_forMessageEventQueue) + return _messageEventQueue.Count > 0 ? _messageEventQueue.Dequeue () : null; + } + + // As client + private void doHandshake () + { + setClientStream (); + var res = sendHandshakeRequest (); + + string msg; + if (!checkHandshakeResponse (res, out msg)) + throw new WebSocketException (CloseStatusCode.ProtocolError, msg); + + if (_protocolsRequested) + _protocol = res.Headers["Sec-WebSocket-Protocol"]; + + if (_extensionsRequested) + processSecWebSocketExtensionsServerHeader (res.Headers["Sec-WebSocket-Extensions"]); + + processCookies (res.Cookies); + } + + private void enqueueToMessageEventQueue (MessageEventArgs e) + { + lock (_forMessageEventQueue) + _messageEventQueue.Enqueue (e); + } + + private void error (string message, Exception exception) + { + try { + OnError.Emit (this, new ErrorEventArgs (message, exception)); + } + catch (Exception ex) { + _logger.Error (ex.Message); + _logger.Debug (ex.ToString ()); + } + } + + private void fatal (string message, Exception exception) + { + var code = exception is WebSocketException + ? ((WebSocketException) exception).Code + : CloseStatusCode.Abnormal; + + fatal (message, (ushort) code); + } + + private void fatal (string message, ushort code) + { + var payload = new PayloadData (code, message); + close (payload, !code.IsReserved (), false, false); + } + + private void fatal (string message, CloseStatusCode code) + { + fatal (message, (ushort) code); + } + + private ClientSslConfiguration getSslConfiguration () + { + if (_sslConfig == null) + _sslConfig = new ClientSslConfiguration (_uri.DnsSafeHost); + + return _sslConfig; + } + + private void init () + { + _compression = CompressionMethod.None; + _cookies = new CookieCollection (); + _forPing = new object (); + _forSend = new object (); + _forState = new object (); + _messageEventQueue = new Queue (); + _forMessageEventQueue = ((ICollection) _messageEventQueue).SyncRoot; + _readyState = WebSocketState.Connecting; + } + + private void message () + { + MessageEventArgs e = null; + lock (_forMessageEventQueue) { + if (_inMessage || _messageEventQueue.Count == 0 || _readyState != WebSocketState.Open) + return; + + _inMessage = true; + e = _messageEventQueue.Dequeue (); + } + + _message (e); + } + + private void messagec (MessageEventArgs e) + { + do { + try { + OnMessage.Emit (this, e); + } + catch (Exception ex) { + _logger.Error (ex.ToString ()); + error ("An error has occurred during an OnMessage event.", ex); + } + + lock (_forMessageEventQueue) { + if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open) { + _inMessage = false; + break; + } + + e = _messageEventQueue.Dequeue (); + } + } + while (true); + } + + private void messages (MessageEventArgs e) + { + try { + OnMessage.Emit (this, e); + } + catch (Exception ex) { + _logger.Error (ex.ToString ()); + error ("An error has occurred during an OnMessage event.", ex); + } + + lock (_forMessageEventQueue) { + if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open) { + _inMessage = false; + return; + } + + e = _messageEventQueue.Dequeue (); + } + + ThreadPool.QueueUserWorkItem (state => messages (e)); + } + + private void open () + { + _inMessage = true; + startReceiving (); + try { + OnOpen.Emit (this, EventArgs.Empty); + } + catch (Exception ex) { + _logger.Error (ex.ToString ()); + error ("An error has occurred during the OnOpen event.", ex); + } + + MessageEventArgs e = null; + lock (_forMessageEventQueue) { + if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open) { + _inMessage = false; + return; + } + + e = _messageEventQueue.Dequeue (); + } + + _message.BeginInvoke (e, ar => _message.EndInvoke (ar), null); + } + + private bool ping (byte[] data) + { + if (_readyState != WebSocketState.Open) + return false; + + var pongReceived = _pongReceived; + if (pongReceived == null) + return false; + + lock (_forPing) { + try { + pongReceived.Reset (); + if (!send (Fin.Final, Opcode.Ping, data, false)) + return false; + + return pongReceived.WaitOne (_waitTime); + } + catch (ObjectDisposedException) { + return false; + } + } + } + + private bool processCloseFrame (WebSocketFrame frame) + { + var payload = frame.PayloadData; + close (payload, !payload.HasReservedCode, false, true); + + return false; + } + + // As client + private void processCookies (CookieCollection cookies) + { + if (cookies.Count == 0) + return; + + _cookies.SetOrRemove (cookies); + } + + private bool processDataFrame (WebSocketFrame frame) + { + enqueueToMessageEventQueue ( + frame.IsCompressed + ? new MessageEventArgs ( + frame.Opcode, frame.PayloadData.ApplicationData.Decompress (_compression)) + : new MessageEventArgs (frame)); + + return true; + } + + private bool processFragmentFrame (WebSocketFrame frame) + { + if (!_inContinuation) { + // Must process first fragment. + if (frame.IsContinuation) + return true; + + _fragmentsOpcode = frame.Opcode; + _fragmentsCompressed = frame.IsCompressed; + _fragmentsBuffer = new MemoryStream (); + _inContinuation = true; + } + + _fragmentsBuffer.WriteBytes (frame.PayloadData.ApplicationData, 1024); + if (frame.IsFinal) { + using (_fragmentsBuffer) { + var data = _fragmentsCompressed + ? _fragmentsBuffer.DecompressToArray (_compression) + : _fragmentsBuffer.ToArray (); + + enqueueToMessageEventQueue (new MessageEventArgs (_fragmentsOpcode, data)); + } + + _fragmentsBuffer = null; + _inContinuation = false; + } + + return true; + } + + private bool processPingFrame (WebSocketFrame frame) + { + _logger.Trace ("A ping was received."); + + var pong = WebSocketFrame.CreatePongFrame (frame.PayloadData, _client); + + lock (_forState) { + if (_readyState != WebSocketState.Open) { + _logger.Error ("The connection is closing."); + return true; + } + + if (!sendBytes (pong.ToArray ())) + return false; + } + + _logger.Trace ("A pong to this ping has been sent."); + + if (_emitOnPing) { + if (_client) + pong.Unmask (); + + enqueueToMessageEventQueue (new MessageEventArgs (frame)); + } + + return true; + } + + private bool processPongFrame (WebSocketFrame frame) + { + _logger.Trace ("A pong was received."); + + try { + _pongReceived.Set (); + } + catch (NullReferenceException ex) { + _logger.Error (ex.Message); + _logger.Debug (ex.ToString ()); + + return false; + } + catch (ObjectDisposedException ex) { + _logger.Error (ex.Message); + _logger.Debug (ex.ToString ()); + + return false; + } + + _logger.Trace ("It has been signaled."); + + return true; + } + + private bool processReceivedFrame (WebSocketFrame frame) + { + string msg; + if (!checkReceivedFrame (frame, out msg)) + throw new WebSocketException (CloseStatusCode.ProtocolError, msg); + + frame.Unmask (); + return frame.IsFragment + ? processFragmentFrame (frame) + : frame.IsData + ? processDataFrame (frame) + : frame.IsPing + ? processPingFrame (frame) + : frame.IsPong + ? processPongFrame (frame) + : frame.IsClose + ? processCloseFrame (frame) + : processUnsupportedFrame (frame); + } + + // As server + private void processSecWebSocketExtensionsClientHeader (string value) + { + if (value == null) + return; + + var buff = new StringBuilder (80); + var comp = false; + + foreach (var elm in value.SplitHeaderValue (',')) { + var extension = elm.Trim (); + if (extension.Length == 0) + continue; + + if (!comp) { + if (extension.IsCompressionExtension (CompressionMethod.Deflate)) { + _compression = CompressionMethod.Deflate; + + buff.AppendFormat ( + "{0}, ", + _compression.ToExtensionString ( + "client_no_context_takeover", "server_no_context_takeover" + ) + ); + + comp = true; + } + } + } + + var len = buff.Length; + if (len <= 2) + return; + + buff.Length = len - 2; + _extensions = buff.ToString (); + } + + // As client + private void processSecWebSocketExtensionsServerHeader (string value) + { + if (value == null) { + _compression = CompressionMethod.None; + return; + } + + _extensions = value; + } + + // As server + private void processSecWebSocketProtocolClientHeader ( + IEnumerable values + ) + { + if (values.Contains (val => val == _protocol)) + return; + + _protocol = null; + } + + private bool processUnsupportedFrame (WebSocketFrame frame) + { + _logger.Fatal ("An unsupported frame:" + frame.PrintToString (false)); + fatal ("There is no way to handle it.", CloseStatusCode.PolicyViolation); + + return false; + } + + // As server + private void refuseHandshake (CloseStatusCode code, string reason) + { + _readyState = WebSocketState.Closing; + + var res = createHandshakeFailureResponse (HttpStatusCode.BadRequest); + sendHttpResponse (res); + + releaseServerResources (); + + _readyState = WebSocketState.Closed; + + var e = new CloseEventArgs ((ushort) code, reason, false); + + try { + OnClose.Emit (this, e); + } + catch (Exception ex) { + _logger.Error (ex.Message); + _logger.Debug (ex.ToString ()); + } + } + + // As client + private void releaseClientResources () + { + if (_stream != null) { + _stream.Dispose (); + _stream = null; + } + + if (_tcpClient != null) { + _tcpClient.Close (); + _tcpClient = null; + } + } + + private void releaseCommonResources () + { + if (_fragmentsBuffer != null) { + _fragmentsBuffer.Dispose (); + _fragmentsBuffer = null; + _inContinuation = false; + } + + if (_pongReceived != null) { + _pongReceived.Close (); + _pongReceived = null; + } + + if (_receivingExited != null) { + _receivingExited.Close (); + _receivingExited = null; + } + } + + private void releaseResources () + { + if (_client) + releaseClientResources (); + else + releaseServerResources (); + + releaseCommonResources (); + } + + // As server + private void releaseServerResources () + { + if (_closeContext == null) + return; + + _closeContext (); + _closeContext = null; + _stream = null; + _context = null; + } + + private bool send (Opcode opcode, Stream stream) + { + lock (_forSend) { + var src = stream; + var compressed = false; + var sent = false; + try { + if (_compression != CompressionMethod.None) { + stream = stream.Compress (_compression); + compressed = true; + } + + sent = send (opcode, stream, compressed); + if (!sent) + error ("A send has been interrupted.", null); + } + catch (Exception ex) { + _logger.Error (ex.ToString ()); + error ("An error has occurred during a send.", ex); + } + finally { + if (compressed) + stream.Dispose (); + + src.Dispose (); + } + + return sent; + } + } + + private bool send (Opcode opcode, Stream stream, bool compressed) + { + var len = stream.Length; + if (len == 0) + return send (Fin.Final, opcode, EmptyBytes, false); + + var quo = len / FragmentLength; + var rem = (int) (len % FragmentLength); + + byte[] buff = null; + if (quo == 0) { + buff = new byte[rem]; + return stream.Read (buff, 0, rem) == rem + && send (Fin.Final, opcode, buff, compressed); + } + + if (quo == 1 && rem == 0) { + buff = new byte[FragmentLength]; + return stream.Read (buff, 0, FragmentLength) == FragmentLength + && send (Fin.Final, opcode, buff, compressed); + } + + /* Send fragments */ + + // Begin + buff = new byte[FragmentLength]; + var sent = stream.Read (buff, 0, FragmentLength) == FragmentLength + && send (Fin.More, opcode, buff, compressed); + + if (!sent) + return false; + + var n = rem == 0 ? quo - 2 : quo - 1; + for (long i = 0; i < n; i++) { + sent = stream.Read (buff, 0, FragmentLength) == FragmentLength + && send (Fin.More, Opcode.Cont, buff, false); + + if (!sent) + return false; + } + + // End + if (rem == 0) + rem = FragmentLength; + else + buff = new byte[rem]; + + return stream.Read (buff, 0, rem) == rem + && send (Fin.Final, Opcode.Cont, buff, false); + } + + private bool send (Fin fin, Opcode opcode, byte[] data, bool compressed) + { + lock (_forState) { + if (_readyState != WebSocketState.Open) { + _logger.Error ("The connection is closing."); + return false; + } + + var frame = new WebSocketFrame (fin, opcode, data, compressed, _client); + return sendBytes (frame.ToArray ()); + } + } + + private void sendAsync (Opcode opcode, Stream stream, Action completed) + { + Func sender = send; + sender.BeginInvoke ( + opcode, + stream, + ar => { + try { + var sent = sender.EndInvoke (ar); + if (completed != null) + completed (sent); + } + catch (Exception ex) { + _logger.Error (ex.ToString ()); + error ( + "An error has occurred during the callback for an async send.", + ex + ); + } + }, + null + ); + } + + private bool sendBytes (byte[] bytes) + { + try { + _stream.Write (bytes, 0, bytes.Length); + } + catch (Exception ex) { + _logger.Error (ex.Message); + _logger.Debug (ex.ToString ()); + + return false; + } + + return true; + } + + // As client + private HttpResponse sendHandshakeRequest () + { + var req = createHandshakeRequest (); + var res = sendHttpRequest (req, 90000); + if (res.IsUnauthorized) { + var chal = res.Headers["WWW-Authenticate"]; + _logger.Warn (String.Format ("Received an authentication requirement for '{0}'.", chal)); + if (chal.IsNullOrEmpty ()) { + _logger.Error ("No authentication challenge is specified."); + return res; + } + + _authChallenge = AuthenticationChallenge.Parse (chal); + if (_authChallenge == null) { + _logger.Error ("An invalid authentication challenge is specified."); + return res; + } + + if (_credentials != null && + (!_preAuth || _authChallenge.Scheme == AuthenticationSchemes.Digest)) { + if (res.HasConnectionClose) { + releaseClientResources (); + setClientStream (); + } + + var authRes = new AuthenticationResponse (_authChallenge, _credentials, _nonceCount); + _nonceCount = authRes.NonceCount; + req.Headers["Authorization"] = authRes.ToString (); + res = sendHttpRequest (req, 15000); + } + } + + if (res.IsRedirect) { + var url = res.Headers["Location"]; + _logger.Warn (String.Format ("Received a redirection to '{0}'.", url)); + if (_enableRedirection) { + if (url.IsNullOrEmpty ()) { + _logger.Error ("No url to redirect is located."); + return res; + } + + Uri uri; + string msg; + if (!url.TryCreateWebSocketUri (out uri, out msg)) { + _logger.Error ("An invalid url to redirect is located: " + msg); + return res; + } + + releaseClientResources (); + + _uri = uri; + _secure = uri.Scheme == "wss"; + + setClientStream (); + return sendHandshakeRequest (); + } + } + + return res; + } + + // As client + private HttpResponse sendHttpRequest (HttpRequest request, int millisecondsTimeout) + { + _logger.Debug ("A request to the server:\n" + request.ToString ()); + var res = request.GetResponse (_stream, millisecondsTimeout); + _logger.Debug ("A response to this request:\n" + res.ToString ()); + + return res; + } + + // As server + private bool sendHttpResponse (HttpResponse response) + { + _logger.Debug ( + String.Format ( + "A response to {0}:\n{1}", _context.UserEndPoint, response + ) + ); + + return sendBytes (response.ToByteArray ()); + } + + // As client + private void sendProxyConnectRequest () + { + var req = HttpRequest.CreateConnectRequest (_uri); + var res = sendHttpRequest (req, 90000); + if (res.IsProxyAuthenticationRequired) { + var chal = res.Headers["Proxy-Authenticate"]; + _logger.Warn ( + String.Format ("Received a proxy authentication requirement for '{0}'.", chal)); + + if (chal.IsNullOrEmpty ()) + throw new WebSocketException ("No proxy authentication challenge is specified."); + + var authChal = AuthenticationChallenge.Parse (chal); + if (authChal == null) + throw new WebSocketException ("An invalid proxy authentication challenge is specified."); + + if (_proxyCredentials != null) { + if (res.HasConnectionClose) { + releaseClientResources (); + _tcpClient = new TcpClient (_proxyUri.DnsSafeHost, _proxyUri.Port); + _stream = _tcpClient.GetStream (); + } + + var authRes = new AuthenticationResponse (authChal, _proxyCredentials, 0); + req.Headers["Proxy-Authorization"] = authRes.ToString (); + res = sendHttpRequest (req, 15000); + } + + if (res.IsProxyAuthenticationRequired) + throw new WebSocketException ("A proxy authentication is required."); + } + + if (res.StatusCode[0] != '2') + throw new WebSocketException ( + "The proxy has failed a connection to the requested host and port."); + } + + // As client + private void setClientStream () + { + if (_proxyUri != null) { + _tcpClient = new TcpClient (_proxyUri.DnsSafeHost, _proxyUri.Port); + _stream = _tcpClient.GetStream (); + sendProxyConnectRequest (); + } + else { + _tcpClient = new TcpClient (_uri.DnsSafeHost, _uri.Port); + _stream = _tcpClient.GetStream (); + } + + if (_secure) { + var conf = getSslConfiguration (); + var host = conf.TargetHost; + if (host != _uri.DnsSafeHost) + throw new WebSocketException ( + CloseStatusCode.TlsHandshakeFailure, "An invalid host name is specified."); + + try { + var sslStream = new SslStream ( + _stream, + false, + conf.ServerCertificateValidationCallback, + conf.ClientCertificateSelectionCallback); + + sslStream.AuthenticateAsClient ( + host, + conf.ClientCertificates, + conf.EnabledSslProtocols, + conf.CheckCertificateRevocation); + + _stream = sslStream; + } + catch (Exception ex) { + throw new WebSocketException (CloseStatusCode.TlsHandshakeFailure, ex); + } + } + } + + private void startReceiving () + { + if (_messageEventQueue.Count > 0) + _messageEventQueue.Clear (); + + _pongReceived = new ManualResetEvent (false); + _receivingExited = new ManualResetEvent (false); + + Action receive = null; + receive = + () => + WebSocketFrame.ReadFrameAsync ( + _stream, + false, + frame => { + if (!processReceivedFrame (frame) || _readyState == WebSocketState.Closed) { + var exited = _receivingExited; + if (exited != null) + exited.Set (); + + return; + } + + // Receive next asap because the Ping or Close needs a response to it. + receive (); + + if (_inMessage || !HasMessage || _readyState != WebSocketState.Open) + return; + + message (); + }, + ex => { + _logger.Fatal (ex.ToString ()); + fatal ("An exception has occurred while receiving.", ex); + } + ); + + receive (); + } + + // As client + private bool validateSecWebSocketAcceptHeader (string value) + { + return value != null && value == CreateResponseKey (_base64Key); + } + + // As client + private bool validateSecWebSocketExtensionsServerHeader (string value) + { + if (value == null) + return true; + + if (value.Length == 0) + return false; + + if (!_extensionsRequested) + return false; + + var comp = _compression != CompressionMethod.None; + foreach (var e in value.SplitHeaderValue (',')) { + var ext = e.Trim (); + if (comp && ext.IsCompressionExtension (_compression)) { + if (!ext.Contains ("server_no_context_takeover")) { + _logger.Error ("The server hasn't sent back 'server_no_context_takeover'."); + return false; + } + + if (!ext.Contains ("client_no_context_takeover")) + _logger.Warn ("The server hasn't sent back 'client_no_context_takeover'."); + + var method = _compression.ToExtensionString (); + var invalid = + ext.SplitHeaderValue (';').Contains ( + t => { + t = t.Trim (); + return t != method + && t != "server_no_context_takeover" + && t != "client_no_context_takeover"; + } + ); + + if (invalid) + return false; + } + else { + return false; + } + } + + return true; + } + + // As client + private bool validateSecWebSocketProtocolServerHeader (string value) + { + if (value == null) + return !_protocolsRequested; + + if (value.Length == 0) + return false; + + return _protocolsRequested && _protocols.Contains (p => p == value); + } + + // As client + private bool validateSecWebSocketVersionServerHeader (string value) + { + return value == null || value == _version; + } + + #endregion + + #region Internal Methods + + // As server + internal void Close (HttpResponse response) + { + _readyState = WebSocketState.Closing; + + sendHttpResponse (response); + releaseServerResources (); + + _readyState = WebSocketState.Closed; + } + + // As server + internal void Close (HttpStatusCode code) + { + Close (createHandshakeFailureResponse (code)); + } + + // As server + internal void Close (PayloadData payloadData, byte[] frameAsBytes) + { + lock (_forState) { + if (_readyState == WebSocketState.Closing) { + _logger.Info ("The closing is already in progress."); + return; + } + + if (_readyState == WebSocketState.Closed) { + _logger.Info ("The connection has already been closed."); + return; + } + + _readyState = WebSocketState.Closing; + } + + _logger.Trace ("Begin closing the connection."); + + var sent = frameAsBytes != null && sendBytes (frameAsBytes); + var received = sent && _receivingExited != null + ? _receivingExited.WaitOne (_waitTime) + : false; + + var res = sent && received; + + _logger.Debug ( + String.Format ( + "Was clean?: {0}\n sent: {1}\n received: {2}", res, sent, received + ) + ); + + releaseServerResources (); + releaseCommonResources (); + + _logger.Trace ("End closing the connection."); + + _readyState = WebSocketState.Closed; + + var e = new CloseEventArgs (payloadData, res); + + try { + OnClose.Emit (this, e); + } + catch (Exception ex) { + _logger.Error (ex.Message); + _logger.Debug (ex.ToString ()); + } + } + + // As client + internal static string CreateBase64Key () + { + var src = new byte[16]; + RandomNumber.GetBytes (src); + + return Convert.ToBase64String (src); + } + + internal static string CreateResponseKey (string base64Key) + { + var buff = new StringBuilder (base64Key, 64); + buff.Append (_guid); + SHA1 sha1 = new SHA1CryptoServiceProvider (); + var src = sha1.ComputeHash (buff.ToString ().GetUTF8EncodedBytes ()); + + return Convert.ToBase64String (src); + } + + // As server + internal void InternalAccept () + { + try { + if (!acceptHandshake ()) + return; + } + catch (Exception ex) { + _logger.Fatal (ex.Message); + _logger.Debug (ex.ToString ()); + + var msg = "An exception has occurred while attempting to accept."; + fatal (msg, ex); + + return; + } + + _readyState = WebSocketState.Open; + + open (); + } + + // As server + internal bool Ping (byte[] frameAsBytes, TimeSpan timeout) + { + if (_readyState != WebSocketState.Open) + return false; + + var pongReceived = _pongReceived; + if (pongReceived == null) + return false; + + lock (_forPing) { + try { + pongReceived.Reset (); + + lock (_forState) { + if (_readyState != WebSocketState.Open) + return false; + + if (!sendBytes (frameAsBytes)) + return false; + } + + return pongReceived.WaitOne (timeout); + } + catch (ObjectDisposedException) { + return false; + } + } + } + + // As server + internal void Send ( + Opcode opcode, byte[] data, Dictionary cache + ) + { + lock (_forSend) { + lock (_forState) { + if (_readyState != WebSocketState.Open) { + _logger.Error ("The connection is closing."); + return; + } + + byte[] found; + if (!cache.TryGetValue (_compression, out found)) { + found = new WebSocketFrame ( + Fin.Final, + opcode, + data.Compress (_compression), + _compression != CompressionMethod.None, + false + ) + .ToArray (); + + cache.Add (_compression, found); + } + + sendBytes (found); + } + } + } + + // As server + internal void Send ( + Opcode opcode, Stream stream, Dictionary cache + ) + { + lock (_forSend) { + Stream found; + if (!cache.TryGetValue (_compression, out found)) { + found = stream.Compress (_compression); + cache.Add (_compression, found); + } + else { + found.Position = 0; + } + + send (opcode, found, _compression != CompressionMethod.None); + } + } + + #endregion + + #region Public Methods + + /// + /// Accepts the handshake request. + /// + /// + /// This method does nothing if the handshake request has already been + /// accepted. + /// + /// + /// + /// This instance is a client. + /// + /// + /// -or- + /// + /// + /// The close process is in progress. + /// + /// + /// -or- + /// + /// + /// The connection has already been closed. + /// + /// + public void Accept () + { + if (_client) { + var msg = "This instance is a client."; + throw new InvalidOperationException (msg); + } + + if (_readyState == WebSocketState.Closing) { + var msg = "The close process is in progress."; + throw new InvalidOperationException (msg); + } + + if (_readyState == WebSocketState.Closed) { + var msg = "The connection has already been closed."; + throw new InvalidOperationException (msg); + } + + if (accept ()) + open (); + } + + /// + /// Accepts the handshake request asynchronously. + /// + /// + /// + /// This method does not wait for the accept process to be complete. + /// + /// + /// This method does nothing if the handshake request has already been + /// accepted. + /// + /// + /// + /// + /// This instance is a client. + /// + /// + /// -or- + /// + /// + /// The close process is in progress. + /// + /// + /// -or- + /// + /// + /// The connection has already been closed. + /// + /// + public void AcceptAsync () + { + if (_client) { + var msg = "This instance is a client."; + throw new InvalidOperationException (msg); + } + + if (_readyState == WebSocketState.Closing) { + var msg = "The close process is in progress."; + throw new InvalidOperationException (msg); + } + + if (_readyState == WebSocketState.Closed) { + var msg = "The connection has already been closed."; + throw new InvalidOperationException (msg); + } + + Func acceptor = accept; + acceptor.BeginInvoke ( + ar => { + if (acceptor.EndInvoke (ar)) + open (); + }, + null + ); + } + + /// + /// Closes the connection. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + public void Close () + { + close (1005, String.Empty); + } + + /// + /// Closes the connection with the specified code. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// A that represents the status code indicating + /// the reason for the close. + /// + /// + /// The status codes are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// + /// is less than 1000 or greater than 4999. + /// + /// + /// + /// is 1011 (server error). + /// It cannot be used by clients. + /// + /// + /// -or- + /// + /// + /// is 1010 (mandatory extension). + /// It cannot be used by servers. + /// + /// + public void Close (ushort code) + { + if (!code.IsCloseStatusCode ()) { + var msg = "Less than 1000 or greater than 4999."; + throw new ArgumentOutOfRangeException ("code", msg); + } + + if (_client && code == 1011) { + var msg = "1011 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!_client && code == 1010) { + var msg = "1010 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + close (code, String.Empty); + } + + /// + /// Closes the connection with the specified code. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It represents the status code indicating the reason for the close. + /// + /// + /// + /// + /// is + /// . + /// It cannot be used by clients. + /// + /// + /// -or- + /// + /// + /// is + /// . + /// It cannot be used by servers. + /// + /// + public void Close (CloseStatusCode code) + { + if (_client && code == CloseStatusCode.ServerError) { + var msg = "ServerError cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!_client && code == CloseStatusCode.MandatoryExtension) { + var msg = "MandatoryExtension cannot be used."; + throw new ArgumentException (msg, "code"); + } + + close ((ushort) code, String.Empty); + } + + /// + /// Closes the connection with the specified code and reason. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// A that represents the status code indicating + /// the reason for the close. + /// + /// + /// The status codes are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// + /// is less than 1000 or greater than 4999. + /// + /// + /// -or- + /// + /// + /// The size of is greater than 123 bytes. + /// + /// + /// + /// + /// is 1011 (server error). + /// It cannot be used by clients. + /// + /// + /// -or- + /// + /// + /// is 1010 (mandatory extension). + /// It cannot be used by servers. + /// + /// + /// -or- + /// + /// + /// is 1005 (no status) and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + public void Close (ushort code, string reason) + { + if (!code.IsCloseStatusCode ()) { + var msg = "Less than 1000 or greater than 4999."; + throw new ArgumentOutOfRangeException ("code", msg); + } + + if (_client && code == 1011) { + var msg = "1011 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!_client && code == 1010) { + var msg = "1010 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (reason.IsNullOrEmpty ()) { + close (code, String.Empty); + return; + } + + if (code == 1005) { + var msg = "1005 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + byte[] bytes; + if (!reason.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "reason"); + } + + if (bytes.Length > 123) { + var msg = "Its size is greater than 123 bytes."; + throw new ArgumentOutOfRangeException ("reason", msg); + } + + close (code, reason); + } + + /// + /// Closes the connection with the specified code and reason. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// One of the enum values. + /// + /// + /// It represents the status code indicating the reason for the close. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// + /// is + /// . + /// It cannot be used by clients. + /// + /// + /// -or- + /// + /// + /// is + /// . + /// It cannot be used by servers. + /// + /// + /// -or- + /// + /// + /// is + /// and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// The size of is greater than 123 bytes. + /// + public void Close (CloseStatusCode code, string reason) + { + if (_client && code == CloseStatusCode.ServerError) { + var msg = "ServerError cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!_client && code == CloseStatusCode.MandatoryExtension) { + var msg = "MandatoryExtension cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (reason.IsNullOrEmpty ()) { + close ((ushort) code, String.Empty); + return; + } + + if (code == CloseStatusCode.NoStatus) { + var msg = "NoStatus cannot be used."; + throw new ArgumentException (msg, "code"); + } + + byte[] bytes; + if (!reason.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "reason"); + } + + if (bytes.Length > 123) { + var msg = "Its size is greater than 123 bytes."; + throw new ArgumentOutOfRangeException ("reason", msg); + } + + close ((ushort) code, reason); + } + + /// + /// Closes the connection asynchronously. + /// + /// + /// + /// This method does not wait for the close to be complete. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + public void CloseAsync () + { + closeAsync (1005, String.Empty); + } + + /// + /// Closes the connection asynchronously with the specified code. + /// + /// + /// + /// This method does not wait for the close to be complete. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// + /// A that represents the status code indicating + /// the reason for the close. + /// + /// + /// The status codes are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// + /// is less than 1000 or greater than 4999. + /// + /// + /// + /// is 1011 (server error). + /// It cannot be used by clients. + /// + /// + /// -or- + /// + /// + /// is 1010 (mandatory extension). + /// It cannot be used by servers. + /// + /// + public void CloseAsync (ushort code) + { + if (!code.IsCloseStatusCode ()) { + var msg = "Less than 1000 or greater than 4999."; + throw new ArgumentOutOfRangeException ("code", msg); + } + + if (_client && code == 1011) { + var msg = "1011 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!_client && code == 1010) { + var msg = "1010 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + closeAsync (code, String.Empty); + } + + /// + /// Closes the connection asynchronously with the specified code. + /// + /// + /// + /// This method does not wait for the close to be complete. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// + /// One of the enum values. + /// + /// + /// It represents the status code indicating the reason for the close. + /// + /// + /// + /// + /// is + /// . + /// It cannot be used by clients. + /// + /// + /// -or- + /// + /// + /// is + /// . + /// It cannot be used by servers. + /// + /// + public void CloseAsync (CloseStatusCode code) + { + if (_client && code == CloseStatusCode.ServerError) { + var msg = "ServerError cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!_client && code == CloseStatusCode.MandatoryExtension) { + var msg = "MandatoryExtension cannot be used."; + throw new ArgumentException (msg, "code"); + } + + closeAsync ((ushort) code, String.Empty); + } + + /// + /// Closes the connection asynchronously with the specified code and reason. + /// + /// + /// + /// This method does not wait for the close to be complete. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// + /// A that represents the status code indicating + /// the reason for the close. + /// + /// + /// The status codes are defined in + /// + /// Section 7.4 of RFC 6455. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// + /// is less than 1000 or greater than 4999. + /// + /// + /// -or- + /// + /// + /// The size of is greater than 123 bytes. + /// + /// + /// + /// + /// is 1011 (server error). + /// It cannot be used by clients. + /// + /// + /// -or- + /// + /// + /// is 1010 (mandatory extension). + /// It cannot be used by servers. + /// + /// + /// -or- + /// + /// + /// is 1005 (no status) and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + public void CloseAsync (ushort code, string reason) + { + if (!code.IsCloseStatusCode ()) { + var msg = "Less than 1000 or greater than 4999."; + throw new ArgumentOutOfRangeException ("code", msg); + } + + if (_client && code == 1011) { + var msg = "1011 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!_client && code == 1010) { + var msg = "1010 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (reason.IsNullOrEmpty ()) { + closeAsync (code, String.Empty); + return; + } + + if (code == 1005) { + var msg = "1005 cannot be used."; + throw new ArgumentException (msg, "code"); + } + + byte[] bytes; + if (!reason.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "reason"); + } + + if (bytes.Length > 123) { + var msg = "Its size is greater than 123 bytes."; + throw new ArgumentOutOfRangeException ("reason", msg); + } + + closeAsync (code, reason); + } + + /// + /// Closes the connection asynchronously with the specified code and reason. + /// + /// + /// + /// This method does not wait for the close to be complete. + /// + /// + /// This method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + /// + /// + /// One of the enum values. + /// + /// + /// It represents the status code indicating the reason for the close. + /// + /// + /// + /// + /// A that represents the reason for the close. + /// + /// + /// The size must be 123 bytes or less in UTF-8. + /// + /// + /// + /// + /// is + /// . + /// It cannot be used by clients. + /// + /// + /// -or- + /// + /// + /// is + /// . + /// It cannot be used by servers. + /// + /// + /// -or- + /// + /// + /// is + /// and there is reason. + /// + /// + /// -or- + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// + /// The size of is greater than 123 bytes. + /// + public void CloseAsync (CloseStatusCode code, string reason) + { + if (_client && code == CloseStatusCode.ServerError) { + var msg = "ServerError cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (!_client && code == CloseStatusCode.MandatoryExtension) { + var msg = "MandatoryExtension cannot be used."; + throw new ArgumentException (msg, "code"); + } + + if (reason.IsNullOrEmpty ()) { + closeAsync ((ushort) code, String.Empty); + return; + } + + if (code == CloseStatusCode.NoStatus) { + var msg = "NoStatus cannot be used."; + throw new ArgumentException (msg, "code"); + } + + byte[] bytes; + if (!reason.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "reason"); + } + + if (bytes.Length > 123) { + var msg = "Its size is greater than 123 bytes."; + throw new ArgumentOutOfRangeException ("reason", msg); + } + + closeAsync ((ushort) code, reason); + } + + /// + /// Establishes a connection. + /// + /// + /// This method does nothing if the connection has already been established. + /// + /// + /// + /// This instance is not a client. + /// + /// + /// -or- + /// + /// + /// The close process is in progress. + /// + /// + /// -or- + /// + /// + /// A series of reconnecting has failed. + /// + /// + public bool Connect () + { + if (!_client) { + var msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + if (_readyState == WebSocketState.Closing) { + var msg = "The close process is in progress."; + throw new InvalidOperationException (msg); + } + + if (_retryCountForConnect > _maxRetryCountForConnect) { + var msg = "A series of reconnecting has failed."; + throw new InvalidOperationException (msg); + } + + if (connect ()) + { + open (); + return true; + } + return false; + } + + /// + /// Establishes a connection asynchronously. + /// + /// + /// + /// This method does not wait for the connect process to be complete. + /// + /// + /// This method does nothing if the connection has already been + /// established. + /// + /// + /// + /// + /// This instance is not a client. + /// + /// + /// -or- + /// + /// + /// The close process is in progress. + /// + /// + /// -or- + /// + /// + /// A series of reconnecting has failed. + /// + /// + public void ConnectAsync () + { + if (!_client) { + var msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + if (_readyState == WebSocketState.Closing) { + var msg = "The close process is in progress."; + throw new InvalidOperationException (msg); + } + + if (_retryCountForConnect > _maxRetryCountForConnect) { + var msg = "A series of reconnecting has failed."; + throw new InvalidOperationException (msg); + } + + Func connector = connect; + connector.BeginInvoke ( + ar => { + if (connector.EndInvoke (ar)) + open (); + }, + null + ); + } + + /// + /// Sends a ping using the WebSocket connection. + /// + /// + /// true if the send has done with no error and a pong has been + /// received within a time; otherwise, false. + /// + public bool Ping () + { + return ping (EmptyBytes); + } + + /// + /// Sends a ping with using the WebSocket + /// connection. + /// + /// + /// true if the send has done with no error and a pong has been + /// received within a time; otherwise, false. + /// + /// + /// + /// A that represents the message to send. + /// + /// + /// The size must be 125 bytes or less in UTF-8. + /// + /// + /// + /// could not be UTF-8-encoded. + /// + /// + /// The size of is greater than 125 bytes. + /// + public bool Ping (string message) + { + if (message.IsNullOrEmpty ()) + return ping (EmptyBytes); + + byte[] bytes; + if (!message.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "message"); + } + + if (bytes.Length > 125) { + var msg = "Its size is greater than 125 bytes."; + throw new ArgumentOutOfRangeException ("message", msg); + } + + return ping (bytes); + } + + /// + /// Sends the specified data using the WebSocket connection. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + public void Send (byte[] data) + { + if (_readyState != WebSocketState.Open) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + send (Opcode.Binary, new MemoryStream (data)); + } + + /// + /// Sends the specified file using the WebSocket connection. + /// + /// + /// + /// A that specifies the file to send. + /// + /// + /// The file is sent as the binary data. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// + /// The file does not exist. + /// + /// + /// -or- + /// + /// + /// The file could not be opened. + /// + /// + public void Send (FileInfo fileInfo) + { + if (_readyState != WebSocketState.Open) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + if (fileInfo == null) + throw new ArgumentNullException ("fileInfo"); + + if (!fileInfo.Exists) { + var msg = "The file does not exist."; + throw new ArgumentException (msg, "fileInfo"); + } + + FileStream stream; + if (!fileInfo.TryOpenRead (out stream)) { + var msg = "The file could not be opened."; + throw new ArgumentException (msg, "fileInfo"); + } + + send (Opcode.Binary, stream); + } + + /// + /// Sends the specified data using the WebSocket connection. + /// + /// + /// A that represents the text data to send. + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// could not be UTF-8-encoded. + /// + public void Send (string data) + { + if (_readyState != WebSocketState.Open) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + byte[] bytes; + if (!data.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "data"); + } + + send (Opcode.Text, new MemoryStream (bytes)); + } + + /// + /// Sends the data from the specified stream using the WebSocket connection. + /// + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// The data is sent as the binary data. + /// + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + public void Send (Stream stream, int length) + { + if (_readyState != WebSocketState.Open) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + if (stream == null) + throw new ArgumentNullException ("stream"); + + if (!stream.CanRead) { + var msg = "It cannot be read."; + throw new ArgumentException (msg, "stream"); + } + + if (length < 1) { + var msg = "Less than 1."; + throw new ArgumentException (msg, "length"); + } + + var bytes = stream.ReadBytes (length); + + var len = bytes.Length; + if (len == 0) { + var msg = "No data could be read from it."; + throw new ArgumentException (msg, "stream"); + } + + if (len < length) { + _logger.Warn ( + String.Format ( + "Only {0} byte(s) of data could be read from the stream.", + len + ) + ); + } + + send (Opcode.Binary, new MemoryStream (bytes)); + } + + /// + /// Sends the specified data asynchronously using the WebSocket connection. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// An array of that represents the binary data to send. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + public void SendAsync (byte[] data, Action completed) + { + if (_readyState != WebSocketState.Open) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + sendAsync (Opcode.Binary, new MemoryStream (data), completed); + } + + /// + /// Sends the specified file asynchronously using the WebSocket connection. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// + /// A that specifies the file to send. + /// + /// + /// The file is sent as the binary data. + /// + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// + /// The file does not exist. + /// + /// + /// -or- + /// + /// + /// The file could not be opened. + /// + /// + public void SendAsync (FileInfo fileInfo, Action completed) + { + if (_readyState != WebSocketState.Open) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + if (fileInfo == null) + throw new ArgumentNullException ("fileInfo"); + + if (!fileInfo.Exists) { + var msg = "The file does not exist."; + throw new ArgumentException (msg, "fileInfo"); + } + + FileStream stream; + if (!fileInfo.TryOpenRead (out stream)) { + var msg = "The file could not be opened."; + throw new ArgumentException (msg, "fileInfo"); + } + + sendAsync (Opcode.Binary, stream, completed); + } + + /// + /// Sends the specified data asynchronously using the WebSocket connection. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// A that represents the text data to send. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// could not be UTF-8-encoded. + /// + public void SendAsync (string data, Action completed) + { + if (_readyState != WebSocketState.Open) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + if (data == null) + throw new ArgumentNullException ("data"); + + byte[] bytes; + if (!data.TryGetUTF8EncodedBytes (out bytes)) { + var msg = "It could not be UTF-8-encoded."; + throw new ArgumentException (msg, "data"); + } + + sendAsync (Opcode.Text, new MemoryStream (bytes), completed); + } + + /// + /// Sends the data from the specified stream asynchronously using + /// the WebSocket connection. + /// + /// + /// This method does not wait for the send to be complete. + /// + /// + /// + /// A instance from which to read the data to send. + /// + /// + /// The data is sent as the binary data. + /// + /// + /// + /// An that specifies the number of bytes to send. + /// + /// + /// + /// An Action<bool> delegate or + /// if not needed. + /// + /// + /// The delegate invokes the method called when the send is complete. + /// + /// + /// true is passed to the method if the send has done with + /// no error; otherwise, false. + /// + /// + /// + /// The current state of the connection is not Open. + /// + /// + /// is . + /// + /// + /// + /// cannot be read. + /// + /// + /// -or- + /// + /// + /// is less than 1. + /// + /// + /// -or- + /// + /// + /// No data could be read from . + /// + /// + public void SendAsync (Stream stream, int length, Action completed) + { + if (_readyState != WebSocketState.Open) { + var msg = "The current state of the connection is not Open."; + throw new InvalidOperationException (msg); + } + + if (stream == null) + throw new ArgumentNullException ("stream"); + + if (!stream.CanRead) { + var msg = "It cannot be read."; + throw new ArgumentException (msg, "stream"); + } + + if (length < 1) { + var msg = "Less than 1."; + throw new ArgumentException (msg, "length"); + } + + var bytes = stream.ReadBytes (length); + + var len = bytes.Length; + if (len == 0) { + var msg = "No data could be read from it."; + throw new ArgumentException (msg, "stream"); + } + + if (len < length) { + _logger.Warn ( + String.Format ( + "Only {0} byte(s) of data could be read from the stream.", + len + ) + ); + } + + sendAsync (Opcode.Binary, new MemoryStream (bytes), completed); + } + + /// + /// Sets an HTTP cookie to send with the handshake request. + /// + /// + /// This method does nothing if the connection has already been + /// established or it is closing. + /// + /// + /// A that represents the cookie to send. + /// + /// + /// This instance is not a client. + /// + /// + /// is . + /// + public void SetCookie (Cookie cookie) + { + string msg = null; + + if (!_client) { + msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + if (cookie == null) + throw new ArgumentNullException ("cookie"); + + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + lock (_forState) { + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + lock (_cookies.SyncRoot) + _cookies.SetOrRemove (cookie); + } + } + + /// + /// Sets the credentials for the HTTP authentication (Basic/Digest). + /// + /// + /// This method does nothing if the connection has already been + /// established or it is closing. + /// + /// + /// + /// A that represents the username associated with + /// the credentials. + /// + /// + /// or an empty string if initializes + /// the credentials. + /// + /// + /// + /// + /// A that represents the password for the username + /// associated with the credentials. + /// + /// + /// or an empty string if not necessary. + /// + /// + /// + /// true if sends the credentials for the Basic authentication in + /// advance with the first handshake request; otherwise, false. + /// + /// + /// This instance is not a client. + /// + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + public void SetCredentials (string username, string password, bool preAuth) + { + string msg = null; + + if (!_client) { + msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + if (!username.IsNullOrEmpty ()) { + if (username.Contains (':') || !username.IsText ()) { + msg = "It contains an invalid character."; + throw new ArgumentException (msg, "username"); + } + } + + if (!password.IsNullOrEmpty ()) { + if (!password.IsText ()) { + msg = "It contains an invalid character."; + throw new ArgumentException (msg, "password"); + } + } + + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + lock (_forState) { + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + if (username.IsNullOrEmpty ()) { + _credentials = null; + _preAuth = false; + + return; + } + + _credentials = new NetworkCredential ( + username, password, _uri.PathAndQuery + ); + + _preAuth = preAuth; + } + } + + /// + /// Sets the URL of the HTTP proxy server through which to connect and + /// the credentials for the HTTP proxy authentication (Basic/Digest). + /// + /// + /// This method does nothing if the connection has already been + /// established or it is closing. + /// + /// + /// + /// A that represents the URL of the proxy server + /// through which to connect. + /// + /// + /// The syntax is http://<host>[:<port>]. + /// + /// + /// or an empty string if initializes the URL and + /// the credentials. + /// + /// + /// + /// + /// A that represents the username associated with + /// the credentials. + /// + /// + /// or an empty string if the credentials are not + /// necessary. + /// + /// + /// + /// + /// A that represents the password for the username + /// associated with the credentials. + /// + /// + /// or an empty string if not necessary. + /// + /// + /// + /// This instance is not a client. + /// + /// + /// + /// is not an absolute URI string. + /// + /// + /// -or- + /// + /// + /// The scheme of is not http. + /// + /// + /// -or- + /// + /// + /// includes the path segments. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + /// -or- + /// + /// + /// contains an invalid character. + /// + /// + public void SetProxy (string url, string username, string password) + { + string msg = null; + + if (!_client) { + msg = "This instance is not a client."; + throw new InvalidOperationException (msg); + } + + Uri uri = null; + + if (!url.IsNullOrEmpty ()) { + if (!Uri.TryCreate (url, UriKind.Absolute, out uri)) { + msg = "Not an absolute URI string."; + throw new ArgumentException (msg, "url"); + } + + if (uri.Scheme != "http") { + msg = "The scheme part is not http."; + throw new ArgumentException (msg, "url"); + } + + if (uri.Segments.Length > 1) { + msg = "It includes the path segments."; + throw new ArgumentException (msg, "url"); + } + } + + if (!username.IsNullOrEmpty ()) { + if (username.Contains (':') || !username.IsText ()) { + msg = "It contains an invalid character."; + throw new ArgumentException (msg, "username"); + } + } + + if (!password.IsNullOrEmpty ()) { + if (!password.IsText ()) { + msg = "It contains an invalid character."; + throw new ArgumentException (msg, "password"); + } + } + + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + lock (_forState) { + if (!canSet (out msg)) { + _logger.Warn (msg); + return; + } + + if (url.IsNullOrEmpty ()) { + _proxyUri = null; + _proxyCredentials = null; + + return; + } + + _proxyUri = uri; + _proxyCredentials = !username.IsNullOrEmpty () + ? new NetworkCredential ( + username, + password, + String.Format ( + "{0}:{1}", _uri.DnsSafeHost, _uri.Port + ) + ) + : null; + } + } + + #endregion + + #region Explicit Interface Implementations + + /// + /// Closes the connection and releases all associated resources. + /// + /// + /// + /// This method closes the connection with close status 1001 (going away). + /// + /// + /// And this method does nothing if the current state of the connection is + /// Closing or Closed. + /// + /// + void IDisposable.Dispose () + { + close (1001, String.Empty); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/WebSocket.cs.meta b/Plugins/websocket-sharp/websocket-sharp/WebSocket.cs.meta new file mode 100644 index 00000000..0836d904 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/WebSocket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d1cad9d3b0b34086a80682ab3e49a2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/WebSocketException.cs b/Plugins/websocket-sharp/websocket-sharp/WebSocketException.cs new file mode 100644 index 00000000..81d7c808 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/WebSocketException.cs @@ -0,0 +1,109 @@ +#region License +/* + * WebSocketException.cs + * + * The MIT License + * + * Copyright (c) 2012-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// The exception that is thrown when a fatal error occurs in + /// the WebSocket communication. + /// + public class WebSocketException : Exception + { + #region Private Fields + + private CloseStatusCode _code; + + #endregion + + #region Internal Constructors + + internal WebSocketException () + : this (CloseStatusCode.Abnormal, null, null) + { + } + + internal WebSocketException (Exception innerException) + : this (CloseStatusCode.Abnormal, null, innerException) + { + } + + internal WebSocketException (string message) + : this (CloseStatusCode.Abnormal, message, null) + { + } + + internal WebSocketException (CloseStatusCode code) + : this (code, null, null) + { + } + + internal WebSocketException (string message, Exception innerException) + : this (CloseStatusCode.Abnormal, message, innerException) + { + } + + internal WebSocketException (CloseStatusCode code, Exception innerException) + : this (code, null, innerException) + { + } + + internal WebSocketException (CloseStatusCode code, string message) + : this (code, message, null) + { + } + + internal WebSocketException ( + CloseStatusCode code, string message, Exception innerException + ) + : base (message ?? code.GetMessage (), innerException) + { + _code = code; + } + + #endregion + + #region Public Properties + + /// + /// Gets the status code indicating the cause of the exception. + /// + /// + /// One of the enum values that represents + /// the status code indicating the cause of the exception. + /// + public CloseStatusCode Code { + get { + return _code; + } + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/WebSocketException.cs.meta b/Plugins/websocket-sharp/websocket-sharp/WebSocketException.cs.meta new file mode 100644 index 00000000..3260e49f --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/WebSocketException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a4f1cbe319cd242dbb4e09156d8b9608 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/WebSocketFrame.cs b/Plugins/websocket-sharp/websocket-sharp/WebSocketFrame.cs new file mode 100644 index 00000000..ba0de3cd --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/WebSocketFrame.cs @@ -0,0 +1,895 @@ +#region License +/* + * WebSocketFrame.cs + * + * The MIT License + * + * Copyright (c) 2012-2019 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +#region Contributors +/* + * Contributors: + * - Chris Swiedler + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace WebSocketSharp +{ + internal class WebSocketFrame : IEnumerable + { + #region Private Fields + + private byte[] _extPayloadLength; + private Fin _fin; + private Mask _mask; + private byte[] _maskingKey; + private Opcode _opcode; + private PayloadData _payloadData; + private byte _payloadLength; + private Rsv _rsv1; + private Rsv _rsv2; + private Rsv _rsv3; + + #endregion + + #region Internal Fields + + /// + /// Represents the ping frame without the payload data as an array of + /// . + /// + /// + /// The value of this field is created from a non masked ping frame, + /// so it can only be used to send a ping from the server. + /// + internal static readonly byte[] EmptyPingBytes; + + #endregion + + #region Static Constructor + + static WebSocketFrame () + { + EmptyPingBytes = CreatePingFrame (false).ToArray (); + } + + #endregion + + #region Private Constructors + + private WebSocketFrame () + { + } + + #endregion + + #region Internal Constructors + + internal WebSocketFrame (Opcode opcode, PayloadData payloadData, bool mask) + : this (Fin.Final, opcode, payloadData, false, mask) + { + } + + internal WebSocketFrame ( + Fin fin, Opcode opcode, byte[] data, bool compressed, bool mask + ) + : this (fin, opcode, new PayloadData (data), compressed, mask) + { + } + + internal WebSocketFrame ( + Fin fin, + Opcode opcode, + PayloadData payloadData, + bool compressed, + bool mask + ) + { + _fin = fin; + _opcode = opcode; + + _rsv1 = opcode.IsData () && compressed ? Rsv.On : Rsv.Off; + _rsv2 = Rsv.Off; + _rsv3 = Rsv.Off; + + var len = payloadData.Length; + if (len < 126) { + _payloadLength = (byte) len; + _extPayloadLength = WebSocket.EmptyBytes; + } + else if (len < 0x010000) { + _payloadLength = (byte) 126; + _extPayloadLength = ((ushort) len).InternalToByteArray (ByteOrder.Big); + } + else { + _payloadLength = (byte) 127; + _extPayloadLength = len.InternalToByteArray (ByteOrder.Big); + } + + if (mask) { + _mask = Mask.On; + _maskingKey = createMaskingKey (); + payloadData.Mask (_maskingKey); + } + else { + _mask = Mask.Off; + _maskingKey = WebSocket.EmptyBytes; + } + + _payloadData = payloadData; + } + + #endregion + + #region Internal Properties + + internal ulong ExactPayloadLength { + get { + return _payloadLength < 126 + ? _payloadLength + : _payloadLength == 126 + ? _extPayloadLength.ToUInt16 (ByteOrder.Big) + : _extPayloadLength.ToUInt64 (ByteOrder.Big); + } + } + + internal int ExtendedPayloadLengthWidth { + get { + return _payloadLength < 126 + ? 0 + : _payloadLength == 126 + ? 2 + : 8; + } + } + + #endregion + + #region Public Properties + + public byte[] ExtendedPayloadLength { + get { + return _extPayloadLength; + } + } + + public Fin Fin { + get { + return _fin; + } + } + + public bool IsBinary { + get { + return _opcode == Opcode.Binary; + } + } + + public bool IsClose { + get { + return _opcode == Opcode.Close; + } + } + + public bool IsCompressed { + get { + return _rsv1 == Rsv.On; + } + } + + public bool IsContinuation { + get { + return _opcode == Opcode.Cont; + } + } + + public bool IsControl { + get { + return _opcode >= Opcode.Close; + } + } + + public bool IsData { + get { + return _opcode == Opcode.Text || _opcode == Opcode.Binary; + } + } + + public bool IsFinal { + get { + return _fin == Fin.Final; + } + } + + public bool IsFragment { + get { + return _fin == Fin.More || _opcode == Opcode.Cont; + } + } + + public bool IsMasked { + get { + return _mask == Mask.On; + } + } + + public bool IsPing { + get { + return _opcode == Opcode.Ping; + } + } + + public bool IsPong { + get { + return _opcode == Opcode.Pong; + } + } + + public bool IsText { + get { + return _opcode == Opcode.Text; + } + } + + public ulong Length { + get { + return 2 + + (ulong) (_extPayloadLength.Length + _maskingKey.Length) + + _payloadData.Length; + } + } + + public Mask Mask { + get { + return _mask; + } + } + + public byte[] MaskingKey { + get { + return _maskingKey; + } + } + + public Opcode Opcode { + get { + return _opcode; + } + } + + public PayloadData PayloadData { + get { + return _payloadData; + } + } + + public byte PayloadLength { + get { + return _payloadLength; + } + } + + public Rsv Rsv1 { + get { + return _rsv1; + } + } + + public Rsv Rsv2 { + get { + return _rsv2; + } + } + + public Rsv Rsv3 { + get { + return _rsv3; + } + } + + #endregion + + #region Private Methods + + private static byte[] createMaskingKey () + { + var key = new byte[4]; + WebSocket.RandomNumber.GetBytes (key); + + return key; + } + + private static string dump (WebSocketFrame frame) + { + var len = frame.Length; + var cnt = (long) (len / 4); + var rem = (int) (len % 4); + + int cntDigit; + string cntFmt; + if (cnt < 10000) { + cntDigit = 4; + cntFmt = "{0,4}"; + } + else if (cnt < 0x010000) { + cntDigit = 4; + cntFmt = "{0,4:X}"; + } + else if (cnt < 0x0100000000) { + cntDigit = 8; + cntFmt = "{0,8:X}"; + } + else { + cntDigit = 16; + cntFmt = "{0,16:X}"; + } + + var spFmt = String.Format ("{{0,{0}}}", cntDigit); + + var headerFmt = String.Format ( + @" +{0} 01234567 89ABCDEF 01234567 89ABCDEF +{0}+--------+--------+--------+--------+\n", + spFmt + ); + + var lineFmt = String.Format ( + "{0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|\n", cntFmt + ); + + var footerFmt = String.Format ( + "{0}+--------+--------+--------+--------+", spFmt + ); + + var buff = new StringBuilder (64); + + Func> linePrinter = + () => { + long lineCnt = 0; + return (arg1, arg2, arg3, arg4) => { + buff.AppendFormat ( + lineFmt, ++lineCnt, arg1, arg2, arg3, arg4 + ); + }; + }; + + var printLine = linePrinter (); + var bytes = frame.ToArray (); + + buff.AppendFormat (headerFmt, String.Empty); + + for (long i = 0; i <= cnt; i++) { + var j = i * 4; + + if (i < cnt) { + printLine ( + Convert.ToString (bytes[j], 2).PadLeft (8, '0'), + Convert.ToString (bytes[j + 1], 2).PadLeft (8, '0'), + Convert.ToString (bytes[j + 2], 2).PadLeft (8, '0'), + Convert.ToString (bytes[j + 3], 2).PadLeft (8, '0') + ); + + continue; + } + + if (rem > 0) { + printLine ( + Convert.ToString (bytes[j], 2).PadLeft (8, '0'), + rem >= 2 + ? Convert.ToString (bytes[j + 1], 2).PadLeft (8, '0') + : String.Empty, + rem == 3 + ? Convert.ToString (bytes[j + 2], 2).PadLeft (8, '0') + : String.Empty, + String.Empty + ); + } + } + + buff.AppendFormat (footerFmt, String.Empty); + return buff.ToString (); + } + + private static string print (WebSocketFrame frame) + { + // Payload Length + var payloadLen = frame._payloadLength; + + // Extended Payload Length + var extPayloadLen = payloadLen > 125 + ? frame.ExactPayloadLength.ToString () + : String.Empty; + + // Masking Key + var maskingKey = BitConverter.ToString (frame._maskingKey); + + // Payload Data + var payload = payloadLen == 0 + ? String.Empty + : payloadLen > 125 + ? "---" + : !frame.IsText + || frame.IsFragment + || frame.IsMasked + || frame.IsCompressed + ? frame._payloadData.ToString () + : utf8Decode (frame._payloadData.ApplicationData); + + var fmt = @" + FIN: {0} + RSV1: {1} + RSV2: {2} + RSV3: {3} + Opcode: {4} + MASK: {5} + Payload Length: {6} +Extended Payload Length: {7} + Masking Key: {8} + Payload Data: {9}"; + + return String.Format ( + fmt, + frame._fin, + frame._rsv1, + frame._rsv2, + frame._rsv3, + frame._opcode, + frame._mask, + payloadLen, + extPayloadLen, + maskingKey, + payload + ); + } + + private static WebSocketFrame processHeader (byte[] header) + { + if (header.Length != 2) { + var msg = "The header part of a frame could not be read."; + throw new WebSocketException (msg); + } + + // FIN + var fin = (header[0] & 0x80) == 0x80 ? Fin.Final : Fin.More; + + // RSV1 + var rsv1 = (header[0] & 0x40) == 0x40 ? Rsv.On : Rsv.Off; + + // RSV2 + var rsv2 = (header[0] & 0x20) == 0x20 ? Rsv.On : Rsv.Off; + + // RSV3 + var rsv3 = (header[0] & 0x10) == 0x10 ? Rsv.On : Rsv.Off; + + // Opcode + var opcode = (byte) (header[0] & 0x0f); + + // MASK + var mask = (header[1] & 0x80) == 0x80 ? Mask.On : Mask.Off; + + // Payload Length + var payloadLen = (byte) (header[1] & 0x7f); + + if (!opcode.IsSupported ()) { + var msg = "A frame has an unsupported opcode."; + throw new WebSocketException (CloseStatusCode.ProtocolError, msg); + } + + if (!opcode.IsData () && rsv1 == Rsv.On) { + var msg = "A non data frame is compressed."; + throw new WebSocketException (CloseStatusCode.ProtocolError, msg); + } + + if (opcode.IsControl ()) { + if (fin == Fin.More) { + var msg = "A control frame is fragmented."; + throw new WebSocketException (CloseStatusCode.ProtocolError, msg); + } + + if (payloadLen > 125) { + var msg = "A control frame has too long payload length."; + throw new WebSocketException (CloseStatusCode.ProtocolError, msg); + } + } + + var frame = new WebSocketFrame (); + frame._fin = fin; + frame._rsv1 = rsv1; + frame._rsv2 = rsv2; + frame._rsv3 = rsv3; + frame._opcode = (Opcode) opcode; + frame._mask = mask; + frame._payloadLength = payloadLen; + + return frame; + } + + private static WebSocketFrame readExtendedPayloadLength ( + Stream stream, WebSocketFrame frame + ) + { + var len = frame.ExtendedPayloadLengthWidth; + if (len == 0) { + frame._extPayloadLength = WebSocket.EmptyBytes; + return frame; + } + + var bytes = stream.ReadBytes (len); + if (bytes.Length != len) { + var msg = "The extended payload length of a frame could not be read."; + throw new WebSocketException (msg); + } + + frame._extPayloadLength = bytes; + return frame; + } + + private static void readExtendedPayloadLengthAsync ( + Stream stream, + WebSocketFrame frame, + Action completed, + Action error + ) + { + var len = frame.ExtendedPayloadLengthWidth; + if (len == 0) { + frame._extPayloadLength = WebSocket.EmptyBytes; + completed (frame); + + return; + } + + stream.ReadBytesAsync ( + len, + bytes => { + if (bytes.Length != len) { + var msg = "The extended payload length of a frame could not be read."; + throw new WebSocketException (msg); + } + + frame._extPayloadLength = bytes; + completed (frame); + }, + error + ); + } + + private static WebSocketFrame readHeader (Stream stream) + { + return processHeader (stream.ReadBytes (2)); + } + + private static void readHeaderAsync ( + Stream stream, Action completed, Action error + ) + { + stream.ReadBytesAsync ( + 2, bytes => completed (processHeader (bytes)), error + ); + } + + private static WebSocketFrame readMaskingKey ( + Stream stream, WebSocketFrame frame + ) + { + if (!frame.IsMasked) { + frame._maskingKey = WebSocket.EmptyBytes; + return frame; + } + + var len = 4; + var bytes = stream.ReadBytes (len); + + if (bytes.Length != len) { + var msg = "The masking key of a frame could not be read."; + throw new WebSocketException (msg); + } + + frame._maskingKey = bytes; + return frame; + } + + private static void readMaskingKeyAsync ( + Stream stream, + WebSocketFrame frame, + Action completed, + Action error + ) + { + if (!frame.IsMasked) { + frame._maskingKey = WebSocket.EmptyBytes; + completed (frame); + + return; + } + + var len = 4; + + stream.ReadBytesAsync ( + len, + bytes => { + if (bytes.Length != len) { + var msg = "The masking key of a frame could not be read."; + throw new WebSocketException (msg); + } + + frame._maskingKey = bytes; + completed (frame); + }, + error + ); + } + + private static WebSocketFrame readPayloadData ( + Stream stream, WebSocketFrame frame + ) + { + var exactLen = frame.ExactPayloadLength; + if (exactLen > PayloadData.MaxLength) { + var msg = "A frame has too long payload length."; + throw new WebSocketException (CloseStatusCode.TooBig, msg); + } + + if (exactLen == 0) { + frame._payloadData = PayloadData.Empty; + return frame; + } + + var len = (long) exactLen; + var bytes = frame._payloadLength < 127 + ? stream.ReadBytes ((int) exactLen) + : stream.ReadBytes (len, 1024); + + if (bytes.LongLength != len) { + var msg = "The payload data of a frame could not be read."; + throw new WebSocketException (msg); + } + + frame._payloadData = new PayloadData (bytes, len); + return frame; + } + + private static void readPayloadDataAsync ( + Stream stream, + WebSocketFrame frame, + Action completed, + Action error + ) + { + var exactLen = frame.ExactPayloadLength; + if (exactLen > PayloadData.MaxLength) { + var msg = "A frame has too long payload length."; + throw new WebSocketException (CloseStatusCode.TooBig, msg); + } + + if (exactLen == 0) { + frame._payloadData = PayloadData.Empty; + completed (frame); + + return; + } + + var len = (long) exactLen; + Action comp = + bytes => { + if (bytes.LongLength != len) { + var msg = "The payload data of a frame could not be read."; + throw new WebSocketException (msg); + } + + frame._payloadData = new PayloadData (bytes, len); + completed (frame); + }; + + if (frame._payloadLength < 127) { + stream.ReadBytesAsync ((int) exactLen, comp, error); + return; + } + + stream.ReadBytesAsync (len, 1024, comp, error); + } + + private static string utf8Decode (byte[] bytes) + { + try { + return Encoding.UTF8.GetString (bytes); + } + catch { + return null; + } + } + + #endregion + + #region Internal Methods + + internal static WebSocketFrame CreateCloseFrame ( + PayloadData payloadData, bool mask + ) + { + return new WebSocketFrame ( + Fin.Final, Opcode.Close, payloadData, false, mask + ); + } + + internal static WebSocketFrame CreatePingFrame (bool mask) + { + return new WebSocketFrame ( + Fin.Final, Opcode.Ping, PayloadData.Empty, false, mask + ); + } + + internal static WebSocketFrame CreatePingFrame (byte[] data, bool mask) + { + return new WebSocketFrame ( + Fin.Final, Opcode.Ping, new PayloadData (data), false, mask + ); + } + + internal static WebSocketFrame CreatePongFrame ( + PayloadData payloadData, bool mask + ) + { + return new WebSocketFrame ( + Fin.Final, Opcode.Pong, payloadData, false, mask + ); + } + + internal static WebSocketFrame ReadFrame (Stream stream, bool unmask) + { + var frame = readHeader (stream); + readExtendedPayloadLength (stream, frame); + readMaskingKey (stream, frame); + readPayloadData (stream, frame); + + if (unmask) + frame.Unmask (); + + return frame; + } + + internal static void ReadFrameAsync ( + Stream stream, + bool unmask, + Action completed, + Action error + ) + { + readHeaderAsync ( + stream, + frame => + readExtendedPayloadLengthAsync ( + stream, + frame, + frame1 => + readMaskingKeyAsync ( + stream, + frame1, + frame2 => + readPayloadDataAsync ( + stream, + frame2, + frame3 => { + if (unmask) + frame3.Unmask (); + + completed (frame3); + }, + error + ), + error + ), + error + ), + error + ); + } + + internal void Unmask () + { + if (_mask == Mask.Off) + return; + + _mask = Mask.Off; + _payloadData.Mask (_maskingKey); + _maskingKey = WebSocket.EmptyBytes; + } + + #endregion + + #region Public Methods + + public IEnumerator GetEnumerator () + { + foreach (var b in ToArray ()) + yield return b; + } + + public void Print (bool dumped) + { + Console.WriteLine (dumped ? dump (this) : print (this)); + } + + public string PrintToString (bool dumped) + { + return dumped ? dump (this) : print (this); + } + + public byte[] ToArray () + { + using (var buff = new MemoryStream ()) { + var header = (int) _fin; + header = (header << 1) + (int) _rsv1; + header = (header << 1) + (int) _rsv2; + header = (header << 1) + (int) _rsv3; + header = (header << 4) + (int) _opcode; + header = (header << 1) + (int) _mask; + header = (header << 7) + (int) _payloadLength; + + buff.Write ( + ((ushort) header).InternalToByteArray (ByteOrder.Big), 0, 2 + ); + + if (_payloadLength > 125) + buff.Write (_extPayloadLength, 0, _payloadLength == 126 ? 2 : 8); + + if (_mask == Mask.On) + buff.Write (_maskingKey, 0, 4); + + if (_payloadLength > 0) { + var bytes = _payloadData.ToArray (); + + if (_payloadLength < 127) + buff.Write (bytes, 0, bytes.Length); + else + buff.WriteBytes (bytes, 1024); + } + + buff.Close (); + return buff.ToArray (); + } + } + + public override string ToString () + { + return BitConverter.ToString (ToArray ()); + } + + #endregion + + #region Explicit Interface Implementations + + IEnumerator IEnumerable.GetEnumerator () + { + return GetEnumerator (); + } + + #endregion + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/WebSocketFrame.cs.meta b/Plugins/websocket-sharp/websocket-sharp/WebSocketFrame.cs.meta new file mode 100644 index 00000000..5b7303c0 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/WebSocketFrame.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba0b6529223344991af8493966eb5191 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/WebSocketState.cs b/Plugins/websocket-sharp/websocket-sharp/WebSocketState.cs new file mode 100644 index 00000000..2cbcd688 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/WebSocketState.cs @@ -0,0 +1,65 @@ +#region License +/* + * WebSocketState.cs + * + * The MIT License + * + * Copyright (c) 2010-2016 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + /// + /// Indicates the state of a WebSocket connection. + /// + /// + /// The values of this enumeration are defined in + /// + /// The WebSocket API. + /// + public enum WebSocketState : ushort + { + /// + /// Equivalent to numeric value 0. Indicates that the connection has not + /// yet been established. + /// + Connecting = 0, + /// + /// Equivalent to numeric value 1. Indicates that the connection has + /// been established, and the communication is possible. + /// + Open = 1, + /// + /// Equivalent to numeric value 2. Indicates that the connection is + /// going through the closing handshake, or the close method has + /// been invoked. + /// + Closing = 2, + /// + /// Equivalent to numeric value 3. Indicates that the connection has + /// been closed or could not be established. + /// + Closed = 3 + } +} diff --git a/Plugins/websocket-sharp/websocket-sharp/WebSocketState.cs.meta b/Plugins/websocket-sharp/websocket-sharp/WebSocketState.cs.meta new file mode 100644 index 00000000..b321e60d --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/WebSocketState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10f4680ba8a1e45a48308f2a8962b021 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.asmdef b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.asmdef new file mode 100644 index 00000000..735375bc --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.asmdef @@ -0,0 +1,16 @@ +{ + "name": "websocket-sharp", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [ + "WebGL" + ], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.asmdef.meta b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.asmdef.meta new file mode 100644 index 00000000..800003c0 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bb32166f4ac51414281e84c4fed2abbd +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.csproj b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.csproj new file mode 100644 index 00000000..0860c031 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.csproj @@ -0,0 +1,149 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {B357BAC7-529E-4D81-A0D2-71041B19C8DE} + Library + WebSocketSharp + websocket-sharp + v3.5 + true + websocket-sharp.snk + + + true + full + false + bin\Debug + DEBUG + prompt + 4 + false + + + none + false + bin\Release + prompt + 4 + false + + + true + full + false + bin\Debug_Ubuntu + DEBUG + prompt + 4 + false + + + none + false + bin\Release_Ubuntu + prompt + 4 + false + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.csproj.meta b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.csproj.meta new file mode 100644 index 00000000..d2950101 --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 034693953d24742eeb5d922ad9abde85 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.snk b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.snk new file mode 100644 index 0000000000000000000000000000000000000000..a2546f385ff1c28221f1071dd2fbc1870d728eb2 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONaL0000f7yF6+!;$wZ%ZuV+(mw^0ZDpvQV{)eT z)hzOzAo>fyaBB95ev6PlIrVnPNZ`ABvU}~*5T_asaF`E&^h;9-(xvYSmgrHTIc_N+d4!r0J+k@O7F^N!rZ!?-v-48IrNAb7!} z-N_==YbBhM_zb%3vcPBeECpwQOr<(i6$!ynrQ~`QXjiMFwVBazO>@JrfgI51ivGl6 zRjei2J2>~wP7}hz?AO{)>lh*();UW|5NUR0!Ji$O!OQ_E@UT|!^m$J!!@8AkltT%j z@^-wS`8NxnHzsxMW{zi$Sgj3%PBZ_5qAu2Olh=Q!lDnQk=0}kkW2jUYzmul4bgJIL zlK?W_`r?N;Z(!Kc`z;*hfOxrjI{zF803Sg&r~jaQ?Y?Fa8?Az+3a++ht8(mR9-o|j zE@`6|n4@2Af4?zHoP|-_#;rVGqar>7nH%|Nigv24jWsE z$LIC>T!MfxCrw6m*qpp=DPHF19B*63GF@WFjU6vWTmP4b`Oq(FIRY0(-TN1xl?|1D z-Sj2XD0j7$83O-B-{7UHg(P)vanCZOjten@X*^b4ZsM;$Wnsvy271`V8$NH_bgN{j zPL(SOf2I?l4(?fnuwJ_P05C5xZ~dI4vhml_=<z#%yL*k|m=6 literal 0 HcmV?d00001 diff --git a/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.snk.meta b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.snk.meta new file mode 100644 index 00000000..5a3ce3bb --- /dev/null +++ b/Plugins/websocket-sharp/websocket-sharp/websocket-sharp.snk.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ac89545414bd5464685d80dfed874b7e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 35ca4eaf6c0bc45c3378b9f6a928d3d672ad66de Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 21:23:28 +0700 Subject: [PATCH 48/58] feat: change websocket client --- Plugins/WebSocket/WebSocket.cs | 848 ++++++++++++++++++ .../WebSocket/WebSocket.cs.meta | 2 +- Plugins/WebSocket/WebSocket.jslib | 333 +++++++ Plugins/WebSocket/WebSocket.jslib.meta | 32 + .../WebSocket/endel.nativewebsocket.asmdef | 3 + .../endel.nativewebsocket.asmdef.meta | 7 + 6 files changed, 1224 insertions(+), 1 deletion(-) create mode 100644 Plugins/WebSocket/WebSocket.cs rename Scripts/Transports/WebSocket/WssTransportSession.cs.meta => Plugins/WebSocket/WebSocket.cs.meta (83%) create mode 100644 Plugins/WebSocket/WebSocket.jslib create mode 100644 Plugins/WebSocket/WebSocket.jslib.meta create mode 100644 Plugins/WebSocket/endel.nativewebsocket.asmdef create mode 100644 Plugins/WebSocket/endel.nativewebsocket.asmdef.meta diff --git a/Plugins/WebSocket/WebSocket.cs b/Plugins/WebSocket/WebSocket.cs new file mode 100644 index 00000000..503cf436 --- /dev/null +++ b/Plugins/WebSocket/WebSocket.cs @@ -0,0 +1,848 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.WebSockets; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using AOT; +using System.Runtime.InteropServices; +using UnityEngine; +using System.Collections; + +public class MainThreadUtil : MonoBehaviour +{ + public static MainThreadUtil Instance { get; private set; } + public static SynchronizationContext synchronizationContext { get; private set; } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + public static void Setup() + { + Instance = new GameObject("MainThreadUtil") + .AddComponent(); + synchronizationContext = SynchronizationContext.Current; + } + + public static void Run(IEnumerator waitForUpdate) + { + synchronizationContext.Post(_ => Instance.StartCoroutine( + waitForUpdate), null); + } + + void Awake() + { + gameObject.hideFlags = HideFlags.HideAndDontSave; + DontDestroyOnLoad(gameObject); + } +} + +public class WaitForUpdate : CustomYieldInstruction +{ + public override bool keepWaiting + { + get { return false; } + } + + public MainThreadAwaiter GetAwaiter() + { + var awaiter = new MainThreadAwaiter(); + MainThreadUtil.Run(CoroutineWrapper(this, awaiter)); + return awaiter; + } + + public class MainThreadAwaiter : INotifyCompletion + { + Action continuation; + + public bool IsCompleted { get; set; } + + public void GetResult() { } + + public void Complete() + { + IsCompleted = true; + continuation?.Invoke(); + } + + void INotifyCompletion.OnCompleted(Action continuation) + { + this.continuation = continuation; + } + } + + public static IEnumerator CoroutineWrapper(IEnumerator theWorker, MainThreadAwaiter awaiter) + { + yield return theWorker; + awaiter.Complete(); + } +} + +namespace NativeWebSocket +{ + public delegate void WebSocketOpenEventHandler(); + public delegate void WebSocketMessageEventHandler(byte[] data); + public delegate void WebSocketErrorEventHandler(string errorMsg); + public delegate void WebSocketCloseEventHandler(WebSocketCloseCode closeCode); + + public enum WebSocketCloseCode + { + /* Do NOT use NotSet - it's only purpose is to indicate that the close code cannot be parsed. */ + NotSet = 0, + Normal = 1000, + Away = 1001, + ProtocolError = 1002, + UnsupportedData = 1003, + Undefined = 1004, + NoStatus = 1005, + Abnormal = 1006, + InvalidData = 1007, + PolicyViolation = 1008, + TooBig = 1009, + MandatoryExtension = 1010, + ServerError = 1011, + TlsHandshakeFailure = 1015 + } + + public enum WebSocketState + { + Connecting, + Open, + Closing, + Closed + } + + public interface IWebSocket + { + event WebSocketOpenEventHandler OnOpen; + event WebSocketMessageEventHandler OnMessage; + event WebSocketErrorEventHandler OnError; + event WebSocketCloseEventHandler OnClose; + + WebSocketState State { get; } + } + + public static class WebSocketHelpers + { + public static WebSocketCloseCode ParseCloseCodeEnum(int closeCode) + { + + if (WebSocketCloseCode.IsDefined(typeof(WebSocketCloseCode), closeCode)) + { + return (WebSocketCloseCode)closeCode; + } + else + { + return WebSocketCloseCode.Undefined; + } + + } + + public static WebSocketException GetErrorMessageFromCode(int errorCode, Exception inner) + { + switch (errorCode) + { + case -1: + return new WebSocketUnexpectedException("WebSocket instance not found.", inner); + case -2: + return new WebSocketInvalidStateException("WebSocket is already connected or in connecting state.", inner); + case -3: + return new WebSocketInvalidStateException("WebSocket is not connected.", inner); + case -4: + return new WebSocketInvalidStateException("WebSocket is already closing.", inner); + case -5: + return new WebSocketInvalidStateException("WebSocket is already closed.", inner); + case -6: + return new WebSocketInvalidStateException("WebSocket is not in open state.", inner); + case -7: + return new WebSocketInvalidArgumentException("Cannot close WebSocket. An invalid code was specified or reason is too long.", inner); + default: + return new WebSocketUnexpectedException("Unknown error.", inner); + } + } + } + + public class WebSocketException : Exception + { + public WebSocketException() { } + public WebSocketException(string message) : base(message) { } + public WebSocketException(string message, Exception inner) : base(message, inner) { } + } + + public class WebSocketUnexpectedException : WebSocketException + { + public WebSocketUnexpectedException() { } + public WebSocketUnexpectedException(string message) : base(message) { } + public WebSocketUnexpectedException(string message, Exception inner) : base(message, inner) { } + } + + public class WebSocketInvalidArgumentException : WebSocketException + { + public WebSocketInvalidArgumentException() { } + public WebSocketInvalidArgumentException(string message) : base(message) { } + public WebSocketInvalidArgumentException(string message, Exception inner) : base(message, inner) { } + } + + public class WebSocketInvalidStateException : WebSocketException + { + public WebSocketInvalidStateException() { } + public WebSocketInvalidStateException(string message) : base(message) { } + public WebSocketInvalidStateException(string message, Exception inner) : base(message, inner) { } + } + + public class WaitForBackgroundThread + { + public ConfiguredTaskAwaitable.ConfiguredTaskAwaiter GetAwaiter() + { + return Task.Run(() => { }).ConfigureAwait(false).GetAwaiter(); + } + } + +#if UNITY_WEBGL && !UNITY_EDITOR + + /// + /// WebSocket class bound to JSLIB. + /// + public class WebSocket : IWebSocket { + + /* WebSocket JSLIB functions */ + [DllImport ("__Internal")] + public static extern int WebSocketConnect (int instanceId); + + [DllImport ("__Internal")] + public static extern int WebSocketClose (int instanceId, int code, string reason); + + [DllImport ("__Internal")] + public static extern int WebSocketSend (int instanceId, byte[] dataPtr, int dataLength); + + [DllImport ("__Internal")] + public static extern int WebSocketSendText (int instanceId, string message); + + [DllImport ("__Internal")] + public static extern int WebSocketGetState (int instanceId); + + protected int instanceId; + + public event WebSocketOpenEventHandler OnOpen; + public event WebSocketMessageEventHandler OnMessage; + public event WebSocketErrorEventHandler OnError; + public event WebSocketCloseEventHandler OnClose; + + public WebSocket (string url, Dictionary headers = null) { + if (!WebSocketFactory.isInitialized) { + WebSocketFactory.Initialize (); + } + + int instanceId = WebSocketFactory.WebSocketAllocate (url); + WebSocketFactory.instances.Add (instanceId, this); + + this.instanceId = instanceId; + } + + public WebSocket (string url, string subprotocol, Dictionary headers = null) { + if (!WebSocketFactory.isInitialized) { + WebSocketFactory.Initialize (); + } + + int instanceId = WebSocketFactory.WebSocketAllocate (url); + WebSocketFactory.instances.Add (instanceId, this); + + WebSocketFactory.WebSocketAddSubProtocol(instanceId, subprotocol); + + this.instanceId = instanceId; + } + + public WebSocket (string url, List subprotocols, Dictionary headers = null) { + if (!WebSocketFactory.isInitialized) { + WebSocketFactory.Initialize (); + } + + int instanceId = WebSocketFactory.WebSocketAllocate (url); + WebSocketFactory.instances.Add (instanceId, this); + + foreach (string subprotocol in subprotocols) { + WebSocketFactory.WebSocketAddSubProtocol(instanceId, subprotocol); + } + + this.instanceId = instanceId; + } + + ~WebSocket () { + WebSocketFactory.HandleInstanceDestroy (this.instanceId); + } + + public int GetInstanceId () { + return this.instanceId; + } + + public Task Connect () { + int ret = WebSocketConnect (this.instanceId); + + if (ret < 0) + throw WebSocketHelpers.GetErrorMessageFromCode (ret, null); + + return Task.CompletedTask; + } + + public void CancelConnection () { + if (State == WebSocketState.Open) + Close (WebSocketCloseCode.Abnormal); + } + + public Task Close (WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null) { + int ret = WebSocketClose (this.instanceId, (int) code, reason); + + if (ret < 0) + throw WebSocketHelpers.GetErrorMessageFromCode (ret, null); + + return Task.CompletedTask; + } + + public Task Send (byte[] data) { + int ret = WebSocketSend (this.instanceId, data, data.Length); + + if (ret < 0) + throw WebSocketHelpers.GetErrorMessageFromCode (ret, null); + + return Task.CompletedTask; + } + + public Task SendText (string message) { + int ret = WebSocketSendText (this.instanceId, message); + + if (ret < 0) + throw WebSocketHelpers.GetErrorMessageFromCode (ret, null); + + return Task.CompletedTask; + } + + public WebSocketState State { + get { + int state = WebSocketGetState (this.instanceId); + + if (state < 0) + throw WebSocketHelpers.GetErrorMessageFromCode (state, null); + + switch (state) { + case 0: + return WebSocketState.Connecting; + + case 1: + return WebSocketState.Open; + + case 2: + return WebSocketState.Closing; + + case 3: + return WebSocketState.Closed; + + default: + return WebSocketState.Closed; + } + } + } + + public void DelegateOnOpenEvent () { + this.OnOpen?.Invoke (); + } + + public void DelegateOnMessageEvent (byte[] data) { + this.OnMessage?.Invoke (data); + } + + public void DelegateOnErrorEvent (string errorMsg) { + this.OnError?.Invoke (errorMsg); + } + + public void DelegateOnCloseEvent (int closeCode) { + this.OnClose?.Invoke (WebSocketHelpers.ParseCloseCodeEnum (closeCode)); + } + + } + +#else + + public class WebSocket : IWebSocket + { + public event WebSocketOpenEventHandler OnOpen; + public event WebSocketMessageEventHandler OnMessage; + public event WebSocketErrorEventHandler OnError; + public event WebSocketCloseEventHandler OnClose; + + private Uri uri; + private Dictionary headers; + private List subprotocols; + private ClientWebSocket m_Socket = new ClientWebSocket(); + + private CancellationTokenSource m_TokenSource; + private CancellationToken m_CancellationToken; + + private readonly object OutgoingMessageLock = new object(); + private readonly object IncomingMessageLock = new object(); + + private bool isSending = false; + private List> sendBytesQueue = new List>(); + private List> sendTextQueue = new List>(); + + public WebSocket(string url, Dictionary headers = null) + { + uri = new Uri(url); + + if (headers == null) + { + this.headers = new Dictionary(); + } + else + { + this.headers = headers; + } + + subprotocols = new List(); + + string protocol = uri.Scheme; + if (!protocol.Equals("ws") && !protocol.Equals("wss")) + throw new ArgumentException("Unsupported protocol: " + protocol); + } + + public WebSocket(string url, string subprotocol, Dictionary headers = null) + { + uri = new Uri(url); + + if (headers == null) + { + this.headers = new Dictionary(); + } + else + { + this.headers = headers; + } + + subprotocols = new List {subprotocol}; + + string protocol = uri.Scheme; + if (!protocol.Equals("ws") && !protocol.Equals("wss")) + throw new ArgumentException("Unsupported protocol: " + protocol); + } + + public WebSocket(string url, List subprotocols, Dictionary headers = null) + { + uri = new Uri(url); + + if (headers == null) + { + this.headers = new Dictionary(); + } + else + { + this.headers = headers; + } + + this.subprotocols = subprotocols; + + string protocol = uri.Scheme; + if (!protocol.Equals("ws") && !protocol.Equals("wss")) + throw new ArgumentException("Unsupported protocol: " + protocol); + } + + public void CancelConnection() + { + m_TokenSource?.Cancel(); + } + + public async Task Connect() + { + try + { + m_TokenSource = new CancellationTokenSource(); + m_CancellationToken = m_TokenSource.Token; + + m_Socket = new ClientWebSocket(); + + foreach (var header in headers) + { + m_Socket.Options.SetRequestHeader(header.Key, header.Value); + } + + foreach (string subprotocol in subprotocols) { + m_Socket.Options.AddSubProtocol(subprotocol); + } + + await m_Socket.ConnectAsync(uri, m_CancellationToken); + OnOpen?.Invoke(); + + await Receive(); + } + catch (Exception ex) + { + OnError?.Invoke(ex.Message); + OnClose?.Invoke(WebSocketCloseCode.Abnormal); + } + finally + { + if (m_Socket != null) + { + m_TokenSource.Cancel(); + m_Socket.Dispose(); + } + } + } + + public WebSocketState State + { + get + { + switch (m_Socket.State) + { + case System.Net.WebSockets.WebSocketState.Connecting: + return WebSocketState.Connecting; + + case System.Net.WebSockets.WebSocketState.Open: + return WebSocketState.Open; + + case System.Net.WebSockets.WebSocketState.CloseSent: + case System.Net.WebSockets.WebSocketState.CloseReceived: + return WebSocketState.Closing; + + case System.Net.WebSockets.WebSocketState.Closed: + return WebSocketState.Closed; + + default: + return WebSocketState.Closed; + } + } + } + + public Task Send(byte[] bytes) + { + // return m_Socket.SendAsync(buffer, WebSocketMessageType.Binary, true, CancellationToken.None); + return SendMessage(sendBytesQueue, WebSocketMessageType.Binary, new ArraySegment(bytes)); + } + + public Task SendText(string message) + { + var encoded = Encoding.UTF8.GetBytes(message); + + // m_Socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); + return SendMessage(sendTextQueue, WebSocketMessageType.Text, new ArraySegment(encoded, 0, encoded.Length)); + } + + private async Task SendMessage(List> queue, WebSocketMessageType messageType, ArraySegment buffer) + { + // Return control to the calling method immediately. + // await Task.Yield (); + + // Make sure we have data. + if (buffer.Count == 0) + { + return; + } + + // The state of the connection is contained in the context Items dictionary. + bool sending; + + lock (OutgoingMessageLock) + { + sending = isSending; + + // If not, we are now. + if (!isSending) + { + isSending = true; + } + } + + if (!sending) + { + // Lock with a timeout, just in case. + if (!Monitor.TryEnter(m_Socket, 1000)) + { + // If we couldn't obtain exclusive access to the socket in one second, something is wrong. + await m_Socket.CloseAsync(WebSocketCloseStatus.InternalServerError, string.Empty, m_CancellationToken); + return; + } + + try + { + // Send the message synchronously. + var t = m_Socket.SendAsync(buffer, messageType, true, m_CancellationToken); + t.Wait(m_CancellationToken); + } + finally + { + Monitor.Exit(m_Socket); + } + + // Note that we've finished sending. + lock (OutgoingMessageLock) + { + isSending = false; + } + + // Handle any queued messages. + await HandleQueue(queue, messageType); + } + else + { + // Add the message to the queue. + lock (OutgoingMessageLock) + { + queue.Add(buffer); + } + } + } + + private async Task HandleQueue(List> queue, WebSocketMessageType messageType) + { + var buffer = new ArraySegment(); + lock (OutgoingMessageLock) + { + // Check for an item in the queue. + if (queue.Count > 0) + { + // Pull it off the top. + buffer = queue[0]; + queue.RemoveAt(0); + } + } + + // Send that message. + if (buffer.Count > 0) + { + await SendMessage(queue, messageType, buffer); + } + } + + private List m_MessageList = new List(); + + // simple dispatcher for queued messages. + public void DispatchMessageQueue() + { + if (m_MessageList.Count == 0) + { + return; + } + + List messageListCopy; + + lock (IncomingMessageLock) + { + messageListCopy = new List(m_MessageList); + m_MessageList.Clear(); + } + + var len = messageListCopy.Count; + for (int i = 0; i < len; i++) + { + OnMessage?.Invoke(messageListCopy[i]); + } + } + + public async Task Receive() + { + WebSocketCloseCode closeCode = WebSocketCloseCode.Abnormal; + await new WaitForBackgroundThread(); + + ArraySegment buffer = new ArraySegment(new byte[8192]); + try + { + while (m_Socket.State == System.Net.WebSockets.WebSocketState.Open) + { + WebSocketReceiveResult result = null; + + using (var ms = new MemoryStream()) + { + do + { + result = await m_Socket.ReceiveAsync(buffer, m_CancellationToken); + ms.Write(buffer.Array, buffer.Offset, result.Count); + } + while (!result.EndOfMessage); + + ms.Seek(0, SeekOrigin.Begin); + + if (result.MessageType == WebSocketMessageType.Text) + { + lock (IncomingMessageLock) + { + m_MessageList.Add(ms.ToArray()); + } + + //using (var reader = new StreamReader(ms, Encoding.UTF8)) + //{ + // string message = reader.ReadToEnd(); + // OnMessage?.Invoke(this, new MessageEventArgs(message)); + //} + } + else if (result.MessageType == WebSocketMessageType.Binary) + { + lock (IncomingMessageLock) + { + m_MessageList.Add(ms.ToArray()); + } + } + else if (result.MessageType == WebSocketMessageType.Close) + { + await Close(); + closeCode = WebSocketHelpers.ParseCloseCodeEnum((int)result.CloseStatus); + break; + } + } + } + } + catch (Exception) + { + m_TokenSource.Cancel(); + } + finally + { + await new WaitForUpdate(); + OnClose?.Invoke(closeCode); + } + } + + public async Task Close() + { + if (State == WebSocketState.Open) + { + await m_Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, m_CancellationToken); + } + } + } +#endif + + /// + /// Factory + /// + + /// + /// Class providing static access methods to work with JSLIB WebSocket or WebSocketSharp interface + /// + public static class WebSocketFactory + { + +#if UNITY_WEBGL && !UNITY_EDITOR + /* Map of websocket instances */ + public static Dictionary instances = new Dictionary (); + + /* Delegates */ + public delegate void OnOpenCallback (int instanceId); + public delegate void OnMessageCallback (int instanceId, System.IntPtr msgPtr, int msgSize); + public delegate void OnErrorCallback (int instanceId, System.IntPtr errorPtr); + public delegate void OnCloseCallback (int instanceId, int closeCode); + + /* WebSocket JSLIB callback setters and other functions */ + [DllImport ("__Internal")] + public static extern int WebSocketAllocate (string url); + + [DllImport ("__Internal")] + public static extern int WebSocketAddSubProtocol (int instanceId, string subprotocol); + + [DllImport ("__Internal")] + public static extern void WebSocketFree (int instanceId); + + [DllImport ("__Internal")] + public static extern void WebSocketSetOnOpen (OnOpenCallback callback); + + [DllImport ("__Internal")] + public static extern void WebSocketSetOnMessage (OnMessageCallback callback); + + [DllImport ("__Internal")] + public static extern void WebSocketSetOnError (OnErrorCallback callback); + + [DllImport ("__Internal")] + public static extern void WebSocketSetOnClose (OnCloseCallback callback); + + /* If callbacks was initialized and set */ + public static bool isInitialized = false; + + /* + * Initialize WebSocket callbacks to JSLIB + */ + public static void Initialize () { + + WebSocketSetOnOpen (DelegateOnOpenEvent); + WebSocketSetOnMessage (DelegateOnMessageEvent); + WebSocketSetOnError (DelegateOnErrorEvent); + WebSocketSetOnClose (DelegateOnCloseEvent); + + isInitialized = true; + + } + + /// + /// Called when instance is destroyed (by destructor) + /// Method removes instance from map and free it in JSLIB implementation + /// + /// Instance identifier. + public static void HandleInstanceDestroy (int instanceId) { + + instances.Remove (instanceId); + WebSocketFree (instanceId); + + } + + [MonoPInvokeCallback (typeof (OnOpenCallback))] + public static void DelegateOnOpenEvent (int instanceId) { + + WebSocket instanceRef; + + if (instances.TryGetValue (instanceId, out instanceRef)) { + instanceRef.DelegateOnOpenEvent (); + } + + } + + [MonoPInvokeCallback (typeof (OnMessageCallback))] + public static void DelegateOnMessageEvent (int instanceId, System.IntPtr msgPtr, int msgSize) { + + WebSocket instanceRef; + + if (instances.TryGetValue (instanceId, out instanceRef)) { + byte[] msg = new byte[msgSize]; + Marshal.Copy (msgPtr, msg, 0, msgSize); + + instanceRef.DelegateOnMessageEvent (msg); + } + + } + + [MonoPInvokeCallback (typeof (OnErrorCallback))] + public static void DelegateOnErrorEvent (int instanceId, System.IntPtr errorPtr) { + + WebSocket instanceRef; + + if (instances.TryGetValue (instanceId, out instanceRef)) { + + string errorMsg = Marshal.PtrToStringAuto (errorPtr); + instanceRef.DelegateOnErrorEvent (errorMsg); + + } + + } + + [MonoPInvokeCallback (typeof (OnCloseCallback))] + public static void DelegateOnCloseEvent (int instanceId, int closeCode) { + + WebSocket instanceRef; + + if (instances.TryGetValue (instanceId, out instanceRef)) { + instanceRef.DelegateOnCloseEvent (closeCode); + } + + } +#endif + + /// + /// Create WebSocket client instance + /// + /// The WebSocket instance. + /// WebSocket valid URL. + public static WebSocket CreateInstance(string url) + { + return new WebSocket(url); + } + + } + +} diff --git a/Scripts/Transports/WebSocket/WssTransportSession.cs.meta b/Plugins/WebSocket/WebSocket.cs.meta similarity index 83% rename from Scripts/Transports/WebSocket/WssTransportSession.cs.meta rename to Plugins/WebSocket/WebSocket.cs.meta index cc6a5263..708e6f1c 100644 --- a/Scripts/Transports/WebSocket/WssTransportSession.cs.meta +++ b/Plugins/WebSocket/WebSocket.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 102c4270c7677314898bb6da06d9f7a3 +guid: df0e653fbf9005342904aa0f14d46088 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Plugins/WebSocket/WebSocket.jslib b/Plugins/WebSocket/WebSocket.jslib new file mode 100644 index 00000000..052f2132 --- /dev/null +++ b/Plugins/WebSocket/WebSocket.jslib @@ -0,0 +1,333 @@ + +var LibraryWebSocket = { + $webSocketState: { + /* + * Map of instances + * + * Instance structure: + * { + * url: string, + * ws: WebSocket + * } + */ + instances: {}, + + /* Last instance ID */ + lastId: 0, + + /* Event listeners */ + onOpen: null, + onMesssage: null, + onError: null, + onClose: null, + + /* Debug mode */ + debug: false + }, + + /** + * Set onOpen callback + * + * @param callback Reference to C# static function + */ + WebSocketSetOnOpen: function(callback) { + + webSocketState.onOpen = callback; + + }, + + /** + * Set onMessage callback + * + * @param callback Reference to C# static function + */ + WebSocketSetOnMessage: function(callback) { + + webSocketState.onMessage = callback; + + }, + + /** + * Set onError callback + * + * @param callback Reference to C# static function + */ + WebSocketSetOnError: function(callback) { + + webSocketState.onError = callback; + + }, + + /** + * Set onClose callback + * + * @param callback Reference to C# static function + */ + WebSocketSetOnClose: function(callback) { + + webSocketState.onClose = callback; + + }, + + /** + * Allocate new WebSocket instance struct + * + * @param url Server URL + */ + WebSocketAllocate: function(url) { + + var urlStr = UTF8ToString(url); + var id = webSocketState.lastId++; + + webSocketState.instances[id] = { + subprotocols: [], + url: urlStr, + ws: null + }; + + return id; + + }, + + /** + * Add subprotocol to instance + * + * @param instanceId Instance ID + * @param subprotocol Subprotocol name to add to instance + */ + WebSocketAddSubProtocol: function(instanceId, subprotocol) { + + var subprotocolStr = UTF8ToString(subprotocol); + webSocketState.instances[instanceId].subprotocols.push(subprotocolStr); + + }, + + /** + * Remove reference to WebSocket instance + * + * If socket is not closed function will close it but onClose event will not be emitted because + * this function should be invoked by C# WebSocket destructor. + * + * @param instanceId Instance ID + */ + WebSocketFree: function(instanceId) { + + var instance = webSocketState.instances[instanceId]; + + if (!instance) return 0; + + // Close if not closed + if (instance.ws && instance.ws.readyState < 2) + instance.ws.close(); + + // Remove reference + delete webSocketState.instances[instanceId]; + + return 0; + + }, + + /** + * Connect WebSocket to the server + * + * @param instanceId Instance ID + */ + WebSocketConnect: function(instanceId) { + + var instance = webSocketState.instances[instanceId]; + if (!instance) return -1; + + if (instance.ws !== null) + return -2; + + instance.ws = new WebSocket(instance.url, instance.subprotocols); + + instance.ws.binaryType = 'arraybuffer'; + + instance.ws.onopen = function() { + + if (webSocketState.debug) + console.log("[JSLIB WebSocket] Connected."); + + if (webSocketState.onOpen) + Module.dynCall_vi(webSocketState.onOpen, instanceId); + + }; + + instance.ws.onmessage = function(ev) { + + if (webSocketState.debug) + console.log("[JSLIB WebSocket] Received message:", ev.data); + + if (webSocketState.onMessage === null) + return; + + if (ev.data instanceof ArrayBuffer) { + + var dataBuffer = new Uint8Array(ev.data); + + var buffer = _malloc(dataBuffer.length); + HEAPU8.set(dataBuffer, buffer); + + try { + Module.dynCall_viii(webSocketState.onMessage, instanceId, buffer, dataBuffer.length); + } finally { + _free(buffer); + } + + } else { + var dataBuffer = (new TextEncoder()).encode(ev.data); + + var buffer = _malloc(dataBuffer.length); + HEAPU8.set(dataBuffer, buffer); + + try { + Module.dynCall_viii(webSocketState.onMessage, instanceId, buffer, dataBuffer.length); + } finally { + _free(buffer); + } + + } + + }; + + instance.ws.onerror = function(ev) { + + if (webSocketState.debug) + console.log("[JSLIB WebSocket] Error occured."); + + if (webSocketState.onError) { + + var msg = "WebSocket error."; + var length = lengthBytesUTF8(msg) + 1; + var buffer = _malloc(length); + stringToUTF8(msg, buffer, length); + + try { + Module.dynCall_vii(webSocketState.onError, instanceId, buffer); + } finally { + _free(buffer); + } + + } + + }; + + instance.ws.onclose = function(ev) { + + if (webSocketState.debug) + console.log("[JSLIB WebSocket] Closed."); + + if (webSocketState.onClose) + Module.dynCall_vii(webSocketState.onClose, instanceId, ev.code); + + delete instance.ws; + + }; + + return 0; + + }, + + /** + * Close WebSocket connection + * + * @param instanceId Instance ID + * @param code Close status code + * @param reasonPtr Pointer to reason string + */ + WebSocketClose: function(instanceId, code, reasonPtr) { + + var instance = webSocketState.instances[instanceId]; + if (!instance) return -1; + + if (!instance.ws) + return -3; + + if (instance.ws.readyState === 2) + return -4; + + if (instance.ws.readyState === 3) + return -5; + + var reason = ( reasonPtr ? UTF8ToString(reasonPtr) : undefined ); + + try { + instance.ws.close(code, reason); + } catch(err) { + return -7; + } + + return 0; + + }, + + /** + * Send message over WebSocket + * + * @param instanceId Instance ID + * @param bufferPtr Pointer to the message buffer + * @param length Length of the message in the buffer + */ + WebSocketSend: function(instanceId, bufferPtr, length) { + + var instance = webSocketState.instances[instanceId]; + if (!instance) return -1; + + if (!instance.ws) + return -3; + + if (instance.ws.readyState !== 1) + return -6; + + instance.ws.send(HEAPU8.buffer.slice(bufferPtr, bufferPtr + length)); + + return 0; + + }, + + /** + * Send text message over WebSocket + * + * @param instanceId Instance ID + * @param bufferPtr Pointer to the message buffer + * @param length Length of the message in the buffer + */ + WebSocketSendText: function(instanceId, message) { + + var instance = webSocketState.instances[instanceId]; + if (!instance) return -1; + + if (!instance.ws) + return -3; + + if (instance.ws.readyState !== 1) + return -6; + + instance.ws.send(UTF8ToString(message)); + + return 0; + + }, + + /** + * Return WebSocket readyState + * + * @param instanceId Instance ID + */ + WebSocketGetState: function(instanceId) { + + var instance = webSocketState.instances[instanceId]; + if (!instance) return -1; + + if (instance.ws) + return instance.ws.readyState; + else + return 3; + + } + +}; + +autoAddDeps(LibraryWebSocket, '$webSocketState'); +mergeInto(LibraryManager.library, LibraryWebSocket); diff --git a/Plugins/WebSocket/WebSocket.jslib.meta b/Plugins/WebSocket/WebSocket.jslib.meta new file mode 100644 index 00000000..a4f0052d --- /dev/null +++ b/Plugins/WebSocket/WebSocket.jslib.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: 3b767cc116f846f4b813fe00142b8736 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + WebGL: WebGL + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/WebSocket/endel.nativewebsocket.asmdef b/Plugins/WebSocket/endel.nativewebsocket.asmdef new file mode 100644 index 00000000..871f704e --- /dev/null +++ b/Plugins/WebSocket/endel.nativewebsocket.asmdef @@ -0,0 +1,3 @@ +{ + "name": "endel.nativewebsocket" +} diff --git a/Plugins/WebSocket/endel.nativewebsocket.asmdef.meta b/Plugins/WebSocket/endel.nativewebsocket.asmdef.meta new file mode 100644 index 00000000..01d2d89b --- /dev/null +++ b/Plugins/WebSocket/endel.nativewebsocket.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 04376767bc1f3b428aefa3d20743e819 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 6e8991ee47744e7d982eb316421d48a93a1f4d3e Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 21:24:01 +0700 Subject: [PATCH 49/58] feat: change web socket transport implementation # Conflicts: # Scripts/Transports/WebSocket/WebSocketTransportFactory.cs # Scripts/Transports/WebSocket/WsClientWrapper.cs # Scripts/Transports/WebSocket/WsTransportClient.cs # Scripts/Transports/WebSocket/WsTransportSession.cs # Scripts/Transports/WebSocket/WssTransportClient.cs # Scripts/Transports/WebSocket/WssTransportSession.cs --- .../WebSocket/WebSocketServerBehavior.cs | 69 +++++ ...s.meta => WebSocketServerBehavior.cs.meta} | 2 +- .../WebSocket/WebSocketTransport.cs | 261 ++++++++++-------- .../WebSocket/WebSocketTransportFactory.cs | 13 +- .../Transports/WebSocket/WsClientWrapper.cs | 227 --------------- .../WebSocket/WsClientWrapper.cs.meta | 11 - .../Transports/WebSocket/WsTransportClient.cs | 80 ------ .../WebSocket/WsTransportClient.cs.meta | 11 - .../Transports/WebSocket/WsTransportServer.cs | 52 ---- .../WebSocket/WsTransportSession.cs | 77 ------ .../WebSocket/WsTransportSession.cs.meta | 11 - .../WebSocket/WssTransportClient.cs | 80 ------ .../WebSocket/WssTransportClient.cs.meta | 11 - .../WebSocket/WssTransportServer.cs | 52 ---- .../WebSocket/WssTransportServer.cs.meta | 11 - .../WebSocket/WssTransportSession.cs | 77 ------ 16 files changed, 226 insertions(+), 819 deletions(-) create mode 100644 Scripts/Transports/WebSocket/WebSocketServerBehavior.cs rename Scripts/Transports/WebSocket/{WsTransportServer.cs.meta => WebSocketServerBehavior.cs.meta} (83%) delete mode 100644 Scripts/Transports/WebSocket/WsClientWrapper.cs delete mode 100644 Scripts/Transports/WebSocket/WsClientWrapper.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WsTransportClient.cs delete mode 100644 Scripts/Transports/WebSocket/WsTransportClient.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WsTransportServer.cs delete mode 100644 Scripts/Transports/WebSocket/WsTransportSession.cs delete mode 100644 Scripts/Transports/WebSocket/WsTransportSession.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WssTransportClient.cs delete mode 100644 Scripts/Transports/WebSocket/WssTransportClient.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WssTransportServer.cs delete mode 100644 Scripts/Transports/WebSocket/WssTransportServer.cs.meta delete mode 100644 Scripts/Transports/WebSocket/WssTransportSession.cs diff --git a/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs b/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs new file mode 100644 index 00000000..5e6f9018 --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs @@ -0,0 +1,69 @@ +using System.Collections.Generic; +using LiteNetLib.Utils; +#if !UNITY_WEBGL || UNITY_EDITOR +using WebSocketSharp; +using WebSocketSharp.Server; +#endif + +namespace LiteNetLibManager +{ +#if !UNITY_WEBGL || UNITY_EDITOR + public class WebSocketServerBehavior : WebSocketBehavior + { + public long ConnectionId { get; private set; } + private Queue eventQueue; + private Dictionary serverPeers; + + public void Initialize(long connectionId, Queue eventQueue, Dictionary serverPeers) + { + ConnectionId = connectionId; + this.eventQueue = eventQueue; + this.serverPeers = serverPeers; + } + + protected override void OnOpen() + { + base.OnOpen(); + if (serverPeers != null) + serverPeers[ConnectionId] = this; + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ConnectEvent, + connectionId = ConnectionId, + }); + } + + protected override void OnMessage(MessageEventArgs e) + { + base.OnMessage(e); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DataEvent, + connectionId = ConnectionId, + reader = new NetDataReader(e.RawData), + }); + } + + protected override void OnError(ErrorEventArgs e) + { + base.OnError(e); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + }); + } + + protected override void OnClose(CloseEventArgs e) + { + base.OnClose(e); + if (serverPeers != null) + serverPeers.Remove(ConnectionId); + eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DisconnectEvent, + connectionId = ConnectionId, + }); + } + } +#endif +} diff --git a/Scripts/Transports/WebSocket/WsTransportServer.cs.meta b/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs.meta similarity index 83% rename from Scripts/Transports/WebSocket/WsTransportServer.cs.meta rename to Scripts/Transports/WebSocket/WebSocketServerBehavior.cs.meta index 56bf51f1..36bf1d5e 100644 --- a/Scripts/Transports/WebSocket/WsTransportServer.cs.meta +++ b/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d125cf39ccfa55e429fe21497e2f7cb9 +guid: fef67ccb1a96bc84e9762aac2dd60861 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Scripts/Transports/WebSocket/WebSocketTransport.cs b/Scripts/Transports/WebSocket/WebSocketTransport.cs index cadf2468..94d9cd94 100644 --- a/Scripts/Transports/WebSocket/WebSocketTransport.cs +++ b/Scripts/Transports/WebSocket/WebSocketTransport.cs @@ -1,123 +1,164 @@ -using LiteNetLib; +using System.Collections.Generic; +using LiteNetLib; using LiteNetLib.Utils; -using System.Collections.Concurrent; -using System.Net; -using System.Net.Security; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; using System.Threading; #if !UNITY_WEBGL || UNITY_EDITOR -using NetCoreServer; +using System.Security.Cryptography.X509Certificates; +using WebSocketSharp; +using WebSocketSharp.Server; #endif namespace LiteNetLibManager { - public class WebSocketTransport : ITransport, ITransportConnectionGenerator + public class WebSocketTransport : ITransport { - private long _nextConnectionId = 1; + private string _path = "/netcode"; private bool _secure; private string _certificateFilePath; private string _certificatePassword; - private readonly ConcurrentQueue _clientEventQueue; - private WsClientWrapper _wsClient; + private string _certificateBase64String; + private NativeWebSocket.WebSocket _client; + private readonly Queue _clientEventQueue; #if !UNITY_WEBGL || UNITY_EDITOR - private WsTransportServer _wsServer; - private WssTransportServer _wssServer; + private WebSocketServer _server; + private long _nextConnectionId = 1; + private readonly Dictionary _serverPeers; + private readonly Queue _serverEventQueue; #endif + public int ServerPeersCount + { + get + { + int result = 0; +#if !UNITY_WEBGL || UNITY_EDITOR + if (_server != null) + { + foreach (WebSocketServiceHost host in _server.WebSocketServices.Hosts) + { + result += host.Sessions.Count; + } + } +#endif + return result; + } + } + public int ServerMaxConnections { get; private set; } public bool IsClientStarted { - get { return _wsClient.IsClientStarted; } + get { return _client != null && _client.State == NativeWebSocket.WebSocketState.Open; } } - public bool IsServerStarted { get { #if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - return _wsServer != null && _wsServer.IsStarted; - else - return _wssServer != null && _wssServer.IsStarted; + return _server != null && _server.IsListening; #else return false; #endif } } - public int ServerPeersCount + public bool HasImplementedPing => false; + + public WebSocketTransport(bool secure, string certificateFilePath, string certificatePassword, string certificateBase64String) { - get - { + _secure = secure; + _certificateFilePath = certificateFilePath; + _certificatePassword = certificatePassword; + _certificateBase64String = certificateBase64String; + _clientEventQueue = new Queue(); #if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - { - if (_wsServer != null) - return _wsServer.PeersCount; - } - else - { - if (_wssServer != null) - return _wssServer.PeersCount; - } + _serverPeers = new Dictionary(); + _serverEventQueue = new Queue(); #endif - return 0; - } } - public int ServerMaxConnections + public bool StartClient(string address, int port) { - get + if (IsClientStarted) + return false; + string protocol = _secure ? "wss" : "ws"; + string url = $"{protocol}://{address}:{port}{_path}"; + Logging.Log(nameof(WebSocketTransport), $"Connecting to {url}"); + _client = new NativeWebSocket.WebSocket(url); + _client.OnOpen += OnClientOpen; + _client.OnMessage += OnClientMessage; + _client.OnError += OnClientError; + _client.OnClose += OnClientClose; + _ = _client.Connect(); + return true; + } + + public void StopClient() + { + if (_client != null) + _ = _client.Close(); + _client = null; + } + + private void OnClientOpen() + { + _clientEventQueue.Enqueue(new TransportEventData() { -#if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - { - if (_wsServer != null) - return _wsServer.MaxConnections; - } - else - { - if (_wssServer != null) - return _wssServer.MaxConnections; - } -#endif - return 0; - } + type = ENetworkEvent.ConnectEvent, + }); } - public bool HasImplementedPing + private void OnClientMessage(byte[] data) { - get { return false; } + _clientEventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DataEvent, + reader = new NetDataReader(data), + }); } - public WebSocketTransport(bool secure, string certificateFilePath, string certificatePassword) + private void OnClientError(string errorMsg) { - _secure = secure; - _certificateFilePath = certificateFilePath; - _certificatePassword = certificatePassword; - _clientEventQueue = new ConcurrentQueue(); - _wsClient = new WsClientWrapper(_clientEventQueue, secure, SslProtocols.Tls12); + _clientEventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + errorMessage = errorMsg, + }); } - public bool StartClient(string address, int port) + private void OnClientClose(NativeWebSocket.WebSocketCloseCode closeCode) { - while (_clientEventQueue.TryDequeue(out _)) { } - return _wsClient.StartClient(address, port); + _clientEventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DisconnectEvent, + disconnectInfo = GetDisconnectInfo(closeCode), + }); } - public void StopClient() + private DisconnectInfo GetDisconnectInfo(NativeWebSocket.WebSocketCloseCode closeCode) { - _wsClient.StopClient(); + DisconnectInfo info = new DisconnectInfo(); + return info; } public bool ClientReceive(out TransportEventData eventData) { - return _wsClient.ClientReceive(out eventData); + eventData = default; + if (_client == null) + return false; + _client.DispatchMessageQueue(); + if (_clientEventQueue.Count == 0) + return false; + eventData = _clientEventQueue.Dequeue(); + return true; } public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { - return _wsClient.ClientSend(dataChannel, deliveryMethod, writer); + if (IsClientStarted) + { + _client.Send(writer.Data); + return true; + } + return false; } public bool StartServer(int port, int maxConnections) @@ -125,49 +166,43 @@ public bool StartServer(int port, int maxConnections) #if !UNITY_WEBGL || UNITY_EDITOR if (IsServerStarted) return false; - if (!_secure) + ServerMaxConnections = maxConnections; + _serverPeers.Clear(); + _server = new WebSocketServer(port, _secure); + if (_secure) { - _wsServer = new WsTransportServer(this, IPAddress.Any, port, maxConnections); - _wsServer.OptionDualMode = true; - _wsServer.OptionNoDelay = true; - return _wsServer.Start(); + if (!string.IsNullOrEmpty(_certificateFilePath) && !string.IsNullOrEmpty(_certificatePassword)) + { + _server.SslConfiguration.ServerCertificate = new X509Certificate2(_certificateFilePath, _certificatePassword); + } + if (!string.IsNullOrEmpty(_certificateBase64String)) + { + byte[] bytes = System.Convert.FromBase64String(_certificateBase64String); + _server.SslConfiguration.ServerCertificate = new X509Certificate2(bytes); + } } - else + _server.AddWebSocketService(_path, (behavior) => { - SslContext context = new SslContext(SslProtocols.Tls12, new X509Certificate2(_certificateFilePath, _certificatePassword), CertValidationCallback); - _wssServer = new WssTransportServer(this, context, IPAddress.Any, port, maxConnections); - _wssServer.OptionDualMode = true; - _wssServer.OptionNoDelay = true; - return _wssServer.Start(); - } + long newConnectionId = GetNewConnectionID(); + behavior.Initialize(newConnectionId, _serverEventQueue, _serverPeers); + }); + _server.Start(); + return true; #else return false; #endif } - private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - return true; - } - public bool ServerReceive(out TransportEventData eventData) { eventData = default(TransportEventData); #if !UNITY_WEBGL || UNITY_EDITOR if (!IsServerStarted) return false; - if (!_secure) - { - if (_wsServer.EventQueue.Count == 0) - return false; - return _wsServer.EventQueue.TryDequeue(out eventData); - } - else - { - if (_wssServer.EventQueue.Count == 0) - return false; - return _wssServer.EventQueue.TryDequeue(out eventData); - } + if (_serverEventQueue.Count == 0) + return false; + eventData = _serverEventQueue.Dequeue(); + return true; #else return false; #endif @@ -176,37 +211,35 @@ public bool ServerReceive(out TransportEventData eventData) public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { #if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - return _wsServer != null && _wsServer.SendAsync(connectionId, writer.Data); - else - return _wssServer != null && _wssServer.SendAsync(connectionId, writer.Data); -#else - return false; + if (IsServerStarted && _serverPeers.ContainsKey(connectionId) && _serverPeers[connectionId].ConnectionState == WebSocketState.Open) + { + _serverPeers[connectionId].Context.WebSocket.Send(writer.Data); + return true; + } #endif + return false; } public bool ServerDisconnect(long connectionId) { #if !UNITY_WEBGL || UNITY_EDITOR - if (!_secure) - return _wsServer != null && _wsServer.Disconnect(connectionId); - else - return _wssServer != null && _wssServer.Disconnect(connectionId); -#else - return false; + if (IsServerStarted && _serverPeers.ContainsKey(connectionId)) + { + _serverPeers[connectionId].Context.WebSocket.Close(); + _serverPeers.Remove(connectionId); + return true; + } #endif + return false; } public void StopServer() { #if !UNITY_WEBGL || UNITY_EDITOR - if (_wsServer != null) - _wsServer.Dispose(); - if (_wssServer != null) - _wssServer.Dispose(); - _wsServer = null; - _wssServer = null; + if (_server != null) + _server.Stop(); _nextConnectionId = 1; + _server = null; #endif } @@ -223,12 +256,12 @@ public long GetNewConnectionID() public long GetClientRtt() { - throw new System.NotImplementedException(); + return 0; } public long GetServerRtt(long connectionId) { - throw new System.NotImplementedException(); + return 0; } } } diff --git a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs index 8da7f92a..21431eff 100644 --- a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs +++ b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs @@ -2,13 +2,18 @@ { public class WebSocketTransportFactory : BaseTransportFactory, IWebSocketTransportFactory { - public bool Secure { get; set; } - public string CertificateFilePath { get; set; } = string.Empty; - public string CertificatePassword { get; set; } = string.Empty; + public bool secure = false; + public string certificateFilePath = string.Empty; + public string certificatePassword = string.Empty; + public string certificateBase64String = string.Empty; + public bool Secure { get { return secure; } set { secure = value; } } + public string CertificateFilePath { get { return certificateFilePath; } set { certificateFilePath = value; } } + public string CertificatePassword { get { return certificatePassword; } set { certificatePassword = value; } } + public string CertificateBase64String { get { return certificateBase64String; } set { certificateBase64String = value; } } public override ITransport Build() { - return new WebSocketTransport(Secure, CertificateFilePath, CertificatePassword); + return new WebSocketTransport(secure, certificateFilePath, certificatePassword, certificateBase64String); } } } diff --git a/Scripts/Transports/WebSocket/WsClientWrapper.cs b/Scripts/Transports/WebSocket/WsClientWrapper.cs deleted file mode 100644 index cbe8fed0..00000000 --- a/Scripts/Transports/WebSocket/WsClientWrapper.cs +++ /dev/null @@ -1,227 +0,0 @@ -using LiteNetLib; -using System.Net.Security; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; -using System.Collections.Concurrent; -using LiteNetLib.Utils; -using System.Net; -using System.Net.Sockets; -using System; -using System.Runtime.InteropServices; -using System.Text; -#if !UNITY_WEBGL || UNITY_EDITOR -using NetCoreServer; -#endif - -namespace LiteNetLibManager -{ - public class WsClientWrapper - { -#if UNITY_WEBGL && !UNITY_EDITOR - [DllImport("__Internal")] - private static extern int SocketCreate_LnlM(string url); - [DllImport("__Internal")] - private static extern int GetSocketState_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern int GetSocketEventType_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern int GetSocketErrorCode_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern int GetSocketDataLength_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern void GetSocketData_LnlM(int wsNativeInstance, byte[] ptr, int length); - [DllImport("__Internal")] - private static extern void SocketEventDequeue_LnlM(int wsNativeInstance); - [DllImport("__Internal")] - private static extern void SocketSend_LnlM(int wsNativeInstance, byte[] ptr, int length); - [DllImport("__Internal")] - private static extern void SocketClose_LnlM(int wsNativeInstance); - - private int wsNativeInstance = -1; - private byte[] tempBuffers; - private bool dirtyIsConnected = false; -#endif - -#if !UNITY_WEBGL || UNITY_EDITOR - private WsTransportClient wsClient; - private WssTransportClient wssClient; -#endif - private readonly ConcurrentQueue clientEventQueue; - private readonly bool secure; - private readonly SslProtocols sslProtocols; - - public bool IsClientStarted - { - get - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (secure) - return wssClient != null && wssClient.IsConnected; - else - return wsClient != null && wsClient.IsConnected; -#else - return GetSocketState_LnlM(wsNativeInstance) == 1; -#endif - } - } - - public WsClientWrapper(ConcurrentQueue clientEventQueue, bool secure, SslProtocols sslProtocols) - { - this.clientEventQueue = clientEventQueue; - this.secure = secure; - this.sslProtocols = sslProtocols; - } - - public bool StartClient(string address, int port) - { - if (IsClientStarted) - { - Logging.Log(nameof(WsClientWrapper), "Client started, so it can't be started again"); - return false; - } -#if !UNITY_WEBGL || UNITY_EDITOR - IPAddress[] ipAddresses = Dns.GetHostAddresses(address); - if (ipAddresses.Length == 0) - { - Logging.Log(nameof(WsClientWrapper), "Cannot find IP addresses from " + address); - return false; - } - - int indexOfAddress = -1; - for (int i = 0; i < ipAddresses.Length; ++i) - { - if (ipAddresses[i].AddressFamily == AddressFamily.InterNetwork) - { - indexOfAddress = i; - break; - } - } - - if (indexOfAddress < 0) - { - Logging.Log(nameof(WsClientWrapper), "Cannot find index of address from " + address); - return false; - } - - string url = (secure ? "wss://" : "ws://") + ipAddresses[indexOfAddress] + ":" + port; - Logging.Log(nameof(WsClientWrapper), $"Connecting to {url}"); - if (secure) - { - SslContext context = new SslContext(sslProtocols, new X509Certificate2(), CertValidationCallback); - wssClient = new WssTransportClient(clientEventQueue, context, ipAddresses[indexOfAddress], port); - wssClient.OptionDualMode = true; - wssClient.OptionNoDelay = true; - return wssClient.ConnectAsync(); - } - else - { - wsClient = new WsTransportClient(clientEventQueue, ipAddresses[indexOfAddress], port); - wsClient.OptionDualMode = true; - wsClient.OptionNoDelay = true; - return wsClient.ConnectAsync(); - } -#else - string url = (secure ? "wss://" : "ws://") + address + ":" + port; - Logging.Log(nameof(WsClientWrapper), $"Connecting to {url}"); - wsNativeInstance = SocketCreate_LnlM(url.ToString()); - return true; -#endif - } - - public void StopClient() - { -#if !UNITY_WEBGL || UNITY_EDITOR - if (wssClient != null) - wssClient.Dispose(); - wssClient = null; - if (wsClient != null) - wsClient.Dispose(); - wsClient = null; -#else - SocketClose_LnlM(wsNativeInstance); -#endif - } - - private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - return true; - } - - public bool ClientReceive(out TransportEventData eventData) - { - eventData = default(TransportEventData); -#if !UNITY_WEBGL || UNITY_EDITOR - if (clientEventQueue.Count == 0) - return false; - return clientEventQueue.TryDequeue(out eventData); -#else - int eventType = GetSocketEventType_LnlM(wsNativeInstance); - if (eventType < 0) - return false; - switch ((ENetworkEvent)eventType) - { - case ENetworkEvent.DataEvent: - eventData.type = ENetworkEvent.DataEvent; - eventData.reader = new NetDataReader(GetSocketData()); - break; - case ENetworkEvent.ConnectEvent: - eventData.type = ENetworkEvent.ConnectEvent; - break; - case ENetworkEvent.DisconnectEvent: - eventData.type = ENetworkEvent.DisconnectEvent; - eventData.disconnectInfo = GetDisconnectInfo(GetSocketErrorCode_LnlM(wsNativeInstance)); - break; - case ENetworkEvent.ErrorEvent: - eventData.type = ENetworkEvent.ErrorEvent; - eventData.errorMessage = GetErrorMessage(GetSocketErrorCode_LnlM(wsNativeInstance)); - break; - } - SocketEventDequeue_LnlM(wsNativeInstance); - return true; -#endif - } - -#if UNITY_WEBGL && !UNITY_EDITOR - private byte[] GetSocketData() - { - int length = GetSocketDataLength_LnlM(wsNativeInstance); - if (length == 0) - return null; - byte[] buffer = new byte[length]; - GetSocketData_LnlM(wsNativeInstance, buffer, length); - return buffer; - } -#endif - -#if UNITY_WEBGL && !UNITY_EDITOR - public string GetErrorMessage(int errorCode) - { - // TODO: Implement this - return string.Empty; - } -#endif - -#if UNITY_WEBGL && !UNITY_EDITOR - public DisconnectInfo GetDisconnectInfo(int errorCode) - { - // TODO: Implement this - return default; - } -#endif - - public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) - { - if (!IsClientStarted) - return false; -#if !UNITY_WEBGL || UNITY_EDITOR - if (secure) - return wssClient.SendBinaryAsync(writer.Data, 0, writer.Data.Length); - else - return wsClient.SendBinaryAsync(writer.Data, 0, writer.Data.Length); -#else - SocketSend_LnlM(wsNativeInstance, writer.Data, writer.Data.Length); - return true; -#endif - } - } -} diff --git a/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta b/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta deleted file mode 100644 index c3a2e414..00000000 --- a/Scripts/Transports/WebSocket/WsClientWrapper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9e3299f36c6c27e47935f2cf0616dfde -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsTransportClient.cs b/Scripts/Transports/WebSocket/WsTransportClient.cs deleted file mode 100644 index 8c988d70..00000000 --- a/Scripts/Transports/WebSocket/WsTransportClient.cs +++ /dev/null @@ -1,80 +0,0 @@ -using LiteNetLib.Utils; -using NetCoreServer; -using System; -using System.Collections.Concurrent; -using System.Net; -using System.Net.Sockets; -using HttpRequest = NetCoreServer.HttpRequest; -using HttpResponse = NetCoreServer.HttpResponse; - -namespace LiteNetLibManager -{ - public class WsTransportClient : WsClient - { - private readonly ConcurrentQueue eventQueue; - - public WsTransportClient(ConcurrentQueue eventQueue, IPAddress address, int port) : base(address, port) - { - this.eventQueue = eventQueue; - } - - public override void OnWsConnecting(HttpRequest request) - { - Uri uri = new Uri($"wss://{((IPEndPoint)Endpoint).Address}:{((IPEndPoint)Endpoint).Port}"); - request.SetBegin("GET", uri.PathAndQuery); - request.SetHeader("Host", ((IPEndPoint)Endpoint).Port == 80 ? uri.DnsSafeHost : uri.Authority); - request.SetHeader("Upgrade", "websocket"); - request.SetHeader("Connection", "Upgrade"); - request.SetHeader("Sec-WebSocket-Key", Convert.ToBase64String(WsNonce)); - request.SetHeader("Sec-WebSocket-Version", "13"); - request.Cache.Append("\r\n"); - } - - public override void OnWsConnected(HttpResponse response) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ConnectEvent, - }); - } - - protected override void OnDisconnected() - { - base.OnDisconnected(); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DisconnectEvent, - }); - } - - public override void OnWsError(string error) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - errorMessage = error, - }); - } - - protected override void OnError(SocketError error) - { - base.OnError(error); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - socketError = error, - }); - } - - public override void OnWsReceived(byte[] buffer, long offset, long size) - { - byte[] coppiedBuffer = new byte[size]; - Array.Copy(buffer, offset, coppiedBuffer, 0, size); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(coppiedBuffer), - }); - } - } -} diff --git a/Scripts/Transports/WebSocket/WsTransportClient.cs.meta b/Scripts/Transports/WebSocket/WsTransportClient.cs.meta deleted file mode 100644 index f9adf82a..00000000 --- a/Scripts/Transports/WebSocket/WsTransportClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ced6efcdfe0e93142ac54704ee49777c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WsTransportServer.cs b/Scripts/Transports/WebSocket/WsTransportServer.cs deleted file mode 100644 index 26544374..00000000 --- a/Scripts/Transports/WebSocket/WsTransportServer.cs +++ /dev/null @@ -1,52 +0,0 @@ -using NetCoreServer; -using System.Collections.Concurrent; -using System.Net; - -namespace LiteNetLibManager -{ - public class WsTransportServer : WsServer - { - public ConcurrentDictionary AcceptedClients { get; private set; } - public ConcurrentQueue EventQueue { get; private set; } - public int PeersCount { get { return AcceptedClients.Count; } } - public int MaxConnections { get; private set; } - - private ITransportConnectionGenerator connectionGenerator; - - public WsTransportServer(ITransportConnectionGenerator connectionGenerator, IPAddress address, int port, int maxConnections) : base(address, port) - { - this.connectionGenerator = connectionGenerator; - AcceptedClients = new ConcurrentDictionary(); - EventQueue = new ConcurrentQueue(); - MaxConnections = maxConnections; - } - - protected override TcpSession CreateSession() - { - WsTransportSession newSession = new WsTransportSession(connectionGenerator.GetNewConnectionID(), this); - if (PeersCount >= MaxConnections) - { - newSession.Disconnect(); - return null; - } - AcceptedClients.TryAdd(newSession.ConnectionId, newSession); - return newSession; - } - - internal bool SendAsync(long connectionId, byte[] buffer) - { - return AcceptedClients.ContainsKey(connectionId) && AcceptedClients[connectionId].SendBinaryAsync(buffer, 0, buffer.Length); - } - - internal bool Disconnect(long connectionId) - { - WsTransportSession session; - if (AcceptedClients.TryRemove(connectionId, out session)) - { - session.Dispose(); - return true; - } - return false; - } - } -} diff --git a/Scripts/Transports/WebSocket/WsTransportSession.cs b/Scripts/Transports/WebSocket/WsTransportSession.cs deleted file mode 100644 index 0b1875fd..00000000 --- a/Scripts/Transports/WebSocket/WsTransportSession.cs +++ /dev/null @@ -1,77 +0,0 @@ -using LiteNetLib.Utils; -using NetCoreServer; -using System; -using System.Net.Sockets; -using HttpRequest = NetCoreServer.HttpRequest; - -namespace LiteNetLibManager -{ - public class WsTransportSession : WsSession - { - public long ConnectionId { get; private set; } - - private readonly WsTransportServer _server; - - public WsTransportSession(long connectionId, WsTransportServer server) : base(server) - { - ConnectionId = connectionId; - _server = server; - } - - public override void OnWsConnected(HttpRequest request) - { - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ConnectEvent, - }); - } - - protected override void OnDisconnected() - { - base.OnDisconnected(); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.DisconnectEvent, - disconnectInfo = new LiteNetLib.DisconnectInfo() - { - Reason = LiteNetLib.DisconnectReason.RemoteConnectionClose, - }, - }); - } - - public override void OnWsError(string error) - { - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ErrorEvent, - errorMessage = error, - }); - } - - protected override void OnError(SocketError error) - { - base.OnError(error); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ErrorEvent, - socketError = error, - }); - } - - public override void OnWsReceived(byte[] buffer, long offset, long size) - { - byte[] coppiedBuffer = new byte[size]; - Array.Copy(buffer, offset, coppiedBuffer, 0, size); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(coppiedBuffer), - }); - } - } -} diff --git a/Scripts/Transports/WebSocket/WsTransportSession.cs.meta b/Scripts/Transports/WebSocket/WsTransportSession.cs.meta deleted file mode 100644 index 1577484e..00000000 --- a/Scripts/Transports/WebSocket/WsTransportSession.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 28d95ae7bbc891b48b174d9bb18d7297 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportClient.cs b/Scripts/Transports/WebSocket/WssTransportClient.cs deleted file mode 100644 index eaaa34e4..00000000 --- a/Scripts/Transports/WebSocket/WssTransportClient.cs +++ /dev/null @@ -1,80 +0,0 @@ -using LiteNetLib.Utils; -using NetCoreServer; -using System; -using System.Collections.Concurrent; -using System.Net; -using System.Net.Sockets; -using HttpRequest = NetCoreServer.HttpRequest; -using HttpResponse = NetCoreServer.HttpResponse; - -namespace LiteNetLibManager -{ - public class WssTransportClient : WssClient - { - private readonly ConcurrentQueue eventQueue; - - public WssTransportClient(ConcurrentQueue eventQueue, SslContext context, IPAddress address, int port) : base(context, address, port) - { - this.eventQueue = eventQueue; - } - - public override void OnWsConnecting(HttpRequest request) - { - Uri uri = new Uri($"wss://{((IPEndPoint)Endpoint).Address}:{((IPEndPoint)Endpoint).Port}"); - request.SetBegin("GET", uri.PathAndQuery); - request.SetHeader("Host", ((IPEndPoint)Endpoint).Port == 443 ? uri.DnsSafeHost : uri.Authority); - request.SetHeader("Upgrade", "websocket"); - request.SetHeader("Connection", "Upgrade"); - request.SetHeader("Sec-WebSocket-Key", Convert.ToBase64String(WsNonce)); - request.SetHeader("Sec-WebSocket-Version", "13"); - request.Cache.Append("\r\n"); - } - - public override void OnWsConnected(HttpResponse response) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ConnectEvent, - }); - } - - protected override void OnDisconnected() - { - base.OnDisconnected(); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DisconnectEvent, - }); - } - - public override void OnWsError(string error) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - errorMessage = error, - }); - } - - protected override void OnError(SocketError error) - { - base.OnError(error); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - socketError = error, - }); - } - - public override void OnWsReceived(byte[] buffer, long offset, long size) - { - byte[] coppiedBuffer = new byte[size]; - Array.Copy(buffer, offset, coppiedBuffer, 0, size); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(coppiedBuffer), - }); - } - } -} diff --git a/Scripts/Transports/WebSocket/WssTransportClient.cs.meta b/Scripts/Transports/WebSocket/WssTransportClient.cs.meta deleted file mode 100644 index cc6432f7..00000000 --- a/Scripts/Transports/WebSocket/WssTransportClient.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 411ce407868cabf48b577e10208c7de6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportServer.cs b/Scripts/Transports/WebSocket/WssTransportServer.cs deleted file mode 100644 index 7d103cbc..00000000 --- a/Scripts/Transports/WebSocket/WssTransportServer.cs +++ /dev/null @@ -1,52 +0,0 @@ -using NetCoreServer; -using System.Collections.Concurrent; -using System.Net; - -namespace LiteNetLibManager -{ - public class WssTransportServer : WssServer - { - public ConcurrentDictionary AcceptedClients { get; private set; } - public ConcurrentQueue EventQueue { get; private set; } - public int PeersCount { get { return AcceptedClients.Count; } } - public int MaxConnections { get; private set; } - - private ITransportConnectionGenerator connectionGenerator; - - public WssTransportServer(ITransportConnectionGenerator connectionGenerator, SslContext context, IPAddress address, int port, int maxConnections) : base(context, address, port) - { - this.connectionGenerator = connectionGenerator; - AcceptedClients = new ConcurrentDictionary(); - EventQueue = new ConcurrentQueue(); - MaxConnections = maxConnections; - } - - protected override SslSession CreateSession() - { - WssTransportSession newSession = new WssTransportSession(connectionGenerator.GetNewConnectionID(), this); - if (PeersCount >= MaxConnections) - { - newSession.Disconnect(); - return null; - } - AcceptedClients.TryAdd(newSession.ConnectionId, newSession); - return newSession; - } - - internal bool SendAsync(long connectionId, byte[] buffer) - { - return AcceptedClients.ContainsKey(connectionId) && AcceptedClients[connectionId].SendBinaryAsync(buffer, 0, buffer.Length); - } - - internal bool Disconnect(long connectionId) - { - WssTransportSession session; - if (AcceptedClients.TryRemove(connectionId, out session)) - { - session.Dispose(); - return true; - } - return false; - } - } -} diff --git a/Scripts/Transports/WebSocket/WssTransportServer.cs.meta b/Scripts/Transports/WebSocket/WssTransportServer.cs.meta deleted file mode 100644 index bd3ef160..00000000 --- a/Scripts/Transports/WebSocket/WssTransportServer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 84aec65ce7a649e4b8f3cc4fb192f821 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Transports/WebSocket/WssTransportSession.cs b/Scripts/Transports/WebSocket/WssTransportSession.cs deleted file mode 100644 index b1b02ae3..00000000 --- a/Scripts/Transports/WebSocket/WssTransportSession.cs +++ /dev/null @@ -1,77 +0,0 @@ -using LiteNetLib.Utils; -using NetCoreServer; -using System; -using System.Net.Sockets; -using HttpRequest = NetCoreServer.HttpRequest; - -namespace LiteNetLibManager -{ - public class WssTransportSession : WssSession - { - public long ConnectionId { get; private set; } - - private readonly WssTransportServer _server; - - public WssTransportSession(long connectionId, WssTransportServer server) : base(server) - { - ConnectionId = connectionId; - _server = server; - } - - public override void OnWsConnected(HttpRequest request) - { - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ConnectEvent, - }); - } - - protected override void OnDisconnected() - { - base.OnDisconnected(); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.DisconnectEvent, - disconnectInfo = new LiteNetLib.DisconnectInfo() - { - Reason = LiteNetLib.DisconnectReason.RemoteConnectionClose, - }, - }); - } - - public override void OnWsError(string error) - { - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ErrorEvent, - errorMessage = error, - }); - } - - protected override void OnError(SocketError error) - { - base.OnError(error); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.ErrorEvent, - socketError = error, - }); - } - - public override void OnWsReceived(byte[] buffer, long offset, long size) - { - byte[] coppiedBuffer = new byte[size]; - Array.Copy(buffer, offset, coppiedBuffer, 0, size); - _server.EventQueue.Enqueue(new TransportEventData() - { - connectionId = ConnectionId, - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(coppiedBuffer), - }); - } - } -} From e0a39151f374db52cedfd0cd6c7a723124e7ab27 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 21:24:11 +0700 Subject: [PATCH 50/58] feat: change web socket transport implementation --- .../Transports/MixTransport/MixTransport.cs | 275 ++++++++---------- .../MixTransport/MixTransportFactory.cs | 25 +- 2 files changed, 144 insertions(+), 156 deletions(-) diff --git a/Scripts/Transports/MixTransport/MixTransport.cs b/Scripts/Transports/MixTransport/MixTransport.cs index a0861c33..313b12d2 100644 --- a/Scripts/Transports/MixTransport/MixTransport.cs +++ b/Scripts/Transports/MixTransport/MixTransport.cs @@ -1,32 +1,33 @@ using System.Collections.Generic; -using LiteNetLib; -using LiteNetLib.Utils; -using System.Collections.Concurrent; using System.Net; -using System.Net.Security; -using System.Security.Authentication; +using System.Net.Sockets; using System.Security.Cryptography.X509Certificates; -using System.Threading; +using LiteNetLib; +using LiteNetLib.Utils; #if !UNITY_WEBGL || UNITY_EDITOR -using NetCoreServer; +using WebSocketSharp; +using WebSocketSharp.Server; #endif namespace LiteNetLibManager { - public sealed class MixTransport : ITransport, ITransportConnectionGenerator + public sealed class MixTransport : ITransport { - private long _nextConnectionId = 1; - private bool _webSocketSecure; - private string _webSocketCertificateFilePath; - private string _webSocketCertificatePassword; + private long nextConnectionId = 1; + private long tempConnectionId; + private bool webSocketSecure; + private string webSocketCertificateFilePath; + private string webSocketCertificatePassword; // WebSocket data #if UNITY_WEBGL - private WsClientWrapper _wsClient; + private byte[] tempBuffers; + private bool wsDirtyIsConnected; + private WebSocket wsClient; #endif #if !UNITY_WEBGL || UNITY_EDITOR - private WsTransportServer _wsServer; - private WssTransportServer _wssServer; + private WebSocketServer wsServer; + private readonly Dictionary wsServerPeers; #endif // LiteNetLib data @@ -41,15 +42,12 @@ public int ServerPeersCount if (Server != null) result += Server.ConnectedPeersCount; #if !UNITY_WEBGL - if (!_webSocketSecure) + if (wsServer != null) { - if (_wsServer != null) - result += _wsServer.PeersCount; - } - else - { - if (_wssServer != null) - result += _wssServer.PeersCount; + foreach (WebSocketServiceHost host in wsServer.WebSocketServices.Hosts) + { + result += host.Sessions.Count; + } } #endif return result; @@ -61,7 +59,7 @@ public bool IsClientStarted get { #if UNITY_WEBGL - return _wsClient.IsClientStarted; + return wsClient != null && wsClient.IsConnected; #else return Client != null && Client.FirstPeer != null && Client.FirstPeer.ConnectionState == ConnectionState.Connected; #endif @@ -75,57 +73,52 @@ public bool IsServerStarted // Don't integrate server networking to WebGL clients return false; #else - if (Server == null) - return false; - if (!_webSocketSecure) - return _wsServer != null && _wsServer.IsStarted; - else - return _wssServer != null && _wssServer.IsStarted; + return wsServer != null && Server != null; #endif } } - public bool HasImplementedPing - { - get - { -#if UNITY_WEBGL - return false; -#else - return true; -#endif - } - } + public bool HasImplementedPing => false; + + private readonly Dictionary serverPeers; + private readonly Queue clientEventQueue; + private readonly Queue serverEventQueue; + private readonly byte clientDataChannelsCount; + private readonly byte serverDataChannelsCount; - private readonly Dictionary _serverPeers = new Dictionary(); - private readonly ConcurrentQueue _clientEventQueue = new ConcurrentQueue(); - private readonly ConcurrentQueue _serverEventQueue = new ConcurrentQueue(); - private readonly byte _clientDataChannelsCount; - private readonly byte _serverDataChannelsCount; - private readonly int _webSocketPortOffset; + private readonly int webSocketPortOffset; public MixTransport(string connectKey, int webSocketPortOffset, bool webSocketSecure, string webSocketCertificateFilePath, string webSocketCertificatePassword, byte clientDataChannelsCount, byte serverDataChannelsCount) { ConnectKey = connectKey; - _clientDataChannelsCount = clientDataChannelsCount; - _serverDataChannelsCount = serverDataChannelsCount; - _webSocketPortOffset = webSocketPortOffset; - _webSocketSecure = webSocketSecure; - _webSocketCertificateFilePath = webSocketCertificateFilePath; - _webSocketCertificatePassword = webSocketCertificatePassword; -#if UNITY_WEBGL - _wsClient = new WsClientWrapper(_clientEventQueue, webSocketSecure, SslProtocols.Tls12); +#if !UNITY_WEBGL + wsServerPeers = new Dictionary(); + serverPeers = new Dictionary(); + clientEventQueue = new Queue(); + serverEventQueue = new Queue(); + this.clientDataChannelsCount = clientDataChannelsCount; + this.serverDataChannelsCount = serverDataChannelsCount; #endif + this.webSocketPortOffset = webSocketPortOffset; + this.webSocketSecure = webSocketSecure; + this.webSocketCertificateFilePath = webSocketCertificateFilePath; + this.webSocketCertificatePassword = webSocketCertificatePassword; } public bool StartClient(string address, int port) { - while (_clientEventQueue.TryDequeue(out _)) { } #if UNITY_WEBGL - return _wsClient.StartClient(address, port); + wsDirtyIsConnected = false; + int wsPort = port + webSocketPortOffset; + string url = (webSocketSecure ? "wss://" : "ws://") + address + ":" + port; + Logging.Log(nameof(MixTransport), $"Connecting to {url}"); + wsClient = new WebSocket(new System.Uri(url)); + wsClient.Connect(); + return true; #else - Client = new NetManager(new MixTransportEventListener(this, _clientEventQueue)); - Client.ChannelsCount = _clientDataChannelsCount; + clientEventQueue.Clear(); + Client = new NetManager(new LiteNetLibTransportClientEventListener(clientEventQueue)); + Client.ChannelsCount = clientDataChannelsCount; return Client.Start() && Client.Connect(address, port, ConnectKey) != null; #endif } @@ -133,7 +126,9 @@ public bool StartClient(string address, int port) public void StopClient() { #if UNITY_WEBGL - _wsClient.StopClient(); + if (wsClient != null) + wsClient.Close(); + wsClient = null; #else if (Client != null) Client.Stop(); @@ -145,29 +140,61 @@ public bool ClientReceive(out TransportEventData eventData) { eventData = default(TransportEventData); #if UNITY_WEBGL - return _wsClient.ClientReceive(out eventData); + if (wsClient == null) + return false; + if (wsDirtyIsConnected != wsClient.IsConnected) + { + wsDirtyIsConnected = wsClient.IsConnected; + if (wsClient.IsConnected) + { + // Connect state changed to connected, so it's connect event + eventData.type = ENetworkEvent.ConnectEvent; + } + else + { + // Connect state changed to not connected, so it's disconnect event + eventData.type = ENetworkEvent.DisconnectEvent; + } + return true; + } + else + { + tempBuffers = wsClient.Recv(); + if (tempBuffers != null) + { + eventData.type = ENetworkEvent.DataEvent; + eventData.reader = new NetDataReader(tempBuffers); + return true; + } + } + return false; #else if (Client == null) return false; Client.PollEvents(); - if (_clientEventQueue.Count == 0) + if (clientEventQueue.Count == 0) return false; - return _clientEventQueue.TryDequeue(out eventData); + eventData = clientEventQueue.Dequeue(); + return true; #endif } public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { #if UNITY_WEBGL - return _wsClient.ClientSend(dataChannel, deliveryMethod, writer); + if (IsClientStarted) + { + wsClient.Send(writer.Data); + return true; + } #else if (IsClientStarted) { Client.FirstPeer.Send(writer, dataChannel, deliveryMethod); return true; } - return false; #endif + return false; } public bool StartServer(int port, int maxConnections) @@ -178,42 +205,30 @@ public bool StartServer(int port, int maxConnections) #else if (IsServerStarted) return false; - ServerMaxConnections = maxConnections; - while (_serverEventQueue.TryDequeue(out _)) { } + serverEventQueue.Clear(); // Start WebSocket Server - if (!_webSocketSecure) - { - _wsServer = new WsTransportServer(this, IPAddress.Any, port + _webSocketPortOffset, maxConnections); - _wsServer.OptionDualMode = true; - _wsServer.OptionNoDelay = true; - if (!_wsServer.Start()) - return false; - } - else + wsServerPeers.Clear(); + int wsPort = port + webSocketPortOffset; + wsServer = new WebSocketServer(wsPort, webSocketSecure); + if (webSocketSecure) + wsServer.SslConfiguration.ServerCertificate = new X509Certificate2(webSocketCertificateFilePath, webSocketCertificatePassword); + wsServer.AddWebSocketService("/", (behavior) => { - SslContext context = new SslContext(SslProtocols.Tls12, new X509Certificate2(_webSocketCertificateFilePath, _webSocketCertificatePassword), CertValidationCallback); - _wssServer = new WssTransportServer(this, context, IPAddress.Any, port + _webSocketPortOffset, maxConnections); - _wssServer.OptionDualMode = true; - _wssServer.OptionNoDelay = true; - if (!_wssServer.Start()) - return false; - } + tempConnectionId = GetNewConnectionID(); + behavior.Initialize(tempConnectionId, serverEventQueue, wsServerPeers); + }); + wsServer.Start(); // Start LiteNetLib Server - _serverPeers.Clear(); - Server = new NetManager(new MixTransportEventListener(this, _serverEventQueue, _serverPeers)); - Server.ChannelsCount = _serverDataChannelsCount; + serverPeers.Clear(); + Server = new NetManager(new LiteNetLibTransportServerEventListener(this, ConnectKey, serverEventQueue, serverPeers)); + Server.ChannelsCount = serverDataChannelsCount; return Server.Start(port); #endif } - private bool CertValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - return sslPolicyErrors == SslPolicyErrors.None; - } - public bool ServerReceive(out TransportEventData eventData) { eventData = default(TransportEventData); @@ -221,25 +236,13 @@ public bool ServerReceive(out TransportEventData eventData) // Don't integrate server networking to WebGL clients return false; #else - if (!IsServerStarted) + if (wsServer == null || Server == null) return false; - - if (!_webSocketSecure) - { - if (_wsServer.EventQueue.Count > 0) - return _wsServer.EventQueue.TryDequeue(out eventData); - } - else - { - if (_wssServer.EventQueue.Count > 0) - return _wssServer.EventQueue.TryDequeue(out eventData); - } - Server.PollEvents(); - if (_serverEventQueue.Count > 0) - return _serverEventQueue.TryDequeue(out eventData); - - return false; + if (serverEventQueue.Count == 0) + return false; + eventData = serverEventQueue.Dequeue(); + return true; #endif } @@ -247,21 +250,15 @@ public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliv { #if !UNITY_WEBGL // WebSocket Server Send - if (!_webSocketSecure) + if (IsServerStarted && wsServerPeers.ContainsKey(connectionId) && wsServerPeers[connectionId].ConnectionState == WebSocketState.Open) { - if (_wsServer != null && _wsServer.SendAsync(connectionId, writer.Data)) - return true; - } - else - { - if (_wssServer != null && _wssServer.SendAsync(connectionId, writer.Data)) - return true; + wsServerPeers[connectionId].Context.WebSocket.Send(writer.Data); + return true; } - // LiteNetLib Server Send - if (IsServerStarted && _serverPeers.ContainsKey(connectionId) && _serverPeers[connectionId].ConnectionState == ConnectionState.Connected) + if (IsServerStarted && serverPeers.ContainsKey(connectionId) && serverPeers[connectionId].ConnectionState == ConnectionState.Connected) { - _serverPeers[connectionId].Send(writer, dataChannel, deliveryMethod); + serverPeers[connectionId].Send(writer, dataChannel, deliveryMethod); return true; } #endif @@ -272,22 +269,17 @@ public bool ServerDisconnect(long connectionId) { #if !UNITY_WEBGL // WebSocket Server Disconnect - if (!_webSocketSecure) - { - if (_wsServer != null && _wsServer.Disconnect(connectionId)) - return true; - } - else + if (IsServerStarted && wsServerPeers.ContainsKey(connectionId)) { - if (_wssServer != null && _wssServer.Disconnect(connectionId)) - return true; + wsServerPeers[connectionId].Context.WebSocket.Close(); + wsServerPeers.Remove(connectionId); + return true; } - // LiteNetLib Server Disconnect - if (IsServerStarted && _serverPeers.ContainsKey(connectionId)) + if (IsServerStarted && serverPeers.ContainsKey(connectionId)) { - Server.DisconnectPeer(_serverPeers[connectionId]); - _serverPeers.Remove(connectionId); + Server.DisconnectPeer(serverPeers[connectionId]); + serverPeers.Remove(connectionId); return true; } #endif @@ -297,16 +289,13 @@ public bool ServerDisconnect(long connectionId) public void StopServer() { #if !UNITY_WEBGL - if (_wsServer != null) - _wsServer.Dispose(); - if (_wssServer != null) - _wssServer.Dispose(); - _wsServer = null; - _wssServer = null; + if (wsServer != null) + wsServer.Stop(); + wsServer = null; if (Server != null) Server.Stop(); Server = null; - _nextConnectionId = 1; + nextConnectionId = 1; #endif } @@ -318,25 +307,17 @@ public void Destroy() public long GetNewConnectionID() { - return Interlocked.Increment(ref _nextConnectionId); + return nextConnectionId++; } public long GetClientRtt() { -#if UNITY_WEBGL return 0; -#else - return Client.FirstPeer.RoundTripTime; -#endif } public long GetServerRtt(long connectionId) { -#if UNITY_WEBGL return 0; -#else - return _serverPeers[connectionId].RoundTripTime; -#endif } } } diff --git a/Scripts/Transports/MixTransport/MixTransportFactory.cs b/Scripts/Transports/MixTransport/MixTransportFactory.cs index 961f498f..d3ad93b5 100644 --- a/Scripts/Transports/MixTransport/MixTransportFactory.cs +++ b/Scripts/Transports/MixTransport/MixTransportFactory.cs @@ -1,19 +1,26 @@ -namespace LiteNetLibManager +using UnityEngine; + +namespace LiteNetLibManager { public class MixTransportFactory : BaseTransportFactory, IWebSocketTransportFactory { - public string ConnectKey { get; set; } = "SampleConnectKey"; - public int WebSocketPortOffset { get; set; } = 100; - public byte ClientDataChannelsCount { get; set; } = 16; - public byte ServerDataChannelsCount { get; set; } = 16; - public bool Secure { get; set; } - public string CertificateFilePath { get; set; } = string.Empty; - public string CertificatePassword { get; set; } = string.Empty; + public string connectKey = "SampleConnectKey"; + public int webSocketPortOffset = 100; + public bool webSocketSecure = false; + public string webSocketCertificateFilePath = string.Empty; + public string webSocketCertificatePassword = string.Empty; + [Range(1, 64)] + public byte clientDataChannelsCount = 16; + [Range(1, 64)] + public byte serverDataChannelsCount = 16; + public bool Secure { get { return webSocketSecure; } set { webSocketSecure = value; } } + public string CertificateFilePath { get { return webSocketCertificateFilePath; } set { webSocketCertificateFilePath = value; } } + public string CertificatePassword { get { return webSocketCertificatePassword; } set { webSocketCertificatePassword = value; } } public override ITransport Build() { - return new MixTransport(ConnectKey, WebSocketPortOffset, Secure, CertificateFilePath, CertificatePassword, ClientDataChannelsCount, ServerDataChannelsCount); + return new MixTransport(connectKey, webSocketPortOffset, webSocketSecure, webSocketCertificateFilePath, webSocketCertificatePassword, clientDataChannelsCount, serverDataChannelsCount); } } } From 4a7127b6e618fcf7545110dc49930f5febe4d1d3 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 21:43:49 +0700 Subject: [PATCH 51/58] fix: ambiguous codes --- Scripts/Transports/WebSocket/WebSocketServerBehavior.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs b/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs index 5e6f9018..85450d3e 100644 --- a/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs +++ b/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs @@ -44,7 +44,7 @@ protected override void OnMessage(MessageEventArgs e) }); } - protected override void OnError(ErrorEventArgs e) + protected override void OnError(WebSocketSharp.ErrorEventArgs e) { base.OnError(e); eventQueue.Enqueue(new TransportEventData() From 12898f63e88b6de55036c253c484a40386004eae Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 21:44:16 +0700 Subject: [PATCH 52/58] fix: unable to compile codes --- .../MixTransport/MixTransportFactory.cs | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/Scripts/Transports/MixTransport/MixTransportFactory.cs b/Scripts/Transports/MixTransport/MixTransportFactory.cs index d3ad93b5..94315c99 100644 --- a/Scripts/Transports/MixTransport/MixTransportFactory.cs +++ b/Scripts/Transports/MixTransport/MixTransportFactory.cs @@ -1,26 +1,18 @@ -using UnityEngine; - -namespace LiteNetLibManager +namespace LiteNetLibManager { public class MixTransportFactory : BaseTransportFactory, IWebSocketTransportFactory { - public string connectKey = "SampleConnectKey"; - public int webSocketPortOffset = 100; - public bool webSocketSecure = false; - public string webSocketCertificateFilePath = string.Empty; - public string webSocketCertificatePassword = string.Empty; - [Range(1, 64)] - public byte clientDataChannelsCount = 16; - [Range(1, 64)] - public byte serverDataChannelsCount = 16; - public bool Secure { get { return webSocketSecure; } set { webSocketSecure = value; } } - public string CertificateFilePath { get { return webSocketCertificateFilePath; } set { webSocketCertificateFilePath = value; } } - public string CertificatePassword { get { return webSocketCertificatePassword; } set { webSocketCertificatePassword = value; } } - + public string ConnectKey { get; set; } = "SampleConnectKey"; + public int WebSocketPortOffset { get; set; } = 100; + public byte ClientDataChannelsCount { get; set; } = 16; + public byte ServerDataChannelsCount { get; set; } = 16; + public bool Secure { get; set; } + public string CertificateFilePath { get; set; } = string.Empty; + public string CertificatePassword { get; set; } = string.Empty; public override ITransport Build() { - return new MixTransport(connectKey, webSocketPortOffset, webSocketSecure, webSocketCertificateFilePath, webSocketCertificatePassword, clientDataChannelsCount, serverDataChannelsCount); + return new MixTransport(ConnectKey, WebSocketPortOffset, Secure, CertificateFilePath, CertificatePassword, ClientDataChannelsCount, ServerDataChannelsCount); } } } From 7911aa6b7913917eb2c55fdbf457cddbccd3d528 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 22:00:34 +0700 Subject: [PATCH 53/58] Revert "feat: change websocket client" This reverts commit 780e3f902a799ac71d7e6be0010818bdb8ae18ee. --- Plugins/WebSocket/WebSocket.cs | 848 ------------------ Plugins/WebSocket/WebSocket.jslib | 333 ------- Plugins/WebSocket/WebSocket_LnlM.asmdef | 3 + ...asmdef.meta => WebSocket_LnlM.asmdef.meta} | 2 +- Plugins/WebSocket/WebSocket_LnlM.jslib | 143 +++ ...t.jslib.meta => WebSocket_LnlM.jslib.meta} | 0 .../WebSocket/endel.nativewebsocket.asmdef | 3 - .../WebSocket/WssTransportSession.cs.meta | 2 +- 8 files changed, 148 insertions(+), 1186 deletions(-) delete mode 100644 Plugins/WebSocket/WebSocket.cs delete mode 100644 Plugins/WebSocket/WebSocket.jslib create mode 100644 Plugins/WebSocket/WebSocket_LnlM.asmdef rename Plugins/WebSocket/{endel.nativewebsocket.asmdef.meta => WebSocket_LnlM.asmdef.meta} (76%) create mode 100644 Plugins/WebSocket/WebSocket_LnlM.jslib rename Plugins/WebSocket/{WebSocket.jslib.meta => WebSocket_LnlM.jslib.meta} (100%) delete mode 100644 Plugins/WebSocket/endel.nativewebsocket.asmdef rename Plugins/WebSocket/WebSocket.cs.meta => Scripts/Transports/WebSocket/WssTransportSession.cs.meta (83%) diff --git a/Plugins/WebSocket/WebSocket.cs b/Plugins/WebSocket/WebSocket.cs deleted file mode 100644 index 503cf436..00000000 --- a/Plugins/WebSocket/WebSocket.cs +++ /dev/null @@ -1,848 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net.WebSockets; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -using AOT; -using System.Runtime.InteropServices; -using UnityEngine; -using System.Collections; - -public class MainThreadUtil : MonoBehaviour -{ - public static MainThreadUtil Instance { get; private set; } - public static SynchronizationContext synchronizationContext { get; private set; } - - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] - public static void Setup() - { - Instance = new GameObject("MainThreadUtil") - .AddComponent(); - synchronizationContext = SynchronizationContext.Current; - } - - public static void Run(IEnumerator waitForUpdate) - { - synchronizationContext.Post(_ => Instance.StartCoroutine( - waitForUpdate), null); - } - - void Awake() - { - gameObject.hideFlags = HideFlags.HideAndDontSave; - DontDestroyOnLoad(gameObject); - } -} - -public class WaitForUpdate : CustomYieldInstruction -{ - public override bool keepWaiting - { - get { return false; } - } - - public MainThreadAwaiter GetAwaiter() - { - var awaiter = new MainThreadAwaiter(); - MainThreadUtil.Run(CoroutineWrapper(this, awaiter)); - return awaiter; - } - - public class MainThreadAwaiter : INotifyCompletion - { - Action continuation; - - public bool IsCompleted { get; set; } - - public void GetResult() { } - - public void Complete() - { - IsCompleted = true; - continuation?.Invoke(); - } - - void INotifyCompletion.OnCompleted(Action continuation) - { - this.continuation = continuation; - } - } - - public static IEnumerator CoroutineWrapper(IEnumerator theWorker, MainThreadAwaiter awaiter) - { - yield return theWorker; - awaiter.Complete(); - } -} - -namespace NativeWebSocket -{ - public delegate void WebSocketOpenEventHandler(); - public delegate void WebSocketMessageEventHandler(byte[] data); - public delegate void WebSocketErrorEventHandler(string errorMsg); - public delegate void WebSocketCloseEventHandler(WebSocketCloseCode closeCode); - - public enum WebSocketCloseCode - { - /* Do NOT use NotSet - it's only purpose is to indicate that the close code cannot be parsed. */ - NotSet = 0, - Normal = 1000, - Away = 1001, - ProtocolError = 1002, - UnsupportedData = 1003, - Undefined = 1004, - NoStatus = 1005, - Abnormal = 1006, - InvalidData = 1007, - PolicyViolation = 1008, - TooBig = 1009, - MandatoryExtension = 1010, - ServerError = 1011, - TlsHandshakeFailure = 1015 - } - - public enum WebSocketState - { - Connecting, - Open, - Closing, - Closed - } - - public interface IWebSocket - { - event WebSocketOpenEventHandler OnOpen; - event WebSocketMessageEventHandler OnMessage; - event WebSocketErrorEventHandler OnError; - event WebSocketCloseEventHandler OnClose; - - WebSocketState State { get; } - } - - public static class WebSocketHelpers - { - public static WebSocketCloseCode ParseCloseCodeEnum(int closeCode) - { - - if (WebSocketCloseCode.IsDefined(typeof(WebSocketCloseCode), closeCode)) - { - return (WebSocketCloseCode)closeCode; - } - else - { - return WebSocketCloseCode.Undefined; - } - - } - - public static WebSocketException GetErrorMessageFromCode(int errorCode, Exception inner) - { - switch (errorCode) - { - case -1: - return new WebSocketUnexpectedException("WebSocket instance not found.", inner); - case -2: - return new WebSocketInvalidStateException("WebSocket is already connected or in connecting state.", inner); - case -3: - return new WebSocketInvalidStateException("WebSocket is not connected.", inner); - case -4: - return new WebSocketInvalidStateException("WebSocket is already closing.", inner); - case -5: - return new WebSocketInvalidStateException("WebSocket is already closed.", inner); - case -6: - return new WebSocketInvalidStateException("WebSocket is not in open state.", inner); - case -7: - return new WebSocketInvalidArgumentException("Cannot close WebSocket. An invalid code was specified or reason is too long.", inner); - default: - return new WebSocketUnexpectedException("Unknown error.", inner); - } - } - } - - public class WebSocketException : Exception - { - public WebSocketException() { } - public WebSocketException(string message) : base(message) { } - public WebSocketException(string message, Exception inner) : base(message, inner) { } - } - - public class WebSocketUnexpectedException : WebSocketException - { - public WebSocketUnexpectedException() { } - public WebSocketUnexpectedException(string message) : base(message) { } - public WebSocketUnexpectedException(string message, Exception inner) : base(message, inner) { } - } - - public class WebSocketInvalidArgumentException : WebSocketException - { - public WebSocketInvalidArgumentException() { } - public WebSocketInvalidArgumentException(string message) : base(message) { } - public WebSocketInvalidArgumentException(string message, Exception inner) : base(message, inner) { } - } - - public class WebSocketInvalidStateException : WebSocketException - { - public WebSocketInvalidStateException() { } - public WebSocketInvalidStateException(string message) : base(message) { } - public WebSocketInvalidStateException(string message, Exception inner) : base(message, inner) { } - } - - public class WaitForBackgroundThread - { - public ConfiguredTaskAwaitable.ConfiguredTaskAwaiter GetAwaiter() - { - return Task.Run(() => { }).ConfigureAwait(false).GetAwaiter(); - } - } - -#if UNITY_WEBGL && !UNITY_EDITOR - - /// - /// WebSocket class bound to JSLIB. - /// - public class WebSocket : IWebSocket { - - /* WebSocket JSLIB functions */ - [DllImport ("__Internal")] - public static extern int WebSocketConnect (int instanceId); - - [DllImport ("__Internal")] - public static extern int WebSocketClose (int instanceId, int code, string reason); - - [DllImport ("__Internal")] - public static extern int WebSocketSend (int instanceId, byte[] dataPtr, int dataLength); - - [DllImport ("__Internal")] - public static extern int WebSocketSendText (int instanceId, string message); - - [DllImport ("__Internal")] - public static extern int WebSocketGetState (int instanceId); - - protected int instanceId; - - public event WebSocketOpenEventHandler OnOpen; - public event WebSocketMessageEventHandler OnMessage; - public event WebSocketErrorEventHandler OnError; - public event WebSocketCloseEventHandler OnClose; - - public WebSocket (string url, Dictionary headers = null) { - if (!WebSocketFactory.isInitialized) { - WebSocketFactory.Initialize (); - } - - int instanceId = WebSocketFactory.WebSocketAllocate (url); - WebSocketFactory.instances.Add (instanceId, this); - - this.instanceId = instanceId; - } - - public WebSocket (string url, string subprotocol, Dictionary headers = null) { - if (!WebSocketFactory.isInitialized) { - WebSocketFactory.Initialize (); - } - - int instanceId = WebSocketFactory.WebSocketAllocate (url); - WebSocketFactory.instances.Add (instanceId, this); - - WebSocketFactory.WebSocketAddSubProtocol(instanceId, subprotocol); - - this.instanceId = instanceId; - } - - public WebSocket (string url, List subprotocols, Dictionary headers = null) { - if (!WebSocketFactory.isInitialized) { - WebSocketFactory.Initialize (); - } - - int instanceId = WebSocketFactory.WebSocketAllocate (url); - WebSocketFactory.instances.Add (instanceId, this); - - foreach (string subprotocol in subprotocols) { - WebSocketFactory.WebSocketAddSubProtocol(instanceId, subprotocol); - } - - this.instanceId = instanceId; - } - - ~WebSocket () { - WebSocketFactory.HandleInstanceDestroy (this.instanceId); - } - - public int GetInstanceId () { - return this.instanceId; - } - - public Task Connect () { - int ret = WebSocketConnect (this.instanceId); - - if (ret < 0) - throw WebSocketHelpers.GetErrorMessageFromCode (ret, null); - - return Task.CompletedTask; - } - - public void CancelConnection () { - if (State == WebSocketState.Open) - Close (WebSocketCloseCode.Abnormal); - } - - public Task Close (WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null) { - int ret = WebSocketClose (this.instanceId, (int) code, reason); - - if (ret < 0) - throw WebSocketHelpers.GetErrorMessageFromCode (ret, null); - - return Task.CompletedTask; - } - - public Task Send (byte[] data) { - int ret = WebSocketSend (this.instanceId, data, data.Length); - - if (ret < 0) - throw WebSocketHelpers.GetErrorMessageFromCode (ret, null); - - return Task.CompletedTask; - } - - public Task SendText (string message) { - int ret = WebSocketSendText (this.instanceId, message); - - if (ret < 0) - throw WebSocketHelpers.GetErrorMessageFromCode (ret, null); - - return Task.CompletedTask; - } - - public WebSocketState State { - get { - int state = WebSocketGetState (this.instanceId); - - if (state < 0) - throw WebSocketHelpers.GetErrorMessageFromCode (state, null); - - switch (state) { - case 0: - return WebSocketState.Connecting; - - case 1: - return WebSocketState.Open; - - case 2: - return WebSocketState.Closing; - - case 3: - return WebSocketState.Closed; - - default: - return WebSocketState.Closed; - } - } - } - - public void DelegateOnOpenEvent () { - this.OnOpen?.Invoke (); - } - - public void DelegateOnMessageEvent (byte[] data) { - this.OnMessage?.Invoke (data); - } - - public void DelegateOnErrorEvent (string errorMsg) { - this.OnError?.Invoke (errorMsg); - } - - public void DelegateOnCloseEvent (int closeCode) { - this.OnClose?.Invoke (WebSocketHelpers.ParseCloseCodeEnum (closeCode)); - } - - } - -#else - - public class WebSocket : IWebSocket - { - public event WebSocketOpenEventHandler OnOpen; - public event WebSocketMessageEventHandler OnMessage; - public event WebSocketErrorEventHandler OnError; - public event WebSocketCloseEventHandler OnClose; - - private Uri uri; - private Dictionary headers; - private List subprotocols; - private ClientWebSocket m_Socket = new ClientWebSocket(); - - private CancellationTokenSource m_TokenSource; - private CancellationToken m_CancellationToken; - - private readonly object OutgoingMessageLock = new object(); - private readonly object IncomingMessageLock = new object(); - - private bool isSending = false; - private List> sendBytesQueue = new List>(); - private List> sendTextQueue = new List>(); - - public WebSocket(string url, Dictionary headers = null) - { - uri = new Uri(url); - - if (headers == null) - { - this.headers = new Dictionary(); - } - else - { - this.headers = headers; - } - - subprotocols = new List(); - - string protocol = uri.Scheme; - if (!protocol.Equals("ws") && !protocol.Equals("wss")) - throw new ArgumentException("Unsupported protocol: " + protocol); - } - - public WebSocket(string url, string subprotocol, Dictionary headers = null) - { - uri = new Uri(url); - - if (headers == null) - { - this.headers = new Dictionary(); - } - else - { - this.headers = headers; - } - - subprotocols = new List {subprotocol}; - - string protocol = uri.Scheme; - if (!protocol.Equals("ws") && !protocol.Equals("wss")) - throw new ArgumentException("Unsupported protocol: " + protocol); - } - - public WebSocket(string url, List subprotocols, Dictionary headers = null) - { - uri = new Uri(url); - - if (headers == null) - { - this.headers = new Dictionary(); - } - else - { - this.headers = headers; - } - - this.subprotocols = subprotocols; - - string protocol = uri.Scheme; - if (!protocol.Equals("ws") && !protocol.Equals("wss")) - throw new ArgumentException("Unsupported protocol: " + protocol); - } - - public void CancelConnection() - { - m_TokenSource?.Cancel(); - } - - public async Task Connect() - { - try - { - m_TokenSource = new CancellationTokenSource(); - m_CancellationToken = m_TokenSource.Token; - - m_Socket = new ClientWebSocket(); - - foreach (var header in headers) - { - m_Socket.Options.SetRequestHeader(header.Key, header.Value); - } - - foreach (string subprotocol in subprotocols) { - m_Socket.Options.AddSubProtocol(subprotocol); - } - - await m_Socket.ConnectAsync(uri, m_CancellationToken); - OnOpen?.Invoke(); - - await Receive(); - } - catch (Exception ex) - { - OnError?.Invoke(ex.Message); - OnClose?.Invoke(WebSocketCloseCode.Abnormal); - } - finally - { - if (m_Socket != null) - { - m_TokenSource.Cancel(); - m_Socket.Dispose(); - } - } - } - - public WebSocketState State - { - get - { - switch (m_Socket.State) - { - case System.Net.WebSockets.WebSocketState.Connecting: - return WebSocketState.Connecting; - - case System.Net.WebSockets.WebSocketState.Open: - return WebSocketState.Open; - - case System.Net.WebSockets.WebSocketState.CloseSent: - case System.Net.WebSockets.WebSocketState.CloseReceived: - return WebSocketState.Closing; - - case System.Net.WebSockets.WebSocketState.Closed: - return WebSocketState.Closed; - - default: - return WebSocketState.Closed; - } - } - } - - public Task Send(byte[] bytes) - { - // return m_Socket.SendAsync(buffer, WebSocketMessageType.Binary, true, CancellationToken.None); - return SendMessage(sendBytesQueue, WebSocketMessageType.Binary, new ArraySegment(bytes)); - } - - public Task SendText(string message) - { - var encoded = Encoding.UTF8.GetBytes(message); - - // m_Socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); - return SendMessage(sendTextQueue, WebSocketMessageType.Text, new ArraySegment(encoded, 0, encoded.Length)); - } - - private async Task SendMessage(List> queue, WebSocketMessageType messageType, ArraySegment buffer) - { - // Return control to the calling method immediately. - // await Task.Yield (); - - // Make sure we have data. - if (buffer.Count == 0) - { - return; - } - - // The state of the connection is contained in the context Items dictionary. - bool sending; - - lock (OutgoingMessageLock) - { - sending = isSending; - - // If not, we are now. - if (!isSending) - { - isSending = true; - } - } - - if (!sending) - { - // Lock with a timeout, just in case. - if (!Monitor.TryEnter(m_Socket, 1000)) - { - // If we couldn't obtain exclusive access to the socket in one second, something is wrong. - await m_Socket.CloseAsync(WebSocketCloseStatus.InternalServerError, string.Empty, m_CancellationToken); - return; - } - - try - { - // Send the message synchronously. - var t = m_Socket.SendAsync(buffer, messageType, true, m_CancellationToken); - t.Wait(m_CancellationToken); - } - finally - { - Monitor.Exit(m_Socket); - } - - // Note that we've finished sending. - lock (OutgoingMessageLock) - { - isSending = false; - } - - // Handle any queued messages. - await HandleQueue(queue, messageType); - } - else - { - // Add the message to the queue. - lock (OutgoingMessageLock) - { - queue.Add(buffer); - } - } - } - - private async Task HandleQueue(List> queue, WebSocketMessageType messageType) - { - var buffer = new ArraySegment(); - lock (OutgoingMessageLock) - { - // Check for an item in the queue. - if (queue.Count > 0) - { - // Pull it off the top. - buffer = queue[0]; - queue.RemoveAt(0); - } - } - - // Send that message. - if (buffer.Count > 0) - { - await SendMessage(queue, messageType, buffer); - } - } - - private List m_MessageList = new List(); - - // simple dispatcher for queued messages. - public void DispatchMessageQueue() - { - if (m_MessageList.Count == 0) - { - return; - } - - List messageListCopy; - - lock (IncomingMessageLock) - { - messageListCopy = new List(m_MessageList); - m_MessageList.Clear(); - } - - var len = messageListCopy.Count; - for (int i = 0; i < len; i++) - { - OnMessage?.Invoke(messageListCopy[i]); - } - } - - public async Task Receive() - { - WebSocketCloseCode closeCode = WebSocketCloseCode.Abnormal; - await new WaitForBackgroundThread(); - - ArraySegment buffer = new ArraySegment(new byte[8192]); - try - { - while (m_Socket.State == System.Net.WebSockets.WebSocketState.Open) - { - WebSocketReceiveResult result = null; - - using (var ms = new MemoryStream()) - { - do - { - result = await m_Socket.ReceiveAsync(buffer, m_CancellationToken); - ms.Write(buffer.Array, buffer.Offset, result.Count); - } - while (!result.EndOfMessage); - - ms.Seek(0, SeekOrigin.Begin); - - if (result.MessageType == WebSocketMessageType.Text) - { - lock (IncomingMessageLock) - { - m_MessageList.Add(ms.ToArray()); - } - - //using (var reader = new StreamReader(ms, Encoding.UTF8)) - //{ - // string message = reader.ReadToEnd(); - // OnMessage?.Invoke(this, new MessageEventArgs(message)); - //} - } - else if (result.MessageType == WebSocketMessageType.Binary) - { - lock (IncomingMessageLock) - { - m_MessageList.Add(ms.ToArray()); - } - } - else if (result.MessageType == WebSocketMessageType.Close) - { - await Close(); - closeCode = WebSocketHelpers.ParseCloseCodeEnum((int)result.CloseStatus); - break; - } - } - } - } - catch (Exception) - { - m_TokenSource.Cancel(); - } - finally - { - await new WaitForUpdate(); - OnClose?.Invoke(closeCode); - } - } - - public async Task Close() - { - if (State == WebSocketState.Open) - { - await m_Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, m_CancellationToken); - } - } - } -#endif - - /// - /// Factory - /// - - /// - /// Class providing static access methods to work with JSLIB WebSocket or WebSocketSharp interface - /// - public static class WebSocketFactory - { - -#if UNITY_WEBGL && !UNITY_EDITOR - /* Map of websocket instances */ - public static Dictionary instances = new Dictionary (); - - /* Delegates */ - public delegate void OnOpenCallback (int instanceId); - public delegate void OnMessageCallback (int instanceId, System.IntPtr msgPtr, int msgSize); - public delegate void OnErrorCallback (int instanceId, System.IntPtr errorPtr); - public delegate void OnCloseCallback (int instanceId, int closeCode); - - /* WebSocket JSLIB callback setters and other functions */ - [DllImport ("__Internal")] - public static extern int WebSocketAllocate (string url); - - [DllImport ("__Internal")] - public static extern int WebSocketAddSubProtocol (int instanceId, string subprotocol); - - [DllImport ("__Internal")] - public static extern void WebSocketFree (int instanceId); - - [DllImport ("__Internal")] - public static extern void WebSocketSetOnOpen (OnOpenCallback callback); - - [DllImport ("__Internal")] - public static extern void WebSocketSetOnMessage (OnMessageCallback callback); - - [DllImport ("__Internal")] - public static extern void WebSocketSetOnError (OnErrorCallback callback); - - [DllImport ("__Internal")] - public static extern void WebSocketSetOnClose (OnCloseCallback callback); - - /* If callbacks was initialized and set */ - public static bool isInitialized = false; - - /* - * Initialize WebSocket callbacks to JSLIB - */ - public static void Initialize () { - - WebSocketSetOnOpen (DelegateOnOpenEvent); - WebSocketSetOnMessage (DelegateOnMessageEvent); - WebSocketSetOnError (DelegateOnErrorEvent); - WebSocketSetOnClose (DelegateOnCloseEvent); - - isInitialized = true; - - } - - /// - /// Called when instance is destroyed (by destructor) - /// Method removes instance from map and free it in JSLIB implementation - /// - /// Instance identifier. - public static void HandleInstanceDestroy (int instanceId) { - - instances.Remove (instanceId); - WebSocketFree (instanceId); - - } - - [MonoPInvokeCallback (typeof (OnOpenCallback))] - public static void DelegateOnOpenEvent (int instanceId) { - - WebSocket instanceRef; - - if (instances.TryGetValue (instanceId, out instanceRef)) { - instanceRef.DelegateOnOpenEvent (); - } - - } - - [MonoPInvokeCallback (typeof (OnMessageCallback))] - public static void DelegateOnMessageEvent (int instanceId, System.IntPtr msgPtr, int msgSize) { - - WebSocket instanceRef; - - if (instances.TryGetValue (instanceId, out instanceRef)) { - byte[] msg = new byte[msgSize]; - Marshal.Copy (msgPtr, msg, 0, msgSize); - - instanceRef.DelegateOnMessageEvent (msg); - } - - } - - [MonoPInvokeCallback (typeof (OnErrorCallback))] - public static void DelegateOnErrorEvent (int instanceId, System.IntPtr errorPtr) { - - WebSocket instanceRef; - - if (instances.TryGetValue (instanceId, out instanceRef)) { - - string errorMsg = Marshal.PtrToStringAuto (errorPtr); - instanceRef.DelegateOnErrorEvent (errorMsg); - - } - - } - - [MonoPInvokeCallback (typeof (OnCloseCallback))] - public static void DelegateOnCloseEvent (int instanceId, int closeCode) { - - WebSocket instanceRef; - - if (instances.TryGetValue (instanceId, out instanceRef)) { - instanceRef.DelegateOnCloseEvent (closeCode); - } - - } -#endif - - /// - /// Create WebSocket client instance - /// - /// The WebSocket instance. - /// WebSocket valid URL. - public static WebSocket CreateInstance(string url) - { - return new WebSocket(url); - } - - } - -} diff --git a/Plugins/WebSocket/WebSocket.jslib b/Plugins/WebSocket/WebSocket.jslib deleted file mode 100644 index 052f2132..00000000 --- a/Plugins/WebSocket/WebSocket.jslib +++ /dev/null @@ -1,333 +0,0 @@ - -var LibraryWebSocket = { - $webSocketState: { - /* - * Map of instances - * - * Instance structure: - * { - * url: string, - * ws: WebSocket - * } - */ - instances: {}, - - /* Last instance ID */ - lastId: 0, - - /* Event listeners */ - onOpen: null, - onMesssage: null, - onError: null, - onClose: null, - - /* Debug mode */ - debug: false - }, - - /** - * Set onOpen callback - * - * @param callback Reference to C# static function - */ - WebSocketSetOnOpen: function(callback) { - - webSocketState.onOpen = callback; - - }, - - /** - * Set onMessage callback - * - * @param callback Reference to C# static function - */ - WebSocketSetOnMessage: function(callback) { - - webSocketState.onMessage = callback; - - }, - - /** - * Set onError callback - * - * @param callback Reference to C# static function - */ - WebSocketSetOnError: function(callback) { - - webSocketState.onError = callback; - - }, - - /** - * Set onClose callback - * - * @param callback Reference to C# static function - */ - WebSocketSetOnClose: function(callback) { - - webSocketState.onClose = callback; - - }, - - /** - * Allocate new WebSocket instance struct - * - * @param url Server URL - */ - WebSocketAllocate: function(url) { - - var urlStr = UTF8ToString(url); - var id = webSocketState.lastId++; - - webSocketState.instances[id] = { - subprotocols: [], - url: urlStr, - ws: null - }; - - return id; - - }, - - /** - * Add subprotocol to instance - * - * @param instanceId Instance ID - * @param subprotocol Subprotocol name to add to instance - */ - WebSocketAddSubProtocol: function(instanceId, subprotocol) { - - var subprotocolStr = UTF8ToString(subprotocol); - webSocketState.instances[instanceId].subprotocols.push(subprotocolStr); - - }, - - /** - * Remove reference to WebSocket instance - * - * If socket is not closed function will close it but onClose event will not be emitted because - * this function should be invoked by C# WebSocket destructor. - * - * @param instanceId Instance ID - */ - WebSocketFree: function(instanceId) { - - var instance = webSocketState.instances[instanceId]; - - if (!instance) return 0; - - // Close if not closed - if (instance.ws && instance.ws.readyState < 2) - instance.ws.close(); - - // Remove reference - delete webSocketState.instances[instanceId]; - - return 0; - - }, - - /** - * Connect WebSocket to the server - * - * @param instanceId Instance ID - */ - WebSocketConnect: function(instanceId) { - - var instance = webSocketState.instances[instanceId]; - if (!instance) return -1; - - if (instance.ws !== null) - return -2; - - instance.ws = new WebSocket(instance.url, instance.subprotocols); - - instance.ws.binaryType = 'arraybuffer'; - - instance.ws.onopen = function() { - - if (webSocketState.debug) - console.log("[JSLIB WebSocket] Connected."); - - if (webSocketState.onOpen) - Module.dynCall_vi(webSocketState.onOpen, instanceId); - - }; - - instance.ws.onmessage = function(ev) { - - if (webSocketState.debug) - console.log("[JSLIB WebSocket] Received message:", ev.data); - - if (webSocketState.onMessage === null) - return; - - if (ev.data instanceof ArrayBuffer) { - - var dataBuffer = new Uint8Array(ev.data); - - var buffer = _malloc(dataBuffer.length); - HEAPU8.set(dataBuffer, buffer); - - try { - Module.dynCall_viii(webSocketState.onMessage, instanceId, buffer, dataBuffer.length); - } finally { - _free(buffer); - } - - } else { - var dataBuffer = (new TextEncoder()).encode(ev.data); - - var buffer = _malloc(dataBuffer.length); - HEAPU8.set(dataBuffer, buffer); - - try { - Module.dynCall_viii(webSocketState.onMessage, instanceId, buffer, dataBuffer.length); - } finally { - _free(buffer); - } - - } - - }; - - instance.ws.onerror = function(ev) { - - if (webSocketState.debug) - console.log("[JSLIB WebSocket] Error occured."); - - if (webSocketState.onError) { - - var msg = "WebSocket error."; - var length = lengthBytesUTF8(msg) + 1; - var buffer = _malloc(length); - stringToUTF8(msg, buffer, length); - - try { - Module.dynCall_vii(webSocketState.onError, instanceId, buffer); - } finally { - _free(buffer); - } - - } - - }; - - instance.ws.onclose = function(ev) { - - if (webSocketState.debug) - console.log("[JSLIB WebSocket] Closed."); - - if (webSocketState.onClose) - Module.dynCall_vii(webSocketState.onClose, instanceId, ev.code); - - delete instance.ws; - - }; - - return 0; - - }, - - /** - * Close WebSocket connection - * - * @param instanceId Instance ID - * @param code Close status code - * @param reasonPtr Pointer to reason string - */ - WebSocketClose: function(instanceId, code, reasonPtr) { - - var instance = webSocketState.instances[instanceId]; - if (!instance) return -1; - - if (!instance.ws) - return -3; - - if (instance.ws.readyState === 2) - return -4; - - if (instance.ws.readyState === 3) - return -5; - - var reason = ( reasonPtr ? UTF8ToString(reasonPtr) : undefined ); - - try { - instance.ws.close(code, reason); - } catch(err) { - return -7; - } - - return 0; - - }, - - /** - * Send message over WebSocket - * - * @param instanceId Instance ID - * @param bufferPtr Pointer to the message buffer - * @param length Length of the message in the buffer - */ - WebSocketSend: function(instanceId, bufferPtr, length) { - - var instance = webSocketState.instances[instanceId]; - if (!instance) return -1; - - if (!instance.ws) - return -3; - - if (instance.ws.readyState !== 1) - return -6; - - instance.ws.send(HEAPU8.buffer.slice(bufferPtr, bufferPtr + length)); - - return 0; - - }, - - /** - * Send text message over WebSocket - * - * @param instanceId Instance ID - * @param bufferPtr Pointer to the message buffer - * @param length Length of the message in the buffer - */ - WebSocketSendText: function(instanceId, message) { - - var instance = webSocketState.instances[instanceId]; - if (!instance) return -1; - - if (!instance.ws) - return -3; - - if (instance.ws.readyState !== 1) - return -6; - - instance.ws.send(UTF8ToString(message)); - - return 0; - - }, - - /** - * Return WebSocket readyState - * - * @param instanceId Instance ID - */ - WebSocketGetState: function(instanceId) { - - var instance = webSocketState.instances[instanceId]; - if (!instance) return -1; - - if (instance.ws) - return instance.ws.readyState; - else - return 3; - - } - -}; - -autoAddDeps(LibraryWebSocket, '$webSocketState'); -mergeInto(LibraryManager.library, LibraryWebSocket); diff --git a/Plugins/WebSocket/WebSocket_LnlM.asmdef b/Plugins/WebSocket/WebSocket_LnlM.asmdef new file mode 100644 index 00000000..162d95ad --- /dev/null +++ b/Plugins/WebSocket/WebSocket_LnlM.asmdef @@ -0,0 +1,3 @@ +{ + "name": "WebSocket" +} diff --git a/Plugins/WebSocket/endel.nativewebsocket.asmdef.meta b/Plugins/WebSocket/WebSocket_LnlM.asmdef.meta similarity index 76% rename from Plugins/WebSocket/endel.nativewebsocket.asmdef.meta rename to Plugins/WebSocket/WebSocket_LnlM.asmdef.meta index 01d2d89b..e6d36a40 100644 --- a/Plugins/WebSocket/endel.nativewebsocket.asmdef.meta +++ b/Plugins/WebSocket/WebSocket_LnlM.asmdef.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 04376767bc1f3b428aefa3d20743e819 +guid: d969dd435f4843f4a9b7e2a7c04f4839 AssemblyDefinitionImporter: externalObjects: {} userData: diff --git a/Plugins/WebSocket/WebSocket_LnlM.jslib b/Plugins/WebSocket/WebSocket_LnlM.jslib new file mode 100644 index 00000000..50c300f0 --- /dev/null +++ b/Plugins/WebSocket/WebSocket_LnlM.jslib @@ -0,0 +1,143 @@ +var LibraryWebSockets_LnlM = { + $webSocketInstances_LnlM: [], + + // Create instance and connect to server + // Events: DataEvent = 0, ConnectEvent = 1, DisconnectEvent = 2, ErrorEvent = 3 + SocketCreate_LnlM: function(url) + { + var str = UTF8ToString(url); + var socket = { + socket: new WebSocket(str), + buffer: new Uint8Array(0), + events: [] + } + + socket.socket.binaryType = 'arraybuffer'; + + socket.socket.onopen = function(e) { + socket.events.push({ + type: 1, + }); + }; + + socket.socket.onmessage = function(e) { + // TODO: handle other data types? + if (e.data instanceof Blob) + { + var reader = new FileReader(); + reader.addEventListener("loadend", function() { + socket.events.push({ + type: 0, + data: new Uint8Array(reader.result) + }); + }); + reader.readAsArrayBuffer(e.data); + } + else if (e.data instanceof ArrayBuffer) + { + socket.events.push({ + type: 0, + data: new Uint8Array(e.data) + }); + } + }; + + socket.socket.onerror = function(e) { + // Ref: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code + socket.events.push({ + type: 3, + code: e.code, + reason: e.reason, + }); + }; + + socket.socket.onclose = function(e) { + // Ref: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code + socket.events.push({ + type: 2, + code: e.code, + reason: e.reason, + }); + }; + + // Return instance pointer + var instance = webSocketInstances_LnlM.push(socket) - 1; + return instance; + }, + + // Get connection state + GetSocketState_LnlM: function (socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + // Ref: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState + if (!socket) + return 3; + return socket.socket.readyState; + }, + + // Get latest event type + GetSocketEventType_LnlM: function(socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0) + return -1; + return socket.events[0].type; + }, + + // Get latest error code + GetSocketErrorCode_LnlM: function(socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0 || (socket.events[0].type != 3 && socket.events[0].type != 2)) + return 0; + return socket.events[0].code; + }, + + // Get latest data length + GetSocketDataLength_LnlM: function(socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0 || socket.events[0].type != 0 || socket.events[0].data.length == 0) + return 0; + return socket.events[0].data.length; + }, + + // Get latest data byte array + GetSocketData_LnlM: function(socketInstance, ptr, length) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0 || socket.events[0].type != 0 || socket.events[0].data.length == 0 || socket.events[0].data.length > length) + return; + HEAPU8.set(socket.events[0].data, ptr); + }, + + // Dequeue network event + SocketEventDequeue_LnlM: function(socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0) + return; + socket.events = socket.events.slice(1); + }, + + // Send message + SocketSend_LnlM: function (socketInstance, ptr, length) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket) + return; + socket.socket.send(HEAPU8.buffer.slice(ptr, ptr + length)); + }, + + // Close connection + SocketClose_LnlM: function (socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket) + return; + socket.socket.close(); + } +}; + +autoAddDeps(LibraryWebSockets_LnlM, '$webSocketInstances_LnlM'); +mergeInto(LibraryManager.library, LibraryWebSockets_LnlM); diff --git a/Plugins/WebSocket/WebSocket.jslib.meta b/Plugins/WebSocket/WebSocket_LnlM.jslib.meta similarity index 100% rename from Plugins/WebSocket/WebSocket.jslib.meta rename to Plugins/WebSocket/WebSocket_LnlM.jslib.meta diff --git a/Plugins/WebSocket/endel.nativewebsocket.asmdef b/Plugins/WebSocket/endel.nativewebsocket.asmdef deleted file mode 100644 index 871f704e..00000000 --- a/Plugins/WebSocket/endel.nativewebsocket.asmdef +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "endel.nativewebsocket" -} diff --git a/Plugins/WebSocket/WebSocket.cs.meta b/Scripts/Transports/WebSocket/WssTransportSession.cs.meta similarity index 83% rename from Plugins/WebSocket/WebSocket.cs.meta rename to Scripts/Transports/WebSocket/WssTransportSession.cs.meta index 708e6f1c..cc6a5263 100644 --- a/Plugins/WebSocket/WebSocket.cs.meta +++ b/Scripts/Transports/WebSocket/WssTransportSession.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: df0e653fbf9005342904aa0f14d46088 +guid: 102c4270c7677314898bb6da06d9f7a3 MonoImporter: externalObjects: {} serializedVersion: 2 From cdc5c208986c1f50ea04d5f157c3f2a9f9b3d38e Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 23:39:29 +0700 Subject: [PATCH 54/58] feat: change web socket client structure --- Plugins/WebSocket/WebSocket_LnlM.asmdef | 3 - Plugins/WebSocket/WebSocket_LnlM.asmdef.meta | 7 - ...LnlM.jslib => WebSocketClient_JSLIB.jslib} | 75 ++++-- ....meta => WebSocketClient_JSLIB.jslib.meta} | 0 Scripts/LiteNetLibManager.asmdef | 6 +- .../Transports/WebSocket/WebSocketClient.cs | 236 ++++++++++++++++++ ...ession.cs.meta => WebSocketClient.cs.meta} | 2 +- .../WebSocket/WebSocketTransport.cs | 68 +---- 8 files changed, 303 insertions(+), 94 deletions(-) delete mode 100644 Plugins/WebSocket/WebSocket_LnlM.asmdef delete mode 100644 Plugins/WebSocket/WebSocket_LnlM.asmdef.meta rename Plugins/{WebSocket/WebSocket_LnlM.jslib => WebSocketClient_JSLIB.jslib} (72%) rename Plugins/{WebSocket/WebSocket_LnlM.jslib.meta => WebSocketClient_JSLIB.jslib.meta} (100%) create mode 100644 Scripts/Transports/WebSocket/WebSocketClient.cs rename Scripts/Transports/WebSocket/{WssTransportSession.cs.meta => WebSocketClient.cs.meta} (83%) diff --git a/Plugins/WebSocket/WebSocket_LnlM.asmdef b/Plugins/WebSocket/WebSocket_LnlM.asmdef deleted file mode 100644 index 162d95ad..00000000 --- a/Plugins/WebSocket/WebSocket_LnlM.asmdef +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "WebSocket" -} diff --git a/Plugins/WebSocket/WebSocket_LnlM.asmdef.meta b/Plugins/WebSocket/WebSocket_LnlM.asmdef.meta deleted file mode 100644 index e6d36a40..00000000 --- a/Plugins/WebSocket/WebSocket_LnlM.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: d969dd435f4843f4a9b7e2a7c04f4839 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Plugins/WebSocket/WebSocket_LnlM.jslib b/Plugins/WebSocketClient_JSLIB.jslib similarity index 72% rename from Plugins/WebSocket/WebSocket_LnlM.jslib rename to Plugins/WebSocketClient_JSLIB.jslib index 50c300f0..14f27654 100644 --- a/Plugins/WebSocket/WebSocket_LnlM.jslib +++ b/Plugins/WebSocketClient_JSLIB.jslib @@ -14,12 +14,6 @@ var LibraryWebSockets_LnlM = { socket.socket.binaryType = 'arraybuffer'; - socket.socket.onopen = function(e) { - socket.events.push({ - type: 1, - }); - }; - socket.socket.onmessage = function(e) { // TODO: handle other data types? if (e.data instanceof Blob) @@ -42,12 +36,9 @@ var LibraryWebSockets_LnlM = { } }; - socket.socket.onerror = function(e) { - // Ref: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code + socket.socket.onopen = function(e) { socket.events.push({ - type: 3, - code: e.code, - reason: e.reason, + type: 1, }); }; @@ -57,6 +48,15 @@ var LibraryWebSockets_LnlM = { type: 2, code: e.code, reason: e.reason, + wasClean: e.wasClean, + }); + }; + + socket.socket.onerror = function(e) { + // Ref: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code + socket.events.push({ + type: 3, + message: e.message, }); }; @@ -84,15 +84,6 @@ var LibraryWebSockets_LnlM = { return socket.events[0].type; }, - // Get latest error code - GetSocketErrorCode_LnlM: function(socketInstance) - { - var socket = webSocketInstances_LnlM[socketInstance]; - if (!socket || socket.events.length == 0 || (socket.events[0].type != 3 && socket.events[0].type != 2)) - return 0; - return socket.events[0].code; - }, - // Get latest data length GetSocketDataLength_LnlM: function(socketInstance) { @@ -111,6 +102,50 @@ var LibraryWebSockets_LnlM = { HEAPU8.set(socket.events[0].data, ptr); }, + // Get latest error message + GetSocketErrorMessage_LnlM: function(socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0 || socket.events[0].type != 3) + return undefined; + var message = socket.events[0].message; + var length = lengthBytesUTF8(message) + 1; + var buffer = _malloc(length); + stringToUTF8(message, buffer, length); + return buffer; + }, + + // Get latest disconnect code + GetSocketDisconnectCode_LnlM: function(socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0 || socket.events[0].type != 2) + return 0; + return socket.events[0].code; + }, + + // Get latest disconnect reason + GetSocketDisconnectReason_LnlM: function(socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0 || socket.events[0].type != 2) + return undefined; + var reason = socket.events[0].reason; + var length = lengthBytesUTF8(reason) + 1; + var buffer = _malloc(length); + stringToUTF8(reason, buffer, length); + return buffer; + }, + + // Get latest disconnect wasClean + GetSocketDisconnectWasClean_LnlM: function(socketInstance) + { + var socket = webSocketInstances_LnlM[socketInstance]; + if (!socket || socket.events.length == 0 || socket.events[0].type != 2) + return 0; + return socket.events[0].wasClean; + }, + // Dequeue network event SocketEventDequeue_LnlM: function(socketInstance) { diff --git a/Plugins/WebSocket/WebSocket_LnlM.jslib.meta b/Plugins/WebSocketClient_JSLIB.jslib.meta similarity index 100% rename from Plugins/WebSocket/WebSocket_LnlM.jslib.meta rename to Plugins/WebSocketClient_JSLIB.jslib.meta diff --git a/Scripts/LiteNetLibManager.asmdef b/Scripts/LiteNetLibManager.asmdef index 0ce564e5..dbc8315b 100644 --- a/Scripts/LiteNetLibManager.asmdef +++ b/Scripts/LiteNetLibManager.asmdef @@ -6,8 +6,10 @@ "GUID:f51ebe6a0ceec4240a699833d6309b23", "GUID:33661e06c33d31b4c9223810bf503247", "GUID:19622d0c1901810479006eab0c2d3555", - "GUID:d969dd435f4843f4a9b7e2a7c04f4839", - "GUID:302cce8bc3ee0014da34daebe3087f54" + "GUID:9e24947de15b9834991c9d8411ea37cf", + "GUID:84651a3751eca9349aac36a66bba901b", + "GUID:33af501272c564055a528a917e4a2c71", + "GUID:bb32166f4ac51414281e84c4fed2abbd" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Scripts/Transports/WebSocket/WebSocketClient.cs b/Scripts/Transports/WebSocket/WebSocketClient.cs new file mode 100644 index 00000000..341aef90 --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketClient.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Collections; +using UnityEngine; +using System.Runtime.InteropServices; +using LiteNetLib; + +namespace LiteNetLibManager +{ + public class WebSocketClient + { +#if UNITY_WEBGL && !UNITY_EDITOR + [DllImport("__Internal")] + private static extern int SocketCreate(string url); + + [DllImport("__Internal")] + private static extern int SocketState(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern void SocketSend(int wsNativeInstance, byte[] ptr, int length); + + [DllImport("__Internal")] + private static extern void SocketRecv(int wsNativeInstance, byte[] ptr, int length); + + [DllImport("__Internal")] + private static extern int SocketRecvLength(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern void SocketClose(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern int SocketError(int wsNativeInstance, byte[] ptr, int length); + + [DllImport("__Internal")] + private static extern int SocketCreate_LnlM(string url); + + [DllImport("__Internal")] + private static extern int GetSocketState_LnlM(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern int GetSocketEventType_LnlM(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern int GetSocketDataLength_LnlM(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern void GetSocketData_LnlM(int wsNativeInstance, byte[] ptr, int length); + + [DllImport("__Internal")] + private static extern string GetSocketErrorMessage_LnlM(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern int GetSocketDisconnectCode_LnlM(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern string GetSocketDisconnectReason_LnlM(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern bool GetSocketDisconnectWasClean_LnlM(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern void SocketEventDequeue_LnlM(int wsNativeInstance); + + [DllImport("__Internal")] + private static extern void SocketSend_LnlM(int wsNativeInstance, byte[] ptr, int length); + + [DllImport("__Internal")] + private static extern void SocketClose_LnlM(int wsNativeInstance); + + private int _wsNativeInstance = 0; +#else + private WebSocketSharp.WebSocket _socket; + private readonly Queue _clientEventQueue; + private string _error = null; +#endif + + private readonly string _url; + + public WebSocketClient(string url) + { + _url = url; + _clientEventQueue = new Queue(); + } + + public void Connect() + { +#if UNITY_WEBGL && !UNITY_EDITOR + _wsNativeInstance = SocketCreate_LnlM(_url); +#else + if (IsOpen) + _socket?.Close(); + _socket = new WebSocketSharp.WebSocket(_url); + _socket.OnMessage += _socket_OnMessage; + _socket.OnOpen += _socket_OnOpen; + _socket.OnClose += _socket_OnClose; + _socket.OnError += _socket_OnError; + _socket.ConnectAsync(); +#endif + } + + private void _socket_OnMessage(object sender, WebSocketSharp.MessageEventArgs e) + { + _clientEventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DataEvent, + reader = new LiteNetLib.Utils.NetDataReader(e.RawData), + }); + } + + private void _socket_OnOpen(object sender, EventArgs e) + { + _clientEventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ConnectEvent, + }); + } + + private void _socket_OnClose(object sender, WebSocketSharp.CloseEventArgs e) + { + _clientEventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DisconnectEvent, + disconnectInfo = GetDisconnectInfo(e.Code, e.Reason, e.WasClean), + }); + } + + private void _socket_OnError(object sender, WebSocketSharp.ErrorEventArgs e) + { + _clientEventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + errorMessage = e.Message, + }); + } + + public void Close() + { +#if UNITY_WEBGL && !UNITY_EDITOR + SocketClose_LnlM(_wsNativeInstance); +#else + _socket.CloseAsync(); +#endif + } + + public bool ClientReceive(out TransportEventData eventData) + { + eventData = default; +#if !UNITY_WEBGL || UNITY_EDITOR + if (_clientEventQueue.Count == 0) + return false; + return _clientEventQueue.TryDequeue(out eventData); +#else + int eventType = GetSocketEventType_LnlM(_wsNativeInstance); + if (eventType < 0) + return false; + switch ((ENetworkEvent)eventType) + { + case ENetworkEvent.DataEvent: + eventData.type = ENetworkEvent.DataEvent; + eventData.reader = new NetDataReader(GetSocketData()); + break; + case ENetworkEvent.ConnectEvent: + eventData.type = ENetworkEvent.ConnectEvent; + break; + case ENetworkEvent.DisconnectEvent: + eventData.type = ENetworkEvent.DisconnectEvent; + eventData.disconnectInfo = GetDisconnectInfo( + GetSocketDisconnectCode_LnlM(_wsNativeInstance), + GetSocketDisconnectReason_LnlM(_wsNativeInstance), + GetSocketDisconnectWasClean_LnlM(_wsNativeInstance)); + break; + case ENetworkEvent.ErrorEvent: + eventData.type = ENetworkEvent.ErrorEvent; + eventData.errorMessage = GetSocketErrorMessage_LnlM(_wsNativeInstance); + break; + } + SocketEventDequeue_LnlM(_wsNativeInstance); + return true; +#endif + } + +#if UNITY_WEBGL && !UNITY_EDITOR + private byte[] GetSocketData() + { + int length = GetSocketDataLength_LnlM(_wsNativeInstance); + if (length == 0) + return null; + byte[] buffer = new byte[length]; + GetSocketData_LnlM(_wsNativeInstance, buffer, length); + return buffer; + } +#endif + + /// + /// https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/ + /// + /// + /// + public DisconnectInfo GetDisconnectInfo(int code, string reason, bool wasClean) + { + // TODO: Implement this + return new DisconnectInfo() + { + + }; + } + + public bool ClientSend(byte[] buffer) + { + if (!IsOpen) + return false; +#if !UNITY_WEBGL || UNITY_EDITOR + _socket.Send(buffer); +#else + SocketSend_LnlM(_wsNativeInstance, buffer.Data, buffer.Data.Length); +#endif + return true; + } + + public bool IsOpen + { + get + { +#if UNITY_WEBGL && !UNITY_EDITOR + return GetSocketState_LnlM(_wsNativeInstance) == 1; +#else + return _socket.ReadyState == WebSocketSharp.WebSocketState.Open; +#endif + } + } + } +} \ No newline at end of file diff --git a/Scripts/Transports/WebSocket/WssTransportSession.cs.meta b/Scripts/Transports/WebSocket/WebSocketClient.cs.meta similarity index 83% rename from Scripts/Transports/WebSocket/WssTransportSession.cs.meta rename to Scripts/Transports/WebSocket/WebSocketClient.cs.meta index cc6a5263..1364a5da 100644 --- a/Scripts/Transports/WebSocket/WssTransportSession.cs.meta +++ b/Scripts/Transports/WebSocket/WebSocketClient.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 102c4270c7677314898bb6da06d9f7a3 +guid: 90506f489744ff64d9f0b6246e14e98b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Scripts/Transports/WebSocket/WebSocketTransport.cs b/Scripts/Transports/WebSocket/WebSocketTransport.cs index 94d9cd94..b8007f57 100644 --- a/Scripts/Transports/WebSocket/WebSocketTransport.cs +++ b/Scripts/Transports/WebSocket/WebSocketTransport.cs @@ -17,8 +17,7 @@ public class WebSocketTransport : ITransport private string _certificateFilePath; private string _certificatePassword; private string _certificateBase64String; - private NativeWebSocket.WebSocket _client; - private readonly Queue _clientEventQueue; + private WebSocketClient _client; #if !UNITY_WEBGL || UNITY_EDITOR private WebSocketServer _server; private long _nextConnectionId = 1; @@ -46,7 +45,7 @@ public int ServerPeersCount public int ServerMaxConnections { get; private set; } public bool IsClientStarted { - get { return _client != null && _client.State == NativeWebSocket.WebSocketState.Open; } + get { return _client != null && _client.IsOpen; } } public bool IsServerStarted { @@ -68,7 +67,6 @@ public WebSocketTransport(bool secure, string certificateFilePath, string certif _certificateFilePath = certificateFilePath; _certificatePassword = certificatePassword; _certificateBase64String = certificateBase64String; - _clientEventQueue = new Queue(); #if !UNITY_WEBGL || UNITY_EDITOR _serverPeers = new Dictionary(); _serverEventQueue = new Queue(); @@ -82,80 +80,28 @@ public bool StartClient(string address, int port) string protocol = _secure ? "wss" : "ws"; string url = $"{protocol}://{address}:{port}{_path}"; Logging.Log(nameof(WebSocketTransport), $"Connecting to {url}"); - _client = new NativeWebSocket.WebSocket(url); - _client.OnOpen += OnClientOpen; - _client.OnMessage += OnClientMessage; - _client.OnError += OnClientError; - _client.OnClose += OnClientClose; - _ = _client.Connect(); + _client = new WebSocketClient(url); + _client.Connect(); return true; } public void StopClient() { if (_client != null) - _ = _client.Close(); + _client.Close(); _client = null; } - private void OnClientOpen() - { - _clientEventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ConnectEvent, - }); - } - - private void OnClientMessage(byte[] data) - { - _clientEventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DataEvent, - reader = new NetDataReader(data), - }); - } - - private void OnClientError(string errorMsg) - { - _clientEventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - errorMessage = errorMsg, - }); - } - - private void OnClientClose(NativeWebSocket.WebSocketCloseCode closeCode) - { - _clientEventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DisconnectEvent, - disconnectInfo = GetDisconnectInfo(closeCode), - }); - } - - private DisconnectInfo GetDisconnectInfo(NativeWebSocket.WebSocketCloseCode closeCode) - { - DisconnectInfo info = new DisconnectInfo(); - return info; - } - public bool ClientReceive(out TransportEventData eventData) { - eventData = default; - if (_client == null) - return false; - _client.DispatchMessageQueue(); - if (_clientEventQueue.Count == 0) - return false; - eventData = _clientEventQueue.Dequeue(); - return true; + return _client.ClientReceive(out eventData); } public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { if (IsClientStarted) { - _client.Send(writer.Data); + _client.ClientSend(writer.Data); return true; } return false; From 6ffa3b719a87c0670d9d072d509a453f9a6bf961 Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 21 Oct 2024 23:45:41 +0700 Subject: [PATCH 55/58] feat: delete unused libs --- Scripts/LiteNetLibManager.asmdef | 3 --- 1 file changed, 3 deletions(-) diff --git a/Scripts/LiteNetLibManager.asmdef b/Scripts/LiteNetLibManager.asmdef index dbc8315b..10922f7c 100644 --- a/Scripts/LiteNetLibManager.asmdef +++ b/Scripts/LiteNetLibManager.asmdef @@ -6,9 +6,6 @@ "GUID:f51ebe6a0ceec4240a699833d6309b23", "GUID:33661e06c33d31b4c9223810bf503247", "GUID:19622d0c1901810479006eab0c2d3555", - "GUID:9e24947de15b9834991c9d8411ea37cf", - "GUID:84651a3751eca9349aac36a66bba901b", - "GUID:33af501272c564055a528a917e4a2c71", "GUID:bb32166f4ac51414281e84c4fed2abbd" ], "includePlatforms": [], From cede8f1e2ae71c26b4a2a27ebcf22ee93fff90ea Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Tue, 22 Oct 2024 02:06:04 +0700 Subject: [PATCH 56/58] Update README.md --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1f559822..38d85c0a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ # LiteNetLibManager LiteNetLib Network Manager for Unity, this is required LiteNetLib (https://github.com/RevenantX/LiteNetLib) -The document: https://insthync.github.io/LiteNetLibManager - +[Document](https://insthync.github.io/LiteNetLibManager) ## Dependencies -- LiteNetLib -- UniTask -- ZLogger -- ZString -- NetCoreServer \ No newline at end of file +- [LiteNetLib](https://github.com/RevenantX/LiteNetLib) +- [UniTask](https://github.com/Cysharp/UniTask) +- [ZLogger](https://github.com/Cysharp/ZLogger) +- [ZString](https://github.com/Cysharp/ZString) +- [websocket-sharp](https://github.com/sta/websocket-sharp) From 661247465fdddd466903a4f263ebd790a598ba2d Mon Sep 17 00:00:00 2001 From: insthync Date: Wed, 4 Dec 2024 03:16:55 +0700 Subject: [PATCH 57/58] fix: redundant codes # Conflicts: # Scripts/GameApi/LiteNetLibSyncField.cs --- Scripts/Extensions/NetDataReaderExtension.cs | 2 +- Scripts/Extensions/NetDataWriterExtension.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/Extensions/NetDataReaderExtension.cs b/Scripts/Extensions/NetDataReaderExtension.cs index 3f241725..6889cbd5 100644 --- a/Scripts/Extensions/NetDataReaderExtension.cs +++ b/Scripts/Extensions/NetDataReaderExtension.cs @@ -129,7 +129,7 @@ public static Vector4 GetVector4(this NetDataReader reader) return new Vector4(reader.GetFloat(), reader.GetFloat(), reader.GetFloat(), reader.GetFloat()); } - public static TValue[] GetArray(this NetDataReader reader) + public static TValue[] GetArrayExtension(this NetDataReader reader) { int count = reader.GetInt(); TValue[] result = new TValue[count]; diff --git a/Scripts/Extensions/NetDataWriterExtension.cs b/Scripts/Extensions/NetDataWriterExtension.cs index 4ce531ee..16e8cda5 100644 --- a/Scripts/Extensions/NetDataWriterExtension.cs +++ b/Scripts/Extensions/NetDataWriterExtension.cs @@ -203,7 +203,7 @@ public static void PutVector4(this NetDataWriter writer, Vector4 value) writer.Put(value.w); } - public static void PutArray(this NetDataWriter writer, TValue[] array) + public static void PutArrayExtension(this NetDataWriter writer, TValue[] array) { if (array == null) { From 6168b3a30bb0a543f99429a5b110b5fe3657f15a Mon Sep 17 00:00:00 2001 From: Ittipon Teerapruettikulchai Date: Mon, 2 Jun 2025 21:31:24 +0700 Subject: [PATCH 58/58] feat: change websocket transport follow main branch --- .../Transports/IWebSocketTransportFactory.cs | 5 +- .../LiteNetLib/LiteNetLibTransport.cs | 6 +- .../LiteNetLibTransportServerEventListener.cs | 32 +- .../Transports/MixTransport/MixTransport.cs | 328 ++++-------------- .../MixTransport/MixTransportEventListener.cs | 105 ------ .../MixTransport/MixTransportFactory.cs | 7 +- .../Transports/WebSocket/WebSocketClient.cs | 236 +++++++++---- .../WebSocket/WebSocketCloseCode.cs | 24 ++ .../WebSocketCloseCode.cs.meta} | 2 +- .../Transports/WebSocket/WebSocketServer.cs | 166 +++++++++ ...havior.cs.meta => WebSocketServer.cs.meta} | 2 +- .../WebSocket/WebSocketServerBehavior.cs | 69 ---- .../WebSocket/WebSocketTransport.cs | 100 +++--- .../WebSocket/WebSocketTransportFactory.cs | 14 +- .../Transports/WebSocket/WebSocketUtils.cs | 31 ++ .../WebSocket/WebSocketUtils.cs.meta | 11 + 16 files changed, 532 insertions(+), 606 deletions(-) delete mode 100644 Scripts/Transports/MixTransport/MixTransportEventListener.cs create mode 100644 Scripts/Transports/WebSocket/WebSocketCloseCode.cs rename Scripts/Transports/{MixTransport/MixTransportEventListener.cs.meta => WebSocket/WebSocketCloseCode.cs.meta} (83%) create mode 100644 Scripts/Transports/WebSocket/WebSocketServer.cs rename Scripts/Transports/WebSocket/{WebSocketServerBehavior.cs.meta => WebSocketServer.cs.meta} (83%) delete mode 100644 Scripts/Transports/WebSocket/WebSocketServerBehavior.cs create mode 100644 Scripts/Transports/WebSocket/WebSocketUtils.cs create mode 100644 Scripts/Transports/WebSocket/WebSocketUtils.cs.meta diff --git a/Scripts/Transports/IWebSocketTransportFactory.cs b/Scripts/Transports/IWebSocketTransportFactory.cs index dc460ce8..752065b1 100644 --- a/Scripts/Transports/IWebSocketTransportFactory.cs +++ b/Scripts/Transports/IWebSocketTransportFactory.cs @@ -1,11 +1,10 @@ -using System.Security.Authentication; - -namespace LiteNetLibManager +namespace LiteNetLibManager { public interface IWebSocketTransportFactory { bool Secure { get; set; } string CertificateFilePath { get; set; } string CertificatePassword { get; set; } + string CertificateBase64String { get; set; } } } diff --git a/Scripts/Transports/LiteNetLib/LiteNetLibTransport.cs b/Scripts/Transports/LiteNetLib/LiteNetLibTransport.cs index c1af2b61..127bd9fb 100644 --- a/Scripts/Transports/LiteNetLib/LiteNetLibTransport.cs +++ b/Scripts/Transports/LiteNetLib/LiteNetLibTransport.cs @@ -71,7 +71,7 @@ public void StopClient() public bool ClientReceive(out TransportEventData eventData) { - eventData = default(TransportEventData); + eventData = default; if (Client == null) return false; Client.PollEvents(); @@ -105,7 +105,7 @@ public bool StartServer(int port, int maxConnections) public bool ServerReceive(out TransportEventData eventData) { - eventData = default(TransportEventData); + eventData = default; if (Server == null) return false; Server.PollEvents(); @@ -117,7 +117,7 @@ public bool ServerReceive(out TransportEventData eventData) public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { - if (IsServerStarted && _serverPeers.ContainsKey(connectionId) && _serverPeers.ContainsKey(connectionId) && _serverPeers[connectionId].ConnectionState == ConnectionState.Connected) + if (IsServerStarted && _serverPeers.ContainsKey(connectionId) && _serverPeers[connectionId].ConnectionState == ConnectionState.Connected) { _serverPeers[connectionId].Send(writer, dataChannel, deliveryMethod); return true; diff --git a/Scripts/Transports/LiteNetLib/LiteNetLibTransportServerEventListener.cs b/Scripts/Transports/LiteNetLib/LiteNetLibTransportServerEventListener.cs index 313858bf..a011aa78 100644 --- a/Scripts/Transports/LiteNetLib/LiteNetLibTransportServerEventListener.cs +++ b/Scripts/Transports/LiteNetLib/LiteNetLibTransportServerEventListener.cs @@ -7,30 +7,30 @@ namespace LiteNetLibManager { public class LiteNetLibTransportServerEventListener : INetEventListener { - private readonly ITransport transport; - private readonly string connectKey; - private readonly Queue eventQueue; - private readonly Dictionary serverPeers; + private readonly ITransport _transport; + private readonly string _connectKey; + private readonly Queue _eventQueue; + private readonly Dictionary _serverPeers; public LiteNetLibTransportServerEventListener(ITransport transport, string connectKey, Queue eventQueue, Dictionary serverPeers) { - this.transport = transport; - this.connectKey = connectKey; - this.eventQueue = eventQueue; - this.serverPeers = serverPeers; + _transport = transport; + _connectKey = connectKey; + _eventQueue = eventQueue; + _serverPeers = serverPeers; } public void OnConnectionRequest(ConnectionRequest request) { - if (transport.ServerPeersCount < transport.ServerMaxConnections) - request.AcceptIfKey(connectKey); + if (_transport.ServerPeersCount < _transport.ServerMaxConnections) + request.AcceptIfKey(_connectKey); else request.Reject(); } public void OnNetworkError(IPEndPoint endPoint, SocketError socketError) { - eventQueue.Enqueue(new TransportEventData() + _eventQueue.Enqueue(new TransportEventData() { type = ENetworkEvent.ErrorEvent, endPoint = endPoint, @@ -44,7 +44,7 @@ public void OnNetworkLatencyUpdate(NetPeer peer, int latency) public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) { - eventQueue.Enqueue(new TransportEventData() + _eventQueue.Enqueue(new TransportEventData() { type = ENetworkEvent.DataEvent, connectionId = peer.Id, @@ -58,8 +58,8 @@ public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketRead public void OnPeerConnected(NetPeer peer) { - serverPeers[peer.Id] = peer; - eventQueue.Enqueue(new TransportEventData() + _serverPeers[peer.Id] = peer; + _eventQueue.Enqueue(new TransportEventData() { type = ENetworkEvent.ConnectEvent, connectionId = peer.Id, @@ -68,8 +68,8 @@ public void OnPeerConnected(NetPeer peer) public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) { - serverPeers.Remove(peer.Id); - eventQueue.Enqueue(new TransportEventData() + _serverPeers.Remove(peer.Id); + _eventQueue.Enqueue(new TransportEventData() { type = ENetworkEvent.DisconnectEvent, connectionId = peer.Id, diff --git a/Scripts/Transports/MixTransport/MixTransport.cs b/Scripts/Transports/MixTransport/MixTransport.cs index 313b12d2..28558d37 100644 --- a/Scripts/Transports/MixTransport/MixTransport.cs +++ b/Scripts/Transports/MixTransport/MixTransport.cs @@ -1,323 +1,127 @@ -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Security.Cryptography.X509Certificates; -using LiteNetLib; +using LiteNetLib; using LiteNetLib.Utils; -#if !UNITY_WEBGL || UNITY_EDITOR -using WebSocketSharp; -using WebSocketSharp.Server; -#endif namespace LiteNetLibManager { public sealed class MixTransport : ITransport { - private long nextConnectionId = 1; - private long tempConnectionId; - private bool webSocketSecure; - private string webSocketCertificateFilePath; - private string webSocketCertificatePassword; + private bool _useWebSocketForClient; + private LiteNetLibTransport _lnlTransport; + private WebSocketTransport _wsTransport; + private int _webSocketPortOffset; - // WebSocket data -#if UNITY_WEBGL - private byte[] tempBuffers; - private bool wsDirtyIsConnected; - private WebSocket wsClient; -#endif -#if !UNITY_WEBGL || UNITY_EDITOR - private WebSocketServer wsServer; - private readonly Dictionary wsServerPeers; -#endif - - // LiteNetLib data - public NetManager Client { get; private set; } - public NetManager Server { get; private set; } - public string ConnectKey { get; private set; } - public int ServerPeersCount - { - get - { - int result = 0; - if (Server != null) - result += Server.ConnectedPeersCount; -#if !UNITY_WEBGL - if (wsServer != null) - { - foreach (WebSocketServiceHost host in wsServer.WebSocketServices.Hosts) - { - result += host.Sessions.Count; - } - } -#endif - return result; - } - } - public int ServerMaxConnections { get; private set; } - public bool IsClientStarted + public MixTransport(bool useWebSocketForClient, string connectKey, byte clientDataChannelsCount, byte serverDataChannelsCount, + int webSocketPortOffset, bool secure, string certificateFilePath, string certificateBase64String, string certificatePassword) { - get - { -#if UNITY_WEBGL - return wsClient != null && wsClient.IsConnected; -#else - return Client != null && Client.FirstPeer != null && Client.FirstPeer.ConnectionState == ConnectionState.Connected; -#endif - } - } - public bool IsServerStarted - { - get - { -#if UNITY_WEBGL - // Don't integrate server networking to WebGL clients - return false; -#else - return wsServer != null && Server != null; -#endif - } + _useWebSocketForClient = useWebSocketForClient; + _lnlTransport = new LiteNetLibTransport(connectKey, clientDataChannelsCount, serverDataChannelsCount); + _wsTransport = new WebSocketTransport(secure, certificateFilePath, certificateBase64String, certificatePassword); + _webSocketPortOffset = webSocketPortOffset; } - public bool HasImplementedPing => false; + public int ServerPeersCount => _lnlTransport.ServerPeersCount + _wsTransport.ServerPeersCount; - private readonly Dictionary serverPeers; - private readonly Queue clientEventQueue; - private readonly Queue serverEventQueue; - private readonly byte clientDataChannelsCount; - private readonly byte serverDataChannelsCount; + public int ServerMaxConnections => _lnlTransport.ServerMaxConnections + _wsTransport.ServerMaxConnections; - private readonly int webSocketPortOffset; + public bool IsClientStarted => !_useWebSocketForClient ? _lnlTransport.IsClientStarted : _wsTransport.IsClientStarted; - public MixTransport(string connectKey, int webSocketPortOffset, bool webSocketSecure, string webSocketCertificateFilePath, string webSocketCertificatePassword, byte clientDataChannelsCount, byte serverDataChannelsCount) - { - ConnectKey = connectKey; -#if !UNITY_WEBGL - wsServerPeers = new Dictionary(); - serverPeers = new Dictionary(); - clientEventQueue = new Queue(); - serverEventQueue = new Queue(); - this.clientDataChannelsCount = clientDataChannelsCount; - this.serverDataChannelsCount = serverDataChannelsCount; -#endif - this.webSocketPortOffset = webSocketPortOffset; - this.webSocketSecure = webSocketSecure; - this.webSocketCertificateFilePath = webSocketCertificateFilePath; - this.webSocketCertificatePassword = webSocketCertificatePassword; - } + public bool IsServerStarted => _lnlTransport.IsServerStarted || _wsTransport.IsServerStarted; - public bool StartClient(string address, int port) + public bool HasImplementedPing => !_useWebSocketForClient ? _lnlTransport.HasImplementedPing : _wsTransport.HasImplementedPing; + + public long GetClientRtt() { -#if UNITY_WEBGL - wsDirtyIsConnected = false; - int wsPort = port + webSocketPortOffset; - string url = (webSocketSecure ? "wss://" : "ws://") + address + ":" + port; - Logging.Log(nameof(MixTransport), $"Connecting to {url}"); - wsClient = new WebSocket(new System.Uri(url)); - wsClient.Connect(); - return true; -#else - clientEventQueue.Clear(); - Client = new NetManager(new LiteNetLibTransportClientEventListener(clientEventQueue)); - Client.ChannelsCount = clientDataChannelsCount; - return Client.Start() && Client.Connect(address, port, ConnectKey) != null; -#endif + if (!_useWebSocketForClient) + return _lnlTransport.GetClientRtt(); + else + return _wsTransport.GetClientRtt(); } - public void StopClient() + public long GetServerRtt(long connectionId) { -#if UNITY_WEBGL - if (wsClient != null) - wsClient.Close(); - wsClient = null; -#else - if (Client != null) - Client.Stop(); - Client = null; -#endif + if (!_useWebSocketForClient) + return _lnlTransport.GetServerRtt(connectionId); + else + return _wsTransport.GetServerRtt(connectionId); } public bool ClientReceive(out TransportEventData eventData) { - eventData = default(TransportEventData); -#if UNITY_WEBGL - if (wsClient == null) - return false; - if (wsDirtyIsConnected != wsClient.IsConnected) - { - wsDirtyIsConnected = wsClient.IsConnected; - if (wsClient.IsConnected) - { - // Connect state changed to connected, so it's connect event - eventData.type = ENetworkEvent.ConnectEvent; - } - else - { - // Connect state changed to not connected, so it's disconnect event - eventData.type = ENetworkEvent.DisconnectEvent; - } - return true; - } + if (!_useWebSocketForClient) + return _lnlTransport.ClientReceive(out eventData); else - { - tempBuffers = wsClient.Recv(); - if (tempBuffers != null) - { - eventData.type = ENetworkEvent.DataEvent; - eventData.reader = new NetDataReader(tempBuffers); - return true; - } - } - return false; -#else - if (Client == null) - return false; - Client.PollEvents(); - if (clientEventQueue.Count == 0) - return false; - eventData = clientEventQueue.Dequeue(); - return true; -#endif + return _wsTransport.ClientReceive(out eventData); } public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { -#if UNITY_WEBGL - if (IsClientStarted) - { - wsClient.Send(writer.Data); - return true; - } -#else - if (IsClientStarted) - { - Client.FirstPeer.Send(writer, dataChannel, deliveryMethod); - return true; - } -#endif - return false; + if (!_useWebSocketForClient) + return _lnlTransport.ClientSend(dataChannel, deliveryMethod, writer); + else + return _wsTransport.ClientSend(dataChannel, deliveryMethod, writer); } - public bool StartServer(int port, int maxConnections) + public void Destroy() { -#if UNITY_WEBGL - // Don't integrate server networking to WebGL clients - return false; -#else - if (IsServerStarted) - return false; - ServerMaxConnections = maxConnections; - serverEventQueue.Clear(); - - // Start WebSocket Server - wsServerPeers.Clear(); - int wsPort = port + webSocketPortOffset; - wsServer = new WebSocketServer(wsPort, webSocketSecure); - if (webSocketSecure) - wsServer.SslConfiguration.ServerCertificate = new X509Certificate2(webSocketCertificateFilePath, webSocketCertificatePassword); - wsServer.AddWebSocketService("/", (behavior) => - { - tempConnectionId = GetNewConnectionID(); - behavior.Initialize(tempConnectionId, serverEventQueue, wsServerPeers); - }); - wsServer.Start(); - - // Start LiteNetLib Server - serverPeers.Clear(); - Server = new NetManager(new LiteNetLibTransportServerEventListener(this, ConnectKey, serverEventQueue, serverPeers)); - Server.ChannelsCount = serverDataChannelsCount; - return Server.Start(port); -#endif + _lnlTransport.Destroy(); + _wsTransport.Destroy(); } - public bool ServerReceive(out TransportEventData eventData) + public bool ServerDisconnect(long connectionId) { - eventData = default(TransportEventData); -#if UNITY_WEBGL - // Don't integrate server networking to WebGL clients + if (_lnlTransport.ServerDisconnect(connectionId)) + return true; + if (_wsTransport.ServerDisconnect(connectionId)) + return true; return false; -#else - if (wsServer == null || Server == null) - return false; - Server.PollEvents(); - if (serverEventQueue.Count == 0) - return false; - eventData = serverEventQueue.Dequeue(); - return true; -#endif } - public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) + public bool ServerReceive(out TransportEventData eventData) { -#if !UNITY_WEBGL - // WebSocket Server Send - if (IsServerStarted && wsServerPeers.ContainsKey(connectionId) && wsServerPeers[connectionId].ConnectionState == WebSocketState.Open) - { - wsServerPeers[connectionId].Context.WebSocket.Send(writer.Data); + if (_lnlTransport.ServerReceive(out eventData)) return true; - } - // LiteNetLib Server Send - if (IsServerStarted && serverPeers.ContainsKey(connectionId) && serverPeers[connectionId].ConnectionState == ConnectionState.Connected) - { - serverPeers[connectionId].Send(writer, dataChannel, deliveryMethod); + if (_wsTransport.ServerReceive(out eventData)) return true; - } -#endif return false; } - public bool ServerDisconnect(long connectionId) + public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { -#if !UNITY_WEBGL - // WebSocket Server Disconnect - if (IsServerStarted && wsServerPeers.ContainsKey(connectionId)) - { - wsServerPeers[connectionId].Context.WebSocket.Close(); - wsServerPeers.Remove(connectionId); + if (_lnlTransport.ServerSend(connectionId, dataChannel, deliveryMethod, writer)) return true; - } - // LiteNetLib Server Disconnect - if (IsServerStarted && serverPeers.ContainsKey(connectionId)) - { - Server.DisconnectPeer(serverPeers[connectionId]); - serverPeers.Remove(connectionId); + if (_wsTransport.ServerSend(connectionId, dataChannel, deliveryMethod, writer)) return true; - } -#endif return false; } - public void StopServer() - { -#if !UNITY_WEBGL - if (wsServer != null) - wsServer.Stop(); - wsServer = null; - if (Server != null) - Server.Stop(); - Server = null; - nextConnectionId = 1; -#endif - } - - public void Destroy() + public bool StartClient(string address, int port) { - StopClient(); - StopServer(); + if (!_useWebSocketForClient) + return _lnlTransport.StartClient(address, port); + else + return _wsTransport.StartClient(address, port + _webSocketPortOffset); } - public long GetNewConnectionID() + public bool StartServer(int port, int maxConnections) { - return nextConnectionId++; + if (_lnlTransport.StartServer(port, maxConnections / 2) && + _wsTransport.StartServer(port + _webSocketPortOffset, maxConnections / 2)) + return true; + return false; } - public long GetClientRtt() + public void StopClient() { - return 0; + if (!_useWebSocketForClient) + _lnlTransport.StopClient(); + else + _wsTransport.StopClient(); } - public long GetServerRtt(long connectionId) + public void StopServer() { - return 0; + _lnlTransport.StopServer(); + _wsTransport.StopServer(); } } } diff --git a/Scripts/Transports/MixTransport/MixTransportEventListener.cs b/Scripts/Transports/MixTransport/MixTransportEventListener.cs deleted file mode 100644 index e7308541..00000000 --- a/Scripts/Transports/MixTransport/MixTransportEventListener.cs +++ /dev/null @@ -1,105 +0,0 @@ -using LiteNetLib; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; - -namespace LiteNetLibManager -{ - public class MixTransportEventListener : INetEventListener - { - private MixTransport mixTransport; - private ConcurrentQueue eventQueue; - private Dictionary peersDict; - private Dictionary peerIdsDict; - - public MixTransportEventListener(MixTransport mixTransport, ConcurrentQueue eventQueue) - { - // This is constructor for client - this.mixTransport = mixTransport; - this.eventQueue = eventQueue; - } - - public MixTransportEventListener(MixTransport mixTransport, ConcurrentQueue eventQueue, Dictionary peersDict) : this(mixTransport, eventQueue) - { - // This is constructor for server - this.peersDict = peersDict; - peerIdsDict = new Dictionary(); - } - - public void OnConnectionRequest(ConnectionRequest request) - { - if (mixTransport.Server.ConnectedPeersCount < mixTransport.ServerMaxConnections) - request.AcceptIfKey(mixTransport.ConnectKey); - else - request.Reject(); - } - - public void OnNetworkError(IPEndPoint endPoint, SocketError socketError) - { - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - endPoint = endPoint, - socketError = socketError, - }); - } - - public void OnNetworkLatencyUpdate(NetPeer peer, int latency) - { - } - - public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) - { - long tempConnectionId = 0; - if (peerIdsDict != null && peersDict != null) - tempConnectionId = peerIdsDict[peer.Id]; - - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DataEvent, - connectionId = tempConnectionId, - reader = reader, - }); - } - - public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) - { - } - - public void OnPeerConnected(NetPeer peer) - { - long tempConnectionId = 0; - if (peerIdsDict != null && peersDict != null) - { - tempConnectionId = mixTransport.GetNewConnectionID(); - peersDict[tempConnectionId] = peer; - peerIdsDict[peer.Id] = tempConnectionId; - } - - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ConnectEvent, - connectionId = tempConnectionId, - }); - } - - public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) - { - long tempConnectionId = 0; - if (peerIdsDict != null && peersDict != null) - { - tempConnectionId = peerIdsDict[peer.Id]; - peersDict.Remove(tempConnectionId); - peerIdsDict.Remove(peer.Id); - } - - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DisconnectEvent, - connectionId = tempConnectionId, - disconnectInfo = disconnectInfo, - }); - } - } -} diff --git a/Scripts/Transports/MixTransport/MixTransportFactory.cs b/Scripts/Transports/MixTransport/MixTransportFactory.cs index 94315c99..a951aee7 100644 --- a/Scripts/Transports/MixTransport/MixTransportFactory.cs +++ b/Scripts/Transports/MixTransport/MixTransportFactory.cs @@ -6,13 +6,16 @@ public class MixTransportFactory : BaseTransportFactory, IWebSocketTransportFact public int WebSocketPortOffset { get; set; } = 100; public byte ClientDataChannelsCount { get; set; } = 16; public byte ServerDataChannelsCount { get; set; } = 16; - public bool Secure { get; set; } + public bool ShouldUseWebSocket { get; set; } = false; + public bool Secure { get; set; } = false; public string CertificateFilePath { get; set; } = string.Empty; + public string CertificateBase64String { get; set; } = string.Empty; public string CertificatePassword { get; set; } = string.Empty; public override ITransport Build() { - return new MixTransport(ConnectKey, WebSocketPortOffset, Secure, CertificateFilePath, CertificatePassword, ClientDataChannelsCount, ServerDataChannelsCount); + return new MixTransport(ShouldUseWebSocket, ConnectKey, ClientDataChannelsCount, ServerDataChannelsCount, + WebSocketPortOffset, Secure, CertificateFilePath, CertificateBase64String, CertificatePassword); } } } diff --git a/Scripts/Transports/WebSocket/WebSocketClient.cs b/Scripts/Transports/WebSocket/WebSocketClient.cs index 341aef90..7ae88e31 100644 --- a/Scripts/Transports/WebSocket/WebSocketClient.cs +++ b/Scripts/Transports/WebSocket/WebSocketClient.cs @@ -1,40 +1,18 @@ +using Cysharp.Threading.Tasks; +using LiteNetLib.Utils; using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Collections; -using UnityEngine; +using System.Net.WebSockets; using System.Runtime.InteropServices; -using LiteNetLib; +using System.Threading; +using UnityEngine; namespace LiteNetLibManager { public class WebSocketClient { #if UNITY_WEBGL && !UNITY_EDITOR - [DllImport("__Internal")] - private static extern int SocketCreate(string url); - - [DllImport("__Internal")] - private static extern int SocketState(int wsNativeInstance); - - [DllImport("__Internal")] - private static extern void SocketSend(int wsNativeInstance, byte[] ptr, int length); - - [DllImport("__Internal")] - private static extern void SocketRecv(int wsNativeInstance, byte[] ptr, int length); - - [DllImport("__Internal")] - private static extern int SocketRecvLength(int wsNativeInstance); - - [DllImport("__Internal")] - private static extern void SocketClose(int wsNativeInstance); - - [DllImport("__Internal")] - private static extern int SocketError(int wsNativeInstance, byte[] ptr, int length); - [DllImport("__Internal")] private static extern int SocketCreate_LnlM(string url); @@ -73,87 +51,204 @@ public class WebSocketClient private int _wsNativeInstance = 0; #else - private WebSocketSharp.WebSocket _socket; - private readonly Queue _clientEventQueue; - private string _error = null; + private ClientWebSocket _socket = null; + private CancellationTokenSource _tokenSource; + private CancellationToken _cancellationToken; + private CancellationTokenSource _connectTokenSource; + private CancellationToken _connectCancellationToken; #endif + private readonly ConcurrentQueue _clientEventQueue; private readonly string _url; public WebSocketClient(string url) { _url = url; - _clientEventQueue = new Queue(); + _clientEventQueue = new ConcurrentQueue(); } - public void Connect() + public bool Connect() { #if UNITY_WEBGL && !UNITY_EDITOR _wsNativeInstance = SocketCreate_LnlM(_url); + return true; #else - if (IsOpen) - _socket?.Close(); - _socket = new WebSocketSharp.WebSocket(_url); - _socket.OnMessage += _socket_OnMessage; - _socket.OnOpen += _socket_OnOpen; - _socket.OnClose += _socket_OnClose; - _socket.OnError += _socket_OnError; - _socket.ConnectAsync(); + ProceedConnect(); + return true; +#endif + } + +#if !UNITY_WEBGL || UNITY_EDITOR + public async void ProceedConnect() + { + await ProceedConnectTask(); + } #endif + + +#if !UNITY_WEBGL || UNITY_EDITOR + private async UniTask ProceedConnectTask() + { + // Cancellation for the whole system + _tokenSource = new CancellationTokenSource(); + _cancellationToken = _tokenSource.Token; + // Cancellation for connect + _connectTokenSource = new CancellationTokenSource(); + _connectCancellationToken = _connectTokenSource.Token; + // Timeout after 30 seconds + _connectTokenSource.CancelAfter(30000); + try + { + _socket = new ClientWebSocket(); + await _socket.ConnectAsync(new Uri(_url), _connectCancellationToken); + _socket_OnOpen(); + } + catch (Exception ex) + { + Logging.LogError($"[WebSockerClient] Unable to connect to {_url}, {ex.Message}\n{ex.StackTrace}"); + _socket_OnError(ex.Message); + _socket_OnClose(WebSocketCloseCode.AbnormalClosure, ex.Message, false); + CancelConnection(); + _socket?.Dispose(); + _socket = null; + } + Receive(); } +#endif + +#if !UNITY_WEBGL || UNITY_EDITOR + public void CancelConnection() + { + if (_tokenSource != null && !_tokenSource.IsCancellationRequested) + _tokenSource.Cancel(); + if (_connectTokenSource != null && !_connectTokenSource.IsCancellationRequested) + _connectTokenSource.Cancel(); + } +#endif - private void _socket_OnMessage(object sender, WebSocketSharp.MessageEventArgs e) +#if !UNITY_WEBGL || UNITY_EDITOR + public async void Receive() + { + await ReceiveTask(); + } +#endif + +#if !UNITY_WEBGL || UNITY_EDITOR + public async UniTask ReceiveTask() + { + WebSocketCloseCode closeCode = WebSocketCloseCode.AbnormalClosure; + await UniTask.SwitchToThreadPool(); + ArraySegment buffer = new ArraySegment(new byte[8192]); + try + { + while (_socket.State == WebSocketState.Open) + { + WebSocketReceiveResult result = null; + using (MemoryStream ms = new MemoryStream()) + { + do + { + result = await _socket.ReceiveAsync(buffer, _cancellationToken); + ms.Write(buffer.Array, buffer.Offset, result.Count); + } + while (!result.EndOfMessage); + + ms.Seek(0, SeekOrigin.Begin); + + if (result.MessageType == WebSocketMessageType.Text) + { + _socket_OnMessage(ms.ToArray()); + } + else if (result.MessageType == WebSocketMessageType.Binary) + { + _socket_OnMessage(ms.ToArray()); + } + else if (result.MessageType == WebSocketMessageType.Close) + { + closeCode = (WebSocketCloseCode)result.CloseStatus; + break; + } + } + } + } + catch (Exception ex) + { + Logging.LogError($"[WebSockerClient] Error occuring while proceed receiving, {ex.Message}\n{ex.StackTrace}"); + _socket_OnError(ex.Message); + CancelConnection(); + } + finally + { + _socket_OnClose(closeCode, string.Empty, false); + } + } +#endif + +#if !UNITY_WEBGL || UNITY_EDITOR + private void _socket_OnMessage(byte[] rawData) { _clientEventQueue.Enqueue(new TransportEventData() { type = ENetworkEvent.DataEvent, - reader = new LiteNetLib.Utils.NetDataReader(e.RawData), + reader = new NetDataReader(rawData), }); } +#endif - private void _socket_OnOpen(object sender, EventArgs e) +#if !UNITY_WEBGL || UNITY_EDITOR + private void _socket_OnOpen() { _clientEventQueue.Enqueue(new TransportEventData() { type = ENetworkEvent.ConnectEvent, }); } +#endif - private void _socket_OnClose(object sender, WebSocketSharp.CloseEventArgs e) +#if !UNITY_WEBGL || UNITY_EDITOR + private void _socket_OnClose(WebSocketCloseCode code, string reason, bool wasClean) { _clientEventQueue.Enqueue(new TransportEventData() { type = ENetworkEvent.DisconnectEvent, - disconnectInfo = GetDisconnectInfo(e.Code, e.Reason, e.WasClean), + disconnectInfo = WebSocketUtils.GetDisconnectInfo((int)code, reason, wasClean), }); } +#endif - private void _socket_OnError(object sender, WebSocketSharp.ErrorEventArgs e) +#if !UNITY_WEBGL || UNITY_EDITOR + private void _socket_OnError(string message) { _clientEventQueue.Enqueue(new TransportEventData() { type = ENetworkEvent.ErrorEvent, - errorMessage = e.Message, + errorMessage = message, }); } +#endif - public void Close() + public async void Close() { #if UNITY_WEBGL && !UNITY_EDITOR SocketClose_LnlM(_wsNativeInstance); #else - _socket.CloseAsync(); + CancelConnection(); + try + { + if (_socket != null && _socket.State == WebSocketState.Open) + await _socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); + } + catch (Exception ex) + { + Logging.LogError($"[WebSocketClient] Error occuring while closing, {ex.Message}\n{ex.StackTrace}"); + } #endif } public bool ClientReceive(out TransportEventData eventData) { eventData = default; -#if !UNITY_WEBGL || UNITY_EDITOR - if (_clientEventQueue.Count == 0) - return false; - return _clientEventQueue.TryDequeue(out eventData); -#else +#if UNITY_WEBGL && !UNITY_EDITOR int eventType = GetSocketEventType_LnlM(_wsNativeInstance); if (eventType < 0) return false; @@ -168,7 +263,7 @@ public bool ClientReceive(out TransportEventData eventData) break; case ENetworkEvent.DisconnectEvent: eventData.type = ENetworkEvent.DisconnectEvent; - eventData.disconnectInfo = GetDisconnectInfo( + eventData.disconnectInfo = WebSocketUtils.GetDisconnectInfo( GetSocketDisconnectCode_LnlM(_wsNativeInstance), GetSocketDisconnectReason_LnlM(_wsNativeInstance), GetSocketDisconnectWasClean_LnlM(_wsNativeInstance)); @@ -180,6 +275,10 @@ public bool ClientReceive(out TransportEventData eventData) } SocketEventDequeue_LnlM(_wsNativeInstance); return true; +#else + if (_clientEventQueue.Count == 0) + return false; + return _clientEventQueue.TryDequeue(out eventData); #endif } @@ -195,28 +294,15 @@ private byte[] GetSocketData() } #endif - /// - /// https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/ - /// - /// - /// - public DisconnectInfo GetDisconnectInfo(int code, string reason, bool wasClean) - { - // TODO: Implement this - return new DisconnectInfo() - { - - }; - } - - public bool ClientSend(byte[] buffer) + public bool ClientSend(NetDataWriter writer) { + var buffer = writer.CopyData(); if (!IsOpen) return false; -#if !UNITY_WEBGL || UNITY_EDITOR - _socket.Send(buffer); +#if UNITY_WEBGL && !UNITY_EDITOR + SocketSend_LnlM(_wsNativeInstance, buffer, buffer.Length); #else - SocketSend_LnlM(_wsNativeInstance, buffer.Data, buffer.Data.Length); + _socket?.SendAsync(buffer, WebSocketMessageType.Binary, true, _cancellationToken); #endif return true; } @@ -228,7 +314,7 @@ public bool IsOpen #if UNITY_WEBGL && !UNITY_EDITOR return GetSocketState_LnlM(_wsNativeInstance) == 1; #else - return _socket.ReadyState == WebSocketSharp.WebSocketState.Open; + return _socket != null && _socket.State == WebSocketState.Open; #endif } } diff --git a/Scripts/Transports/WebSocket/WebSocketCloseCode.cs b/Scripts/Transports/WebSocket/WebSocketCloseCode.cs new file mode 100644 index 00000000..093db8fa --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketCloseCode.cs @@ -0,0 +1,24 @@ +namespace LiteNetLibManager +{ + /// + /// https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code + /// + public enum WebSocketCloseCode : ushort + { + NormalClosure = 1000, + EndpointUnavailable = 1001, + ProtocolError = 1002, + InvalidMessageType = 1003, + Empty = 1005, + AbnormalClosure = 1006, + InvalidPayloadData = 1007, + PolicyViolation = 1008, + MessageTooBig = 1009, + MandatoryExtension = 1010, + InternalServerError = 1011, + ServiceRestart = 1012, + TryAgainLater = 1013, + BadGateway = 1014, + TlsHandshakeFailure = 1015 + } +} \ No newline at end of file diff --git a/Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta b/Scripts/Transports/WebSocket/WebSocketCloseCode.cs.meta similarity index 83% rename from Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta rename to Scripts/Transports/WebSocket/WebSocketCloseCode.cs.meta index 5346cdfa..006c6b22 100644 --- a/Scripts/Transports/MixTransport/MixTransportEventListener.cs.meta +++ b/Scripts/Transports/WebSocket/WebSocketCloseCode.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: eab9350e2510f084599682f02cc2cd08 +guid: dd679452feb93ff4192032dd85703883 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Scripts/Transports/WebSocket/WebSocketServer.cs b/Scripts/Transports/WebSocket/WebSocketServer.cs new file mode 100644 index 00000000..efb997fd --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketServer.cs @@ -0,0 +1,166 @@ +using LiteNetLib.Utils; +using System; +using System.Collections.Concurrent; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using UnityEngine; + +namespace LiteNetLibManager +{ + public class WebSocketServer + { +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + private Fleck.WebSocketServer _listener = null; + private readonly string _location; + private readonly X509Certificate2 _cert; + private readonly ConcurrentQueue _eventQueue; + private readonly ConcurrentDictionary _peers = new ConcurrentDictionary(); + private long _connectionIdOffsets = 1000000; + private long _nextConnectionId = 1; +#endif + + public bool IsRunning + { + get + { +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + return _listener != null; +#else + return false; +#endif + } + } + public int PeersCount + { + get + { +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + return _peers.Count; +#else + return 0; +#endif + } + } + + public WebSocketServer(string location, X509Certificate2 cert, ConcurrentQueue eventQueue) + { +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + _location = location; + _cert = cert; + _eventQueue = eventQueue; +#endif + } + + public bool StartServer() + { +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + try + { + _listener = new Fleck.WebSocketServer(_location); + _listener.Certificate = _cert; + _listener.Start(OnClientConnected); + _nextConnectionId = 1; + Logging.Log($"[WebSocketServer] Started on {_location}"); + } + catch (Exception ex) + { + Logging.LogError($"[WebSocketServer] Unable to start server: {ex.Message}\n{ex.StackTrace}"); + return false; + } + return true; +#else + return false; +#endif + } + + public void Stop() + { +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + _listener?.Dispose(); + _listener = null; +#endif + } + +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + private void OnClientConnected(Fleck.IWebSocketConnection conn) + { + long connectionId = GetNewConnectionID(); + conn.OnOpen = () => _socket_OnOpen(conn, connectionId); + conn.OnBinary = (data) => _socket_OnMessage(conn, connectionId, data.ToArray()); + conn.OnClose = () => _socket_OnClose(conn, connectionId, WebSocketCloseCode.NormalClosure, string.Empty, true); + conn.OnError = (ex) => _socket_OnError(conn, ex.Message); + } + + private void _socket_OnMessage(Fleck.IWebSocketConnection conn, long connectionId, byte[] rawData) + { + _eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DataEvent, + connectionId = connectionId, + reader = new NetDataReader(rawData), + }); + } + + private void _socket_OnOpen(Fleck.IWebSocketConnection conn, long connectionId) + { + _peers[connectionId] = conn; + _eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ConnectEvent, + connectionId = connectionId, + }); + } + + private void _socket_OnClose(Fleck.IWebSocketConnection conn, long connectionId, WebSocketCloseCode code, string reason, bool wasClean) + { + _peers.TryRemove(connectionId, out _); + _eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.DisconnectEvent, + connectionId = connectionId, + disconnectInfo = WebSocketUtils.GetDisconnectInfo((int)code, reason, wasClean), + }); + } + + private void _socket_OnError(Fleck.IWebSocketConnection conn, string message) + { + _eventQueue.Enqueue(new TransportEventData() + { + type = ENetworkEvent.ErrorEvent, + endPoint = new IPEndPoint(IPAddress.Parse(conn.ConnectionInfo.ClientIpAddress), conn.ConnectionInfo.ClientPort), + errorMessage = message, + }); + } + + public long GetNewConnectionID() + { + return _connectionIdOffsets + Interlocked.Increment(ref _nextConnectionId); + } +#endif + + public bool Send(long connectionId, NetDataWriter writer) + { +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + if (!_peers.TryGetValue(connectionId, out var ws) || !ws.IsAvailable) + return false; + ws.Send(writer.CopyData()); + return true; +#else + return false; +#endif + } + + public bool Disconnect(long connectionId) + { +#if UNITY_EDITOR || UNITY_STANDALONE || !UNITY_2017_1_OR_NEWER + if (!_peers.TryRemove(connectionId, out var ws)) + return false; + ws.Close(); + return true; +#else + return false; +#endif + } + } +} diff --git a/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs.meta b/Scripts/Transports/WebSocket/WebSocketServer.cs.meta similarity index 83% rename from Scripts/Transports/WebSocket/WebSocketServerBehavior.cs.meta rename to Scripts/Transports/WebSocket/WebSocketServer.cs.meta index 36bf1d5e..fe1a2daa 100644 --- a/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs.meta +++ b/Scripts/Transports/WebSocket/WebSocketServer.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fef67ccb1a96bc84e9762aac2dd60861 +guid: 2a176290120ffa74582a1ef3374fe0f5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs b/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs deleted file mode 100644 index 85450d3e..00000000 --- a/Scripts/Transports/WebSocket/WebSocketServerBehavior.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System.Collections.Generic; -using LiteNetLib.Utils; -#if !UNITY_WEBGL || UNITY_EDITOR -using WebSocketSharp; -using WebSocketSharp.Server; -#endif - -namespace LiteNetLibManager -{ -#if !UNITY_WEBGL || UNITY_EDITOR - public class WebSocketServerBehavior : WebSocketBehavior - { - public long ConnectionId { get; private set; } - private Queue eventQueue; - private Dictionary serverPeers; - - public void Initialize(long connectionId, Queue eventQueue, Dictionary serverPeers) - { - ConnectionId = connectionId; - this.eventQueue = eventQueue; - this.serverPeers = serverPeers; - } - - protected override void OnOpen() - { - base.OnOpen(); - if (serverPeers != null) - serverPeers[ConnectionId] = this; - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ConnectEvent, - connectionId = ConnectionId, - }); - } - - protected override void OnMessage(MessageEventArgs e) - { - base.OnMessage(e); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DataEvent, - connectionId = ConnectionId, - reader = new NetDataReader(e.RawData), - }); - } - - protected override void OnError(WebSocketSharp.ErrorEventArgs e) - { - base.OnError(e); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.ErrorEvent, - }); - } - - protected override void OnClose(CloseEventArgs e) - { - base.OnClose(e); - if (serverPeers != null) - serverPeers.Remove(ConnectionId); - eventQueue.Enqueue(new TransportEventData() - { - type = ENetworkEvent.DisconnectEvent, - connectionId = ConnectionId, - }); - } - } -#endif -} diff --git a/Scripts/Transports/WebSocket/WebSocketTransport.cs b/Scripts/Transports/WebSocket/WebSocketTransport.cs index b8007f57..aa130262 100644 --- a/Scripts/Transports/WebSocket/WebSocketTransport.cs +++ b/Scripts/Transports/WebSocket/WebSocketTransport.cs @@ -1,45 +1,36 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; using LiteNetLib; using LiteNetLib.Utils; -using System.Threading; +using UnityEngine; + #if !UNITY_WEBGL || UNITY_EDITOR using System.Security.Cryptography.X509Certificates; -using WebSocketSharp; -using WebSocketSharp.Server; #endif namespace LiteNetLibManager { public class WebSocketTransport : ITransport { - private string _path = "/netcode"; + private string _path = "netcode"; private bool _secure; private string _certificateFilePath; - private string _certificatePassword; private string _certificateBase64String; + private string _certificatePassword; private WebSocketClient _client; #if !UNITY_WEBGL || UNITY_EDITOR private WebSocketServer _server; - private long _nextConnectionId = 1; - private readonly Dictionary _serverPeers; - private readonly Queue _serverEventQueue; + private readonly ConcurrentQueue _serverEventQueue; #endif public int ServerPeersCount { get { - int result = 0; #if !UNITY_WEBGL || UNITY_EDITOR - if (_server != null) - { - foreach (WebSocketServiceHost host in _server.WebSocketServices.Hosts) - { - result += host.Sessions.Count; - } - } + return _server.PeersCount; +#else + return 0; #endif - return result; } } public int ServerMaxConnections { get; private set; } @@ -52,7 +43,7 @@ public bool IsServerStarted get { #if !UNITY_WEBGL || UNITY_EDITOR - return _server != null && _server.IsListening; + return _server != null && _server.IsRunning; #else return false; #endif @@ -61,15 +52,14 @@ public bool IsServerStarted public bool HasImplementedPing => false; - public WebSocketTransport(bool secure, string certificateFilePath, string certificatePassword, string certificateBase64String) + public WebSocketTransport(bool secure, string certificateFilePath, string certificateBase64String, string certificatePassword) { _secure = secure; _certificateFilePath = certificateFilePath; - _certificatePassword = certificatePassword; _certificateBase64String = certificateBase64String; + _certificatePassword = certificatePassword; #if !UNITY_WEBGL || UNITY_EDITOR - _serverPeers = new Dictionary(); - _serverEventQueue = new Queue(); + _serverEventQueue = new ConcurrentQueue(); #endif } @@ -78,11 +68,10 @@ public bool StartClient(string address, int port) if (IsClientStarted) return false; string protocol = _secure ? "wss" : "ws"; - string url = $"{protocol}://{address}:{port}{_path}"; - Logging.Log(nameof(WebSocketTransport), $"Connecting to {url}"); + string url = $"{protocol}://{address}:{port}/{_path}/"; + Logging.Log($"[WebSocketTransport] Connecting to {url}"); _client = new WebSocketClient(url); - _client.Connect(); - return true; + return _client.Connect(); } public void StopClient() @@ -94,14 +83,17 @@ public void StopClient() public bool ClientReceive(out TransportEventData eventData) { - return _client.ClientReceive(out eventData); + eventData = default; + if (_client != null) + return _client.ClientReceive(out eventData); + return false; } public bool ClientSend(byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { if (IsClientStarted) { - _client.ClientSend(writer.Data); + _client.ClientSend(writer); return true; } return false; @@ -113,27 +105,28 @@ public bool StartServer(int port, int maxConnections) if (IsServerStarted) return false; ServerMaxConnections = maxConnections; - _serverPeers.Clear(); - _server = new WebSocketServer(port, _secure); + string location = _secure ? $"wss://0.0.0.0:{port}/{_path}/" : $"ws://0.0.0.0:{port}/{_path}/"; + X509Certificate2 cert = null; if (_secure) { - if (!string.IsNullOrEmpty(_certificateFilePath) && !string.IsNullOrEmpty(_certificatePassword)) + if (!string.IsNullOrEmpty(_certificateFilePath)) { - _server.SslConfiguration.ServerCertificate = new X509Certificate2(_certificateFilePath, _certificatePassword); + if (!string.IsNullOrEmpty(_certificatePassword)) + cert = new X509Certificate2(_certificateFilePath, _certificatePassword); + else + cert = new X509Certificate2(_certificateFilePath); } if (!string.IsNullOrEmpty(_certificateBase64String)) { byte[] bytes = System.Convert.FromBase64String(_certificateBase64String); - _server.SslConfiguration.ServerCertificate = new X509Certificate2(bytes); + if (!string.IsNullOrEmpty(_certificatePassword)) + cert = new X509Certificate2(bytes, _certificatePassword); + else + cert = new X509Certificate2(bytes); } } - _server.AddWebSocketService(_path, (behavior) => - { - long newConnectionId = GetNewConnectionID(); - behavior.Initialize(newConnectionId, _serverEventQueue, _serverPeers); - }); - _server.Start(); - return true; + _server = new WebSocketServer(location, cert, _serverEventQueue); + return _server.StartServer(); #else return false; #endif @@ -141,13 +134,13 @@ public bool StartServer(int port, int maxConnections) public bool ServerReceive(out TransportEventData eventData) { - eventData = default(TransportEventData); + eventData = default; #if !UNITY_WEBGL || UNITY_EDITOR if (!IsServerStarted) return false; if (_serverEventQueue.Count == 0) return false; - eventData = _serverEventQueue.Dequeue(); + _serverEventQueue.TryDequeue(out eventData); return true; #else return false; @@ -157,11 +150,8 @@ public bool ServerReceive(out TransportEventData eventData) public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliveryMethod, NetDataWriter writer) { #if !UNITY_WEBGL || UNITY_EDITOR - if (IsServerStarted && _serverPeers.ContainsKey(connectionId) && _serverPeers[connectionId].ConnectionState == WebSocketState.Open) - { - _serverPeers[connectionId].Context.WebSocket.Send(writer.Data); - return true; - } + if (IsServerStarted) + return _server.Send(connectionId, writer); #endif return false; } @@ -169,12 +159,8 @@ public bool ServerSend(long connectionId, byte dataChannel, DeliveryMethod deliv public bool ServerDisconnect(long connectionId) { #if !UNITY_WEBGL || UNITY_EDITOR - if (IsServerStarted && _serverPeers.ContainsKey(connectionId)) - { - _serverPeers[connectionId].Context.WebSocket.Close(); - _serverPeers.Remove(connectionId); - return true; - } + if (IsServerStarted) + return _server.Disconnect(connectionId); #endif return false; } @@ -184,7 +170,6 @@ public void StopServer() #if !UNITY_WEBGL || UNITY_EDITOR if (_server != null) _server.Stop(); - _nextConnectionId = 1; _server = null; #endif } @@ -195,11 +180,6 @@ public void Destroy() StopServer(); } - public long GetNewConnectionID() - { - return Interlocked.Increment(ref _nextConnectionId); - } - public long GetClientRtt() { return 0; diff --git a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs index 21431eff..f42b60c3 100644 --- a/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs +++ b/Scripts/Transports/WebSocket/WebSocketTransportFactory.cs @@ -2,18 +2,14 @@ { public class WebSocketTransportFactory : BaseTransportFactory, IWebSocketTransportFactory { - public bool secure = false; - public string certificateFilePath = string.Empty; - public string certificatePassword = string.Empty; - public string certificateBase64String = string.Empty; - public bool Secure { get { return secure; } set { secure = value; } } - public string CertificateFilePath { get { return certificateFilePath; } set { certificateFilePath = value; } } - public string CertificatePassword { get { return certificatePassword; } set { certificatePassword = value; } } - public string CertificateBase64String { get { return certificateBase64String; } set { certificateBase64String = value; } } + public bool Secure { get; set; } = false; + public string CertificateFilePath { get; set; } = string.Empty; + public string CertificateBase64String { get; set; } = string.Empty; + public string CertificatePassword { get; set; } = string.Empty; public override ITransport Build() { - return new WebSocketTransport(secure, certificateFilePath, certificatePassword, certificateBase64String); + return new WebSocketTransport(Secure, CertificateFilePath, CertificateBase64String, CertificatePassword); } } } diff --git a/Scripts/Transports/WebSocket/WebSocketUtils.cs b/Scripts/Transports/WebSocket/WebSocketUtils.cs new file mode 100644 index 00000000..6b764f95 --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketUtils.cs @@ -0,0 +1,31 @@ +using LiteNetLib; +using System.Net.Sockets; + +namespace LiteNetLibManager +{ + public static class WebSocketUtils + { + + /// + /// https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/ + /// + /// + /// + /// + /// + public static DisconnectInfo GetDisconnectInfo(int code, string reason, bool wasClean) + { + // TODO: Implement this + WebSocketCloseCode castedCode = (WebSocketCloseCode)code; + DisconnectReason disconnectReason = DisconnectReason.ConnectionFailed; + SocketError socketErrorCode = SocketError.ConnectionReset; + if (castedCode == WebSocketCloseCode.NormalClosure) + socketErrorCode = SocketError.Success; + return new DisconnectInfo() + { + Reason = disconnectReason, + SocketErrorCode = socketErrorCode, + }; + } + } +} diff --git a/Scripts/Transports/WebSocket/WebSocketUtils.cs.meta b/Scripts/Transports/WebSocket/WebSocketUtils.cs.meta new file mode 100644 index 00000000..09d2bdca --- /dev/null +++ b/Scripts/Transports/WebSocket/WebSocketUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d88998fbda5d3c47a49da9d741d1c31 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: