Application.Lifecycle.cs 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #nullable enable
  2. using System.Diagnostics;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.Reflection;
  5. using Microsoft.VisualBasic;
  6. using Terminal.Gui.App;
  7. using Terminal.Gui.Drivers;
  8. using Terminal.Gui.Views;
  9. namespace Terminal.Gui.App;
  10. public static partial class Application // Lifecycle (Init/Shutdown)
  11. {
  12. /// <summary>Initializes a new instance of a Terminal.Gui Application. <see cref="Shutdown"/> must be called when the application is closing.</summary>
  13. /// <para>Call this method once per instance (or after <see cref="Shutdown"/> has been called).</para>
  14. /// <para>
  15. /// This function loads the right <see cref="IDriver"/> for the platform, Creates a <see cref="Toplevel"/>. and
  16. /// assigns it to <see cref="Top"/>
  17. /// </para>
  18. /// <para>
  19. /// <see cref="Shutdown"/> must be called when the application is closing (typically after
  20. /// <see cref="Run{T}"/> has returned) to ensure resources are cleaned up and
  21. /// terminal settings
  22. /// restored.
  23. /// </para>
  24. /// <para>
  25. /// The <see cref="Run{T}"/> function combines
  26. /// <see cref="Init(IDriver,string)"/> and <see cref="Run(Toplevel, Func{Exception, bool})"/>
  27. /// into a single
  28. /// call. An application can use <see cref="Run{T}"/> without explicitly calling
  29. /// <see cref="Init(IDriver,string)"/>.
  30. /// </para>
  31. /// <param name="driver">
  32. /// The <see cref="IDriver"/> to use. If neither <paramref name="driver"/> or
  33. /// <paramref name="driverName"/> are specified the default driver for the platform will be used.
  34. /// </param>
  35. /// <param name="driverName">
  36. /// The short name (e.g. "dotnet", "windows", "unix", or "fake") of the
  37. /// <see cref="IDriver"/> to use. If neither <paramref name="driver"/> or <paramref name="driverName"/> are
  38. /// specified the default driver for the platform will be used.
  39. /// </param>
  40. [RequiresUnreferencedCode ("AOT")]
  41. [RequiresDynamicCode ("AOT")]
  42. public static void Init (IDriver? driver = null, string? driverName = null)
  43. {
  44. ApplicationImpl.Instance.Init (driver, driverName ?? ForceDriver);
  45. }
  46. /// <summary>
  47. /// Gets or sets the main thread ID for the application.
  48. /// </summary>
  49. public static int? MainThreadId
  50. {
  51. get => ((ApplicationImpl)ApplicationImpl.Instance).MainThreadId;
  52. set => ((ApplicationImpl)ApplicationImpl.Instance).MainThreadId = value;
  53. }
  54. /// <summary>Shutdown an application initialized with <see cref="Init"/>.</summary>
  55. /// <remarks>
  56. /// Shutdown must be called for every call to <see cref="Init"/> or
  57. /// <see cref="Application.Run(Toplevel, Func{Exception, bool})"/> to ensure all resources are cleaned
  58. /// up (Disposed)
  59. /// and terminal settings are restored.
  60. /// </remarks>
  61. public static void Shutdown () => ApplicationImpl.Instance.Shutdown ();
  62. /// <summary>
  63. /// Gets whether the application has been initialized with <see cref="Init"/> and not yet shutdown with <see cref="Shutdown"/>.
  64. /// </summary>
  65. /// <remarks>
  66. /// <para>
  67. /// The <see cref="InitializedChanged"/> event is raised after the <see cref="Init"/> and <see cref="Shutdown"/> methods have been called.
  68. /// </para>
  69. /// </remarks>
  70. public static bool Initialized
  71. {
  72. get => ApplicationImpl.Instance.Initialized;
  73. internal set => ApplicationImpl.Instance.Initialized = value;
  74. }
  75. /// <inheritdoc cref="IApplication.InitializedChanged"/>
  76. public static event EventHandler<EventArgs<bool>>? InitializedChanged
  77. {
  78. add => ApplicationImpl.Instance.InitializedChanged += value;
  79. remove => ApplicationImpl.Instance.InitializedChanged -= value;
  80. }
  81. // IMPORTANT: Ensure all property/fields are reset here. See Init_ResetState_Resets_Properties unit test.
  82. // Encapsulate all setting of initial state for Application; Having
  83. // this in a function like this ensures we don't make mistakes in
  84. // guaranteeing that the state of this singleton is deterministic when Init
  85. // starts running and after Shutdown returns.
  86. internal static void ResetState (bool ignoreDisposed = false) => ApplicationImpl.Instance?.ResetState (ignoreDisposed);
  87. }