150 lines
4.4 KiB
C#
150 lines
4.4 KiB
C#
using Dashboard.Collections;
|
|
using Dashboard.Windowing;
|
|
using BindingFlags = System.Reflection.BindingFlags;
|
|
|
|
namespace Dashboard.Pal
|
|
{
|
|
public abstract class DeviceContext : IContextBase<DeviceContext, IDeviceContextExtension>
|
|
{
|
|
private readonly TypeDictionary<IDeviceContextExtension> _extensions =
|
|
new TypeDictionary<IDeviceContextExtension>(true);
|
|
private readonly TypeDictionary<IDeviceContextExtension, Func<IDeviceContextExtension>> _preloadedExtensions =
|
|
new TypeDictionary<IDeviceContextExtension, Func<IDeviceContextExtension>>(true);
|
|
|
|
private readonly Dictionary<string, object> _attributes = new Dictionary<string, object>();
|
|
|
|
|
|
public Application Application { get; }
|
|
public IWindow? Window { get; }
|
|
public abstract string DriverName { get; }
|
|
public abstract string DriverVendor { get; }
|
|
public abstract Version DriverVersion { get; }
|
|
|
|
public bool IsDisposed { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Optional debugging object for your pleasure.
|
|
/// </summary>
|
|
public IContextDebugger? Debugger { get; set; }
|
|
|
|
protected DeviceContext(Application app, IWindow? window)
|
|
{
|
|
Application = app;
|
|
Window = window;
|
|
app.OnDeviceContextCreated(this);
|
|
}
|
|
|
|
~DeviceContext()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
public virtual void Begin() { }
|
|
|
|
// public abstract void Paint(object renderbuffer);
|
|
|
|
public virtual void End() { }
|
|
|
|
public bool IsExtensionAvailable<T>() where T : IDeviceContextExtension
|
|
{
|
|
return _extensions.Contains<T>() || _preloadedExtensions.Contains<T>();
|
|
}
|
|
|
|
public bool ExtensionPreload<T>(Func<IDeviceContextExtension> loader) where T : IDeviceContextExtension
|
|
{
|
|
return _preloadedExtensions.Add<T>(loader);
|
|
}
|
|
|
|
public bool ExtensionPreload<T>() where T : IDeviceContextExtension, new()
|
|
{
|
|
return _preloadedExtensions.Add<T>(() => new T());
|
|
}
|
|
|
|
public T ExtensionRequire<T>() where T : IDeviceContextExtension
|
|
{
|
|
T? extension = default;
|
|
|
|
if (_extensions.TryGet(out extension))
|
|
return extension;
|
|
|
|
lock (_extensions)
|
|
{
|
|
if (_extensions.TryGet(out extension))
|
|
return extension;
|
|
|
|
if (_preloadedExtensions.Remove<T>(out Func<IDeviceContextExtension>? loader))
|
|
{
|
|
extension = (T)loader!();
|
|
}
|
|
else
|
|
{
|
|
extension = Activator.CreateInstance<T>();
|
|
}
|
|
|
|
_extensions.Add(extension);
|
|
extension.Require(this);
|
|
}
|
|
|
|
return extension;
|
|
}
|
|
|
|
public bool ExtensionLoad<T>(T instance) where T : IDeviceContextExtension
|
|
{
|
|
if (_extensions.Contains(instance))
|
|
return false;
|
|
|
|
_extensions.Add(instance);
|
|
return true;
|
|
}
|
|
|
|
public void SetAttribute(string name, object? v)
|
|
{
|
|
if (v != null)
|
|
_attributes[name] = v;
|
|
else
|
|
_attributes.Remove(name);
|
|
}
|
|
|
|
public void SetAttribute<T>(string name, T v) => SetAttribute(name, (object?)v);
|
|
|
|
public object? GetAttribute(string name)
|
|
{
|
|
return _attributes.GetValueOrDefault(name);
|
|
}
|
|
|
|
public T? GetAttribute<T>(string name)
|
|
{
|
|
object? o = GetAttribute(name);
|
|
if (o != null)
|
|
return (T?)o;
|
|
return default;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Implement your dispose in this function.
|
|
/// </summary>
|
|
/// <param name="isDisposing">True if disposing, false otherwise.</param>
|
|
protected virtual void Dispose(bool isDisposing)
|
|
{
|
|
if (!isDisposing) return;
|
|
|
|
foreach (IDeviceContextExtension 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);
|
|
}
|
|
}
|