2026-07-18 19:33:05 +08:00
|
|
|
namespace OECS;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Describes a query over the ECS world.
|
|
|
|
|
/// Composed of a set of required component types ("with") and
|
|
|
|
|
/// a set of excluded component types ("without").
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class QueryDescriptor
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Component types that must be present on matching entities.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IReadOnlySet<Type> With { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Component types that must NOT be present on matching entities.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IReadOnlySet<Type> Without { get; }
|
|
|
|
|
|
|
|
|
|
internal QueryDescriptor(HashSet<Type> with, HashSet<Type> without)
|
|
|
|
|
{
|
|
|
|
|
With = with;
|
|
|
|
|
Without = without;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns true if this query has no "with" components (matches nothing).
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal bool IsEmpty => With.Count == 0;
|
2026-07-18 19:58:23 +08:00
|
|
|
|
|
|
|
|
public override bool Equals(object? obj)
|
|
|
|
|
{
|
|
|
|
|
if (obj is not QueryDescriptor other) return false;
|
|
|
|
|
if (With.Count != other.With.Count || Without.Count != other.Without.Count)
|
|
|
|
|
return false;
|
|
|
|
|
return With.SetEquals(other.With) && Without.SetEquals(other.Without);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
|
{
|
|
|
|
|
var hash = new HashCode();
|
2026-07-18 20:07:43 +08:00
|
|
|
foreach (var t in With.OrderBy(t => t.GUID.ToString()))
|
2026-07-18 19:58:23 +08:00
|
|
|
hash.Add(t);
|
2026-07-18 20:07:43 +08:00
|
|
|
foreach (var t in Without.OrderBy(t => t.GUID.ToString()))
|
2026-07-18 19:58:23 +08:00
|
|
|
hash.Add(t);
|
|
|
|
|
return hash.ToHashCode();
|
|
|
|
|
}
|
2026-07-18 19:33:05 +08:00
|
|
|
}
|