Changed array types, increasing performance
This commit is contained in:
parent
529f99abbd
commit
999ffa41dd
@ -16,18 +16,22 @@ package nz.ac.massey.javaecs;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
class ComponentArray{
|
class ComponentArray{
|
||||||
// The object data array
|
// The object data array
|
||||||
private List<Object> componentArray = new ArrayList<>();
|
private List<Object> componentArray;
|
||||||
// The mappings between data and entity
|
// The mappings between data and entity
|
||||||
private Map<Entity, Integer> entityComponentDataMap = new HashMap<>();
|
private Map<Entity, Integer> entityComponentDataMap;
|
||||||
private Map<Integer, Entity> componentDataEntityMap = new HashMap<>();
|
private Map<Integer, Entity> componentDataEntityMap;
|
||||||
|
|
||||||
|
public ComponentArray(int initialSize){
|
||||||
|
componentArray = new ArrayList<>(initialSize);
|
||||||
|
entityComponentDataMap = new HashMap<>(initialSize);
|
||||||
|
componentDataEntityMap = new HashMap<>(initialSize);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Gets the data Object associated with the entity.
|
* Gets the data Object associated with the entity.
|
||||||
* @param entity the entity to find data for
|
* @param entity the entity to find data for
|
||||||
|
@ -121,11 +121,21 @@ class ComponentManager{
|
|||||||
* @return true if the component was registered successfully, else false
|
* @return true if the component was registered successfully, else false
|
||||||
*/
|
*/
|
||||||
protected boolean registerComponent(Type type){
|
protected boolean registerComponent(Type type){
|
||||||
|
return registerComponent(type, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the component type
|
||||||
|
* @param type the class type to register
|
||||||
|
* @param arraySize the number of elements to prereserve space for.
|
||||||
|
* @return true if the component was registered successfully, else false
|
||||||
|
*/
|
||||||
|
protected boolean registerComponent(Type type, int arraySize){
|
||||||
if (componentArrays.containsKey(type)){
|
if (componentArrays.containsKey(type)){
|
||||||
Engine.writeErr("Component " + type.getTypeName() + " is already registered");
|
Engine.writeErr("Component " + type.getTypeName() + " is already registered");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
componentArrays.put(type, new ComponentArray());
|
componentArrays.put(type, new ComponentArray(arraySize));
|
||||||
indexComponentType.put(componentPosIndex.size(), type);
|
indexComponentType.put(componentPosIndex.size(), type);
|
||||||
componentPosIndex.put(type, componentPosIndex.size());
|
componentPosIndex.put(type, componentPosIndex.size());
|
||||||
return true;
|
return true;
|
||||||
|
@ -9,10 +9,10 @@ package nz.ac.massey.javaecs;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.LinkedList;
|
import java.util.Deque;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Queue;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
// Define the manager classes internally - should be moved to seperate source files as appropriate
|
// Define the manager classes internally - should be moved to seperate source files as appropriate
|
||||||
@ -22,7 +22,11 @@ import java.util.ArrayList;
|
|||||||
* I.e. Controls adding and removing entities, and registration and deregistration of components.
|
* I.e. Controls adding and removing entities, and registration and deregistration of components.
|
||||||
*/
|
*/
|
||||||
class EntityManager{
|
class EntityManager{
|
||||||
private Queue<Entity> unusedEntities;
|
// According to https://stackoverflow.com/questions/12524826/why-should-i-use-deque-over-stack
|
||||||
|
// ArrayDeque is likely faster than a LinkedList, when used as one.
|
||||||
|
// We can also supply a size to the constructor of ArrayDeque, which avoids resizing the collection
|
||||||
|
// at initialisation time (took 1.4s vs 1.8s for 1M)
|
||||||
|
private Deque<Entity> unusedEntities;
|
||||||
private List<BitSet> entityRegistrations;
|
private List<BitSet> entityRegistrations;
|
||||||
private int maxSize = 1024;
|
private int maxSize = 1024;
|
||||||
|
|
||||||
@ -30,8 +34,8 @@ class EntityManager{
|
|||||||
* Initialise the EntityManager with the default max size of 1024
|
* Initialise the EntityManager with the default max size of 1024
|
||||||
*/
|
*/
|
||||||
public EntityManager(){
|
public EntityManager(){
|
||||||
unusedEntities = new LinkedList<>();
|
unusedEntities = new ArrayDeque<>(maxSize);
|
||||||
entityRegistrations = new ArrayList<>();
|
entityRegistrations = new ArrayList<>(maxSize); // Init to maxSize to increase performance
|
||||||
|
|
||||||
for (int i = 0; i < maxSize; i++) {
|
for (int i = 0; i < maxSize; i++) {
|
||||||
unusedEntities.add(new Entity(i));
|
unusedEntities.add(new Entity(i));
|
||||||
@ -45,8 +49,8 @@ class EntityManager{
|
|||||||
*/
|
*/
|
||||||
public EntityManager(int maxEntities){
|
public EntityManager(int maxEntities){
|
||||||
maxSize = maxEntities;
|
maxSize = maxEntities;
|
||||||
unusedEntities = new LinkedList<>();
|
unusedEntities = new ArrayDeque<>(maxSize);
|
||||||
entityRegistrations = new ArrayList<>();
|
entityRegistrations = new ArrayList<>(maxEntities);
|
||||||
|
|
||||||
for (int i = 0; i < maxEntities; i++) {
|
for (int i = 0; i < maxEntities; i++) {
|
||||||
unusedEntities.add(new Entity(i));
|
unusedEntities.add(new Entity(i));
|
||||||
@ -180,7 +184,7 @@ class EntityManager{
|
|||||||
// Consistency should be maintained.
|
// Consistency should be maintained.
|
||||||
// This is computationally expensive; we must re-order every assigned entity above newSize, if the newSize is smaller
|
// This is computationally expensive; we must re-order every assigned entity above newSize, if the newSize is smaller
|
||||||
if (newSize < maxSize){
|
if (newSize < maxSize){
|
||||||
List<Entity> outOfBounds = new ArrayList<>();
|
Deque<Entity> outOfBounds = new ArrayDeque<>(maxSize - newSize);
|
||||||
for (int i = newSize; i < maxSize; i++) {
|
for (int i = newSize; i < maxSize; i++) {
|
||||||
Entity entityI = Entity.asEntity(i);
|
Entity entityI = Entity.asEntity(i);
|
||||||
if (!unusedEntities.remove(entityI)){
|
if (!unusedEntities.remove(entityI)){
|
||||||
@ -189,14 +193,15 @@ class EntityManager{
|
|||||||
outOfBounds.add(entityI);
|
outOfBounds.add(entityI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Entity integer : outOfBounds) {
|
while(outOfBounds.size() > 0){
|
||||||
|
Entity old = outOfBounds.remove();
|
||||||
Entity newPos = addEntity();
|
Entity newPos = addEntity();
|
||||||
setRegistrations(newPos, getRegistrations(integer));
|
setRegistrations(newPos, getRegistrations(old));
|
||||||
// Invoke an update in the SystemManager
|
// Invoke an update in the SystemManager
|
||||||
systemManager.entityDestroyed(integer);
|
systemManager.entityDestroyed(old);
|
||||||
systemManager.entityRegistrationsChanged(newPos, getRegistrations(newPos));
|
systemManager.entityRegistrationsChanged(newPos, getRegistrations(newPos));
|
||||||
// Invoke the change in the components
|
// Invoke the change in the components
|
||||||
componentManager.moveAllComponentData(integer, newPos, getRegistrations(integer));
|
componentManager.moveAllComponentData(old, newPos, getRegistrations(old));
|
||||||
}
|
}
|
||||||
for (int i = newSize; i < maxSize; i++) {
|
for (int i = newSize; i < maxSize; i++) {
|
||||||
// Remove out-of-bounds data
|
// Remove out-of-bounds data
|
||||||
|
Loading…
x
Reference in New Issue
Block a user