diff --git a/src/entityComponentSystem/PooledComponentManager.hpp b/src/entityComponentSystem/PooledComponentManager.hpp index 34ccd6c..946a128 100644 --- a/src/entityComponentSystem/PooledComponentManager.hpp +++ b/src/entityComponentSystem/PooledComponentManager.hpp @@ -5,8 +5,6 @@ #include #include -#include - // TODO: Replace FragmentedPool with a better pool #include "../util/FragmentedPool.hpp" #include "EntityTypes.hpp" @@ -112,17 +110,15 @@ protected: return nullptr; } - // This function is executed once for each entity which is being subscribed - // This should only be used if your manager must do something per-component - otherwise, you - // should write a custom solution - // The component is already in the pool. - virtual void SubscribeEntity(PooledComponent& component) + // Do whatever your custom manager does for subscribing here. + // The components are already in the pool. + virtual void SubscribeEntitiesInternal(std::vector*>& components) { } - // Do whatever your custom manager does for unsubscribing here. Don't implement if you don't - // have to - virtual void UnsubscribeEntity(PooledComponent& component) + // Do whatever your custom manager does for unsubscribing here. + // The components are still in the subscription list and pool + virtual void UnsubscribeEntitiesInternal(std::vector*>& components) { } @@ -139,6 +135,8 @@ public: // If the entity is already subscribed, the input component will be tossed out void SubscribeEntities(const std::vector >& components) { + std::vector*> newSubscribers(components.size()); + for (typename std::vector >::const_iterator it = components.begin(); it != components.end(); ++it) { @@ -148,19 +146,21 @@ public: if (EntityListFindEntity(Subscribers, currentPooledComponent.entity)) continue; - FragmentedPoolData >* newPooledComponentPooled = + FragmentedPoolData >* newPooledComponent = PooledComponents.GetNewData(); // Pool is full! // TODO: handle this elegantly - assert(newPooledComponentPooled); + assert(newPooledComponent); - newPooledComponentPooled->data = currentPooledComponent; + newPooledComponent->data = currentPooledComponent; Subscribers.push_back(currentPooledComponent.entity); - SubscribeEntity(newPooledComponentPooled->data); + newSubscribers.push_back(&newPooledComponent->data); } + + SubscribeEntitiesInternal(newSubscribers); } virtual void UnsubscribeEntities(const EntityList& entities) @@ -171,6 +171,29 @@ public: // Ensure that we only unsubscribe entities which are actually Subscribers EntityListRemoveUniqueEntitiesInSuspect(Subscribers, entitiesToUnsubscribe); + std::vector*> unsubscribers(entitiesToUnsubscribe.size()); + + // Build the list of components we are going to be unsubscribing for the + // child of this class. We can probably make this one loop, but we'll save that for later + for (EntityListConstIterator it = entitiesToUnsubscribe.begin(); + it != entitiesToUnsubscribe.end(); ++it) + { + Entity currentEntity = (*it); + + for (int i = 0; i < PooledComponents.GetPoolSize(); i++) + { + FragmentedPoolData >* currentPooledComponent = + PooledComponents.GetActiveDataAtIndex(i); + + if (currentPooledComponent && currentPooledComponent->data.entity == currentEntity) + unsubscribers.push_back(¤tPooledComponent->data); + } + } + + // Let child do whatever it needs to unsubscribe the given entities + UnsubscribeEntitiesInternal(unsubscribers); + + // Remove the entities from pool (freeing memory) for (EntityListConstIterator it = entitiesToUnsubscribe.begin(); it != entitiesToUnsubscribe.end(); ++it) { @@ -182,10 +205,7 @@ public: PooledComponents.GetActiveDataAtIndex(i); if (currentPooledComponent && currentPooledComponent->data.entity == currentEntity) - { - UnsubscribeEntity(currentPooledComponent->data); PooledComponents.RemoveData(currentPooledComponent); - } } } diff --git a/src/project/galavantSublime/galavant.sublime-project b/src/project/galavantSublime/galavant.sublime-project index 0973180..bda0a3c 100644 --- a/src/project/galavantSublime/galavant.sublime-project +++ b/src/project/galavantSublime/galavant.sublime-project @@ -46,5 +46,13 @@ "name": "Jam", "shell_cmd": "jam" } - ] + ], + + "settings": + { + //"sublimegdb_workingdir": "${folder:${project_path:your_executable_name}}", + "sublimegdb_workingdir": "../../../../galavant/bin/entityComponentTest", + + "sublimegdb_commandline": "gdb --interpreter=mi ./entityComponentTest" + } } \ No newline at end of file diff --git a/src/unitTesting/EntityComponentSystem_test.cpp b/src/unitTesting/EntityComponentSystem_test.cpp index 4fc61b6..1cfa7c2 100644 --- a/src/unitTesting/EntityComponentSystem_test.cpp +++ b/src/unitTesting/EntityComponentSystem_test.cpp @@ -107,8 +107,8 @@ void TestEntityCreationAndDestruction(void) } }; - TestComponentManager testComponentManager; EntityComponentManager entityComponentManager; + TestComponentManager testComponentManager; std::cout << "Testing Entity Creation and Destruction...\n"; @@ -178,10 +178,6 @@ void TestEntityComponentTypes(void) } std::cout << "\tDone\n"; } - virtual void UnsubscribeEntity(PooledComponent& component) - { - std::cout << "\t\tUnsubscribing " << component.entity << "\n"; - } }; std::cout << "\nTesting Entity Component Types...\n";