using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Microsoft.VisualBasic;
using Terminal.Gui.App;
using Terminal.Gui.Drivers;
using Terminal.Gui.Views;
namespace Terminal.Gui.App;
public static partial class Application // Lifecycle (Init/Shutdown)
{
///
/// Gets the observable collection of all application instances.
/// External observers can subscribe to this collection to monitor application lifecycle.
///
public static ObservableCollection Apps { get; } = [];
///
/// Gets the singleton instance used by the legacy static Application model.
///
///
///
/// For new code, prefer using to get an instance-based application.
/// This property is provided for backward compatibility and internal use.
///
///
/// This property returns the same singleton instance used by the legacy static
/// methods like and .
///
///
[Obsolete ("The legacy static Application object is going away. Use Application.Create() for new code.")]
public static IApplication Instance => ApplicationImpl.Instance;
///
/// Creates a new instance.
///
///
/// If , the application will run in example mode where metadata is collected
/// and demo keys are automatically sent when the first TopRunnable is modal.
///
///
/// The recommended pattern is for developers to call Application.Create() and then use the returned
/// instance for all subsequent application operations.
///
/// A new instance.
///
/// Thrown if the legacy static Application model has already been used in this process.
///
public static IApplication Create (bool example = false)
{
//Debug.Fail ("Application.Create() called");
ApplicationImpl.MarkInstanceBasedModelUsed ();
ApplicationImpl app = new () { IsExample = example };
Apps.Add (app);
return app;
}
///
[RequiresUnreferencedCode ("AOT")]
[RequiresDynamicCode ("AOT")]
[Obsolete ("The legacy static Application object is going away.")]
public static void Init (string? driverName = null)
{
//Debug.Fail ("Application.Init() called - parallelizable tests should not use legacy static Application model");
ApplicationImpl.Instance.Init (driverName ?? ForceDriver);
}
///
/// Gets or sets the main thread ID for the application.
///
[Obsolete ("The legacy static Application object is going away.")]
public static int? MainThreadId
{
get => ApplicationImpl.Instance.MainThreadId;
internal set => ApplicationImpl.Instance.MainThreadId = value;
}
///
[Obsolete ("The legacy static Application object is going away.")]
public static void Shutdown () => ApplicationImpl.Instance.Dispose ();
///
[Obsolete ("The legacy static Application object is going away.")]
public static bool Initialized
{
get => ApplicationImpl.Instance.Initialized;
internal set => ApplicationImpl.Instance.Initialized = value;
}
///
[Obsolete ("The legacy static Application object is going away.")]
public static event EventHandler>? InitializedChanged
{
add => ApplicationImpl.Instance.InitializedChanged += value;
remove => ApplicationImpl.Instance.InitializedChanged -= value;
}
// IMPORTANT: Ensure all property/fields are reset here. See Init_ResetState_Resets_Properties unit test.
// Encapsulate all setting of initial state for Application; Having
// this in a function like this ensures we don't make mistakes in
// guaranteeing that the state of this singleton is deterministic when Init
// starts running and after Shutdown returns.
[Obsolete ("The legacy static Application object is going away.")]
internal static void ResetState (bool ignoreDisposed = false)
{
// Use the static reset method to bypass the fence check
ApplicationImpl.ResetStateStatic (ignoreDisposed);
}
}