using Dashboard.Collections; using Dashboard.Windowing; namespace Dashboard.Pal { public abstract class AppContext : IContextBase { public abstract string DriverName { get; } public abstract string DriverVendor { get; } public abstract Version DriverVersion { get; } public virtual string AppTitle { get; set; } = "Dashboard Application"; public bool IsInitialized { get; private set; } = false; public bool IsDisposed { get; private set; } = false; public IContextDebugger? Debugger { get; set; } private readonly TypeDictionary _extensions = new TypeDictionary(true); private readonly TypeDictionary> _preloadedExtensions = new TypeDictionary>(true); ~AppContext() { InvokeDispose(false); } public void Initialize() { if (IsInitialized) return; IsInitialized = true; InitializeInternal(); } protected virtual void InitializeInternal() { } public virtual void RunEvents(bool wait) { if (!IsInitialized) Initialize(); } public void Run() => Run(true, CancellationToken.None); public void Run(bool wait) => Run(wait, CancellationToken.None); public void Run(bool waitForEvents, CancellationToken token) { InitializeInternal(); while (!token.IsCancellationRequested) { RunEvents(waitForEvents); } } #region Window API /// /// Creates a window. It could be a virtual window, or a physical window. /// /// A window. public abstract IWindow CreateWindow(); /// /// Always creates a physical window. /// /// A physical window. public abstract IPhysicalWindow CreatePhysicalWindow(); /// /// Create a physical window with a window manager. /// /// A physical window with the given window manager. public IPhysicalWindow CreatePhysicalWindow(IWindowManager wm) { IPhysicalWindow window = CreatePhysicalWindow(); window.WindowManager = wm; return window; } #endregion public bool IsExtensionAvailable() where T : IAppContextExtension { return _extensions.Contains() || _preloadedExtensions.Contains(); } public bool ExtensionPreload() where T : IAppContextExtension, new() { return _preloadedExtensions.Add(() => new T()); } public T ExtensionRequire() where T : IAppContextExtension, new() { T? extension = default; if (_extensions.TryGet(out extension)) return extension; lock (_extensions) { if (_extensions.TryGet(out extension)) return extension; if (_preloadedExtensions.Remove(out Func? loader)) { extension = (T)loader!(); } else { extension = new T(); } _extensions.Add(extension); extension.Require(this); } return extension; } protected virtual void Dispose(bool isDisposing) { if (!isDisposing) return; foreach (IAppContextExtension extension in _extensions) { extension.Dispose(); } GC.SuppressFinalize(this); } private void InvokeDispose(bool isDisposing) { if (IsDisposed) return; IsDisposed = true; Dispose(isDisposing); } public void Dispose() => InvokeDispose(true); } }