using FishNet.Managing.Timing;
using FishNet.Object;
using GameKit.Dependencies.Utilities;
using UnityEngine;
namespace FishNet.Utility.Template
{
///
/// Subscribes to tick events making them available as virtual methods.
///
public abstract class TickNetworkBehaviour : NetworkBehaviour
{
#region Types.
[System.Flags]
[System.Serializable]
public enum TickCallback : uint
{
None = 0,
PreTick = (1 << 0),
Tick = (1 << 1),
PostTick = (1 << 2),
Update = (1 << 3),
LateUpdate = (1 << 4),
Everything = Enums.SHIFT_EVERYTHING_UINT,
}
#endregion
///
/// Tick callbacks to use.
///
[Tooltip("Tick callbacks to use.")]
[SerializeField]
private TickCallback _tickCallbacks = (TickCallback.Tick | TickCallback.PostTick);
///
/// Last subscription state.
///
private bool _subscribed;
///
/// TimeManager subscribed to.
///
private TimeManager _timeManager;
internal override void OnStartNetwork_Internal()
{
_timeManager = base.TimeManager;
ChangeSubscriptions(subscribe: true);
base.OnStartNetwork_Internal();
}
internal override void OnStopNetwork_Internal()
{
ChangeSubscriptions(subscribe: false);
base.OnStopNetwork_Internal();
}
///
/// Updates callbacks to use and changes subscriptions accordingly.
///
/// Next value.
public void SetTickCallbacks(TickCallback value)
{
ChangeSubscriptions(subscribe: false);
_tickCallbacks = value;
if (value != TickCallback.None)
ChangeSubscriptions(subscribe: true);
}
private void ChangeSubscriptions(bool subscribe)
{
TimeManager tm = _timeManager;
if (tm == null)
return;
if (subscribe == _subscribed)
return;
_subscribed = subscribe;
if (subscribe)
{
if (TickCallbackFastContains(_tickCallbacks, TickCallback.PreTick))
tm.OnPreTick += TimeManager_OnPreTick;
if (TickCallbackFastContains(_tickCallbacks, TickCallback.Tick))
tm.OnTick += TimeManager_OnTick;
if (TickCallbackFastContains(_tickCallbacks, TickCallback.PostTick))
tm.OnPostTick += TimeManager_OnPostTick;
if (TickCallbackFastContains(_tickCallbacks, TickCallback.Update))
tm.OnUpdate += TimeManager_OnUpdate;
if (TickCallbackFastContains(_tickCallbacks, TickCallback.LateUpdate))
tm.OnLateUpdate += TimeManager_OnLateUpdate;
}
else
{
if (TickCallbackFastContains(_tickCallbacks, TickCallback.PreTick))
tm.OnPreTick -= TimeManager_OnPreTick;
if (TickCallbackFastContains(_tickCallbacks, TickCallback.Tick))
tm.OnTick -= TimeManager_OnTick;
if (TickCallbackFastContains(_tickCallbacks, TickCallback.PostTick))
tm.OnPostTick -= TimeManager_OnPostTick;
if (TickCallbackFastContains(_tickCallbacks, TickCallback.Update))
tm.OnUpdate -= TimeManager_OnUpdate;
if (TickCallbackFastContains(_tickCallbacks, TickCallback.LateUpdate))
tm.OnLateUpdate -= TimeManager_OnLateUpdate;
}
}
protected virtual void TimeManager_OnPreTick() { }
protected virtual void TimeManager_OnTick() { }
protected virtual void TimeManager_OnPostTick() { }
protected virtual void TimeManager_OnUpdate() { }
protected virtual void TimeManager_OnLateUpdate() { }
private bool TickCallbackFastContains(TickCallback whole, TickCallback part) => ((whole & part) == part);
}
}