// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved. // This code can only be used under the standard Unity Asset Store End User License Agreement // A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms using Doozy.Runtime.Reactor.Internal; namespace Doozy.Runtime.Reactor.Ticker { /// Base class that registers to a tick service and ticks a target callback (when registered) public abstract class Heartbeat : IUseTickService { public bool isActive { get; private set; } /// Time updater public virtual double timeSinceStartup => 0f; public double lastUpdateTime { get; set; } public double deltaTime { get { double delta = timeSinceStartup - lastUpdateTime; lastUpdateTime = timeSinceStartup; return delta; } } /// /// Callback invoked every time the tick service (this Heartbeat is registered to) ticks /// Register to a tick service to Start invoking on every tick /// Unregister from the tick service to Stop invoking on every tick /// public ReactionCallback onTickCallback { get; internal set; } /// Construct a Heartbeat with a target callback /// Target callback protected Heartbeat(ReactionCallback onTickCallback) => this.onTickCallback = onTickCallback; /// Tick the target callback public virtual void Tick() => onTickCallback?.Invoke(); /// Register to a Tick Service to Start ticking the callback public virtual void RegisterToTickService() { isActive = true; lastUpdateTime = timeSinceStartup; } /// Unregister from the Tick Service to Stop ticking the callback public virtual void UnregisterFromTickService() { isActive = false; } } public static class HeartbeatExtensions { /// /// Clear any callbacks from being called by onTickCallback /// This method sets onTickCallback to null /// /// Target Heartbeat public static T ClearOnTickCallback(this T target) where T : Heartbeat { target.onTickCallback = null; return target; } /// /// Set a target callback that will be invoked every time the tick service (this Heartbeat is registered to) ticks /// This method clears any other callbacks for onTickCallback and sets a single one /// /// Target Heartbeat /// Target callback public static T SetOnTickCallback(this T target, ReactionCallback callback) where T : Heartbeat { target.onTickCallback = callback; return target; } /// /// Add a target callback that will be invoked every time the tick service (this Heartbeat is registered to) ticks /// This method allows adding multiple callbacks for onTickCallback /// /// Target Heartbeat /// Target callback public static T AddOnTickCallback(this T target, ReactionCallback callback) where T : Heartbeat { target.onTickCallback -= callback; //sanity check target.onTickCallback += callback; return target; } /// /// Remove a target callback from being invoked every time the tick service (this Heartbeat is registered to) ticks /// /// Target Heartbeat /// Target callback public static T RemoveOnTickCallback(this T target, ReactionCallback callback) where T : Heartbeat { target.onTickCallback -= callback; return target; } } }