From 11ae6c425c0405b82ed5987553a4d9c90e9d81f3 Mon Sep 17 00:00:00 2001 From: Brychan Dempsey Date: Sat, 22 May 2021 22:30:44 +1200 Subject: [PATCH] Added a dynamic resize funtion --- .../ComponentArray.java | 11 ++++ .../ComponentManager.java | 11 ++++ .../ECS.java | 9 +++ .../EntityManager.java | 56 +++++++++++++++++++ 4 files changed, 87 insertions(+) diff --git a/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ComponentArray.java b/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ComponentArray.java index 2cc52fc..d0938ca 100644 --- a/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ComponentArray.java +++ b/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ComponentArray.java @@ -65,6 +65,17 @@ class ComponentArray{ 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){ if (!entityComponentDataMap.containsKey(entity)){ System.err.println("Attempted to retrieve non-existent data"); diff --git a/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ComponentManager.java b/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ComponentManager.java index fa8ebd7..f116629 100644 --- a/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ComponentManager.java +++ b/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ComponentManager.java @@ -48,4 +48,15 @@ class ComponentManager{ public Integer getComponentIndex(Type 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); + } + } } \ No newline at end of file diff --git a/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ECS.java b/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ECS.java index 39365a5..383d4e1 100644 --- a/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ECS.java +++ b/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/ECS.java @@ -53,6 +53,15 @@ public class ECS { 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 * @param entity the entity to destroy diff --git a/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/EntityManager.java b/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/EntityManager.java index 47ca6f0..e2793b5 100644 --- a/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/EntityManager.java +++ b/javaecs/src/main/java/nz/ac/massey/programming_project_159333_s1_2021/EntityManager.java @@ -26,8 +26,10 @@ import java.util.ArrayList; class EntityManager{ Queue unusedEntities; List entityRegistrations; + int currentSize; public EntityManager(){ + currentSize = 1024; unusedEntities = new LinkedList<>(); entityRegistrations = new ArrayList<>(); @@ -38,6 +40,7 @@ class EntityManager{ } public EntityManager(int maxEntities){ + currentSize = maxEntities; unusedEntities = new LinkedList<>(); entityRegistrations = new ArrayList<>(); @@ -72,4 +75,57 @@ class EntityManager{ public BitSet getRegistrations(int 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 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; + } + } } \ No newline at end of file