Added a dynamic resize funtion

This commit is contained in:
Brychan Dempsey 2021-05-22 22:30:44 +12:00
parent 39c3de7dcb
commit 11ae6c425c
4 changed files with 87 additions and 0 deletions

View File

@ -65,6 +65,17 @@ class ComponentArray{
componentArray.add(component); componentArray.add(component);
} }
/**
* Moves component data to another entity. (Copies, deletes and inserts data)
* @param sourceEntity
* @param destinationEntity
*/
public void moveData(int sourceEntity, int destinationEntity){
Object data = entityComponentDataMap.get(sourceEntity);
removeData(sourceEntity);
insertData(destinationEntity, data);
}
public Object getData(int entity){ public Object getData(int entity){
if (!entityComponentDataMap.containsKey(entity)){ if (!entityComponentDataMap.containsKey(entity)){
System.err.println("Attempted to retrieve non-existent data"); System.err.println("Attempted to retrieve non-existent data");

View File

@ -48,4 +48,15 @@ class ComponentManager{
public Integer getComponentIndex(Type type){ public Integer getComponentIndex(Type type){
return componentPosIndex.get(type); return componentPosIndex.get(type);
} }
/**
* Moves component data from one entity to another
* @param sourceEntity
* @param destinationEntity
*/
public void moveComponentData(int sourceEntity, int destinationEntity){
for (Type key : componentArrays.keySet()) {
componentArrays.get(key).moveData(sourceEntity, destinationEntity);
}
}
} }

View File

@ -53,6 +53,15 @@ public class ECS {
return entityManager.addEntity(); return entityManager.addEntity();
} }
/**
* Attempts to resize the maximum number of entities
* @param newSize the new maximum number of entities
* @return true if the operation succeeded
*/
boolean resizeMaximum(int newSize){
return entityManager.resize(newSize, systemManager, componentManager);
}
/** /**
* Signals each manager to remove the specified entity * Signals each manager to remove the specified entity
* @param entity the entity to destroy * @param entity the entity to destroy

View File

@ -26,8 +26,10 @@ import java.util.ArrayList;
class EntityManager{ class EntityManager{
Queue<Integer> unusedEntities; Queue<Integer> unusedEntities;
List<BitSet> entityRegistrations; List<BitSet> entityRegistrations;
int currentSize;
public EntityManager(){ public EntityManager(){
currentSize = 1024;
unusedEntities = new LinkedList<>(); unusedEntities = new LinkedList<>();
entityRegistrations = new ArrayList<>(); entityRegistrations = new ArrayList<>();
@ -38,6 +40,7 @@ class EntityManager{
} }
public EntityManager(int maxEntities){ public EntityManager(int maxEntities){
currentSize = maxEntities;
unusedEntities = new LinkedList<>(); unusedEntities = new LinkedList<>();
entityRegistrations = new ArrayList<>(); entityRegistrations = new ArrayList<>();
@ -72,4 +75,57 @@ class EntityManager{
public BitSet getRegistrations(int entity){ public BitSet getRegistrations(int entity){
return entityRegistrations.get(entity); return entityRegistrations.get(entity);
} }
public void setRegistrations(int entity, BitSet registrations){
entityRegistrations.set(entity, registrations);
}
public boolean resize(int newSize, SystemManager systemManager, ComponentManager componentManager){
if (newSize >= currentSize - unusedEntities.size()){
System.err.println("Attempted to resize the maximum entity count to a number smaller than the current assigned entity count.");
return false;
}
else if (newSize == currentSize){
System.err.println("Attempted to set the newSize to the current size");
return true;
}
else{
// Consistency should be maintained.
// This is computationally expensive; we must re-order every assigned entity above newSize, if the newSize is smaller
if (newSize < currentSize){
List<Integer> outOfBounds = new ArrayList<>();
for (int i = newSize; i < currentSize; i++) {
if (!unusedEntities.remove(i)){
// Could not remove element, as it didn't exist (already assigned).
// must find it and reassign it a new in-bounds value
outOfBounds.add(i);
}
}
for (Integer integer : outOfBounds) {
int newPos = addEntity();
setRegistrations(newPos, getRegistrations(integer));
// Invoke an update in the SystemManager
systemManager.entityDestroyed(integer);
systemManager.entitySignatureChanged(newPos, getRegistrations(newPos));
// Invoke the change in the components
componentManager.moveComponentData(integer, newPos);
componentManager.entityDestroyed(integer);
}
for (int i = newSize; i < currentSize; i++) {
// Remove out-of-bounds data
entityRegistrations.remove(i);
}
}
else{
// Init unassigned values
for (int i = currentSize; i < newSize; i++) {
unusedEntities.add(i);
entityRegistrations.add(new BitSet());
}
}
// Finally, set the current size
currentSize = newSize;
return true;
}
}
} }