Application.Lifecycle.cs 4.2 KB

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