encompass-cs/encompass-cs/EntitySetQueryBuilder.cs

71 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using Encompass.Collections;
namespace Encompass
{
/// <summary>
/// EntitySetQuery is used to efficiently obtain a set of Entities that have all required Components and do not have any forbidden Components.
/// </summary>
public class EntitySetQueryBuilder
{
internal EntitySetQueryBuilder(EntityManager entityManager, ComponentUpdateManager componentUpdateManager, IEnumerable<Type> pendingTypes, IEnumerable<Type> existingTypes)
{
EntityManager = entityManager;
ComponentUpdateManager = componentUpdateManager;
WithMask = BitSet1024Builder.Zeroes();
WithoutMask = BitSet1024Builder.Zeroes();
PendingMask = BitSet1024Builder.Zeroes();
foreach (var type in pendingTypes)
{
PendingMask = PendingMask.Set(componentUpdateManager.TypeToIndex[type]);
}
ExistingMask = BitSet1024Builder.Zeroes();
foreach (var type in existingTypes)
{
ExistingMask = ExistingMask.Set(componentUpdateManager.TypeToIndex[type]);
}
}
private EntityManager EntityManager { get; }
private ComponentUpdateManager ComponentUpdateManager { get; }
private BitSet1024 WithMask { get; set; }
private BitSet1024 WithoutMask { get; set; }
private BitSet1024 PendingMask { get; set; }
private BitSet1024 ExistingMask { get; set; }
/// <summary>
/// Designates that the given component type is required.
/// </summary>
public EntitySetQueryBuilder With<TComponent>() where TComponent : struct, IComponent
{
WithMask = WithMask.Set(ComponentUpdateManager.TypeToIndex[typeof(TComponent)]);
return this;
}
/// <summary>
/// Designates that the given component type is forbidden.
/// </summary>
public EntitySetQueryBuilder Without<TComponent>() where TComponent : struct, IComponent
{
WithoutMask = WithoutMask.Set(ComponentUpdateManager.TypeToIndex[typeof(TComponent)]);
return this;
}
public EntitySetQuery Build()
{
return new EntitySetQuery(
EntityManager,
ComponentUpdateManager,
WithMask.And(PendingMask),
WithMask.And(ExistingMask),
WithoutMask.And(PendingMask),
WithoutMask.And(ExistingMask),
WithMask.Not()
);
}
}
}