using System;
using Svelto.DataStructures;
namespace Svelto.ECS
{
///
/// DynamicEntityDescriptor can be used to add entity components to an existing EntityDescriptor that act as flags,
/// at building time.
/// This method allocates, so it shouldn't be abused
///
///
public struct DynamicEntityDescriptor : IDynamicEntityDescriptor where TType : IEntityDescriptor, new()
{
internal DynamicEntityDescriptor(bool isExtendible) : this()
{
var defaultEntities = EntityDescriptorTemplate.descriptor.componentsToBuild;
var length = defaultEntities.Length;
ComponentsToBuild = new IComponentBuilder[length + 1];
Array.Copy(defaultEntities, 0, ComponentsToBuild, 0, length);
//assign it after otherwise the previous copy will overwrite the value in case the item
//is already present
ComponentsToBuild[length] = new ComponentBuilder
(
new EntityInfoComponent
{
componentsToBuild = ComponentsToBuild
}
);
}
public DynamicEntityDescriptor(IComponentBuilder[] extraEntityBuilders) : this()
{
var extraEntitiesLength = extraEntityBuilders.Length;
ComponentsToBuild = Construct(extraEntitiesLength, extraEntityBuilders,
EntityDescriptorTemplate.descriptor.componentsToBuild);
}
public DynamicEntityDescriptor(FasterList extraEntityBuilders) : this()
{
var extraEntities = extraEntityBuilders.ToArrayFast(out _);
var extraEntitiesLength = extraEntityBuilders.count;
ComponentsToBuild = Construct((int) extraEntitiesLength, extraEntities,
EntityDescriptorTemplate.descriptor.componentsToBuild);
}
public void ExtendWith() where T : IEntityDescriptor, new()
{
var newEntitiesToBuild = EntityDescriptorTemplate.descriptor.componentsToBuild;
ComponentsToBuild = Construct(newEntitiesToBuild.Length, newEntitiesToBuild, ComponentsToBuild);
}
public void ExtendWith(IComponentBuilder[] extraEntities)
{
ComponentsToBuild = Construct(extraEntities.Length, extraEntities, ComponentsToBuild);
}
static IComponentBuilder[] Construct(int extraEntitiesLength, IComponentBuilder[] extraEntities,
IComponentBuilder[] startingEntities)
{
IComponentBuilder[] localEntitiesToBuild;
if (extraEntitiesLength == 0)
{
localEntitiesToBuild = startingEntities;
return localEntitiesToBuild;
}
var defaultEntities = startingEntities;
var index = SetupEntityInfoComponent(defaultEntities, out localEntitiesToBuild, extraEntitiesLength);
Array.Copy(extraEntities, 0, localEntitiesToBuild, defaultEntities.Length, extraEntitiesLength);
//assign it after otherwise the previous copy will overwrite the value in case the item
//is already present
localEntitiesToBuild[index] = new ComponentBuilder
(
new EntityInfoComponent
{
componentsToBuild = localEntitiesToBuild
}
);
return localEntitiesToBuild;
}
static int SetupEntityInfoComponent(IComponentBuilder[] defaultEntities, out IComponentBuilder[] componentsToBuild,
int extraLenght)
{
int length = defaultEntities.Length;
int index = -1;
for (var i = 0; i < length; i++)
{
//the special entity already exists
if (defaultEntities[i].GetEntityComponentType() == ComponentBuilderUtilities.ENTITY_INFO_COMPONENT)
{
index = i;
break;
}
}
if (index == -1)
{
index = length + extraLenght;
componentsToBuild = new IComponentBuilder[index + 1];
}
else
componentsToBuild = new IComponentBuilder[length + extraLenght];
Array.Copy(defaultEntities, 0, componentsToBuild, 0, length);
return index;
}
public IComponentBuilder[] componentsToBuild => ComponentsToBuild;
IComponentBuilder[] ComponentsToBuild;
}
}