file-scoped namespaces + formatting

pull/6/head
cosmonaut 2023-11-20 23:13:04 -08:00
parent b27875b9a8
commit 3b1dafdebd
15 changed files with 1074 additions and 1096 deletions

View File

@ -3,50 +3,49 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace MoonTools.ECS.Collections namespace MoonTools.ECS.Collections;
{
public unsafe class IndexableSet<T> : IDisposable where T : unmanaged
{
private Dictionary<T, int> indices;
private T* array;
private int count;
private int capacity;
private bool disposed;
public int Count => count; public unsafe class IndexableSet<T> : IDisposable where T : unmanaged
public Span<T> AsSpan() => new Span<T>(array, count); {
public ReverseSpanEnumerator<T> GetEnumerator() => new ReverseSpanEnumerator<T>(new Span<T>(array, count)); private Dictionary<T, int> Indices;
private T* Array;
public int Count { get; private set; }
private int Capacity;
private bool IsDisposed;
public Span<T> AsSpan() => new Span<T>(Array, Count);
public ReverseSpanEnumerator<T> GetEnumerator() => new ReverseSpanEnumerator<T>(new Span<T>(Array, Count));
public IndexableSet(int capacity = 32) public IndexableSet(int capacity = 32)
{ {
this.capacity = capacity; this.Capacity = capacity;
count = 0; Count = 0;
indices = new Dictionary<T, int>(capacity); Indices = new Dictionary<T, int>(capacity);
array = (T*) NativeMemory.Alloc((nuint) (capacity * Unsafe.SizeOf<T>())); Array = (T*) NativeMemory.Alloc((nuint) (capacity * Unsafe.SizeOf<T>()));
} }
public T this[int i] => array[i]; public T this[int i] => Array[i];
public bool Contains(T element) public bool Contains(T element)
{ {
return indices.ContainsKey(element); return Indices.ContainsKey(element);
} }
public bool Add(T element) public bool Add(T element)
{ {
if (!Contains(element)) if (!Contains(element))
{ {
indices.Add(element, count); Indices.Add(element, Count);
if (count >= capacity) if (Count >= Capacity)
{ {
capacity *= 2; Capacity *= 2;
array = (T*) NativeMemory.Realloc(array, (nuint) (capacity * Unsafe.SizeOf<T>())); Array = (T*) NativeMemory.Realloc(Array, (nuint) (Capacity * Unsafe.SizeOf<T>()));
} }
array[count] = element; Array[Count] = element;
count += 1; Count += 1;
return true; return true;
} }
@ -61,34 +60,34 @@ namespace MoonTools.ECS.Collections
return false; return false;
} }
var index = indices[element]; var index = Indices[element];
for (var i = index; i < Count - 1; i += 1) for (var i = index; i < Count - 1; i += 1)
{ {
array[i] = array[i + 1]; Array[i] = Array[i + 1];
indices[array[i]] = i; Indices[Array[i]] = i;
} }
indices.Remove(element); Indices.Remove(element);
count -= 1; Count -= 1;
return true; return true;
} }
public void Clear() public void Clear()
{ {
indices.Clear(); Indices.Clear();
count = 0; Count = 0;
} }
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (!disposed) if (!IsDisposed)
{ {
NativeMemory.Free(array); NativeMemory.Free(Array);
array = null; Array = null;
disposed = true; IsDisposed = true;
} }
} }
@ -104,5 +103,4 @@ namespace MoonTools.ECS.Collections
Dispose(disposing: true); Dispose(disposing: true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
}
} }

View File

