diff --git a/Escape-the-Dawn/Component.h b/Escape-the-Dawn/Component.h new file mode 100644 index 0000000..e50d5c6 --- /dev/null +++ b/Escape-the-Dawn/Component.h @@ -0,0 +1,14 @@ +#ifndef Component_h__ +#define Component_h__ + +#include + +#include "Entity.h" +#include "ComponentFactory.h" + +struct Component +{ + EntityID Entity; +}; + +#endif // Component_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/ComponentFactory.h b/Escape-the-Dawn/ComponentFactory.h new file mode 100644 index 0000000..cb698a5 --- /dev/null +++ b/Escape-the-Dawn/ComponentFactory.h @@ -0,0 +1,50 @@ +#ifndef ComponentFactory_h__ +#define ComponentFactory_h__ + +#include +#include +#include + +#include "Component.h" + +#define REGISTER_COMPONENT(NAME, TYPE) \ + static ComponentRegistrar registrar(NAME); + +template +class ComponentRegistrar +{ +public: + ComponentRegistrar(std::string name) + { + ComponentFactory::Instance()->Register(name, [](void) -> std::shared_ptr { return new T() }); + } +}; + +class ComponentFactory +{ +public: + static ComponentFactory* Instance() + { + static ComponentFactory factory; + return &factory; + } + + void Register(std::string name, std::function(void)> factoryFunction) + { + m_FactoryFunctions[name] = factoryFunction; + } + + std::shared_ptr Create(std::string name) + { + auto it = m_FactoryFunctions.find(name); + if (it != m_FactoryFunctions.end()) + return it->second(); + else + return nullptr; + } + +private: + std::map(void)>> m_FactoryFunctions; +}; + +#endif // ComponentFactory_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/Components/Transform.h b/Escape-the-Dawn/Components/Transform.h new file mode 100644 index 0000000..1ef6b9a --- /dev/null +++ b/Escape-the-Dawn/Components/Transform.h @@ -0,0 +1,13 @@ +#include "Component.h" + +namespace Components +{ + +REGISTER_COMPONENT("Transform", Transform); +struct Transform : Component +{ + float Position[3]; +}; + +} + diff --git a/Escape-the-Dawn/Entity.h b/Escape-the-Dawn/Entity.h new file mode 100644 index 0000000..11e425f --- /dev/null +++ b/Escape-the-Dawn/Entity.h @@ -0,0 +1 @@ +typedef unsigned int EntityID; \ No newline at end of file diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj b/Escape-the-Dawn/Escape-the-Dawn.vcxproj index aa02a74..00425cb 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj @@ -39,7 +39,7 @@ - $(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath) + $(ProjectDir);$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath) $(SolutionDir)\Libraries\glew-1.10.0\lib\Debug\Win32;$(SolutionDir)\Libraries\glfw-3.0.4\lib\Debug;$(LibraryPath) @@ -48,7 +48,7 @@ $(ProjectName)-$(Configuration) - $(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath) + $(ProjectDir);$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath) $(SolutionDir)\Libraries\glew-1.10.0\lib\Release\Win32;$(SolutionDir)\Libraries\glfw-3.0.4\lib\Release;$(LibraryPath) @@ -90,8 +90,13 @@ + + + + + diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters index bad452f..c3e5060 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters @@ -13,6 +13,9 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {9af04489-86da-41b7-aaba-12d5b6653660} + @@ -26,5 +29,20 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files\Components + + + Header Files + \ No newline at end of file diff --git a/Escape-the-Dawn/World.h b/Escape-the-Dawn/World.h new file mode 100644 index 0000000..419928c --- /dev/null +++ b/Escape-the-Dawn/World.h @@ -0,0 +1,81 @@ +#include +#include +#include +#include + +#include "Entity.h" +#include "Component.h" +#include "Components/Transform.h" + +class World +{ +public: + World() + { + m_LastEntityID = 0; + } + + EntityID CreateEntity(EntityID parent = 0) + { + EntityID newEntity = GenerateEntityID(); + m_SceneGraph.insert(std::pair(newEntity, parent)); + return newEntity; + } + + void RemoveEntity(EntityID entity) + { + m_SceneGraph.erase(entity); + RecycleEntityID(entity); + } + + bool ValidEntity(EntityID entity) + { + return m_SceneGraph.find(entity) != m_SceneGraph.end(); + } + + EntityID GetEntityParent(EntityID entity) + { + auto it = m_SceneGraph.find(entity); + return it == m_SceneGraph.end() ? 0 : it->second; + } + + std::shared_ptr AddComponent(EntityID entity, std::string componentType) + { + std::shared_ptr component = ComponentFactory::Instance()->Create(componentType); + m_ComponentsOfType[componentType].push_back(component); + m_EntityComponents[entity][componentType] = component; + } + + /*std::vector GetEntityChildren(EntityID entity) + { + std::vector children; + auto range = m_SceneGraph.equal_range(entity); + for (auto it = range.first; it != range.second; ++it) + children.push_back(it->second); + return children; + }*/ + +private: + EntityID m_LastEntityID; + std::stack m_RecycledEntityIDs; + // A map of child entities to parent entities + std::unordered_map m_SceneGraph; + std::unordered_map>> m_ComponentsOfType; + std::unordered_map>> m_EntityComponents; + + EntityID GenerateEntityID() + { + if (!m_RecycledEntityIDs.empty()) { + EntityID id = m_RecycledEntityIDs.top(); + m_RecycledEntityIDs.pop(); + return id; + } else { + return ++m_LastEntityID; + } + } + + void RecycleEntityID(EntityID id) + { + m_RecycledEntityIDs.push(id); + } +}; \ No newline at end of file