Skip to content

Commit

Permalink
+Or now supports sub queries
Browse files Browse the repository at this point in the history
  • Loading branch information
andreakarasho committed May 22, 2024
1 parent e46a9ec commit 909e42d
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 31 deletions.
4 changes: 1 addition & 3 deletions samples/MyBattleground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@
ecs.Entity().Set(new Velocity());


ecs.Query<(Optional<Position>, Velocity)>();

//ecs.Entity().Set(new Position() {X = 2}).Set<Likes>();
ecs.Entity().Set(new Position() {X = 3}).Set<Networked>();

ecs.Query<(Position, ManagedData), Or<(Position, With<Networked>)>>()
ecs.Query<(Position, ManagedData), Or<(Position, Without<Networked>)>>()
.Each((EntityView e, ref Position maybe) => {
var isNull = Unsafe.IsNullRef(ref maybe);

Expand Down
10 changes: 5 additions & 5 deletions src/Match.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ public static int Validate(IComparer<ulong> comparer, EcsID[] ids, ReadOnlySpan<
switch (term.Op)
{
case TermOp.With:
if (!ids.Any(id => comparer.Compare(id, term.IDs[0]) == 0))
if (ids.All(id => ComponentComparer.CompareTerms(null, id, term.IDs[0].ID) != 0))

Check warning on line 15 in src/Match.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 15 in src/Match.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.
{
return 1; // Required ID not found
}
break;
case TermOp.Without:
if (ids.Any(id => comparer.Compare(id, term.IDs[0]) == 0))
if (ids.Any(id => ComponentComparer.CompareTerms(null, id, term.IDs[0].ID) == 0))

Check warning on line 21 in src/Match.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 21 in src/Match.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.
{
return -1; // Forbidden ID found
}
Expand All @@ -27,19 +27,19 @@ public static int Validate(IComparer<ulong> comparer, EcsID[] ids, ReadOnlySpan<
// Do nothing, as presence or absence is acceptable
break;
case TermOp.AtLeastOne:
if (!ids.Any(id => term.IDs.Any(tid => comparer.Compare(id, tid) == 0)))
if (!ids.Any(id => term.IDs.Any(tid => ComponentComparer.CompareTerms(null, id, tid.ID)== 0)))

Check warning on line 30 in src/Match.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 30 in src/Match.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.
{
return 1; // At least one required ID not found
}
break;
case TermOp.Exactly:
if (!ids.SequenceEqual(term.IDs))
if (!ids.SequenceEqual(term.IDs.Select(s => s.ID)))
{
return 1; // Exact match required but not found
}
break;
case TermOp.None:
if (ids.Any(id => term.IDs.Any(tid => comparer.Compare(id, tid) == 0)))
if (ids.Any(id => term.IDs.Any(tid => ComponentComparer.CompareTerms(null, id, tid.ID) == 0)))

Check warning on line 42 in src/Match.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 42 in src/Match.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.
{
return -1; // None of the specified IDs should be present
}
Expand Down
5 changes: 3 additions & 2 deletions src/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ internal Query(World world, ImmutableArray<Term> terms)
// which needs a terms.Where(..).Reverse()
foreach (var or in terms.Where(s => s.Op == TermOp.Or))
{
var orIds = or.IDs.Select(s => new Term(s, TermOp.With));
var orIds = or.IDs.Select(s => new Term(s.ID, s.Op));
subQuery = World.GetQuery
(
Hashing.Calculate(orIds.ToArray()),
Expand Down Expand Up @@ -180,7 +180,8 @@ internal void Match()

var ids = _terms
.Where(s => s.Op == TermOp.With || s.Op == TermOp.Exactly)
.SelectMany(s => s.IDs);
.SelectMany(s => s.IDs)
.Select(s => s.ID);

var first = World.FindArchetype(Hashing.Calculate(ids));
if (first == null)
Expand Down
10 changes: 5 additions & 5 deletions src/Term.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ namespace TinyEcs;
[DebuggerDisplay("{IDs} - {Op}")]
public readonly struct Term : IComparable<Term>
{
public readonly ImmutableSortedSet<EcsID> IDs;
public readonly ImmutableSortedSet<(EcsID ID, TermOp Op)> IDs;
public readonly TermOp Op;

public Term(EcsID id, TermOp op)
{
IDs = new SortedSet<EcsID>() { id }.ToImmutableSortedSet();
IDs = new SortedSet<(EcsID ID, TermOp Op)>() { (id, op) }.ToImmutableSortedSet();
Op = op;
}

public Term(IEnumerable<EcsID> ids, TermOp op)
public Term(IEnumerable<(EcsID ID, TermOp Op)> ids, TermOp op)
{
IDs = new SortedSet<EcsID>(ids).ToImmutableSortedSet();
IDs = new SortedSet<(EcsID ID, TermOp Op)>(ids).ToImmutableSortedSet();
Op = op;
}

public readonly int CompareTo(Term other)
{
var idComparison = IDs[0].CompareTo(other.IDs[0]);
var idComparison = IDs[0].ID.CompareTo(other.IDs[0].ID);
if (idComparison != 0)
{
return idComparison;
Expand Down
21 changes: 5 additions & 16 deletions src/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ public static ulong Calculate(ReadOnlySpan<Term> terms)
{
var hc = (ulong)terms.Length;
foreach (ref readonly var val in terms)
hc = unchecked(hc * FIXED + (ulong)val.IDs.Sum(s => s.ID) + (byte)val.Op);
hc = unchecked(hc * FIXED + (ulong)val.IDs.Select(s => s.ID).Sum(s => s.ID) + (byte)val.Op);
return hc;
}

Expand Down Expand Up @@ -508,11 +508,10 @@ private static Term GetTerm(Type type)
var ok = _typesConvertion.TryGetValue(type, out var term);
if (!ok)
{
var exists = _componentInfosByType.ContainsKey(type);
if (exists)
EcsAssert.Assert(ok, $"The tag '{type}' cannot be used as query data");
else
EcsAssert.Assert(ok, $"Component '{type}' not found! Try to register it using 'world.Entity<{type}>()'");
EcsAssert.Assert(ok,
_componentInfosByType.ContainsKey(type)
? $"The tag '{type}' cannot be used as query data"
: $"Component '{type}' not found! Try to register it using 'world.Entity<{type}>()'");
}
return term;
}
Expand Down Expand Up @@ -595,16 +594,6 @@ private static int GetSize()
}
}

static void Validate(Type type)
{
if (typeof(ITuple).IsAssignableFrom(type))
{

}


}

static void ParseTuple(ITuple tuple, List<Term> terms, Func<Type, (bool, string?)> validate)
{
var mainType = tuple.GetType();
Expand Down

0 comments on commit 909e42d

Please sign in to comment.