114 lines
4.1 KiB
Java
114 lines
4.1 KiB
Java
package nz.ac.massey.javaecs;
|
|
/**
|
|
* Component Array
|
|
* Defines the data structure that component data is stored under.
|
|
* Has a list of defined objects, and two associative maps that link
|
|
* the position of the data with the entity number.
|
|
*
|
|
* Therefore, every entity in entityComponentDataMap is valid, so
|
|
* no additional sorting is required
|
|
*
|
|
*
|
|
* Contributors:
|
|
* Brychan Dempsey - brychand@hotmail.com
|
|
*
|
|
*/
|
|
|
|
import java.util.Map;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.ArrayList;
|
|
|
|
|
|
class ComponentArray{
|
|
// The object data array
|
|
private List<Object> componentArray = new ArrayList<>();
|
|
// The mappings between data and entity
|
|
private Map<Integer, Integer> entityComponentDataMap = new HashMap<>();
|
|
private Map<Integer, Integer> componentDataEntityMap = new HashMap<>();
|
|
|
|
/**
|
|
* Gets the data Object associated with the entity.
|
|
* @param entity the entity to find data for
|
|
* @return the Object if the data exists, else null
|
|
*/
|
|
protected Object getData(int entity){
|
|
try{
|
|
return componentArray.get(entityComponentDataMap.get(entity));
|
|
}
|
|
catch (NullPointerException ex){
|
|
ECS.writeErr("Attempted to retrieve non-existent data");
|
|
return null;
|
|
}
|
|
catch (IndexOutOfBoundsException e){
|
|
ECS.writeErr("Index out-of-bounds");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Inserts the provided component and associates it with the entity.
|
|
* @param entity the entity to associate data to
|
|
* @param component the component data
|
|
* @return true if successful, false if the entity is already subscribed to the component
|
|
*/
|
|
protected boolean insertData(int entity, Object component){
|
|
if (entityComponentDataMap.containsKey(entity)){
|
|
ECS.writeErr("Entity is already subscribed to the component");
|
|
return false;
|
|
}
|
|
// Put data at the end of the componentArray
|
|
int index = componentArray.size();
|
|
entityComponentDataMap.put(entity, index);
|
|
componentDataEntityMap.put(index, entity);
|
|
componentArray.add(component);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Moves component data to another entity. (Copies, deletes and inserts data)
|
|
* @param sourceEntity
|
|
* @param destinationEntity
|
|
* @return 0 if successful, -1 if the object is null, -2 if a NullPointerException occurred, and -3 if inserting data failed
|
|
*/
|
|
protected int moveData(int sourceEntity, int destinationEntity){
|
|
try{
|
|
Object data = entityComponentDataMap.get(sourceEntity);
|
|
if (data == null) return -1;
|
|
else if (insertData(destinationEntity, data))
|
|
{
|
|
removeData(sourceEntity);
|
|
return 0;
|
|
}
|
|
else return -3;
|
|
}
|
|
catch (NullPointerException e){
|
|
return -2;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes the data associated with the entity.
|
|
* @param entity the entity to remove the data from
|
|
* @return true if the data was removed. If the data isn't found then returns false
|
|
*/
|
|
protected boolean removeData(int entity){
|
|
if (!entityComponentDataMap.containsKey(entity)){
|
|
ECS.writeErr("Attempted to remove non-existent entity");
|
|
return false;
|
|
}
|
|
// Get the componentData index of the entity
|
|
int removedComponentDataIndex = entityComponentDataMap.get(entity);
|
|
// Replace the removed component with the last component in the array
|
|
componentArray.set(removedComponentDataIndex, componentArray.get(componentArray.size() -1));
|
|
// update the data positions in the map
|
|
int lastEntity = componentDataEntityMap.get(componentArray.size()-1);
|
|
entityComponentDataMap.replace(lastEntity, removedComponentDataIndex);
|
|
componentDataEntityMap.replace(removedComponentDataIndex, lastEntity);
|
|
// Finally, remomve the last elements
|
|
entityComponentDataMap.remove(entity);
|
|
componentDataEntityMap.remove(componentArray.size() -1);
|
|
componentArray.remove(componentArray.size() -1);
|
|
return true;
|
|
}
|
|
} |