namespace Terminal.Gui.App;
///
/// Non-generic base interface for runnable views. Provides common members without type parameter.
///
///
///
/// This interface enables storing heterogeneous runnables in collections (e.g.,
/// )
/// while preserving type safety at usage sites via .
///
///
/// Most code should use directly. This base interface is primarily
/// for framework infrastructure (session management, stacking, etc.).
///
///
/// A runnable view executes as a self-contained blocking session with its own lifecycle,
/// event loop iteration, and focus management./>
/// blocks until
/// is called.
///
///
/// This interface follows the Terminal.Gui Cancellable Work Pattern (CWP) for all lifecycle events.
///
///
///
///
public interface IRunnable
{
#region Result
///
/// Gets or sets the result data extracted when the session was accepted, or if not accepted.
///
///
///
/// This is the non-generic version of the result property. For type-safe access, cast to
/// or access the derived interface's Result property directly.
///
///
/// Implementations should set this in the method
/// (when stopping, i.e., newIsRunning == false) by extracting data from
/// views before they are disposed.
///
///
/// indicates the session was stopped without accepting (ESC key, close without action).
/// Non- contains the result data.
///
///
object? Result { get; set; }
#endregion Result
#region Running or not (added to/removed from RunnableSessionStack)
///
/// Sets the application context for this runnable. Called from .
///
///
void SetApp (IApplication app);
///
/// Gets whether this runnable session is currently running (i.e., on the
/// ).
///
///
///
/// This property returns a cached value that is updated atomically when the runnable is added to or
/// removed from the session stack. The cached state ensures thread-safe access without race conditions.
///
///
/// Returns if this runnable is currently on the ,
/// otherwise.
///
///
/// Runnables are added to the stack during and removed in
/// .
///
///
bool IsRunning { get; }
///
/// Sets the cached IsRunning state. Called by ApplicationImpl within the session stack lock.
/// This method is internal to the framework and should not be called by application code.
///
/// The new IsRunning value.
void SetIsRunning (bool value);
///
/// Requests that this runnable session stop.
///
public void RequestStop ();
///
/// Called by the framework to raise the event.
///
/// The current value of .
/// The new value of (true = starting, false = stopping).
/// if the change was canceled; otherwise .
///
///
/// This method implements the Cancellable Work Pattern. It calls the protected virtual method first,
/// then raises the event if not canceled.
///
///
/// When is (stopping), this is the ideal place
/// for implementations to extract Result from views before the runnable is removed from the stack.
///
///
bool RaiseIsRunningChanging (bool oldIsRunning, bool newIsRunning);
///
/// Raised when is changing (e.g., when or
/// is called).
/// Can be canceled by setting `args.Cancel` to .
///
///
///
/// Subscribe to this event to participate in the runnable lifecycle before state changes occur.
/// When is (stopping),
/// this is the ideal place to extract Result before views are disposed and to optionally
/// cancel the stop operation (e.g., prompt to save changes).
///
///
/// This event follows the Terminal.Gui Cancellable Work Pattern (CWP).
///
///
event EventHandler>? IsRunningChanging;
///
/// Called by the framework to raise the event.
///
/// The new value of (true = started, false = stopped).
///
/// This method is called after the state change has occurred and cannot be canceled.
///
void RaiseIsRunningChangedEvent (bool newIsRunning);
///
/// Raised after has changed (after the runnable has been added to or removed from the
/// ).
///
///
///
/// Subscribe to this event to perform post-state-change logic. When is
/// ,
/// the runnable has started and is on the stack. When , the runnable has stopped and been
/// removed from the stack.
///
///
/// This event follows the Terminal.Gui Cancellable Work Pattern (CWP).
///
///
event EventHandler>? IsRunningChanged;
#endregion Running or not (added to/removed from RunnableSessionStack)
#region Modal or not (top of RunnableSessionStack or not)
///
/// Gets whether this runnable session is at the top of the and thus
/// exclusively receiving mouse and keyboard input.
///
///
///
/// This property returns a cached value that is updated atomically when the runnable's modal state changes.
/// The cached state ensures thread-safe access without race conditions.
///
///
/// Returns if this runnable is at the top of the stack (i.e., this == app.TopRunnable),
/// otherwise.
///
///
/// The runnable at the top of the stack gets all mouse/keyboard input and thus is running "modally".
///
///
bool IsModal { get; }
///
/// Sets the cached IsModal state. Called by ApplicationImpl within the session stack lock.
/// This method is internal to the framework and should not be called by application code.
///
/// The new IsModal value.
void SetIsModal (bool value);
///
/// Gets or sets whether a stop has been requested for this runnable session.
///
bool StopRequested { get; set; }
///
/// Called by the framework to raise the event.
///
/// The new value of (true = became modal/top, false = no longer modal).
///
/// This method is called after the modal state change has occurred and cannot be canceled.
///
void RaiseIsModalChangedEvent (bool newIsModal);
///
/// Raised after this runnable has become modal (top of stack) or ceased being modal.
///
///
///
/// Subscribe to this event to perform post-activation logic (e.g., setting focus, updating UI state).
/// When is , the runnable became modal (top of
/// stack).
/// When , the runnable is no longer modal (another runnable is on top).
///
///
/// This event follows the Terminal.Gui Cancellable Work Pattern (CWP).
///
///
event EventHandler>? IsModalChanged;
#endregion Modal or not (top of RunnableSessionStack or not)
}
///
/// Defines a view that can be run as an independent blocking session with ,
/// returning a typed result.
///
///
/// The type of result data returned when the session completes.
/// Common types: for button indices, for file paths,
/// custom types for complex form data.
///
///
///
/// A runnable view executes as a self-contained blocking session with its own lifecycle,
/// event loop iteration, and focus management. blocks until
/// is called.
///
///
/// When is , the session was stopped without being accepted
/// (e.g., ESC key pressed, window closed). When non-, it contains the result data
/// extracted in (when stopping) before views are disposed.
///
///
/// Implementing does not require deriving from any specific
/// base class or using . These are orthogonal concerns.
///
///
/// This interface follows the Terminal.Gui Cancellable Work Pattern (CWP) for all lifecycle events.
///
///
///
///
public interface IRunnable : IRunnable
{
///
/// Gets or sets the result data extracted when the session was accepted, or if not accepted.
///
///
///
/// Implementations should set this in the method
/// (when stopping, i.e., newIsRunning == false) by extracting data from
/// views before they are disposed.
///
///
/// indicates the session was stopped without accepting (ESC key, close without action).
/// Non- contains the type-safe result data.
///
///
new TResult? Result { get; set; }
}