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