@ -14,7 +14,7 @@ public unsafe class NativeArray<T> : IDisposable where T : unmanaged
public Span<T> ToSpan() => new Span<T>(Elements, Count); public Span<T> ToSpan() => new Span<T>(Elements, Count);
public Span<T>.Enumerator GetEnumerator() => new Span<T>(Elements, Count).GetEnumerator(); public Span<T>.Enumerator GetEnumerator() => new Span<T>(Elements, Count).GetEnumerator();
private bool disposed; private bool IsDisposed;
public NativeArray(int capacity = 16) public NativeArray(int capacity = 16)
{ {
@ -96,12 +96,12 @@ public unsafe class NativeArray<T> : IDisposable where T : unmanaged
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (!disposed) if (!IsDisposed)
{ {
NativeMemory.Free(Elements); NativeMemory.Free(Elements);
Elements = null; Elements = null;
disposed = true; IsDisposed = true;
} }
} }

View File

@ -2,16 +2,16 @@
using System.Collections.Generic; using System.Collections.Generic;
using MoonTools.ECS.Collections; using MoonTools.ECS.Collections;
namespace MoonTools.ECS namespace MoonTools.ECS;
internal class ComponentStorage : IDisposable
{ {
internal unsafe class ComponentStorage : IDisposable
{
internal readonly Dictionary<Entity, int> EntityIDToStorageIndex = new Dictionary<Entity, int>(16); internal readonly Dictionary<Entity, int> EntityIDToStorageIndex = new Dictionary<Entity, int>(16);
internal readonly NativeArray Components; internal readonly NativeArray Components;
internal readonly NativeArray<Entity> EntityIDs; internal readonly NativeArray<Entity> EntityIDs;
internal readonly TypeId TypeId; internal readonly TypeId TypeId;
private bool disposed; private bool IsDisposed;
public ComponentStorage(TypeId typeId, int elementSize) public ComponentStorage(TypeId typeId, int elementSize)
{ {
@ -116,12 +116,12 @@ namespace MoonTools.ECS
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (!disposed) if (!IsDisposed)
{ {
Components.Dispose(); Components.Dispose();
EntityIDs.Dispose(); EntityIDs.Dispose();
disposed = true; IsDisposed = true;
} }
} }
@ -137,5 +137,4 @@ namespace MoonTools.ECS
Dispose(disposing: true); Dispose(disposing: true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
}
} }

View File

@ -1,14 +1,3 @@
using System; namespace MoonTools.ECS;
namespace MoonTools.ECS public readonly record struct Entity(uint ID);
{
public readonly record struct Entity
{
public uint ID { get; }
internal Entity(uint id)
{
ID = id;
}
}
}

View File

@ -1,23 +1,23 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace MoonTools.ECS namespace MoonTools.ECS;
public ref struct ReverseSpanEnumerator<T>
{ {
public ref struct ReverseSpanEnumerator<T>
{
private ReadOnlySpan<T> Span; private ReadOnlySpan<T> Span;
private int index; private int Index;
public ReverseSpanEnumerator<T> GetEnumerator() => this; public ReverseSpanEnumerator<T> GetEnumerator() => this;
public T Current => Span[index]; public T Current => Span[Index];
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() public bool MoveNext()
{ {
if (index > 0) if (Index > 0)
{ {
index -= 1; Index -= 1;
return true; return true;
} }
@ -28,9 +28,8 @@ namespace MoonTools.ECS
public ReverseSpanEnumerator(Span<T> span) public ReverseSpanEnumerator(Span<T> span)
{ {
Span = span; Span = span;
index = span.Length; Index = span.Length;
} }
public static ReverseSpanEnumerator<T> Empty => new ReverseSpanEnumerator<T>(); public static ReverseSpanEnumerator<T> Empty => new ReverseSpanEnumerator<T>();
}
} }

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using MoonTools.ECS.Collections;
using MoonTools.ECS.Collections;
namespace MoonTools.ECS namespace MoonTools.ECS
{ {

View File

@ -1,10 +1,10 @@
using System; using System;
using MoonTools.ECS.Collections; using MoonTools.ECS.Collections;
namespace MoonTools.ECS namespace MoonTools.ECS;
public struct FilterSignature : IEquatable<FilterSignature>
{ {
public struct FilterSignature : IEquatable<FilterSignature>
{
public readonly IndexableSet<TypeId> Included; public readonly IndexableSet<TypeId> Included;
public readonly IndexableSet<TypeId> Excluded; public readonly IndexableSet<TypeId> Excluded;
@ -66,5 +66,4 @@ namespace MoonTools.ECS
{ {
return !(left == right); return !(left == right);
} }
}
} }

View File

@ -1,7 +1,7 @@
namespace MoonTools.ECS namespace MoonTools.ECS;
public abstract class Manipulator : EntityComponentReader
{ {
public abstract class Manipulator : EntityComponentReader
{
public Manipulator(World world) : base(world) public Manipulator(World world) : base(world)
{ {
} }
@ -15,5 +15,4 @@ namespace MoonTools.ECS
protected void Unrelate<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged => World.Unrelate<TRelationKind>(entityA, entityB); protected void Unrelate<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged => World.Unrelate<TRelationKind>(entityA, entityB);
protected void UnrelateAll<TRelationKind>(in Entity entity) where TRelationKind : unmanaged => World.UnrelateAll<TRelationKind>(entity); protected void UnrelateAll<TRelationKind>(in Entity entity) where TRelationKind : unmanaged => World.UnrelateAll<TRelationKind>(entity);
protected void Destroy(in Entity entity) => World.Destroy(entity); protected void Destroy(in Entity entity) => World.Destroy(entity);
}
} }

View File

@ -39,7 +39,7 @@ public class MessageStorage : IDisposable
Messages.Clear(); Messages.Clear();
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (!IsDisposed) if (!IsDisposed)
{ {

View File

@ -1,14 +1,14 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace MoonTools.ECS namespace MoonTools.ECS;
/// <summary>
/// This class implements the well equidistributed long-period linear pseudorandom number generator.
/// Code taken from Chris Lomont: http://lomont.org/papers/2008/Lomont_PRNG_2008.pdf
/// </summary>
public class Random
{ {
/// <summary>
/// This class implements the well equidistributed long-period linear pseudorandom number generator.
/// Code taken from Chris Lomont: http://lomont.org/papers/2008/Lomont_PRNG_2008.pdf
/// </summary>
public class Random
{
public const int STATE_BYTE_COUNT = 68; // 16 state ints + 1 index int public const int STATE_BYTE_COUNT = 68; // 16 state ints + 1 index int
uint[] State = new uint[16]; uint[] State = new uint[16];
@ -67,12 +67,12 @@ namespace MoonTools.ECS
/// <exception cref="ArgumentException">Thrown if the byte span is too short.</exception> /// <exception cref="ArgumentException">Thrown if the byte span is too short.</exception>
public unsafe void SaveState(Span<byte> bytes) public unsafe void SaveState(Span<byte> bytes)
{ {
#if DEBUG #if DEBUG
if (bytes.Length < STATE_BYTE_COUNT) if (bytes.Length < STATE_BYTE_COUNT)
{ {
throw new ArgumentException("Byte span too short!"); throw new ArgumentException("Byte span too short!");
} }
#endif #endif
fixed (byte* ptr = bytes) fixed (byte* ptr = bytes)
{ {
@ -94,12 +94,12 @@ namespace MoonTools.ECS
/// <exception cref="ArgumentException">Thrown if the byte span is too short.</exception> /// <exception cref="ArgumentException">Thrown if the byte span is too short.</exception>
public unsafe void LoadState(Span<byte> bytes) public unsafe void LoadState(Span<byte> bytes)
{ {
#if DEBUG #if DEBUG
if (bytes.Length < STATE_BYTE_COUNT) if (bytes.Length < STATE_BYTE_COUNT)
{ {
throw new ArgumentException("Byte span too short!"); throw new ArgumentException("Byte span too short!");
} }
#endif #endif
fixed (byte* ptr = bytes) fixed (byte* ptr = bytes)
{ {
@ -205,5 +205,4 @@ namespace MoonTools.ECS
var n = NextInternal(); var n = NextInternal();
return ((double) n) / uint.MaxValue; return ((double) n) / uint.MaxValue;
} }
}
} }

View File

@ -1,9 +1,9 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace MoonTools.ECS namespace MoonTools.ECS;
public static class RandomManager
{ {
public static class RandomManager
{
private static Random Random = new Random(); private static Random Random = new Random();
private static int[] Primes = private static int[] Primes =
@ -41,10 +41,10 @@ namespace MoonTools.ECS
return new LinearCongruentialEnumerator(Random.Next(n), x, n); return new LinearCongruentialEnumerator(Random.Next(n), x, n);
} }
} }
public struct LinearCongruentialEnumerator public struct LinearCongruentialEnumerator
{ {
private readonly int start; private readonly int start;
private readonly int count; private readonly int count;
private readonly int prime; private readonly int prime;
@ -78,5 +78,4 @@ namespace MoonTools.ECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (current * prime) % count; get => (current * prime) % count;
} }
}
} }

View File

@ -8,67 +8,67 @@ namespace MoonTools.ECS;
// TODO: implement this entire class with NativeMemory equivalents, can just memcpy for snapshots // TODO: implement this entire class with NativeMemory equivalents, can just memcpy for snapshots
internal class RelationStorage internal class RelationStorage
{ {
internal NativeArray relations; internal NativeArray Relations;
internal NativeArray relationDatas; internal NativeArray RelationDatas;
internal Dictionary<(Entity, Entity), int> indices = new Dictionary<(Entity, Entity), int>(16); internal Dictionary<(Entity, Entity), int> Indices = new Dictionary<(Entity, Entity), int>(16);
internal Dictionary<Entity, IndexableSet<Entity>> outRelations = new Dictionary<Entity, IndexableSet<Entity>>(16); internal Dictionary<Entity, IndexableSet<Entity>> OutRelationSets = new Dictionary<Entity, IndexableSet<Entity>>(16);
internal Dictionary<Entity, IndexableSet<Entity>> inRelations = new Dictionary<Entity, IndexableSet<Entity>>(16); internal Dictionary<Entity, IndexableSet<Entity>> InRelationSets = new Dictionary<Entity, IndexableSet<Entity>>(16);
private Stack<IndexableSet<Entity>> listPool = new Stack<IndexableSet<Entity>>(); private Stack<IndexableSet<Entity>> ListPool = new Stack<IndexableSet<Entity>>();
private bool disposed; private bool IsDisposed;
public RelationStorage(int relationDataSize) public RelationStorage(int relationDataSize)
{ {
relations = new NativeArray(Unsafe.SizeOf<(Entity, Entity)>()); Relations = new NativeArray(Unsafe.SizeOf<(Entity, Entity)>());
relationDatas = new NativeArray(relationDataSize); RelationDatas = new NativeArray(relationDataSize);
} }
public ReverseSpanEnumerator<(Entity, Entity)> All() public ReverseSpanEnumerator<(Entity, Entity)> All()
{ {
return new ReverseSpanEnumerator<(Entity, Entity)>(relations.ToSpan<(Entity, Entity)>()); return new ReverseSpanEnumerator<(Entity, Entity)>(Relations.ToSpan<(Entity, Entity)>());
} }
public unsafe void Set<T>(in Entity entityA, in Entity entityB, in T relationData) where T : unmanaged public unsafe void Set<T>(in Entity entityA, in Entity entityB, in T relationData) where T : unmanaged
{ {
var relation = (entityA, entityB); var relation = (entityA, entityB);
if (indices.TryGetValue(relation, out var index)) if (Indices.TryGetValue(relation, out var index))
{ {
relationDatas.Set(index, relationData); RelationDatas.Set(index, relationData);
return; return;
} }
if (!outRelations.ContainsKey(entityA)) if (!OutRelationSets.ContainsKey(entityA))
{ {
outRelations[entityA] = AcquireHashSetFromPool(); OutRelationSets[entityA] = AcquireHashSetFromPool();
} }
outRelations[entityA].Add(entityB); OutRelationSets[entityA].Add(entityB);
if (!inRelations.ContainsKey(entityB)) if (!InRelationSets.ContainsKey(entityB))
{ {
inRelations[entityB] = AcquireHashSetFromPool(); InRelationSets[entityB] = AcquireHashSetFromPool();
} }
inRelations[entityB].Add(entityA); InRelationSets[entityB].Add(entityA);
relations.Append(relation); Relations.Append(relation);
relationDatas.Append(relationData); RelationDatas.Append(relationData);
indices.Add(relation, relations.Count - 1); Indices.Add(relation, Relations.Count - 1);
} }
public ref T Get<T>(in Entity entityA, in Entity entityB) where T : unmanaged public ref T Get<T>(in Entity entityA, in Entity entityB) where T : unmanaged
{ {
var relationIndex = indices[(entityA, entityB)]; var relationIndex = Indices[(entityA, entityB)];
return ref relationDatas.Get<T>(relationIndex); return ref RelationDatas.Get<T>(relationIndex);
} }
public bool Has(Entity entityA, Entity entityB) public bool Has(Entity entityA, Entity entityB)
{ {
return indices.ContainsKey((entityA, entityB)); return Indices.ContainsKey((entityA, entityB));
} }
public ReverseSpanEnumerator<Entity> OutRelations(Entity Entity) public ReverseSpanEnumerator<Entity> OutRelations(Entity Entity)
{ {
if (outRelations.TryGetValue(Entity, out var entityOutRelations)) if (OutRelationSets.TryGetValue(Entity, out var entityOutRelations))
{ {
return entityOutRelations.GetEnumerator(); return entityOutRelations.GetEnumerator();
} }
@ -86,27 +86,27 @@ internal class RelationStorage
public Entity OutNth(Entity Entity, int n) public Entity OutNth(Entity Entity, int n)
{ {
#if DEBUG #if DEBUG
if (!outRelations.ContainsKey(Entity) || outRelations[Entity].Count == 0) if (!OutRelationSets.ContainsKey(Entity) || OutRelationSets[Entity].Count == 0)
{ {
throw new KeyNotFoundException("No out relations to this entity!"); throw new KeyNotFoundException("No out relations to this entity!");
} }
#endif #endif
return outRelations[Entity][n]; return OutRelationSets[Entity][n];
} }
public bool HasOutRelation(Entity Entity) public bool HasOutRelation(Entity Entity)
{ {
return outRelations.ContainsKey(Entity) && outRelations[Entity].Count > 0; return OutRelationSets.ContainsKey(Entity) && OutRelationSets[Entity].Count > 0;
} }
public int OutRelationCount(Entity Entity) public int OutRelationCount(Entity Entity)
{ {
return outRelations.TryGetValue(Entity, out var entityOutRelations) ? entityOutRelations.Count : 0; return OutRelationSets.TryGetValue(Entity, out var entityOutRelations) ? entityOutRelations.Count : 0;
} }
public ReverseSpanEnumerator<Entity> InRelations(Entity Entity) public ReverseSpanEnumerator<Entity> InRelations(Entity Entity)
{ {
if (inRelations.TryGetValue(Entity, out var entityInRelations)) if (InRelationSets.TryGetValue(Entity, out var entityInRelations))
{ {
return entityInRelations.GetEnumerator(); return entityInRelations.GetEnumerator();
} }
@ -124,23 +124,23 @@ internal class RelationStorage
public Entity InNth(Entity Entity, int n) public Entity InNth(Entity Entity, int n)
{ {
#if DEBUG #if DEBUG
if (!inRelations.ContainsKey(Entity) || inRelations[Entity].Count == 0) if (!InRelationSets.ContainsKey(Entity) || InRelationSets[Entity].Count == 0)
{ {
throw new KeyNotFoundException("No in relations to this entity!"); throw new KeyNotFoundException("No in relations to this entity!");
} }
#endif #endif
return inRelations[Entity][n]; return InRelationSets[Entity][n];
} }
public bool HasInRelation(Entity Entity) public bool HasInRelation(Entity Entity)
{ {
return inRelations.ContainsKey(Entity) && inRelations[Entity].Count > 0; return InRelationSets.ContainsKey(Entity) && InRelationSets[Entity].Count > 0;
} }
public int InRelationCount(Entity Entity) public int InRelationCount(Entity Entity)
{ {
return inRelations.TryGetValue(Entity, out var entityInRelations) ? entityInRelations.Count : 0; return InRelationSets.TryGetValue(Entity, out var entityInRelations) ? entityInRelations.Count : 0;
} }
public (bool, bool) Remove(in Entity entityA, in Entity entityB) public (bool, bool) Remove(in Entity entityA, in Entity entityB)
@ -149,39 +149,39 @@ internal class RelationStorage
var bEmpty = false; var bEmpty = false;
var relation = (entityA, entityB); var relation = (entityA, entityB);
if (outRelations.TryGetValue(entityA, out var entityOutRelations)) if (OutRelationSets.TryGetValue(entityA, out var entityOutRelations))
{ {
entityOutRelations.Remove(entityB); entityOutRelations.Remove(entityB);
if (outRelations[entityA].Count == 0) if (OutRelationSets[entityA].Count == 0)
{ {
aEmpty = true; aEmpty = true;
} }
} }
if (inRelations.TryGetValue(entityB, out var entityInRelations)) if (InRelationSets.TryGetValue(entityB, out var entityInRelations))
{ {
entityInRelations.Remove(entityA); entityInRelations.Remove(entityA);
if (inRelations[entityB].Count == 0) if (InRelationSets[entityB].Count == 0)
{ {
bEmpty = true; bEmpty = true;
} }
} }
if (indices.TryGetValue(relation, out var index)) if (Indices.TryGetValue(relation, out var index))
{ {
var lastElementIndex = relations.Count - 1; var lastElementIndex = Relations.Count - 1;
// move an element into the hole // move an element into the hole
if (index != lastElementIndex) if (index != lastElementIndex)
{ {
var lastRelation = relations.Get<(Entity, Entity)>(lastElementIndex); var lastRelation = Relations.Get<(Entity, Entity)>(lastElementIndex);
indices[lastRelation] = index; Indices[lastRelation] = index;
} }
relationDatas.Delete(index); RelationDatas.Delete(index);
relations.Delete(index); Relations.Delete(index);
indices.Remove(relation); Indices.Remove(relation);
} }
return (aEmpty, bEmpty); return (aEmpty, bEmpty);
@ -189,7 +189,7 @@ internal class RelationStorage
public void RemoveEntity(in Entity entity) public void RemoveEntity(in Entity entity)
{ {
if (outRelations.TryGetValue(entity, out var entityOutRelations)) if (OutRelationSets.TryGetValue(entity, out var entityOutRelations))
{ {
foreach (var entityB in entityOutRelations) foreach (var entityB in entityOutRelations)
{ {
@ -197,10 +197,10 @@ internal class RelationStorage
} }
ReturnHashSetToPool(entityOutRelations); ReturnHashSetToPool(entityOutRelations);
outRelations.Remove(entity); OutRelationSets.Remove(entity);
} }
if (inRelations.TryGetValue(entity, out var entityInRelations)) if (InRelationSets.TryGetValue(entity, out var entityInRelations))
{ {
foreach (var entityA in entityInRelations) foreach (var entityA in entityInRelations)
{ {
@ -208,64 +208,64 @@ internal class RelationStorage
} }
ReturnHashSetToPool(entityInRelations); ReturnHashSetToPool(entityInRelations);
inRelations.Remove(entity); InRelationSets.Remove(entity);
} }
} }
internal IndexableSet<Entity> AcquireHashSetFromPool() internal IndexableSet<Entity> AcquireHashSetFromPool()
{ {
if (listPool.Count == 0) if (ListPool.Count == 0)
{ {
listPool.Push(new IndexableSet<Entity>()); ListPool.Push(new IndexableSet<Entity>());
} }
return listPool.Pop(); return ListPool.Pop();
} }
private void ReturnHashSetToPool(IndexableSet<Entity> hashSet) private void ReturnHashSetToPool(IndexableSet<Entity> hashSet)
{ {
hashSet.Clear(); hashSet.Clear();
listPool.Push(hashSet); ListPool.Push(hashSet);
} }
public void Clear() public void Clear()
{ {
indices.Clear(); Indices.Clear();
foreach (var set in inRelations.Values) foreach (var set in InRelationSets.Values)
{ {
ReturnHashSetToPool(set); ReturnHashSetToPool(set);
} }
inRelations.Clear(); InRelationSets.Clear();
foreach (var set in outRelations.Values) foreach (var set in OutRelationSets.Values)
{ {
ReturnHashSetToPool(set); ReturnHashSetToPool(set);
} }
outRelations.Clear(); OutRelationSets.Clear();
relations.Clear(); Relations.Clear();
relationDatas.Clear(); RelationDatas.Clear();
} }
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (!disposed) if (!IsDisposed)
{ {
Clear(); Clear();
if (disposing) if (disposing)
{ {
foreach (var set in listPool) foreach (var set in ListPool)
{ {
set.Dispose(); set.Dispose();
} }
relations.Dispose(); Relations.Dispose();
relationDatas.Dispose(); RelationDatas.Dispose();
} }
disposed = true; IsDisposed = true;
} }
} }

View File

@ -1,7 +1,6 @@
namespace MoonTools.ECS namespace MoonTools.ECS;
public abstract class Renderer : EntityComponentReader
{ {
public abstract class Renderer : EntityComponentReader
{
public Renderer(World world) : base(world) { } public Renderer(World world) : base(world) { }
}
} }

View File

@ -205,7 +205,7 @@ public class Snapshot
{ {
if (!RelationSnapshots.TryGetValue(typeId, out var snapshot)) if (!RelationSnapshots.TryGetValue(typeId, out var snapshot))
{ {
snapshot = new RelationSnapshot(relationStorage.relationDatas.ElementSize); snapshot = new RelationSnapshot(relationStorage.RelationDatas.ElementSize);
RelationSnapshots.Add(typeId, snapshot); RelationSnapshots.Add(typeId, snapshot);
} }
@ -256,39 +256,39 @@ public class Snapshot
public void Take(RelationStorage relationStorage) public void Take(RelationStorage relationStorage)
{ {
relationStorage.relations.CopyAllTo(Relations); relationStorage.Relations.CopyAllTo(Relations);
relationStorage.relationDatas.CopyAllTo(RelationDatas); relationStorage.RelationDatas.CopyAllTo(RelationDatas);
} }
public void Restore(RelationStorage relationStorage) public void Restore(RelationStorage relationStorage)
{ {
relationStorage.Clear(); relationStorage.Clear();
Relations.CopyAllTo(relationStorage.relations); Relations.CopyAllTo(relationStorage.Relations);
RelationDatas.CopyAllTo(relationStorage.relationDatas); RelationDatas.CopyAllTo(relationStorage.RelationDatas);
for (int index = 0; index < Relations.Count; index += 1) for (int index = 0; index < Relations.Count; index += 1)
{ {
var relation = Relations.Get<(Entity, Entity)>(index); var relation = Relations.Get<(Entity, Entity)>(index);
relationStorage.indices[relation] = index; relationStorage.Indices[relation] = index;
relationStorage.indices[relation] = index; relationStorage.Indices[relation] = index;
if (!relationStorage.outRelations.ContainsKey(relation.Item1)) if (!relationStorage.OutRelationSets.ContainsKey(relation.Item1))
{ {
relationStorage.outRelations[relation.Item1] = relationStorage.OutRelationSets[relation.Item1] =
relationStorage.AcquireHashSetFromPool(); relationStorage.AcquireHashSetFromPool();
} }
relationStorage.outRelations[relation.Item1].Add(relation.Item2); relationStorage.OutRelationSets[relation.Item1].Add(relation.Item2);
if (!relationStorage.inRelations.ContainsKey(relation.Item2)) if (!relationStorage.InRelationSets.ContainsKey(relation.Item2))
{ {
relationStorage.inRelations[relation.Item2] = relationStorage.InRelationSets[relation.Item2] =
relationStorage.AcquireHashSetFromPool(); relationStorage.AcquireHashSetFromPool();
} }
relationStorage.inRelations[relation.Item2].Add(relation.Item1); relationStorage.InRelationSets[relation.Item2].Add(relation.Item1);
} }
} }
} }

View File

@ -3,16 +3,16 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using MoonTools.ECS.Collections; using MoonTools.ECS.Collections;
namespace MoonTools.ECS namespace MoonTools.ECS;
public class World : IDisposable
{ {
public class World : IDisposable
{
// Get TypeId from a Type // Get TypeId from a Type
private readonly Dictionary<Type, TypeId> TypeToId = new Dictionary<Type, TypeId>(); private readonly Dictionary<Type, TypeId> TypeToId = new Dictionary<Type, TypeId>();
#if DEBUG #if DEBUG
private Dictionary<TypeId, Type> IdToType = new Dictionary<TypeId, Type>(); private Dictionary<TypeId, Type> IdToType = new Dictionary<TypeId, Type>();
#endif #endif
// Get element size from a TypeId // Get element size from a TypeId
private readonly Dictionary<TypeId, int> ElementSizes = new Dictionary<TypeId, int>(); private readonly Dictionary<TypeId, int> ElementSizes = new Dictionary<TypeId, int>();
@ -52,9 +52,9 @@ namespace MoonTools.ECS
TypeToId.Add(typeof(T), typeId); TypeToId.Add(typeof(T), typeId);
ElementSizes.Add(typeId, Unsafe.SizeOf<T>()); ElementSizes.Add(typeId, Unsafe.SizeOf<T>());
#if DEBUG #if DEBUG
IdToType.Add(typeId, typeof(T)); IdToType.Add(typeId, typeof(T));
#endif #endif
return typeId; return typeId;
} }
@ -409,7 +409,7 @@ namespace MoonTools.ECS
// DEBUG // DEBUG
// NOTE: these methods are very inefficient // NOTE: these methods are very inefficient
// they should only be used in debugging contexts!! // they should only be used in debugging contexts!!
#if DEBUG #if DEBUG
public ComponentTypeEnumerator Debug_GetAllComponentTypes(Entity entity) public ComponentTypeEnumerator Debug_GetAllComponentTypes(Entity entity)
{ {
return new ComponentTypeEnumerator(this, EntityComponentIndex[entity]); return new ComponentTypeEnumerator(this, EntityComponentIndex[entity]);
@ -456,9 +456,9 @@ namespace MoonTools.ECS
return ComponentIndex < Types.Count; return ComponentIndex < Types.Count;
} }
public unsafe Type Current => World.IdToType[Types[ComponentIndex]]; public Type Current => World.IdToType[Types[ComponentIndex]];
} }
#endif #endif
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
@ -517,5 +517,4 @@ namespace MoonTools.ECS
Dispose(disposing: true); Dispose(disposing: true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
}
} }