99 lines
2.9 KiB
C#
99 lines
2.9 KiB
C#
using Dashboard.Collections;
|
|
|
|
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);
|
|
|
|
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; }
|
|
|
|
~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>() where T : IDeviceContextExtension, new()
|
|
{
|
|
return _preloadedExtensions.Add<T>(() => new T());
|
|
}
|
|
|
|
public T ExtensionRequire<T>() where T : IDeviceContextExtension, new()
|
|
{
|
|
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 = new T();
|
|
}
|
|
|
|
_extensions.Add(extension);
|
|
extension.Require(this);
|
|
}
|
|
|
|
return extension;
|
|
}
|
|
|
|
/// <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);
|
|
}
|
|
}
|