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