using Unity.Burst; using Unity.Burst.CompilerServices; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Jobs; namespace LitMotion { /// /// A job that updates the status of the motion data and outputs the current value. /// /// The type of value to animate /// The type of special parameters given to the motion data /// The type of adapter that support value animation [BurstCompile] public unsafe struct MotionUpdateJob : IJobParallelFor where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter { [NativeDisableUnsafePtrRestriction] internal MotionData* DataPtr; [ReadOnly] public double DeltaTime; [ReadOnly] public double UnscaledDeltaTime; [ReadOnly] public double RealDeltaTime; [WriteOnly] public NativeList.ParallelWriter CompletedIndexList; [WriteOnly] public NativeArray Output; public void Execute([AssumeRange(0, int.MaxValue)] int index) { var ptr = DataPtr + index; ref var state = ref ptr->Core.State; ref var parameters = ref ptr->Core.Parameters; if (Hint.Likely(state.Status is MotionStatus.Scheduled or MotionStatus.Delayed or MotionStatus.Playing) || Hint.Unlikely(state.IsPreserved && state.Status is MotionStatus.Completed)) { if (Hint.Unlikely(state.IsInSequence)) return; var deltaTime = parameters.TimeKind switch { MotionTimeKind.Time => DeltaTime, MotionTimeKind.UnscaledTime => UnscaledDeltaTime, MotionTimeKind.Realtime => RealDeltaTime, _ => default }; var time = state.Time + deltaTime * state.PlaybackSpeed; ptr->Update(time, out var result); Output[index] = result; } else if ((!state.IsPreserved && state.Status is MotionStatus.Completed) || state.Status is MotionStatus.Canceled) { CompletedIndexList.AddNoResize(index); state.Status = MotionStatus.Disposed; } } } }