#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; using System.Threading; using UniRx.Async.Internal; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; namespace UniRx.Async { 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 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 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 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 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 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 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 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 OnValueChanged(this Dropdown dropdown) { return new AsyncUnityEventHandler(dropdown.onValueChanged, dropdown.GetCancellationTokenOnDestroy(), true).OnInvokeAsync(); } public static UniTask OnValueChanged(this Dropdown dropdown, CancellationToken cancellationToken) { return new AsyncUnityEventHandler(dropdown.onValueChanged, cancellationToken, true).OnInvokeAsync(); } } public interface IAsyncClickEventHandler : IDisposable { UniTask OnClickAsync(); } public interface IAsyncValueChangedEventHandler : IDisposable { UniTask OnValueChangedAsync(); } public interface IAsyncEndEditEventHandler : IDisposable { UniTask OnEndEditAsync(); } 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) { if (cancellationToken.IsCancellationRequested) { isDisposed = true; return; } this.action = Invoke; this.unityEvent = unityEvent; this.cancellationToken = cancellationToken; this.callOnce = callOnce; unityEvent.AddListener(action); if (cancellationToken.CanBeCanceled) { registration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); } TaskTracker.TrackActiveTask(this, 3); } public UniTask OnInvokeAsync() { core.Reset(); return new UniTask(this, core.Version); } void Invoke() { core.TrySetResult(AsyncUnit.Default); } static void CancellationCallback(object state) { var self = (AsyncUnityEventHandler)state; self.Dispose(); self.core.TrySetCanceled(self.cancellationToken); } public void Dispose() { if (!isDisposed) { isDisposed = true; TaskTracker.RemoveTracking(this); registration.Dispose(); if (unityEvent != null) { unityEvent.RemoveListener(action); } } } 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 { 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) { if (cancellationToken.IsCancellationRequested) { isDisposed = true; return; } this.action = Invoke; this.unityEvent = unityEvent; this.cancellationToken = cancellationToken; this.callOnce = callOnce; unityEvent.AddListener(action); if (cancellationToken.CanBeCanceled) { registration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this); } TaskTracker.TrackActiveTask(this, 3); } public UniTask OnInvokeAsync() { core.Reset(); return new UniTask(this, core.Version); } void Invoke(T result) { core.TrySetResult(result); } static void CancellationCallback(object state) { var self = (AsyncUnityEventHandler)state; self.Dispose(); self.core.TrySetCanceled(self.cancellationToken); } public void Dispose() { if (!isDisposed) { isDisposed = true; TaskTracker.RemoveTracking(this); registration.Dispose(); if (unityEvent != null) { unityEvent.RemoveListener(action); } } } UniTask IAsyncValueChangedEventHandler.OnValueChangedAsync() { return OnInvokeAsync(); } UniTask IAsyncEndEditEventHandler.OnEndEditAsync() { 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); } } }