I modified SubPixelPerfect’s code slightly so that I can add using static QueryBuilder;
And then I can call QB directly to get a new instance of QueryBuilder without extending ComponentSystem.
I’m using this to build a state machine as outlined in R. Fabian’s Data-Oriented Design book, so I wanted a way to easily extend queries beyond ORing them. I added a Copy property which returns a copy of the QueryBuilder to facilitate this.
I’m basically storing QueryBuilders instead of actual queries and only converting them to an actual EntityArchetypeQuery when I need to. Also to avoid having to call Build I made an implicit conversion operator that converts to EntityArchetypeQuery. I also extended the Any, All, and None methods to take 6 type params.
public class QueryBuilder
{
private List<ComponentType> _all = new List<ComponentType>();
private List<ComponentType> _any = new List<ComponentType>();
private List<ComponentType> _none = new List<ComponentType>();
public QueryBuilder() { }
public QueryBuilder(List<ComponentType> all, List<ComponentType> any, List<ComponentType> none)
{
_all = all;
_any = any;
_none = none;
}
public static QueryBuilder QB => new QueryBuilder();
public EntityArchetypeQuery Build => new EntityArchetypeQuery()
{
All = _all.ToArray(),
None = _none.ToArray(),
Any = _any.ToArray()
};
// Make a deep copy (shallow copy of each array, but the arrays are value types)
public QueryBuilder Copy => new QueryBuilder(_all.ToList(), _any.ToList(), _none.ToList());
// Implicit conversion to EntityArchetypeQuery--avoids the need to call .Build
public static implicit operator EntityArchetypeQuery(QueryBuilder qb)
{
return qb.Build;
}
public QueryBuilder All<T>()
where T : struct, IComponentData
{
_all.Add(ComponentType.Create<T>());
return this;
}
public QueryBuilder All<T, T2>()
where T : struct, IComponentData
where T2 : struct, IComponentData
{
_all.Add(ComponentType.Create<T>());
_all.Add(ComponentType.Create<T2>());
return this;
}
public QueryBuilder All<T, T2, T3>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
{
_all.Add(ComponentType.Create<T>());
_all.Add(ComponentType.Create<T2>());
_all.Add(ComponentType.Create<T3>());
return this;
}
public QueryBuilder All<T, T2, T3, T4>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
{
_all.Add(ComponentType.Create<T>());
_all.Add(ComponentType.Create<T2>());
_all.Add(ComponentType.Create<T3>());
_all.Add(ComponentType.Create<T4>());
return this;
}
public QueryBuilder All<T, T2, T3, T4, T5>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
where T5 : struct, IComponentData
{
_all.Add(ComponentType.Create<T>());
_all.Add(ComponentType.Create<T2>());
_all.Add(ComponentType.Create<T3>());
_all.Add(ComponentType.Create<T4>());
_all.Add(ComponentType.Create<T5>());
return this;
}
public QueryBuilder All<T, T2, T3, T4, T5, T6>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
where T5 : struct, IComponentData
where T6 : struct, IComponentData
{
_all.Add(ComponentType.Create<T>());
_all.Add(ComponentType.Create<T2>());
_all.Add(ComponentType.Create<T3>());
_all.Add(ComponentType.Create<T4>());
_all.Add(ComponentType.Create<T5>());
_all.Add(ComponentType.Create<T6>());
return this;
}
public QueryBuilder None<T>() where T : struct, IComponentData
{
_none.Add(ComponentType.Create<T>());
return this;
}
public QueryBuilder None<T, T2>()
where T : struct, IComponentData
where T2 : struct, IComponentData
{
_none.Add(ComponentType.Create<T>());
_none.Add(ComponentType.Create<T2>());
return this;
}
public QueryBuilder None<T, T2, T3>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
{
_none.Add(ComponentType.Create<T>());
_none.Add(ComponentType.Create<T2>());
_none.Add(ComponentType.Create<T3>());
return this;
}
public QueryBuilder None<T, T2, T3, T4>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
{
_none.Add(ComponentType.Create<T>());
_none.Add(ComponentType.Create<T2>());
_none.Add(ComponentType.Create<T3>());
_none.Add(ComponentType.Create<T4>());
return this;
}
public QueryBuilder None<T, T2, T3, T4, T5>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
where T5 : struct, IComponentData
{
_none.Add(ComponentType.Create<T>());
_none.Add(ComponentType.Create<T2>());
_none.Add(ComponentType.Create<T3>());
_none.Add(ComponentType.Create<T4>());
_none.Add(ComponentType.Create<T5>());
return this;
}
public QueryBuilder None<T, T2, T3, T4, T5, T6>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
where T5 : struct, IComponentData
where T6 : struct, IComponentData
{
_none.Add(ComponentType.Create<T>());
_none.Add(ComponentType.Create<T2>());
_none.Add(ComponentType.Create<T3>());
_none.Add(ComponentType.Create<T4>());
_none.Add(ComponentType.Create<T5>());
_none.Add(ComponentType.Create<T6>());
return this;
}
public QueryBuilder Any<T>() where T : struct, IComponentData
{
_any.Add(ComponentType.Create<T>());
return this;
}
public QueryBuilder Any<T, T2>()
where T : struct, IComponentData
where T2 : struct, IComponentData
{
_any.Add(ComponentType.Create<T>());
_any.Add(ComponentType.Create<T2>());
return this;
}
public QueryBuilder Any<T, T2, T3>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
{
_any.Add(ComponentType.Create<T>());
_any.Add(ComponentType.Create<T2>());
_any.Add(ComponentType.Create<T3>());
return this;
}
public QueryBuilder Any<T, T2, T3, T4>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
{
_any.Add(ComponentType.Create<T>());
_any.Add(ComponentType.Create<T2>());
_any.Add(ComponentType.Create<T3>());
_any.Add(ComponentType.Create<T4>());
return this;
}
public QueryBuilder Any<T, T2, T3, T4, T5>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
where T5 : struct, IComponentData
{
_any.Add(ComponentType.Create<T>());
_any.Add(ComponentType.Create<T2>());
_any.Add(ComponentType.Create<T3>());
_any.Add(ComponentType.Create<T4>());
_any.Add(ComponentType.Create<T5>());
return this;
}
public QueryBuilder Any<T, T2, T3, T4, T5, T6>()
where T : struct, IComponentData
where T2 : struct, IComponentData
where T3 : struct, IComponentData
where T4 : struct, IComponentData
where T5 : struct, IComponentData
where T6 : struct, IComponentData
{
_any.Add(ComponentType.Create<T>());
_any.Add(ComponentType.Create<T2>());
_any.Add(ComponentType.Create<T3>());
_any.Add(ComponentType.Create<T4>());
_any.Add(ComponentType.Create<T5>());
_any.Add(ComponentType.Create<T6>());
return this;
}
}