using System; using System.Collections; namespace GlitchyEngine.Renderer { public class BufferCollection : IEnumerable<(String Name, int Index, Buffer Buffer)> { public typealias BufferEntry = (String Name, int Index, Buffer Buffer); List _buffers ~ DeleteBufferEntries!(_); Dictionary _strToBuf ~ delete _; //delete:append _; Dictionary _idxToBuf ~ delete _; //delete:append _; [AllowAppend] public this() { // Todo: append allocate as soon as it's fixed let buffers = new List(); let strToBuf = new Dictionary(); let idxToBuf = new Dictionary(); _buffers = buffers; _strToBuf = strToBuf; _idxToBuf = idxToBuf; } mixin DeleteBufferEntries(List entries) { if(entries == null) return; for(let entry in entries) { delete entry.Name; entry.Buffer.ReleaseRef(); } delete entries; } public Buffer this[int idx] => _idxToBuf[idx].Buffer; public Buffer this[String name] => _strToBuf[name].Buffer; public Buffer TryGetBuffer(String name) { return TryGetBufferEntry(name)?.Buffer; } public Buffer TryGetBuffer(int index) { return TryGetBufferEntry(index)?.Buffer; } public BufferEntry* TryGetBufferEntry(String name) { if(_strToBuf.TryGetValue(name, let buffer)) { return buffer; } return null; } public BufferEntry* TryGetBufferEntry(int index) { if(_idxToBuf.TryGetValue(index, let buffer)) { return buffer; } return null; } /** * Replaces the buffer with the given index. * @param idx The index (shader buffer register) of the buffer to replace. * @param buffer The new buffer. * @returns True, if the buffer was replaced successfully; false, otherwise. */ public bool TryReplaceBuffer(int idx, Buffer buffer) { if(_idxToBuf.TryGetValue(idx, let bufferEntry)) { Log.EngineLogger.Assert(idx == bufferEntry.Index); bufferEntry.Buffer.ReleaseRef(); buffer.AddRef(); bufferEntry.Buffer = buffer; return true; } else { return false; } } /** * Replaces the buffer with the given name. * @param name The name of the buffer to replace. * @param buffer The new buffer. * @returns True, if the buffer was replaced successfully; false, otherwise. */ public bool TryReplaceBuffer(String name, Buffer buffer) { if(_strToBuf.TryGetValue(name, let bufferEntry)) { Log.EngineLogger.AssertDebug(name == bufferEntry.Name); bufferEntry.Buffer.ReleaseRef(); buffer.AddRef(); bufferEntry.Buffer = buffer; return true; } else { return false; } } public void Add(int index, String name, Buffer buffer) { Add((name, index, buffer)); } public void Add(BufferEntry entry) { BufferEntry copy = (new String(entry.Name), entry.Index, entry.Buffer..AddRef()); _buffers.Add(copy); BufferEntry* copyRef = &_buffers.Back; _strToBuf.Add(copy.Name, copyRef); _idxToBuf.Add(copy.Index, copyRef); } /** * Returns the index of the given Buffer in the _buffer-List. * @param The buffer to find the index of. * @returns The index of the buffer, or null if it isn't in this collection. */ int GetIndexOfBuffer(Buffer buffer) { for(int i < _buffers.Count) { // Only check for reference equality. if(_buffers[i].Buffer === buffer) { return i; } } return -1; } /** * Returns the index of the given Buffer in the _buffer-List. * @param The buffer to find the index of. * @returns The name of the buffer, or null if it isn't in this collection. */ String GetNameOfBuffer(Buffer buffer) { for(int i < _buffers.Count) { // Only check for reference equality. if(_buffers[i].Buffer === buffer) { return _buffers[i].Name; } } return null; } public List.Enumerator GetEnumerator() { return _buffers.GetEnumerator(); } } }