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();
- }
- }
- }
|