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