// System using System; using System.Collections.Generic; // Unity using UnityEngine; // GUPS - AntiCheat - Core using GUPS.AntiCheat.Core.Monitor; using GUPS.AntiCheat.Core.Watch; namespace GUPS.AntiCheat.Monitor { /// /// An abstract base class that defines the common functionality for monitors in a Unity environment. /// Implements the and interfaces. /// /// /// /// The class serves as an abstract base for implementing monitors in Unity applications. /// It provides methods to control the lifecycle of a monitoring process and supports the observer pattern /// through the interface. Monitors can be started, paused, resumed, and stopped, /// and they notify subscribed observers of relevant events during their lifecycle. /// /// public abstract class AMonitor : MonoBehaviour, IMonitor, IWatchAble { // Name #region Name /// /// The name of the monitor. /// public abstract String Name { get; } #endregion // Lifecycle #region Lifecycle /// /// A value indicating whether the monitor is active and should be running (Default: true). /// [SerializeField] [Header("General - Settings")] [Tooltip("A value indicating whether the monitor is active and should be running (Default: true).")] private bool isActive = true; /// /// A value indicating whether the monitor is active and should be running. /// public bool IsActive => this.isActive; /// /// Gets a value indicating whether the monitor has been started and is currently running. /// public bool IsStarted { get; private set; } /// /// Gets a value indicating whether the monitor has been paused and is currently suspended. /// public bool IsPaused { get; private set; } /// /// Initiates the monitoring process, enabling the monitor to start collecting and processing data. /// public void Start() { // Check if the monitor is already started, if so return. if (this.IsStarted) { return; } // Set the monitor as started. this.IsStarted = true; // Notify. this.OnStart(); } /// /// Executed when the monitor is started. Override this method to provide custom start behavior. /// protected virtual void OnStart() { } /// /// Pauses the monitoring process, temporarily suspending data collection and processing without terminating the monitor. /// public void Pause() { // Check if the monitor is paused, if so return. if (this.IsPaused) { return; } // Check if the monitor not started, if so return. if (!this.IsStarted) { return; } // Set the monitor as paused. this.IsPaused = true; // Notify. this.OnPause(); } /// /// Executed when the monitor is paused. Override this method to provide custom pause behavior. /// protected virtual void OnPause() { } /// /// Resumes the monitoring process after a pause, allowing the monitor to continue collecting and processing data. /// public void Resume() { // Check if the monitor is not paused, if so return. if (!this.IsPaused) { return; } // Check if the monitor not started, if so return. if (!this.IsStarted) { return; } // Set the monitor as not paused. this.IsPaused = false; // Notify. this.OnResume(); } /// /// Executed when the monitor is resumed after a pause. Override this method to provide custom resume behavior. /// protected virtual void OnResume() { } /// /// Stops and terminates the monitoring process, concluding data collection and finalizing any necessary cleanup operations. /// public void Stop() { // Check if the monitor is not started, if so return. if (!this.IsStarted) { return; } // Set the monitor as not started. this.IsStarted = false; // Notify. this.OnStop(); } /// /// Executed when the monitor is stopped. Override this method to provide custom stop behavior. /// protected virtual void OnStop() { } /// /// Executed on each Unity update cycle when the monitor is started and not paused. /// private void Update() { // Check if the monitor is started and not paused. if (!this.IsStarted || this.IsPaused) { return; } // Check if the monitor is active. if (!this.isActive) { return; } // Notify. this.OnUpdate(); } /// /// Executed on each Unity update cycle when the monitor is started and not paused. /// Override this method to implement custom update behavior. /// protected virtual void OnUpdate() { } /// /// When the monitor is destroyed, stop the monitor. /// protected virtual void OnDestroy() { // Stop the monitor. this.Stop(); } /// /// Notifies the observers that the monitor has completed. /// public void Dispose() { foreach (var var_Observer in this.observers) { if (var_Observer == null) { continue; } var_Observer.OnCompleted(); } this.observers.Clear(); } #endregion // Observable #region Observable /// /// The list of observers subscribed to the monitor. /// private List> observers = new List>(); /// /// Subscribes an observer to receive notifications of the monitor. /// /// The observer to subscribe. /// An object that can be used to unsubscribe the observer. public IDisposable Subscribe(IObserver _Observer) { if (!this.observers.Contains(_Observer)) { this.observers.Add(_Observer); } return new Unsubscriber(this.observers, _Observer); } /// /// Notifies all subscribed observers with the provided watched monitor subject. /// /// The watched subject to notify observers about. public void Notify(IWatchedSubject _Subject) { foreach (var var_Observer in this.observers) { if (var_Observer == null) { continue; } var_Observer.OnNext(_Subject); } } /// /// Represents a disposable object used to unsubscribe an observer from the monitor. /// private class Unsubscriber : IDisposable { private List> observers; private IObserver observer; /// /// Initializes a new instance of the class. /// /// The list of observers to manage. /// The observer to unsubscribe. public Unsubscriber(List> observers, IObserver observer) { this.observers = observers; this.observer = observer; } /// /// Disposes of the observer, removing it from the list of observers. /// public void Dispose() { if (this.observer != null && this.observers.Contains(this.observer)) { this.observers.Remove(this.observer); } } } #endregion } }