| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 | using System;using System.Collections;using System.Threading;using System.Threading.Tasks;using UnityEngine;namespace LitMotion{    /// <summary>    /// Provides methods for manipulating the motion entity pointed to by MotionHandle.    /// </summary>    public static class MotionHandleExtensions    {        /// <summary>        /// Checks if a motion is currently playing.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <returns>True if motion is active, otherwise false.</returns>        public static bool IsActive(this MotionHandle handle)        {            return MotionStorageManager.IsActive(handle);        }        /// <summary>        /// Complete motion.        /// </summary>        /// <param name="handle">This motion handle</param>        public static void Complete(this MotionHandle handle)        {            MotionStorageManager.CompleteMotion(handle);        }        /// <summary>        /// Cancel motion.        /// </summary>        /// <param name="handle">This motion handle</param>        public static void Cancel(this MotionHandle handle)        {            MotionStorageManager.CancelMotion(handle);        }        /// <summary>        /// Add this motion handle to CompositeMotionHandle.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="compositeMotionHandle">target CompositeMotionHandle</param>        public static MotionHandle AddTo(this MotionHandle handle, CompositeMotionHandle compositeMotionHandle)        {            compositeMotionHandle.Add(handle);            return handle;        }        /// <summary>        /// Link the motion lifecycle to the target object.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="target">Target object</param>        public static MotionHandle AddTo(this MotionHandle handle, GameObject target)        {            GetOrAddComponent<MotionHandleLinker>(target).Register(handle, LinkBehaviour.CancelOnDestroy);            return handle;        }        /// <summary>        /// Link the motion lifecycle to the target object.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="target">Target object</param>        /// <param name="linkBehaviour">Link behaviour</param>        public static MotionHandle AddTo(this MotionHandle handle, GameObject target, LinkBehaviour linkBehaviour)        {            GetOrAddComponent<MotionHandleLinker>(target).Register(handle, linkBehaviour);            return handle;        }        /// <summary>        /// Link the motion lifecycle to the target object.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="target">Target object</param>        public static MotionHandle AddTo(this MotionHandle handle, Component target)        {            GetOrAddComponent<MotionHandleLinker>(target.gameObject).Register(handle, LinkBehaviour.CancelOnDestroy);            return handle;        }        /// <summary>        /// Link the motion lifecycle to the target object.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="target">Target object</param>        /// <param name="linkBehaviour">Link behaviour</param>        public static MotionHandle AddTo(this MotionHandle handle, Component target, LinkBehaviour linkBehaviour)        {            GetOrAddComponent<MotionHandleLinker>(target.gameObject).Register(handle, linkBehaviour);            return handle;        }#if UNITY_2022_2_OR_NEWER        /// <summary>        /// Link the motion lifecycle to the target object.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="target">Target object</param>        public static MotionHandle AddTo(this MotionHandle handle, MonoBehaviour target)        {            target.destroyCancellationToken.Register(() =>            {                if (handle.IsActive()) handle.Cancel();            }, false);            return handle;        }#endif        static TComponent GetOrAddComponent<TComponent>(GameObject target) where TComponent : Component        {            if (!target.TryGetComponent<TComponent>(out var component))            {                component = target.AddComponent<TComponent>();            }            return component;        }        /// <summary>        /// Convert MotionHandle to IDisposable.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <returns></returns>        public static IDisposable ToDisposable(this MotionHandle handle)        {            return new MotionHandleDisposable(handle);        }        /// <summary>        /// Wait for the motion to finish in a coroutine.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <returns></returns>        public static IEnumerator ToYieldInteraction(this MotionHandle handle)        {            while (handle.IsActive())            {                yield return null;            }        }        public static MotionAwaiter GetAwaiter(this MotionHandle handle)        {            return new MotionAwaiter(handle);        }        /// <summary>        /// Convert motion handle to ValueTask.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="cancellationToken">CancellationToken</param>        /// <returns></returns>        public static ValueTask ToValueTask(this MotionHandle handle, CancellationToken cancellationToken = default)        {            if (!handle.IsActive()) return default;            var source = ValueTaskMotionConfiguredSource.Create(handle, CancelBehaviour.CancelAndCancelAwait, cancellationToken, out var token);            return new ValueTask(source, token);        }        /// <summary>        /// Convert motion handle to ValueTask.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="cancelBehaviour">Behavior when canceling</param>        /// <param name="cancellationToken">CancellationToken</param>        /// <returns></returns>        public static ValueTask ToValueTask(this MotionHandle handle, CancelBehaviour cancelBehaviour, CancellationToken cancellationToken = default)        {            if (!handle.IsActive()) return default;            var source = ValueTaskMotionConfiguredSource.Create(handle, cancelBehaviour, cancellationToken, out var token);            return new ValueTask(source, token);        }#if UNITY_2023_1_OR_NEWER        /// <summary>        /// Convert motion handle to Awaitable.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="cancellationToken">CancellationToken</param>        /// <returns></returns>        public static Awaitable ToAwaitable(this MotionHandle handle, CancellationToken cancellationToken = default)        {            if (!handle.IsActive()) return AwaitableMotionConfiguredSource.CompletedSource.Awaitable;            return AwaitableMotionConfiguredSource.Create(handle, CancelBehaviour.CancelAndCancelAwait, cancellationToken).Awaitable;        }        /// <summary>        /// Convert motion handle to Awaitable.        /// </summary>        /// <param name="handle">This motion handle</param>        /// <param name="cancelBehaviour">Behavior when canceling</param>        /// <param name="cancellationToken">CancellationToken</param>        /// <returns></returns>        public static Awaitable ToAwaitable(this MotionHandle handle, CancelBehaviour cancelBehaviour, CancellationToken cancellationToken = default)        {            if (!handle.IsActive()) return AwaitableMotionConfiguredSource.CompletedSource.Awaitable;            return AwaitableMotionConfiguredSource.Create(handle, cancelBehaviour, cancellationToken).Awaitable;        }#endif    }    internal sealed class MotionHandleDisposable : IDisposable    {        public MotionHandleDisposable(MotionHandle handle) => this.handle = handle;        public readonly MotionHandle handle;        public void Dispose()        {            if (handle.IsActive()) handle.Cancel();        }    }}
 |