namespace Terminal.Gui.ViewBase; /// /// Base implementation of for views that can be run as sessions. /// /// /// /// Views can derive from this class or implement directly. /// This base class provides a complete reference implementation of the /// interface following Terminal.Gui's Cancellable Work Pattern. /// /// /// To customize lifecycle behavior, override the protected virtual methods: /// , , , . /// /// public class Runnable : View, IRunnable { /// public bool Running { get; set; } #region IRunnable Implementation (RaiseXxxEvent Methods) /// public virtual bool RaiseStartingEvent () { // CWP Phase 1: Pre-notification via virtual method (can cancel) if (OnStarting ()) { return true; // Starting canceled } // CWP Phase 2: Event notification (can cancel) var args = new System.ComponentModel.CancelEventArgs (); Starting?.Invoke (this, args); if (args.Cancel) { return true; // Starting canceled } // CWP Phase 3: Perform the work (mark as running) Running = true; // CWP Phase 4: Post-notification via virtual method OnStarted (); // CWP Phase 5: Post-notification event Started?.Invoke (this, EventArgs.Empty); return false; // Starting succeeded } /// public virtual void RaiseStartedEvent () { Started?.Invoke (this, EventArgs.Empty); } /// public virtual void RaiseStoppingEvent () { // CWP Phase 1: Pre-notification via virtual method (can cancel) if (OnStopping ()) { return; // Stopping canceled } // CWP Phase 2: Event notification (can cancel) var args = new System.ComponentModel.CancelEventArgs (); Stopping?.Invoke (this, args); if (args.Cancel) { return; // Stopping canceled } // CWP Phase 3: Perform the work (stop the session) Running = false; // CWP Phase 4: Post-notification via virtual method OnStopped (); // CWP Phase 5: Post-notification event Stopped?.Invoke (this, EventArgs.Empty); } #endregion #region Protected Virtual Methods (Override Pattern) /// /// Called before event. Override to cancel starting. /// /// to cancel; to proceed. /// /// /// This is the first phase of the Cancellable Work Pattern for starting. /// Default implementation returns (allow starting). /// /// /// Override this method to provide custom logic for determining whether the runnable /// should start (e.g., validating preconditions). /// /// protected virtual bool OnStarting () { return false; // Default: allow starting } /// /// Called after session has started. Override for post-start work. /// /// /// /// This is the fourth phase of the Cancellable Work Pattern for starting. /// At this point, is . /// Default implementation does nothing. /// /// /// Override this method to perform work that should occur after the session starts. /// /// protected virtual void OnStarted () { // Default: do nothing } /// /// Called before event. Override to cancel stopping. /// /// to cancel; to proceed. /// /// /// This is the first phase of the Cancellable Work Pattern for stopping. /// Default implementation returns (allow stopping). /// /// /// Override this method to provide custom logic for determining whether the runnable /// should stop (e.g., prompting the user to save changes). /// /// protected virtual bool OnStopping () { return false; // Default: allow stopping } /// /// Called after session has stopped. Override for post-stop cleanup. /// /// /// /// This is the fourth phase of the Cancellable Work Pattern for stopping. /// At this point, is . /// Default implementation does nothing. /// /// /// Override this method to perform cleanup work that should occur after the session stops. /// /// protected virtual void OnStopped () { // Default: do nothing } #endregion #region Events // Note: Initializing and Initialized events are inherited from View (ISupportInitialize pattern) /// public event EventHandler? Starting; /// public event EventHandler? Started; /// public event EventHandler? Stopping; /// public event EventHandler? Stopped; #endregion /// /// Stops and closes this runnable session. /// /// /// /// This method calls to initiate the stopping process. /// The Application infrastructure will update this once IApplication supports IRunnable directly. /// /// public virtual void RequestStop () { // TODO: Phase 3 - Update Application.RequestStop to accept IRunnable // For now, directly call RaiseStoppingEvent which follows CWP RaiseStoppingEvent (); } }