132 lines
4.0 KiB
C#
132 lines
4.0 KiB
C#
namespace Dashboard.Drawing.OpenGL
|
|
{
|
|
public class ContextResourcePoolManager
|
|
{
|
|
private readonly Dictionary<IGLContext, ContextResourcePool> _unique = new Dictionary<IGLContext, ContextResourcePool>();
|
|
private readonly Dictionary<int, ContextResourcePool> _shared = new Dictionary<int, ContextResourcePool>();
|
|
|
|
public ContextResourcePool Get(IGLContext context)
|
|
{
|
|
if (context.ContextGroup == -1)
|
|
{
|
|
if (!_unique.TryGetValue(context, out ContextResourcePool? pool))
|
|
{
|
|
pool = new ContextResourcePool(this, context);
|
|
_unique.Add(context, pool);
|
|
}
|
|
|
|
return pool;
|
|
}
|
|
else
|
|
{
|
|
if (!_shared.TryGetValue(context.ContextGroup, out ContextResourcePool? pool))
|
|
{
|
|
pool = new ContextResourcePool(this, context.ContextGroup);
|
|
_shared.Add(context.ContextGroup, pool);
|
|
}
|
|
|
|
return pool;
|
|
}
|
|
}
|
|
|
|
internal void Disposed(ContextResourcePool pool)
|
|
{
|
|
// TODO:
|
|
}
|
|
}
|
|
|
|
public class ContextResourcePool : IGLDisposable, IArc
|
|
{
|
|
private int _references = 0;
|
|
private bool _isDisposed = false;
|
|
private readonly Dictionary<int, IResourceManager> _managers = new Dictionary<int, IResourceManager>();
|
|
|
|
public ContextResourcePoolManager Manager { get; }
|
|
public IGLContext? Context { get; private set; } = null;
|
|
public int ContextGroup { get; private set; } = -1;
|
|
public int References => _references;
|
|
public ContextCollector Collector { get; } = new ContextCollector();
|
|
|
|
internal ContextResourcePool(ContextResourcePoolManager manager, int contextGroup)
|
|
{
|
|
Manager = manager;
|
|
ContextGroup = contextGroup;
|
|
}
|
|
|
|
internal ContextResourcePool(ContextResourcePoolManager manager, IGLContext context)
|
|
{
|
|
Manager = manager;
|
|
Context = context;
|
|
}
|
|
|
|
public T GetResourceManager<T>(bool init = true) where T : IResourceManager, new()
|
|
{
|
|
int index = ManagerAtom<T>.Atom;
|
|
|
|
if (!_managers.TryGetValue(index, out IResourceManager? resourceClass))
|
|
{
|
|
_managers[index] = resourceClass = new T();
|
|
}
|
|
|
|
if (init && resourceClass is IInitializer initializer)
|
|
{
|
|
initializer.Initialize();
|
|
}
|
|
|
|
return (T)resourceClass;
|
|
}
|
|
|
|
~ContextResourcePool()
|
|
{
|
|
Dispose(true, false);
|
|
}
|
|
|
|
public void Dispose() => Dispose(true, false);
|
|
|
|
public void Dispose(bool safeExit) => Dispose(safeExit, true);
|
|
|
|
private void Dispose(bool safeExit, bool disposing)
|
|
{
|
|
if (_isDisposed)
|
|
return;
|
|
_isDisposed = true;
|
|
|
|
Manager.Disposed(this);
|
|
|
|
if (disposing)
|
|
{
|
|
foreach ((int _, IResourceManager manager) in _managers)
|
|
{
|
|
if (manager is IGLDisposable glDisposable)
|
|
glDisposable.Dispose(safeExit);
|
|
else if (manager is IDisposable disposable)
|
|
disposable.Dispose();
|
|
}
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|
|
|
|
public void IncrementReference()
|
|
{
|
|
Interlocked.Increment(ref _references);
|
|
}
|
|
|
|
public bool DecrementReference()
|
|
{
|
|
return Interlocked.Decrement(ref _references) == 0;
|
|
}
|
|
|
|
|
|
private class ManagerAtom
|
|
{
|
|
private static int _counter = -1;
|
|
|
|
protected static int Acquire() => Interlocked.Increment(ref _counter);
|
|
}
|
|
private class ManagerAtom<T> : ManagerAtom where T : IResourceManager
|
|
{
|
|
public static int Atom { get; } = Acquire();
|
|
}
|
|
}
|
|
}
|