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