125 lines
4.2 KiB
C#
125 lines
4.2 KiB
C#
using System.Runtime.CompilerServices;
|
|
|
|
namespace FishNet.Managing.Timing
|
|
{
|
|
|
|
public struct EstimatedTick
|
|
{
|
|
|
|
/// <summary>
|
|
/// How to handle old ticks, specifically related to EstimatedTick.
|
|
/// </summary>
|
|
public enum OldTickOption : byte
|
|
{
|
|
/// <summary>
|
|
/// Completely ignore old ticks.
|
|
/// </summary>
|
|
Discard = 0,
|
|
/// <summary>
|
|
/// Set LastRemoteTick but do not update RemoteTick.
|
|
/// </summary>
|
|
SetLastRemoteTick = 1,
|
|
/// <summary>
|
|
/// Set LastRemoteTick and RemoteTick.
|
|
/// </summary>
|
|
SetRemoteTick = 2,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Local tick when this was last updated.
|
|
/// </summary>
|
|
public uint LocalTick;
|
|
/// <summary>
|
|
/// Last remote tick this was updated with that was not out of order or a duplicate.
|
|
/// </summary>
|
|
public uint RemoteTick;
|
|
/// <summary>
|
|
/// Last remote tick received regardless if it was out of order or a duplicate.
|
|
/// </summary>
|
|
public uint LastRemoteTick;
|
|
/// <summary>
|
|
/// True if the value was updated this tick.
|
|
/// </summary>
|
|
public bool IsCurrent(TimeManager tm) => (!IsUnset && LocalTick == tm.LocalTick);
|
|
/// <summary>
|
|
/// True if value is unset.
|
|
/// </summary>
|
|
//Only need to check one value for unset as they all would be if not set.
|
|
public bool IsUnset => (LocalTick == 0);
|
|
/// <summary>
|
|
/// Number of ticks LocalTick is being current LocalTick.
|
|
/// </summary>
|
|
public uint LocalTickDifference(TimeManager tm)
|
|
{
|
|
long value = (tm.LocalTick - LocalTick);
|
|
//Shouldn't be possible to be less than 0.
|
|
if (value < 0)
|
|
return 0;
|
|
else if (value > uint.MaxValue)
|
|
value = uint.MaxValue;
|
|
|
|
return (uint)value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates values.
|
|
/// </summary>
|
|
/// <param name="nm">NetworkManager to use.</param>
|
|
/// <param name="remoteTick">Remote tick being updated.</param>
|
|
/// <param name="ignoreOldTicks">True to not update if remote tick is older or equal to the last updated value.</param>
|
|
/// <returns>True if was able to update values.</returns>
|
|
public bool Update(TimeManager tm, uint remoteTick, OldTickOption oldTickOption = OldTickOption.Discard)
|
|
{
|
|
//Always set LastRemoteTick even if out of order.
|
|
LastRemoteTick = remoteTick;
|
|
//If cannot update with old values return.
|
|
if (oldTickOption != OldTickOption.SetRemoteTick && remoteTick <= RemoteTick)
|
|
return false;
|
|
|
|
//nm is assumed set here.
|
|
LocalTick = tm.LocalTick;
|
|
RemoteTick = remoteTick;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Current estimated value.
|
|
/// </summary>
|
|
/// <param name="nm">NetworkManager to use. When null default value will be returned.</param>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public uint Value(TimeManager tm)
|
|
{
|
|
return Value(tm, out _);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Current estimated value. Outputs if value is current.
|
|
/// </summary>
|
|
/// <param name="nm">NetworkManager to use. When null default value will be returned.</param>
|
|
/// <param name="isCurrent">True if the value was updated this local tick.</param>
|
|
public uint Value(TimeManager tm, out bool isCurrent)
|
|
{
|
|
isCurrent = IsCurrent(tm);
|
|
if (tm == null)
|
|
return 0;
|
|
if (IsUnset)
|
|
return 0;
|
|
|
|
uint diff = (tm.LocalTick - LocalTick);
|
|
return (diff + RemoteTick);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets values to unset.
|
|
/// </summary>
|
|
public void Reset()
|
|
{
|
|
LocalTick = 0;
|
|
RemoteTick = 0;
|
|
LastRemoteTick = 0;
|
|
}
|
|
}
|
|
|
|
|
|
} |