protected UniTask <T> GetOrAddPromise <T>(ref AsyncTriggerPromise <T> promise, ref AsyncTriggerPromiseDictionary <T> promises, CancellationToken cancellationToken) { if (destroyCalled) { return(UniTask.FromCanceled <T>()); } if (!cancellationToken.CanBeCanceled) { if (promise == null) { promise = new AsyncTriggerPromise <T>(); if (!calledAwake) { PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, new AwakeMonitor(this)); } } return(promise.Task); } if (promises == null) { promises = new AsyncTriggerPromiseDictionary <T>(); } if (promises.TryGetValue(cancellationToken, out var cancellablePromise)) { return(cancellablePromise.Task); } cancellablePromise = new AsyncTriggerPromise <T>(); promises.Add(cancellationToken, cancellablePromise); if (!calledAwake) { PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, new AwakeMonitor(this)); } var registrationToken = cancellationToken.RegisterWithoutCaptureExecutionContext(Callback, Tuple.Create((ICancellationTokenKeyDictionary)promises, (ICancelablePromise)cancellablePromise)); if (registeredCancellations == null) { registeredCancellations = ArrayPool <CancellationTokenRegistration> .Shared.Rent(4); } ArrayPoolUtil.EnsureCapacity(ref registeredCancellations, registeredCancellationsCount + 1, ArrayPool <CancellationTokenRegistration> .Shared); registeredCancellations[registeredCancellationsCount++] = registrationToken; return(cancellablePromise.Task); }
private UniTask RaiseCore(T arg, CancellationToken cancellationToken, EventRaiseMode mode) { if (cancellationToken.IsCancellationRequested) { return(UniTask.FromCanceled(cancellationToken)); } // When _count == 0, there is no need to perform exclusive locking. if (_count == 0) { return(UniTask.CompletedTask); } _lock.Enter(); // ---- enter // Get _count after exclusive locking. var count = _count; if (count == 1) { var func = SafeCast.NotNullAs <Func <T, CancellationToken, UniTask> >(_funcs); _lock.Exit(); // ---- exit return(func.Invoke(arg, cancellationToken)); } else { var funcArray = SafeCast.NotNullAs <Func <T, CancellationToken, UniTask>[]>(_funcs); var funcs = funcArray.AsSpan(0, count); PooledAsyncEventFuncs <Func <T, CancellationToken, UniTask> > copiedFuncs; try { copiedFuncs = new PooledAsyncEventFuncs <Func <T, CancellationToken, UniTask> >(count); funcs.CopyTo(copiedFuncs.AsSpan()); } finally { _lock.Exit(); // ---- exit } if (mode == EventRaiseMode.Parallel) { return(OrderedParallelAsyncEventPromise <T> .CreateTask(copiedFuncs, arg, cancellationToken)); } else { Debug.Assert(mode == EventRaiseMode.Sequential); return(OrderedSequentialAsyncEventPromise <T> .CreateTask(copiedFuncs, arg, cancellationToken)); } } }
public static UniTask RaiseIfNotNull <T>(this AsyncEventRaiser <T>?raiser, T arg, CancellationToken cancellationToken = default) { if (raiser is not null) { return(raiser.Raise(arg, cancellationToken)); } else { if (cancellationToken.IsCancellationRequested) { return(UniTask.FromCanceled(cancellationToken)); } else { return(UniTask.CompletedTask); } } }
public override UniTask ListenAsync() { if (!EpicManager.Initialized) { if (Logger.logEnabled) { if (transportDebug) { DebugLogger.RegularDebugLog("Epic not initialized. Server could not be started."); } } return(UniTask.FromCanceled()); } _server = new Server(this, _epicOptions); _server.StartListening(); _listenCompletionSource = AutoResetUniTaskCompletionSource.Create(); return(_listenCompletionSource.Task); }