using System; using System.Collections.Generic; namespace LitMotion { internal sealed class ManualMotionDispatcherScheduler : IMotionScheduler { readonly ManualMotionDispatcher dispatcher; public ManualMotionDispatcherScheduler(ManualMotionDispatcher dispatcher) { this.dispatcher = dispatcher; } public MotionHandle Schedule(ref MotionBuilder builder) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter { return dispatcher.GetOrCreateRunner().Storage.Create(ref builder); } } /// /// Manually updatable MotionDispatcher /// public sealed class ManualMotionDispatcher { /// /// Default ManualMotionDispatcher /// public static readonly ManualMotionDispatcher Default = new(); /// /// MotionScheduler for scheduling to the dispatcher. /// public IMotionScheduler Scheduler => scheduler; readonly ManualMotionDispatcherScheduler scheduler; readonly Dictionary runners = new(); public ManualMotionDispatcher() { scheduler = new(this); } /// /// ManualMotionDispatcher time. It increases every time Update is called. /// public double Time { get => time; set { Update(value - time); } } double time; /// /// Ensures the storage capacity until it reaches at least capacity. /// /// The minimum capacity to ensure public void EnsureStorageCapacity(int capacity) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter { GetOrCreateRunner().Storage.EnsureCapacity(capacity); } /// /// Update all scheduled motions. /// /// Delta time public void Update(double deltaTime) { time += deltaTime; foreach (var kv in runners) { kv.Value.Update(time, time, time); } } /// /// Cancel all motions and reset data. /// public void Reset() { foreach (var kv in runners) { kv.Value.Reset(); } time = 0; } internal UpdateRunner GetOrCreateRunner() where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter { var key = typeof((TValue, TOptions, TAdapter)); if (!runners.TryGetValue(key, out var runner)) { var storage = new MotionStorage(MotionManager.MotionTypeCount); MotionManager.Register(storage); runner = new UpdateRunner(storage, 0, 0, 0); runners.Add(key, runner); } return (UpdateRunner)runner; } } }