Skip to content

Commit

Permalink
immutable
Browse files Browse the repository at this point in the history
  • Loading branch information
andreakarasho committed Feb 26, 2024
1 parent fdf5a91 commit e9f7d80
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 36 deletions.
13 changes: 7 additions & 6 deletions src/Archetype.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Immutable;
using Microsoft.Collections.Extensions;

namespace TinyEcs;
Expand Down Expand Up @@ -76,7 +77,7 @@ ComponentComparer comparer
_world = world;
_edgesLeft = new List<EcsEdge>();
_edgesRight = new List<EcsEdge>();
Components = components.ToArray();
Components = components.ToImmutableArray();

// var maxID = -1;
// for (var i = 0; i < components.Length; ++i)
Expand All @@ -96,7 +97,7 @@ ComponentComparer comparer

public World World => _world;
public int Count => _count;
public readonly EcsComponent[] Components;
public readonly ImmutableArray<EcsComponent> Components;
internal Span<ArchetypeChunk> Chunks => _chunks.AsSpan(0, (_count + CHUNK_THRESHOLD - 1) / CHUNK_THRESHOLD);

[SkipLocalsInit]
Expand Down Expand Up @@ -286,7 +287,7 @@ private void InsertVertex(Archetype newNode)
return;
}

if (!IsSuperset(newNode.Components))
if (!IsSuperset(newNode.Components.AsSpan()))
{
return;
}
Expand All @@ -298,7 +299,7 @@ private void InsertVertex(Archetype newNode)
MakeEdges(newNode, this, Components[i].ID);
}

