ryujinx/src/Ryujinx.Graphics.Metal/IdList.cs
Evan Husted 852823104f
EXPERIMENTAL: Metal backend (#441)
This is not a continuation of the Metal backend; this is simply bringing
the branch up to date and merging it as-is behind an experiment.

---------

Co-authored-by: Isaac Marovitz <isaacryu@icloud.com>
Co-authored-by: Samuliak <samuliak77@gmail.com>
Co-authored-by: SamoZ256 <96914946+SamoZ256@users.noreply.github.com>
Co-authored-by: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
Co-authored-by: riperiperi <rhy3756547@hotmail.com>
Co-authored-by: Gabriel A <gab.dark.100@gmail.com>
2024-12-24 00:55:16 -06:00

121 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Metal
{
class IdList<T> where T : class
{
private readonly List<T> _list;
private int _freeMin;
public IdList()
{
_list = new List<T>();
_freeMin = 0;
}
public int Add(T value)
{
int id;
int count = _list.Count;
id = _list.IndexOf(null, _freeMin);
if ((uint)id < (uint)count)
{
_list[id] = value;
}
else
{
id = count;
_freeMin = id + 1;
_list.Add(value);
}
return id + 1;
}
public void Remove(int id)
{
id--;
int count = _list.Count;
if ((uint)id >= (uint)count)
{
return;
}
if (id + 1 == count)
{
// Trim unused items.
int removeIndex = id;
while (removeIndex > 0 && _list[removeIndex - 1] == null)
{
removeIndex--;
}
_list.RemoveRange(removeIndex, count - removeIndex);
if (_freeMin > removeIndex)
{
_freeMin = removeIndex;
}
}
else
{
_list[id] = null;
if (_freeMin > id)
{
_freeMin = id;
}
}
}
public bool TryGetValue(int id, out T value)
{
id--;
try
{
if ((uint)id < (uint)_list.Count)
{
value = _list[id];
return value != null;
}
value = null;
return false;
}
catch (ArgumentOutOfRangeException)
{
value = null;
return false;
}
catch (IndexOutOfRangeException)
{
value = null;
return false;
}
}
public void Clear()
{
_list.Clear();
_freeMin = 0;
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < _list.Count; i++)
{
if (_list[i] != null)
{
yield return _list[i];
}
}
}
}
}