namespace Fusion.Addons.KCC { using System; using UnityEngine; public sealed unsafe class KCCNetworkFloatRange : KCCNetworkProperty where TContext : class { // PRIVATE MEMBERS private readonly float _min; private readonly float _max; private readonly float _readAccuracy; private readonly float _writeAccuracy; private readonly Action _set; private readonly Func _get; private readonly Func _interpolate; // CONSTRUCTORS public KCCNetworkFloatRange(TContext context, float min, float max, float accuracy, Action set, Func get, Func interpolate) : base(context, 1) { _min = min; _max = max; _readAccuracy = accuracy > 0.0f ? accuracy : 0.0f; _writeAccuracy = accuracy > 0.0f ? 1.0f / accuracy : 0.0f; _set = set; _get = get; _interpolate = interpolate; } // KCCNetworkProperty INTERFACE public override void Read(int* ptr) { float value; if (_readAccuracy <= 0.0f) { value = *(float*)ptr; } else { value = (*ptr) * _readAccuracy; } _set(Context, value); } public override void Write(int* ptr) { float value = Mathf.Clamp(_get(Context), _min, _max); if (_writeAccuracy <= 0.0f) { *(float*)ptr = value; } else { *ptr = value < 0.0f ? (int)((value * _writeAccuracy) - 0.5f) : (int)((value * _writeAccuracy) + 0.5f); } } public override void Interpolate(KCCInterpolationInfo interpolationInfo) { float fromValue = _readAccuracy <= 0.0f ? interpolationInfo.FromBuffer.ReinterpretState(interpolationInfo.Offset) : interpolationInfo.FromBuffer.ReinterpretState(interpolationInfo.Offset) * _readAccuracy; float toValue = _readAccuracy <= 0.0f ? interpolationInfo.ToBuffer.ReinterpretState(interpolationInfo.Offset) : interpolationInfo.ToBuffer.ReinterpretState(interpolationInfo.Offset) * _readAccuracy; float value; if (_interpolate != null) { value = _interpolate(Context, interpolationInfo.Alpha, fromValue, toValue); } else { value = KCCUtility.InterpolateRange(fromValue, toValue, _min, _max, interpolationInfo.Alpha); } _set(Context, value); } } }