using System; using System.Collections; using UnityEngine; namespace OmiLAXR.Schedules { /// /// Abstract base class for all schedulers in the OmiLAXR system. /// Provides common functionality for starting, stopping, and managing scheduled operations. /// Requires derived classes to implement the core timing logic through the Run method. /// public abstract class Scheduler { [Serializable] public abstract class Settings { [Tooltip("Shows that the Schulder is active.")] public bool isActive = true; [Tooltip("Don't wait for first tick.")] public bool tickImmediate = true; [Tooltip("Autostart Scheduler after creation.")] public bool runImmediate = true; } /// /// Reference to the MonoBehaviour that will own and execute the coroutine. /// This is necessary because only MonoBehaviours can start coroutines in Unity. /// protected readonly MonoBehaviour Owner; /// /// Reference to the running coroutine. Null when the scheduler is not active. /// Used to keep track of and stop the currently running coroutine when needed. /// protected Coroutine Coroutine; /// /// The handler that receives scheduling events (start, tick, end). /// Implements IScheduleHandler to provide a consistent interface for all scheduler types. /// public event Action OnTick; public event Action OnTickStart; public event Action OnTickEnd; private Settings _settings; private bool _isRunning = false; /// /// Initializes a new instance of the Scheduler class. /// /// The MonoBehaviour that will own and execute the coroutine. /// /// /// protected Scheduler(MonoBehaviour owner, Settings settings, Action onTick, Action onTickStart = null, Action onTickEnd = null) { Owner = owner; OnTick += onTick; OnTickStart += onTickStart; OnTickEnd += onTickEnd; _settings = settings; } protected virtual void TriggerOnTick() => OnTick?.Invoke(); protected virtual void TriggerOnTickStart() => OnTickStart?.Invoke(); protected virtual void TriggerOnTickEnd() => OnTickEnd?.Invoke(); /// /// Starts the scheduler. If already running, stops the current scheduler first. /// Calls the handler's OnTickStart method and initiates the coroutine. /// /// If true, executes the callback immediately before the first scheduled event. Default is true. public void Start() { if (_isRunning) return; _settings.isActive = true; OnTickStart?.Invoke(); Coroutine = Owner.StartCoroutine(Run(_settings.tickImmediate)); _isRunning = true; } /// /// Stops the scheduler if it's currently running. /// Calls the handler's OnTickEnd method and cleans up the coroutine reference. /// public void Stop() { if (!_isRunning) return; OnTickEnd?.Invoke(); _settings.isActive = false; if (Coroutine != null) { Owner.StopCoroutine(Coroutine); Coroutine = null; } _isRunning = false; } /// /// Private coroutine wrapper that handles the immediate execution option /// before delegating to the derived class's Run implementation. /// /// If true, executes the callback immediately before waiting for the first scheduled event. /// IEnumerator required for coroutine functionality. private IEnumerator Run(bool immediate) { if (immediate) TriggerOnTick(); yield return Run(); } /// /// Abstract method that derived scheduler classes must implement. /// Defines the core timing logic for when the handler's OnTick method is called. /// /// An IEnumerator for Unity's coroutine system. protected abstract IEnumerator Run(); } }