merge component array into manager

This commit is contained in:
Benjamin Palko 2024-10-10 14:00:33 -04:00
parent 888abc495b
commit ab187a9fa9
4 changed files with 86 additions and 87 deletions

View file

@ -1,47 +0,0 @@
#include <cassert>
#include "componentarray.hpp"
template <typename T>
void ComponentArray<T>::InsertData(Entity entity, T component) {
assert(mEntityToIndexMap.find(entity) == mEntityToIndexMap.end() &&
"Component added to same entity more than once.");
// Put new entry at end and update the maps
size_t newIndex = mSize;
mEntityToIndexMap[entity] = newIndex;
mIndexToEntityMap[newIndex] = entity;
mComponentArray[newIndex] = component;
++mSize;
};
template <typename T> void ComponentArray<T>::RemoveData(Entity entity) {
assert(mEntityToIndexMap.find(entity) != mEntityToIndexMap.end() &&
"Removing non-existent component.");
// Copy element at end into deleted element's place to maintain density
size_t indexOfRemovedEntity = mEntityToIndexMap[entity];
size_t indexOfLastElement = mSize - 1;
mComponentArray[indexOfRemovedEntity] = mComponentArray[indexOfLastElement];
// Update map to point to moved spot
Entity entityOfLastElement = mIndexToEntityMap[indexOfLastElement];
mEntityToIndexMap[entityOfLastElement] = indexOfRemovedEntity;
mIndexToEntityMap[indexOfRemovedEntity] = entityOfLastElement;
mEntityToIndexMap.erase(entity);
mIndexToEntityMap.erase(indexOfLastElement);
--mSize;
};
template <typename T> T &ComponentArray<T>::GetData(Entity entity) {
assert(mEntityToIndexMap.find(entity) != mEntityToIndexMap.end() &&
"Retrieving non-existent component.");
// Return a reference to the entity's component
return mComponentArray[mEntityToIndexMap[entity]];
};
template <typename T> void ComponentArray<T>::EntityDestroyed(Entity entity) {
if (mEntityToIndexMap.find(entity) != mEntityToIndexMap.end()) {
// Remove the entity's component if it existed
RemoveData(entity);
}
};

View file

@ -1,37 +0,0 @@
#ifndef COMPONENTARRAY_HPP
#define COMPONENTARRAY_HPP
#include <unordered_map>
#include <array>
#include "entity.hpp"
class IComponentArray {
public:
virtual ~IComponentArray() = default;
virtual void EntityDestroyed(Entity entity) = 0;
};
template <typename T> class ComponentArray : public IComponentArray {
// The packed array of components (of generic type T),
// set to a specified maximum amount, matching the maximum number
// of entities allowed to exist simultaneously, so that each entity
// has a unique spot.
std::array<T, MAX_ENTITIES> mComponentArray;
// Map from an entity ID to an array index.
std::unordered_map<Entity, size_t> mEntityToIndexMap;
// Map from an array index to an entity ID.
std::unordered_map<size_t, Entity> mIndexToEntityMap;
// Total size of valid entries in the array.
size_t mSize;
public:
void InsertData(Entity entity, T component);
void RemoveData(Entity entity);
T &GetData(Entity entity);
void EntityDestroyed(Entity entity) override;
};
#endif // COMPONENTARRAY_HPP

View file

@ -1,7 +1,61 @@
#include "componentmanager.hpp"
#include "componentarray.hpp"
#include <cassert>
#include <memory>
/**
* ComponentArray
**/
template <typename T>
void ComponentArray<T>::InsertData(Entity entity, T component) {
assert(mEntityToIndexMap.find(entity) == mEntityToIndexMap.end() &&
"Component added to same entity more than once.");
// Put new entry at end and update the maps
size_t newIndex = mSize;
mEntityToIndexMap[entity] = newIndex;
mIndexToEntityMap[newIndex] = entity;
mComponentArray[newIndex] = component;
++mSize;
};
template <typename T> void ComponentArray<T>::RemoveData(Entity entity) {
assert(mEntityToIndexMap.find(entity) != mEntityToIndexMap.end() &&
"Removing non-existent component.");
// Copy element at end into deleted element's place to maintain density
size_t indexOfRemovedEntity = mEntityToIndexMap[entity];
size_t indexOfLastElement = mSize - 1;
mComponentArray[indexOfRemovedEntity] = mComponentArray[indexOfLastElement];
// Update map to point to moved spot
Entity entityOfLastElement = mIndexToEntityMap[indexOfLastElement];
mEntityToIndexMap[entityOfLastElement] = indexOfRemovedEntity;
mIndexToEntityMap[indexOfRemovedEntity] = entityOfLastElement;
mEntityToIndexMap.erase(entity);
mIndexToEntityMap.erase(indexOfLastElement);
--mSize;
};
template <typename T> T &ComponentArray<T>::GetData(Entity entity) {
assert(mEntityToIndexMap.find(entity) != mEntityToIndexMap.end() &&
"Retrieving non-existent component.");
// Return a reference to the entity's component
return mComponentArray[mEntityToIndexMap[entity]];
};
template <typename T> void ComponentArray<T>::EntityDestroyed(Entity entity) {
if (mEntityToIndexMap.find(entity) != mEntityToIndexMap.end()) {
// Remove the entity's component if it existed
RemoveData(entity);
}
};
/**
* ComponentManager
**/
// Private functions
template <typename T>
std::shared_ptr<ComponentArray<T>> ComponentManager::GetComponentArray() {

View file

@ -1,11 +1,40 @@
#ifndef COMPONENTMANAGER_HPP
#define COMPONENTMANAGER_HPP
#include <array>
#include <unordered_map>
#include <memory>
#include <cassert>
#include "entity.hpp"
#include "component.hpp"
#include "componentarray.hpp"
class IComponentArray {
public:
virtual ~IComponentArray() = default;
virtual void EntityDestroyed(Entity entity) = 0;
};
template <typename T> class ComponentArray : public IComponentArray {
// The packed array of components (of generic type T),
// set to a specified maximum amount, matching the maximum number
// of entities allowed to exist simultaneously, so that each entity
// has a unique spot.
std::array<T, MAX_ENTITIES> mComponentArray;
// Map from an entity ID to an array index.
std::unordered_map<Entity, size_t> mEntityToIndexMap;
// Map from an array index to an entity ID.
std::unordered_map<size_t, Entity> mIndexToEntityMap;
// Total size of valid entries in the array.
size_t mSize;
public:
void InsertData(Entity entity, T component);
void RemoveData(Entity entity);
T &GetData(Entity entity);
void EntityDestroyed(Entity entity) override;
};
class ComponentManager {
// Map from type string pointer to a component type