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