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