using System.Collections.Concurrent; using OpenTK.Graphics.OpenGL; namespace Dashboard.Drawing.OpenGL { public class ContextCollector : IDisposable { private readonly ConcurrentQueue _disposedObjects = new ConcurrentQueue(); public void Dispose() { while (_disposedObjects.TryDequeue(out GLObject obj)) { obj.Dispose(); } } void DeleteObject(ObjectIdentifier identifier, int handle) => _disposedObjects.Enqueue(new GLObject(identifier, handle)); public void DeleteTexture(int texture) => DeleteObject(ObjectIdentifier.Texture, texture); public void DeleteBufffer(int buffer) => DeleteObject(ObjectIdentifier.Buffer, buffer); public void DeleteFramebuffer(int framebuffer) => DeleteObject(ObjectIdentifier.Framebuffer, framebuffer); public void DeleteRenderBuffer(int renderbuffer) => DeleteObject(ObjectIdentifier.Renderbuffer, renderbuffer); public void DeleteSampler(int sampler) => DeleteObject(ObjectIdentifier.Sampler, sampler); public void DeleteShader(int shader) => DeleteObject(ObjectIdentifier.Shader, shader); public void DeleteProgram(int program) => DeleteObject(ObjectIdentifier.Program, program); public void DeleteVertexArray(int vertexArray) => DeleteObject(ObjectIdentifier.VertexArray, vertexArray); public void DeleteQuery(int query) => DeleteObject(ObjectIdentifier.Query, query); public void DeleteProgramPipeline(int programPipeline) => DeleteObject(ObjectIdentifier.ProgramPipeline, programPipeline); public void DeleteTransformFeedback(int transformFeedback) => DeleteObject(ObjectIdentifier.TransformFeedback, transformFeedback); private readonly record struct GLObject(ObjectIdentifier Type, int Handle) { public void Dispose() { switch (Type) { case ObjectIdentifier.Texture: GL.DeleteTexture(Handle); break; case ObjectIdentifier.Buffer: GL.DeleteBuffer(Handle); break; case ObjectIdentifier.Framebuffer: GL.DeleteFramebuffer(Handle); break; case ObjectIdentifier.Renderbuffer: GL.DeleteRenderbuffer(Handle); break; case ObjectIdentifier.Sampler: GL.DeleteSampler(Handle); break; case ObjectIdentifier.Shader: GL.DeleteShader(Handle); break; case ObjectIdentifier.VertexArray: GL.DeleteVertexArray(Handle); break; case ObjectIdentifier.Program: GL.DeleteProgram(Handle); break; case ObjectIdentifier.Query: GL.DeleteQuery(Handle); break; case ObjectIdentifier.ProgramPipeline: GL.DeleteProgramPipeline(Handle); break; case ObjectIdentifier.TransformFeedback: GL.DeleteTransformFeedback(Handle); break; } } } public static readonly ContextCollector Global = new ContextCollector(); } }