简单重构拆分 SimulationWorld
This commit is contained in:
+164
@@ -0,0 +1,164 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace SepCore.Simulation
|
||||
{
|
||||
internal abstract class EntityComponentStore
|
||||
{
|
||||
internal interface IColumn
|
||||
{
|
||||
bool IsCreated { get; }
|
||||
void EnsureCapacity(int count);
|
||||
void SwapBackRemove(int index, int lastIndex);
|
||||
void Clear();
|
||||
void Dispose();
|
||||
}
|
||||
|
||||
internal sealed class Column<T> : IColumn where T : unmanaged, ISimulationComponent
|
||||
{
|
||||
private NativeList<T> _data;
|
||||
|
||||
public Column(int capacity)
|
||||
{
|
||||
_data = new NativeList<T>(capacity, Allocator.Persistent);
|
||||
}
|
||||
|
||||
public NativeList<T> Data => _data;
|
||||
|
||||
public bool IsCreated => _data.IsCreated;
|
||||
|
||||
public ref T this[int index] => ref _data.ElementAt(index);
|
||||
|
||||
public void EnsureCapacity(int count)
|
||||
{
|
||||
if (_data.IsCreated && _data.Capacity < count)
|
||||
{
|
||||
_data.Capacity = count;
|
||||
}
|
||||
}
|
||||
|
||||
public void SwapBackRemove(int index, int lastIndex)
|
||||
{
|
||||
if (index != lastIndex)
|
||||
{
|
||||
_data[index] = _data[lastIndex];
|
||||
}
|
||||
|
||||
_data.RemoveAt(lastIndex);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (_data.IsCreated)
|
||||
{
|
||||
_data.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_data.IsCreated)
|
||||
{
|
||||
_data.Dispose();
|
||||
}
|
||||
|
||||
_data = default;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly EntityBinding _binding = new();
|
||||
private readonly List<IColumn> _columns = new();
|
||||
private int _count;
|
||||
|
||||
public int Count => _count;
|
||||
|
||||
public bool IsCreated { get; private set; }
|
||||
|
||||
public void EnsureCapacity(int count)
|
||||
{
|
||||
for (int i = 0; i < _columns.Count; i++)
|
||||
{
|
||||
_columns[i].EnsureCapacity(count);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetSimulationIndex(int entityId, out int index)
|
||||
{
|
||||
return _binding.TryGetSimulationIndex(entityId, out index);
|
||||
}
|
||||
|
||||
public bool RemoveByEntityId(int entityId)
|
||||
{
|
||||
if (!_binding.TryGetSimulationIndex(entityId, out int index))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int lastIndex = _count - 1;
|
||||
bool hasMovedRow = index != lastIndex;
|
||||
int movedEntityId = 0;
|
||||
if (hasMovedRow)
|
||||
{
|
||||
_binding.TryGetEntityId(lastIndex, out movedEntityId);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _columns.Count; i++)
|
||||
{
|
||||
_columns[i].SwapBackRemove(index, lastIndex);
|
||||
}
|
||||
|
||||
_binding.UnbindByEntityId(entityId);
|
||||
if (hasMovedRow)
|
||||
{
|
||||
_binding.RemapIndex(movedEntityId, index);
|
||||
}
|
||||
|
||||
_count--;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
for (int i = 0; i < _columns.Count; i++)
|
||||
{
|
||||
_columns[i].Clear();
|
||||
}
|
||||
|
||||
_binding.Clear();
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
for (int i = 0; i < _columns.Count; i++)
|
||||
{
|
||||
_columns[i].Dispose();
|
||||
}
|
||||
|
||||
_columns.Clear();
|
||||
_binding.Clear();
|
||||
_count = 0;
|
||||
IsCreated = false;
|
||||
}
|
||||
|
||||
protected Column<T> Register<T>(int capacity) where T : unmanaged, ISimulationComponent
|
||||
{
|
||||
Column<T> column = new Column<T>(capacity);
|
||||
_columns.Add(column);
|
||||
return column;
|
||||
}
|
||||
|
||||
protected void MarkInitialized()
|
||||
{
|
||||
IsCreated = true;
|
||||
}
|
||||
|
||||
protected int AppendRow(int entityId)
|
||||
{
|
||||
int index = _count;
|
||||
_binding.Bind(entityId, index);
|
||||
_count++;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user