private bool IsSuperset(Span<EcsComponent> other)
private bool IsSuperset(ReadOnlySpan<EcsComponent> other)
{
int i = 0, j = 0;
while (i < Components.Length && j < other.Length)
Expand All @@ -316,13 +317,13 @@ private bool IsSuperset(Span<EcsComponent> other)

internal int FindMatch(ReadOnlySpan<Term> searching)
{
var currents = Components;
var currents = Components.AsSpan();
var i = 0;
var j = 0;

while (i < currents.Length && j < searching.Length)
{
ref var current = ref currents[i];
ref readonly var current = ref currents[i];
ref readonly var search = ref searching[j];

if (current.ID.CompareTo(search.ID) == 0)
Expand Down
60 changes: 30 additions & 30 deletions src/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ bool add
{
EcsAssert.Assert(!Unsafe.IsNullRef(ref record));

var arch = CreateArchetype(record.Archetype, in cmp, add);
var arch = AttachToArchetype(record.Archetype, in cmp, add);
if (arch == null)
return false;

Expand All @@ -212,7 +212,7 @@ bool add
}

[SkipLocalsInit]
private Archetype? CreateArchetype(Archetype root, ref readonly EcsComponent cmp, bool add)
private Archetype? AttachToArchetype(Archetype root, ref readonly EcsComponent cmp, bool add)
{
if (!add && root.GetComponentIndex(in cmp) < 0)
return null;
Expand Down Expand Up @@ -261,7 +261,7 @@ bool add

private ref Archetype? GetArchetype(Span<EcsComponent> components, bool create)
{
var hash = getHash(components, false);
var hash = Hashing.Calculate(components);
ref var arch = ref Unsafe.NullRef<Archetype>();
if (create)
{
Expand All @@ -283,15 +283,6 @@ bool add
// ) : ref CollectionsMarshal.GetValueRefOrNullRef(_typeIndex, hash);

return ref arch;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static ulong getHash(Span<EcsComponent> components, bool checkSize)
{
var hc = (ulong)components.Length;
foreach (ref var val in components)
hc = unchecked(hc * 314159 + val.ID);
return hc;
}
}

internal Array? Set(EntityView entity, ref EcsRecord record, ref readonly EcsComponent cmp)
Expand All @@ -312,7 +303,6 @@ static ulong getHash(Span<EcsComponent> components, bool checkSize)
if (emit)
{
OnComponentSet?.Invoke(entity, cmp);
//EmitEvent(EcsEventOnSet, entity, cmp.ID);
}

return array;
Expand All @@ -327,7 +317,7 @@ internal bool Has(EcsID entity, ref readonly EcsComponent cmp)
public ReadOnlySpan<EcsComponent> GetType(EcsID id)
{
ref var record = ref GetRecord(id);
return record.Archetype.Components;
return record.Archetype.Components.AsSpan();
}

public void PrintGraph()
Expand All @@ -346,7 +336,7 @@ public FilterQuery Filter(ReadOnlySpan<Term> terms)
}

public IQueryConstruct QueryBuilder() => new QueryBuilder(this);

internal Archetype? FindArchetype(ulong hash, ReadOnlySpan<Term> terms)
{
if (!_typeIndex.TryGetValue(hash, out var arch))
Expand All @@ -357,7 +347,7 @@ public FilterQuery Filter(ReadOnlySpan<Term> terms)
return arch;
}

public void System<TFilter, T0, T1>(QueryFilterDelegate<T0, T1> fn)
public void System<TFilter, T0, T1>(QueryFilterDelegate<T0, T1> fn)
where TFilter : struct where T0 : struct where T1 : struct
{
var hash = Lookup.Query<(T0, T1), TFilter>.Hash;
Expand All @@ -372,8 +362,8 @@ public void System<TFilter, T0, T1>(QueryFilterDelegate<T0, T1> fn)

static void InternalQuery
(
Archetype root,
QueryFilterDelegate<T0, T1> fn,
Archetype root,
QueryFilterDelegate<T0, T1> fn,
ReadOnlySpan<Term> terms,
IDictionary<ulong, Term> withouts
)
Expand Down Expand Up @@ -578,6 +568,25 @@ public QueryInternal Build()
}
}

internal static class Hashing
{
public static ulong Calculate(ReadOnlySpan<EcsComponent> components)
{
var hc = (ulong)components.Length;
foreach (ref readonly var val in components)
hc = unchecked(hc * 314159 + val.ID);
return hc;
}

public static ulong Calculate(ReadOnlySpan<Term> terms)
{
var hc = (ulong)terms.Length;
foreach (ref readonly var val in terms)
hc = unchecked(hc * 314159 + val.ID);
return hc;
}
}

internal static class Lookup
{
private static ulong _index = 0;
Expand Down Expand Up @@ -646,7 +655,7 @@ static void ParseTuple(ITuple tuple, SortedSet<Term> terms)
continue;
}

var id = Lookup.GetID(type);
var id = GetID(type);
terms.Add(new Term()
{
ID = IDOp.GetPairSecond(id),
Expand Down Expand Up @@ -679,15 +688,6 @@ static void ParseType<T>(SortedSet<Term> terms) where T : struct
EcsAssert.Assert(false, $"type not found {type}");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static ulong GetHash(ReadOnlySpan<Term> terms)
{
var hc = (ulong)terms.Length;
foreach (ref readonly var val in terms)
hc = unchecked(hc * 314159 + val.ID);
return hc;
}

internal static class Query<TQuery, TFilter> where TQuery : struct where TFilter : struct
{
public static readonly ImmutableArray<Term> Terms;
Expand All @@ -707,7 +707,7 @@ static Query()
Withs = list.Where(s => s.Op == TermOp.With).ToImmutableDictionary(s => s.ID, k => k);
Withouts = list.Where(s => s.Op == TermOp.Without).ToImmutableDictionary(s => s.ID, k => k);

Hash = GetHash(Withs.Values.ToArray());
Hash = Hashing.Calculate(Withs.Values.ToArray());
}
}

Expand All @@ -726,7 +726,7 @@ static Query()
Withs = list.Where(s => s.Op == TermOp.With).ToImmutableDictionary(s => s.ID, k => k);
Withouts = list.Where(s => s.Op == TermOp.Without).ToImmutableDictionary(s => s.ID, k => k);

Hash = GetHash(Withs.Values.ToArray());
Hash = Hashing.Calculate(Withs.Values.ToArray());
}
}
}
Expand Down

0 comments on commit e9f7d80

Please sign in to comment.