diff --git a/assets/models/BuildingSystem.blend b/assets/models/BuildingSystem.blend index 6404c90..1af0cff 100644 Binary files a/assets/models/BuildingSystem.blend and b/assets/models/BuildingSystem.blend differ diff --git a/src/ai/WorldState.hpp b/src/ai/WorldState.hpp new file mode 100644 index 0000000..6c419fb --- /dev/null +++ b/src/ai/WorldState.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "../world/Position.hpp" + +namespace gv +{ +struct AgentState +{ + Position position; +}; + +/* --WorldState-- +WorldState represents a mutable, copyable reference to all AI-relevant data in the World. + Mutable: The data can be manipulated freely without repurcussion. Note that changing data in + WorldState is NOT expected to actually change the world - WorldState is like a mirror world + Copyable: The data can be copied without a significant amount of time. This means that in order + to support mutability, things like changelists might need to be implemented for large datasets + instead of actually copying the dataset +*/ +struct WorldState +{ + // Because an agent is almost always going to...well, maybe this shouldn't be here. For now it + // will stay. + AgentState SourceAgent; +}; +}; \ No newline at end of file diff --git a/src/ai/htn/HTNPlanner.cpp b/src/ai/htn/HTNPlanner.cpp index 347ad49..5960100 100644 --- a/src/ai/htn/HTNPlanner.cpp +++ b/src/ai/htn/HTNPlanner.cpp @@ -36,10 +36,20 @@ bool DecomposeCompoundTask(TaskCallList& compoundDecompositions, CompoundTask* c return compoundTask->Decompose(compoundDecompositions, state, parameters); } +bool Planner::IsPlanRunning() +{ + return IsPlanRunning(CurrentStatus); +} + +bool Planner::IsPlanRunning(Status status) +{ + return (status > Status::Running_EnumBegin && status < Status::Running_EnumEnd); +} + // When the stack is empty, find a goal task to push onto the task or add tasks as per usual // If any Decompositions or Preconditions fail, we must fail the entire plan because we have // no alternate methods -Planner::Status Planner::PlanStep_BottomLevel(void) +Planner::Status Planner::PlanStep_BottomLevel() { if (InitialCallList.empty()) return Status::Failed_NoTasks; @@ -57,7 +67,7 @@ Planner::Status Planner::PlanStep_BottomLevel(void) if (DebugPrint) { std::cout << "\nPlanStep()\nWorkingCallList.size() = " << WorkingCallList.size() << "\n"; - printTaskCallList(WorkingCallList); + PrintTaskCallList(WorkingCallList); } for (TaskCallListIterator currentTaskCallIter = WorkingCallList.begin(); @@ -156,7 +166,7 @@ Planner::Status Planner::PlanStep_BottomLevel(void) return Status::PlanComplete; } -Planner::Status Planner::PlanStep_StackFrame(void) +Planner::Status Planner::PlanStep_StackFrame() { // Remember: If goal fails to decompose and goal is bottom of stack, fail GoalDecompositionStack::iterator currentStackFrameIter = DecompositionStack.end() - 1; @@ -166,7 +176,7 @@ Planner::Status Planner::PlanStep_StackFrame(void) { std::cout << "\nPlanStep()\ncurrentStackFrame.CallList.size() = " << currentStackFrame.CallList.size() << "\n"; - printTaskCallList(currentStackFrame.CallList); + PrintTaskCallList(currentStackFrame.CallList); std::cout << "Stack Depth: "; for (unsigned int i = 0; i < DecompositionStack.size(); i++) @@ -176,12 +186,12 @@ Planner::Status Planner::PlanStep_StackFrame(void) { std::cout << "----Fullstack working lists\n"; std::cout << "[0]\n"; - printTaskCallList(WorkingCallList); + PrintTaskCallList(WorkingCallList); int i = 1; for (GoalDecomposition& stackFrame : DecompositionStack) { std::cout << "[" << i++ << "]\n"; - printTaskCallList(stackFrame.CallList); + PrintTaskCallList(stackFrame.CallList); } std::cout << "----\n"; } @@ -318,7 +328,7 @@ Planner::Status Planner::PlanStep_StackFrame(void) std::cout << "currentStackFrame.CallList.size() = " << currentStackFrame.CallList.size() << "\n"; std::cout << "Decomposition:\n"; - printTaskCallList(compoundDecompositions); + PrintTaskCallList(compoundDecompositions); } currentStackFrame.CallList.insert(currentStackFrame.CallList.begin(), compoundDecompositions.begin(), @@ -360,9 +370,9 @@ Planner::Status Planner::PlanStep_StackFrame(void) if (DebugPrint) { std::cout << "Collapsing stack frame. Adding List:\n"; - printTaskCallList(currentStackFrame.FinalCallList); + PrintTaskCallList(currentStackFrame.FinalCallList); std::cout << "To parent:\n"; - printTaskCallList(*parentFinalCallList); + PrintTaskCallList(*parentFinalCallList); } parentFinalCallList->insert(parentFinalCallList->end(), @@ -385,7 +395,7 @@ Planner::Status Planner::PlanStep_StackFrame(void) // TODO: Pool various task lists? // TODO: Pull more things out into functions, if possible. It's bad that whenever I make a change to // something I have to change it in two places -Planner::Status Planner::PlanStep(void) +Planner::Status Planner::PlanStep() { Status status = Status::Failed_NoPossiblePlan; @@ -407,10 +417,11 @@ Planner::Status Planner::PlanStep(void) status == Status::Running_FailedGoalDecomposition)) || (BreakOnFailedDecomposition && (status == Status::Running_FailedGoalDecomposition || status == Status::Running_FailedMethodDecomposition))) - return status; + break; - } while (status >= Status::Running_EnumBegin && status <= Status::Running_EnumEnd); + } while (IsPlanRunning(status)); + CurrentStatus = status; return status; } } \ No newline at end of file diff --git a/src/ai/htn/HTNPlanner.hpp b/src/ai/htn/HTNPlanner.hpp index 53c44d4..a90f8c8 100644 --- a/src/ai/htn/HTNPlanner.hpp +++ b/src/ai/htn/HTNPlanner.hpp @@ -2,6 +2,7 @@ #include "HTNTypes.hpp" #include "HTNTasks.hpp" +#include "../WorldState.hpp" namespace Htn { @@ -29,11 +30,20 @@ struct GoalDecomposition typedef std::vector GoalDecompositionStack; -// TODO: Either make planner allow making multiple plans with the same instance, or make it clear -// that it is for a single plan only +/* -- Planner -- +Given the world state and a set of goal tasks, decompose them into a list of primitive tasks which, +when executed, will result in the desired goal tasks being completed. Note that the initial goal +task set can include compound and primitive tasks. + +TODO: Either make planner allow making multiple plans with the same instance, or make it clear +that it is for a single plan only +*/ class Planner { public: + Planner() = default; + ~Planner() = default; + WorldState State; TaskCallList InitialCallList; @@ -79,7 +89,12 @@ public: PlanComplete }; - Status PlanStep(void); + bool IsPlanRunning(); + bool IsPlanRunning(Status status); + + Status CurrentStatus; + + Status PlanStep(); private: GoalDecompositionStack DecompositionStack; @@ -90,7 +105,7 @@ private: // Copy of InitialCallList that Planner can fuck with TaskCallList WorkingCallList; - Status PlanStep_StackFrame(void); - Status PlanStep_BottomLevel(void); + Status PlanStep_StackFrame(); + Status PlanStep_BottomLevel(); }; }; \ No newline at end of file diff --git a/src/ai/htn/HTNTasks.cpp b/src/ai/htn/HTNTasks.cpp index 5d94eb9..55a02b9 100644 --- a/src/ai/htn/HTNTasks.cpp +++ b/src/ai/htn/HTNTasks.cpp @@ -5,7 +5,7 @@ namespace Htn { -int GoalTask::GetNumMethods(void) +int GoalTask::GetNumMethods() { return Methods ? Methods->size() : 0; } @@ -53,22 +53,22 @@ Task::Task(PrimitiveTask* primitive) Type = TaskType::Primitive; } -TaskType Task::GetType(void) const +TaskType Task::GetType() const { return Type; } -GoalTask* Task::GetGoal(void) +GoalTask* Task::GetGoal() { assert(Type == TaskType::Goal); return Goal; } -CompoundTask* Task::GetCompound(void) +CompoundTask* Task::GetCompound() { assert(Type == TaskType::Compound); return Compound; } -PrimitiveTask* Task::GetPrimitive(void) +PrimitiveTask* Task::GetPrimitive() { assert(Type == TaskType::Primitive); return Primitive; @@ -94,7 +94,7 @@ std::ostream& operator<<(std::ostream& os, const Task& task) return os; } -void printTaskList(const TaskList& tasks) +void PrintTaskList(const TaskList& tasks) { std::cout << "TaskList size = " << tasks.size() << " addr " << &tasks << ":\n"; for (unsigned int i = 0; i < tasks.size(); i++) @@ -103,7 +103,7 @@ void printTaskList(const TaskList& tasks) } } -void printTaskCallList(const TaskCallList& tasks) +void PrintTaskCallList(const TaskCallList& tasks) { std::cout << "TaskCallList size = " << tasks.size() << " addr " << &tasks << ":\n"; for (unsigned int i = 0; i < tasks.size(); i++) diff --git a/src/ai/htn/HTNTasks.hpp b/src/ai/htn/HTNTasks.hpp index 36f4a36..d6efd22 100644 --- a/src/ai/htn/HTNTasks.hpp +++ b/src/ai/htn/HTNTasks.hpp @@ -1,6 +1,7 @@ #pragma once #include "HTNTypes.hpp" +#include "../WorldState.hpp" #include @@ -28,9 +29,9 @@ private: TaskList* Methods; public: - GoalTask(void) = default; + GoalTask() = default; - int GetNumMethods(void); + int GetNumMethods(); Task* GetMethodAtIndex(int index); bool DecomposeMethodAtIndex(TaskCallList& decomposition, int index, @@ -42,8 +43,8 @@ public: class CompoundTask { public: - CompoundTask(void) = default; - virtual ~CompoundTask(void) = default; + CompoundTask() = default; + virtual ~CompoundTask() = default; virtual bool StateMeetsPreconditions(const WorldState& state, const ParameterList& parameters) const = 0; virtual bool Decompose(TaskCallList& taskCallList, const WorldState& state, @@ -53,8 +54,8 @@ public: class PrimitiveTask { public: - PrimitiveTask(void) = default; - virtual ~PrimitiveTask(void) = default; + PrimitiveTask() = default; + virtual ~PrimitiveTask() = default; virtual bool StateMeetsPreconditions(const WorldState& state, const ParameterList& parameters) const = 0; virtual void ApplyStateChange(WorldState& state, const ParameterList& parameters) = 0; @@ -76,16 +77,16 @@ enum class TaskType // only allow only one thing to be filled in for it struct Task { - Task(void) = delete; + Task() = delete; Task(GoalTask* goal); Task(CompoundTask* compound); Task(PrimitiveTask* primitive); - TaskType GetType(void) const; + TaskType GetType() const; - GoalTask* GetGoal(void); - CompoundTask* GetCompound(void); - PrimitiveTask* GetPrimitive(void); + GoalTask* GetGoal(); + CompoundTask* GetCompound(); + PrimitiveTask* GetPrimitive(); friend std::ostream& operator<<(std::ostream& os, const Task& task); @@ -102,6 +103,6 @@ private: std::ostream& operator<<(std::ostream& os, const Task& task); -void printTaskList(const TaskList& tasks); -void printTaskCallList(const TaskCallList& tasks); +void PrintTaskList(const TaskList& tasks); +void PrintTaskCallList(const TaskCallList& tasks); } \ No newline at end of file diff --git a/src/ai/htn/HTNTypes.hpp b/src/ai/htn/HTNTypes.hpp index 9990316..0a170db 100644 --- a/src/ai/htn/HTNTypes.hpp +++ b/src/ai/htn/HTNTypes.hpp @@ -29,7 +29,7 @@ struct Parameter float FloatValue; bool BoolValue; - Entity EntityValue; + gv::Entity EntityValue; }; }; @@ -39,5 +39,5 @@ typedef std::vector::const_iterator ParameterListConstIterator; typedef std::vector::reverse_iterator ParameterListReverseIterator; // The arguments passed to most all Task functions -typedef int WorldState; // TODO +typedef int WorldState; // TODO: replace with AI WorldState from WorldState.hpp } \ No newline at end of file diff --git a/src/entityComponentSystem/ComponentManager.cpp b/src/entityComponentSystem/ComponentManager.cpp index dbee5c1..23b7aab 100644 --- a/src/entityComponentSystem/ComponentManager.cpp +++ b/src/entityComponentSystem/ComponentManager.cpp @@ -1,5 +1,7 @@ #include "ComponentManager.hpp" +namespace gv +{ ComponentManager::~ComponentManager() { } @@ -8,7 +10,8 @@ void ComponentManager::UnsubscribeEntities(const EntityList& entities) { } -ComponentType ComponentManager::GetType(void) +ComponentType ComponentManager::GetType() { return Type; +} } \ No newline at end of file diff --git a/src/entityComponentSystem/ComponentManager.hpp b/src/entityComponentSystem/ComponentManager.hpp index fccb999..cbbccb8 100644 --- a/src/entityComponentSystem/ComponentManager.hpp +++ b/src/entityComponentSystem/ComponentManager.hpp @@ -1,8 +1,9 @@ -#ifndef COMPONENTMANAGER_H__ -#define COMPONENTMANAGER_H__ +#pragma once #include "EntityTypes.hpp" +namespace gv +{ // Base class for all ComponentManagers. Note that it is intended to be a very minimal interface // because the Entity Component System is designed to be minimally polymorphic. This is so it is // more obvious when things happen. It also reduces the amount of boilerplate needed when creating a @@ -10,6 +11,7 @@ class ComponentManager { protected: + // You should set this type in your constructor ComponentType Type; public: @@ -17,7 +19,7 @@ public: virtual void UnsubscribeEntities(const EntityList& entities); - ComponentType GetType(void); + ComponentType GetType(); }; -#endif /* end of include guard: COMPONENTMANAGER_H__ */ \ No newline at end of file +}; \ No newline at end of file diff --git a/src/entityComponentSystem/EntityComponentManager.cpp b/src/entityComponentSystem/EntityComponentManager.cpp index 4b95d0d..6bfdf54 100644 --- a/src/entityComponentSystem/EntityComponentManager.cpp +++ b/src/entityComponentSystem/EntityComponentManager.cpp @@ -1,5 +1,7 @@ #include "EntityComponentManager.hpp" +namespace gv +{ Entity EntityComponentManager::NextNewEntity = 1; EntityComponentManager::EntityComponentManager() @@ -80,7 +82,7 @@ void EntityComponentManager::UnsubscribeEntitiesFromAllManagers(EntityList &enti // Destroy all entities which have been marked for destruction. Because an entity is just an ID // and a collection of components, this function must notify all ComponentManagers that the // Entity should be unsubscribed from their services. -void EntityComponentManager::DestroyEntitiesPendingDestruction(void) +void EntityComponentManager::DestroyEntitiesPendingDestruction() { if (!EntitiesPendingDestruction.empty()) { @@ -98,7 +100,7 @@ void EntityComponentManager::DestroyEntitiesPendingDestruction(void) // Destroys all entities that were created by this EntityComponentManager (i.e. all entities in // the ActiveEntities list) -void EntityComponentManager::DestroyAllEntities(void) +void EntityComponentManager::DestroyAllEntities() { // Mark all active entities as pending destruction. I do this because if I just destroyed // ActiveEntities, then EntitiesPendingDestruction could have entities which have already been @@ -110,4 +112,5 @@ void EntityComponentManager::DestroyAllEntities(void) ActiveEntities.clear(); // this should be empty anyways EntitiesPendingDestruction.clear(); +} } \ No newline at end of file diff --git a/src/entityComponentSystem/EntityComponentManager.hpp b/src/entityComponentSystem/EntityComponentManager.hpp index d391a06..48c943f 100644 --- a/src/entityComponentSystem/EntityComponentManager.hpp +++ b/src/entityComponentSystem/EntityComponentManager.hpp @@ -1,11 +1,12 @@ -#ifndef ENTITYCOMPONENTMANAGER_H__ -#define ENTITYCOMPONENTMANAGER_H__ +#pragma once #include #include "EntityTypes.hpp" #include "ComponentManager.hpp" +namespace gv +{ /* --EntityComponentManager-- EntityComponentManager is intended to be a very minimal managing class for the Entity Component System. Its primary task is to facilitate the creation and destruction of Entities. @@ -61,11 +62,10 @@ public: // Destroy all entities which have been marked for destruction. Because an entity is just an ID // and a collection of components, this function must notify all ComponentManagers that the // Entity should be unsubscribed from their services. - void DestroyEntitiesPendingDestruction(void); + void DestroyEntitiesPendingDestruction(); // Destroys all entities that were created by this EntityComponentManager (i.e. all entities in // the ActiveEntities list) - void DestroyAllEntities(void); + void DestroyAllEntities(); }; - -#endif /* end of include guard: ENTITYCOMPONENTMANAGER_H__ */ \ No newline at end of file +}; \ No newline at end of file diff --git a/src/entityComponentSystem/EntityTypes.cpp b/src/entityComponentSystem/EntityTypes.cpp index b1b2186..b2ce6ce 100644 --- a/src/entityComponentSystem/EntityTypes.cpp +++ b/src/entityComponentSystem/EntityTypes.cpp @@ -2,6 +2,8 @@ #include "EntityTypes.hpp" +namespace gv +{ const Entity NullEntity = 0; bool EntityComparator(Entity a, Entity b) @@ -11,7 +13,7 @@ bool EntityComparator(Entity a, Entity b) void EntityListAppendList(EntityList& list, const EntityList& listToAdd) { - list.insert(list.begin(), listToAdd.begin(), listToAdd.end()); + list.insert(list.end(), listToAdd.begin(), listToAdd.end()); } void EntityListSort(EntityList& list) @@ -102,4 +104,6 @@ bool EntityListFindEntity(EntityList& list, Entity entity) return true; } return false; +} + } \ No newline at end of file diff --git a/src/entityComponentSystem/EntityTypes.hpp b/src/entityComponentSystem/EntityTypes.hpp index 0b76135..6b45c2b 100644 --- a/src/entityComponentSystem/EntityTypes.hpp +++ b/src/entityComponentSystem/EntityTypes.hpp @@ -1,8 +1,9 @@ -#ifndef ENTITYTYPES_H__ -#define ENTITYTYPES_H__ +#pragma once #include +namespace gv +{ // An Entity is nothing but an ID. This ID is used to get components from ComponentManagers which // are assigned to the respective entity. Collections of components which are assigned to the same // Entity provide the entity's data and behaviors. @@ -33,4 +34,4 @@ bool EntityListFindEntity(EntityList& list, Entity entity); // This should probably become an enum at some point. typedef unsigned int ComponentType; -#endif /* end of include guard: ENTITYTYPES_H__ */ +}; \ No newline at end of file diff --git a/src/entityComponentSystem/PooledComponentManager.hpp b/src/entityComponentSystem/PooledComponentManager.hpp index 946a128..c7c671e 100644 --- a/src/entityComponentSystem/PooledComponentManager.hpp +++ b/src/entityComponentSystem/PooledComponentManager.hpp @@ -1,5 +1,4 @@ -#ifndef POOLEDCOMPONENTMANAGER_H__ -#define POOLEDCOMPONENTMANAGER_H__ +#pragma once // TODO: Handle full pool better (will be done when FragmentedPool is replaced) #include @@ -10,6 +9,8 @@ #include "EntityTypes.hpp" #include "ComponentManager.hpp" +namespace gv +{ /* --PooledComponentManager-- PooledComponentManager is a general purpose PooledComponentManager that assumes you're managing your components in a standard way. @@ -58,7 +59,7 @@ private: EntityList Subscribers; // TODO: Replace FragmentedPool with a better pool - FragmentedPool > PooledComponents; + FragmentedPool> PooledComponents; protected: typedef int FragmentedPoolIterator; @@ -69,7 +70,7 @@ protected: { for (int i = 0; i < PooledComponents.GetPoolSize(); i++) { - FragmentedPoolData >* currentPooledComponent = + FragmentedPoolData>* currentPooledComponent = PooledComponents.GetActiveDataAtIndex(i); if (currentPooledComponent) @@ -90,7 +91,7 @@ protected: it++; for (; it < PooledComponents.GetPoolSize(); it++) { - FragmentedPoolData >* currentPooledComponent = + FragmentedPoolData>* currentPooledComponent = PooledComponents.GetActiveDataAtIndex(it); if (currentPooledComponent) @@ -103,7 +104,7 @@ protected: PooledComponent* GetComponent(FragmentedPoolIterator& it) { - FragmentedPoolData >* pooledComponent = + FragmentedPoolData>* pooledComponent = PooledComponents.GetActiveDataAtIndex(it); if (pooledComponent) return &pooledComponent->data; @@ -112,12 +113,14 @@ protected: // Do whatever your custom manager does for subscribing here. // The components are already in the pool. + // It is safe to subscribe and unsubscribe components in this function virtual void SubscribeEntitiesInternal(std::vector*>& components) { } // Do whatever your custom manager does for unsubscribing here. // The components are still in the subscription list and pool + // It is safe to subscribe and unsubscribe components in this function virtual void UnsubscribeEntitiesInternal(std::vector*>& components) { } @@ -133,11 +136,11 @@ public: } // If the entity is already subscribed, the input component will be tossed out - void SubscribeEntities(const std::vector >& components) + void SubscribeEntities(const std::vector>& components) { std::vector*> newSubscribers(components.size()); - for (typename std::vector >::const_iterator it = components.begin(); + for (typename std::vector>::const_iterator it = components.begin(); it != components.end(); ++it) { const PooledComponent currentPooledComponent = (*it); @@ -146,7 +149,7 @@ public: if (EntityListFindEntity(Subscribers, currentPooledComponent.entity)) continue; - FragmentedPoolData >* newPooledComponent = + FragmentedPoolData>* newPooledComponent = PooledComponents.GetNewData(); // Pool is full! @@ -182,7 +185,7 @@ public: for (int i = 0; i < PooledComponents.GetPoolSize(); i++) { - FragmentedPoolData >* currentPooledComponent = + FragmentedPoolData>* currentPooledComponent = PooledComponents.GetActiveDataAtIndex(i); if (currentPooledComponent && currentPooledComponent->data.entity == currentEntity) @@ -191,6 +194,9 @@ public: } // Let child do whatever it needs to unsubscribe the given entities + // Note that the child can actually unsubscribe entities in their function. This will + // currently only mean we might try to double-unsubscribe in the code below, which is not + // bad UnsubscribeEntitiesInternal(unsubscribers); // Remove the entities from pool (freeing memory) @@ -201,7 +207,7 @@ public: for (int i = 0; i < PooledComponents.GetPoolSize(); i++) { - FragmentedPoolData >* currentPooledComponent = + FragmentedPoolData>* currentPooledComponent = PooledComponents.GetActiveDataAtIndex(i); if (currentPooledComponent && currentPooledComponent->data.entity == currentEntity) @@ -213,11 +219,10 @@ public: EntityListRemoveNonUniqueEntitiesInSuspect(entitiesToUnsubscribe, Subscribers); } - void Reset(void) + void Reset() { PooledComponents.Clear(); Subscribers.clear(); } }; - -#endif /* end of include guard: POOLEDCOMPONENTMANAGER_H__ */ \ No newline at end of file +} \ No newline at end of file diff --git a/src/experiments/flatbuffers/testFlatbuffers_WriteOut.cpp b/src/experiments/flatbuffers/testFlatbuffers_WriteOut.cpp index 942b5a5..7996209 100644 --- a/src/experiments/flatbuffers/testFlatbuffers_WriteOut.cpp +++ b/src/experiments/flatbuffers/testFlatbuffers_WriteOut.cpp @@ -60,7 +60,7 @@ char *readBinary(const char *filename) return nullptr; } -void testFlatbufferToJSON(void) +void testFlatbufferToJSON() { const char *outputFilename = "Output.json"; const char *flatbufferFilename = "SavedHelloForWrite.bin"; diff --git a/src/game/Jamfile b/src/game/Jamfile new file mode 100644 index 0000000..5ce040c --- /dev/null +++ b/src/game/Jamfile @@ -0,0 +1,5 @@ +SubDir . src game ; + +Library libGalaGame : agent/PlanComponentManager.cpp ; + +MakeLocate libGalaGame.a : lib ; \ No newline at end of file diff --git a/src/game/agent/PlanComponentManager.cpp b/src/game/agent/PlanComponentManager.cpp new file mode 100644 index 0000000..d442723 --- /dev/null +++ b/src/game/agent/PlanComponentManager.cpp @@ -0,0 +1,80 @@ +#include "PlanComponentManager.hpp" + +#include "../../entityComponentSystem/PooledComponentManager.hpp" + +PlanComponentManager::PlanComponentManager() : gv::PooledComponentManager(100) +{ +} + +PlanComponentManager::~PlanComponentManager() +{ +} + +void PlanComponentManager::Initialize() +{ +} + +void PlanComponentManager::Update(float deltaSeconds) +{ + // TODO: Adding true iterator support to pool will drastically help damning this to hell + gv::PooledComponentManager::FragmentedPoolIterator it = + gv::PooledComponentManager::NULL_POOL_ITERATOR; + for (gv::PooledComponent* currentComponent = ActivePoolBegin(it); + currentComponent != nullptr && + it != gv::PooledComponentManager::NULL_POOL_ITERATOR; + currentComponent = GetNextActivePooledComponent(it)) + { + if (!currentComponent) + continue; + + Htn::Planner& componentPlanner = currentComponent->data.Planner; + + // For now, don't follow plan, just ignore finished/failed plans + if (!componentPlanner.IsPlanRunning()) + continue; + + Htn::Planner::Status status = componentPlanner.PlanStep(); + if (!componentPlanner.IsPlanRunning()) + { + if (status == Htn::Planner::Status::PlanComplete) + { + std::cout << "PlanComponentManager: Sucessful plan for Entity " + << currentComponent->entity << "! Final Call List:\n"; + Htn::PrintTaskCallList(componentPlanner.FinalCallList); + } + + if (status < Htn::Planner::Status::Running_EnumBegin) + { + std::cout << "PlanComponentManager: Failed plan for Entity " + << currentComponent->entity << "! Initial Call List:\n"; + Htn::PrintTaskCallList(componentPlanner.InitialCallList); + } + } + } +} + +void PlanComponentManager::SubscribeEntitiesInternal(PlanComponentRefList& components) +{ + for (gv::PooledComponent* currentComponent : components) + { + if (!currentComponent) + continue; + + Htn::Planner& planner = currentComponent->data.Planner; + Htn::TaskCallList& goalCallList = currentComponent->data.Goals; + + planner.InitialCallList.insert(planner.InitialCallList.end(), goalCallList.begin(), + goalCallList.end()); + } +} + +void PlanComponentManager::UnsubscribeEntitiesInternal(PlanComponentRefList& components) +{ + for (gv::PooledComponent* currentComponent : components) + { + if (!currentComponent) + continue; + + // Perform unsubscription + } +} \ No newline at end of file diff --git a/src/game/agent/PlanComponentManager.hpp b/src/game/agent/PlanComponentManager.hpp new file mode 100644 index 0000000..bed6abb --- /dev/null +++ b/src/game/agent/PlanComponentManager.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include "../../entityComponentSystem/PooledComponentManager.hpp" +#include "../../ai/htn/HTNPlanner.cpp" +#include "../../ai/WorldState.hpp" + +struct PlanComponentData +{ + gv::WorldState state; + + Htn::TaskCallList Goals; + +protected: + friend class PlanComponentManager; + Htn::Planner Planner; +}; + +/* --PlanComponentManager-- +Prepare, manage, and execute plan(s) for Entities. + +TODO: PooledComponentManager is going to need to be discarded in order to handle Entities with many +plans. +*/ +class PlanComponentManager : public gv::PooledComponentManager +{ +protected: + typedef std::vector*> PlanComponentRefList; + + virtual void SubscribeEntitiesInternal(PlanComponentRefList& components); + virtual void UnsubscribeEntitiesInternal(PlanComponentRefList& components); + +public: + typedef std::vector> PlanComponentList; + + PlanComponentManager(); + virtual ~PlanComponentManager(); + void Initialize(); + virtual void Update(float deltaSeconds); +}; \ No newline at end of file diff --git a/src/unitTesting/EntityComponentSystem_test.cpp b/src/unitTesting/EntityComponentSystem_test.cpp index 1cfa7c2..569fbc4 100644 --- a/src/unitTesting/EntityComponentSystem_test.cpp +++ b/src/unitTesting/EntityComponentSystem_test.cpp @@ -6,7 +6,9 @@ #include "../entityComponentSystem/ComponentManager.hpp" #include "../entityComponentSystem/PooledComponentManager.hpp" -void TestEntityLists(void) +using namespace gv; + +void TestEntityLists() { EntityList testList = {1, 4, 2, 6, 3, 2, 1244}; @@ -22,7 +24,7 @@ void TestEntityLists(void) std::cout << "Done\n\n"; } -void TestEntityCreationAndDestruction(void) +void TestEntityCreationAndDestruction() { class TestComponentManager : public ComponentManager { @@ -30,7 +32,7 @@ void TestEntityCreationAndDestruction(void) EntityList Subscribers; public: - TestComponentManager(void) + TestComponentManager() { Type = 1; } @@ -149,7 +151,7 @@ void TestEntityCreationAndDestruction(void) std::cout << "Done\n\n"; } -void TestEntityComponentTypes(void) +void TestEntityComponentTypes() { struct TestComponent { diff --git a/src/unitTesting/HTN_test.cpp b/src/unitTesting/HTN_test.cpp index d789b3a..3d095d9 100644 --- a/src/unitTesting/HTN_test.cpp +++ b/src/unitTesting/HTN_test.cpp @@ -10,8 +10,8 @@ class AlwaysFailPrimitiveTask : public Htn::PrimitiveTask { public: - AlwaysFailPrimitiveTask(void) = default; - virtual ~AlwaysFailPrimitiveTask(void) = default; + AlwaysFailPrimitiveTask() = default; + virtual ~AlwaysFailPrimitiveTask() = default; virtual bool StateMeetsPreconditions(const Htn::WorldState& state, const Htn::ParameterList& parameters) const @@ -35,8 +35,8 @@ public: class RequiresStatePrimitiveTask : public Htn::PrimitiveTask { public: - RequiresStatePrimitiveTask(void) = default; - virtual ~RequiresStatePrimitiveTask(void) = default; + RequiresStatePrimitiveTask() = default; + virtual ~RequiresStatePrimitiveTask() = default; virtual bool StateMeetsPreconditions(const Htn::WorldState& state, const Htn::ParameterList& parameters) const @@ -61,8 +61,8 @@ public: class TestPrimitiveTask : public Htn::PrimitiveTask { public: - TestPrimitiveTask(void) = default; - virtual ~TestPrimitiveTask(void) = default; + TestPrimitiveTask() = default; + virtual ~TestPrimitiveTask() = default; virtual bool StateMeetsPreconditions(const Htn::WorldState& state, const Htn::ParameterList& parameters) const @@ -87,9 +87,9 @@ public: class TestCompoundTaskA : public Htn::CompoundTask { public: - TestCompoundTaskA(void) = default; + TestCompoundTaskA() = default; - virtual ~TestCompoundTaskA(void) = default; + virtual ~TestCompoundTaskA() = default; virtual bool StateMeetsPreconditions(const Htn::WorldState& state, const Htn::ParameterList& parameters) const @@ -186,7 +186,7 @@ TEST_CASE("Hierarchical Task Networks Planner") REQUIRE(status == Htn::Planner::Status::PlanComplete); REQUIRE(testPlan.FinalCallList.size() == 1); std::cout << "\n\nFinal Plan length: " << testPlan.FinalCallList.size() << "\n"; - printTaskCallList(testPlan.FinalCallList); + PrintTaskCallList(testPlan.FinalCallList); std::cout << "\n\n"; } @@ -209,7 +209,7 @@ TEST_CASE("Hierarchical Task Networks Planner") REQUIRE(status == Htn::Planner::Status::PlanComplete); REQUIRE(testPlan.FinalCallList.size() == 2); std::cout << "\n\nFinal Plan length: " << testPlan.FinalCallList.size() << "\n"; - printTaskCallList(testPlan.FinalCallList); + PrintTaskCallList(testPlan.FinalCallList); std::cout << "\n\n"; } @@ -239,7 +239,7 @@ TEST_CASE("Hierarchical Task Networks Planner") REQUIRE(status == Htn::Planner::Status::PlanComplete); REQUIRE(testPlan.FinalCallList.size() == 1); std::cout << "\n\nFinal Plan length: " << testPlan.FinalCallList.size() << "\n"; - printTaskCallList(testPlan.FinalCallList); + PrintTaskCallList(testPlan.FinalCallList); std::cout << "\n\n"; } @@ -264,7 +264,7 @@ TEST_CASE("Hierarchical Task Networks Planner") REQUIRE(status == Htn::Planner::Status::PlanComplete); REQUIRE(testPlan.FinalCallList.size() == 2); std::cout << "\n\nFinal Plan length: " << testPlan.FinalCallList.size() << "\n"; - printTaskCallList(testPlan.FinalCallList); + PrintTaskCallList(testPlan.FinalCallList); std::cout << "\n\n"; } @@ -292,7 +292,7 @@ TEST_CASE("Hierarchical Task Networks Planner") REQUIRE(status == Htn::Planner::Status::Failed_NoPossiblePlan); REQUIRE(testPlan.FinalCallList.size() == 0); std::cout << "\n\nFinal Plan length: " << testPlan.FinalCallList.size() << "\n"; - printTaskCallList(testPlan.FinalCallList); + PrintTaskCallList(testPlan.FinalCallList); std::cout << "\n\n"; } @@ -325,7 +325,7 @@ TEST_CASE("Hierarchical Task Networks Planner") REQUIRE(testPlan.FinalCallList.size() == 2); REQUIRE(numIterations == 1); std::cout << "\n\nFinal Plan length: " << testPlan.FinalCallList.size() << "\n"; - printTaskCallList(testPlan.FinalCallList); + PrintTaskCallList(testPlan.FinalCallList); std::cout << "\n\n"; } } \ No newline at end of file diff --git a/src/util/FragmentedPool.hpp b/src/util/FragmentedPool.hpp index c286022..13be306 100644 --- a/src/util/FragmentedPool.hpp +++ b/src/util/FragmentedPool.hpp @@ -5,6 +5,7 @@ #include // This is some old code copied from the Horizon iteration. It's due for a rewrite. +// TODO: Add standard iterator syntax (See ObjectPool.hpp) /* --FragmentedPool-- * FragmentedPool holds any data. It initializes the requested amount of data on construction. @@ -43,11 +44,11 @@ template class FragmentedPool { private: - std::vector > pool; // The pool data, stored in a STL vector - FragmentedPoolData* firstFreeData; // The head of the free data linked list - FragmentedPoolData* firstUsedData; // The head of the used data linked list - unsigned int size; // The size of the pool - unsigned int totalActiveData; // The number of active data in the pool + std::vector> pool; // The pool data itself + FragmentedPoolData* firstFreeData; // The head of the free data linked list + FragmentedPoolData* firstUsedData; // The head of the used data linked list + unsigned int size; // The size of the pool + unsigned int totalActiveData; // The number of active data in the pool // Prepare the data pointers as a linked list void ResetPool() diff --git a/src/util/ObjectPool.hpp b/src/util/ObjectPool.hpp index eb1a149..4550d9a 100644 --- a/src/util/ObjectPool.hpp +++ b/src/util/ObjectPool.hpp @@ -39,12 +39,12 @@ public: NextFreeData = 0; } - typename PoolContainer::iterator begin(void) + typename PoolContainer::iterator begin() { return Pool.begin(); } - typename PoolContainer::iterator end(void) + typename PoolContainer::iterator end() { // Only return the range of data which are actually active in the pool return Pool.begin() + NextFreeData; @@ -55,19 +55,19 @@ public: return 0; // TODO } - unsigned int GetSize(void) + unsigned int GetSize() { return Pool.size(); } - unsigned int GetNumActiveElements(void) + unsigned int GetNumActiveElements() { // Because NextFreeData is the index of the free data nearest to the last active data, it is // equivalent to the number of active data return NextFreeData; } - T* GetNewData(void) + T* GetNewData() { T* newData = GetUnsafe(NextFreeData); NextFreeData++;