diff --git a/Escape-the-Dawn/ComponentFactory.h b/Escape-the-Dawn/ComponentFactory.h index 7001fd3..4596c0b 100644 --- a/Escape-the-Dawn/ComponentFactory.h +++ b/Escape-the-Dawn/ComponentFactory.h @@ -11,7 +11,7 @@ struct Component; #define REGISTER_COMPONENT(NAME, TYPE) \ static ComponentRegistrar registrar(NAME); -template +template class ComponentRegistrar { public: diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj b/Escape-the-Dawn/Escape-the-Dawn.vcxproj index 419f9dc..df41510 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj @@ -92,6 +92,7 @@ + @@ -108,8 +109,9 @@ - + + diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters index 07c9246..3fdf496 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters @@ -1,114 +1,66 @@  - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {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} - - - {7abbf0e9-8bda-475e-bf00-a347f396b892} - - - {091f6f01-79ab-4a49-9639-c7185e89c84e} - - - {26dccea6-3d9c-4d5f-9db2-98621e35ffcb} - - - {e7de2e5a-0a73-437a-8d01-5f23770e5cba} - - - {7673cacc-e435-4028-9354-b2c8b559c7b3} - - - - - Source Files - + + + - Source Files\Systems - - - Source Files\Systems + Systems - Source Files\Systems + Systems + + + Systems - Source Files\Systems + Systems - Source Files\Systems + Systems - Source Files\Systems + Systems - Source Files\Systems - - - Source Files\Renderer + Systems Source Files - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files\Components - - - Header Files - + + + + + + + + - Header Files\Systems - - - Header Files\Systems + Systems - Header Files\Systems + Systems + + + Systems - Header Files\Systems + Systems - Header Files\Systems + Systems - Header Files\Systems + Systems - Header Files\Systems + Systems - - Header Files\Renderer + + Components Header Files @@ -122,4 +74,15 @@ Shaders + + + {657e11f4-52e7-4336-b77f-80f00b85c33f} + + + {59929465-a139-43b9-9c75-48121d156e78} + + + {54f1eb6f-dc00-4e97-a3ef-ac255d755e2e} + + \ No newline at end of file diff --git a/Escape-the-Dawn/System.h b/Escape-the-Dawn/System.h new file mode 100644 index 0000000..4ea04a1 --- /dev/null +++ b/Escape-the-Dawn/System.h @@ -0,0 +1,20 @@ +#ifndef System_h__ +#define System_h__ + +#include "Entity.h" + +class World; + +class System +{ +public: + System(World* world) : m_World(world) { } + virtual ~System() { } + + virtual void Update(double dt, EntityID entity, EntityID parent) = 0; + +protected: + World* m_World; +}; + +#endif // System_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/Systems/CollisionSystem.cpp b/Escape-the-Dawn/Systems/CollisionSystem.cpp index e69de29..5670652 100644 --- a/Escape-the-Dawn/Systems/CollisionSystem.cpp +++ b/Escape-the-Dawn/Systems/CollisionSystem.cpp @@ -0,0 +1,16 @@ +#include "CollisionSystem.h" +#include "World.h" + +void Systems::Collision::Update(double dt, EntityID entity, EntityID parent) +{ + if (parent != 0) + { + auto transform = m_World->GetComponent(entity, "Transform"); + auto parentTransform = m_World->GetComponent(parent, "Transform"); + + transform->Position[0] += parentTransform->Position[0]; + transform->Position[1] += parentTransform->Position[1]; + transform->Position[2] += parentTransform->Position[2]; + } + LOG_INFO("Updating entity %i with parent %i", entity, parent); +} diff --git a/Escape-the-Dawn/Systems/CollisionSystem.h b/Escape-the-Dawn/Systems/CollisionSystem.h index e69de29..c5c1bdd 100644 --- a/Escape-the-Dawn/Systems/CollisionSystem.h +++ b/Escape-the-Dawn/Systems/CollisionSystem.h @@ -0,0 +1,23 @@ +#ifndef CollisionSystem_h__ +#define CollisionSystem_h__ + +#include "System.h" +#include "logging.h" + +#include "Components/Transform.h" + + +namespace Systems +{ + +class Collision : public System +{ +public: + Collision(World* world) : System(world) { } + + void Update(double dt, EntityID entity, EntityID parent) override; +}; + +} + +#endif // CollisionSystem_h__ diff --git a/Escape-the-Dawn/World.cpp b/Escape-the-Dawn/World.cpp new file mode 100644 index 0000000..fe130a8 --- /dev/null +++ b/Escape-the-Dawn/World.cpp @@ -0,0 +1,87 @@ +#include "World.h" + +void World::RecycleEntityID(EntityID id) +{ + m_RecycledEntityIDs.push(id); +} + +EntityID World::GenerateEntityID() +{ + if (!m_RecycledEntityIDs.empty()) { + EntityID id = m_RecycledEntityIDs.top(); + m_RecycledEntityIDs.pop(); + return id; + } else { + return ++m_LastEntityID; + } +} + +void World::RecursiveUpdate(std::shared_ptr system, double dt, EntityID parentEntity) +{ + for (auto pair : m_EntityParents) { + EntityID child = pair.first; + EntityID parent = pair.second; + + if (parent == parentEntity) { + system->Update(dt, child, parent); + RecursiveUpdate(system, dt, child); + } + } +} + +void World::Update(double dt) +{ + for (auto system : m_Systems) { + RecursiveUpdate(system, dt, 0); + } +} + +void World::AddSystem(System* system) +{ + +} + +//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; +//} + +EntityID World::GetEntityParent(EntityID entity) +{ + auto it = m_EntityParents.find(entity); + return it == m_EntityParents.end() ? 0 : it->second; +} + +bool World::ValidEntity(EntityID entity) +{ + return m_EntityParents.find(entity) != m_EntityParents.end(); +} + +void World::RemoveEntity(EntityID entity) +{ + m_EntityParents.erase(entity); + RecycleEntityID(entity); +} + +EntityID World::CreateEntity(EntityID parent /*= 0*/) +{ + EntityID newEntity = GenerateEntityID(); + m_EntityParents.insert(std::pair(newEntity, parent)); + return newEntity; +} + +World::~World() +{ + +} + +World::World() +{ + m_LastEntityID = 0; + + m_Systems.push_back(std::make_shared(this)); +} \ No newline at end of file diff --git a/Escape-the-Dawn/World.h b/Escape-the-Dawn/World.h index 9f00114..1dec1c5 100644 --- a/Escape-the-Dawn/World.h +++ b/Escape-the-Dawn/World.h @@ -9,79 +9,60 @@ #include "Entity.h" #include "Component.h" #include "ComponentFactory.h" -//#include "Components/Transform.h" +#include "System.h" +#include "Systems/CollisionSystem.h" class World { public: - World() - { - m_LastEntityID = 0; - } + World(); + ~World(); - EntityID CreateEntity(EntityID parent = 0) - { - EntityID newEntity = GenerateEntityID(); - m_SceneGraph.insert(std::pair(newEntity, parent)); - return newEntity; - } + EntityID CreateEntity(EntityID parent = 0); - void RemoveEntity(EntityID entity) - { - m_SceneGraph.erase(entity); - RecycleEntityID(entity); - } + void RemoveEntity(EntityID entity); - bool ValidEntity(EntityID entity) - { - return m_SceneGraph.find(entity) != m_SceneGraph.end(); - } + bool ValidEntity(EntityID entity); - EntityID GetEntityParent(EntityID entity) - { - auto it = m_SceneGraph.find(entity); - return it == m_SceneGraph.end() ? 0 : it->second; - } + EntityID GetEntityParent(EntityID entity); - std::shared_ptr AddComponent(EntityID entity, std::string componentType) + template + std::shared_ptr AddComponent(EntityID entity, std::string componentType) { - std::shared_ptr component = ComponentFactory::Instance()->Create(componentType); + std::shared_ptr component = std::static_pointer_cast(ComponentFactory::Instance()->Create(componentType)); m_ComponentsOfType[componentType].push_back(component); m_EntityComponents[entity][componentType] = component; + return component; } - /*std::vector GetEntityChildren(EntityID entity) + template + std::shared_ptr GetComponent(EntityID entity, std::string componentType) { - 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; - }*/ + return std::static_pointer_cast(m_EntityComponents[entity][componentType]); + } + + /*std::vector GetEntityChildren(EntityID entity);*/ + + void AddSystem(System* system); + + // Recursively update through the scene graph + void Update(double dt); + + void RecursiveUpdate(std::shared_ptr system, double dt, EntityID parentEntity); private: EntityID m_LastEntityID; std::stack m_RecycledEntityIDs; - // A map of child entities to parent entities - std::unordered_map m_SceneGraph; + // A bottom to top tree. A map of child entities to parent entities. + std::unordered_map m_EntityParents; + std::unordered_map>> m_ComponentsOfType; std::unordered_map>> m_EntityComponents; + std::vector> m_Systems; - EntityID GenerateEntityID() - { - if (!m_RecycledEntityIDs.empty()) { - EntityID id = m_RecycledEntityIDs.top(); - m_RecycledEntityIDs.pop(); - return id; - } else { - return ++m_LastEntityID; - } - } + EntityID GenerateEntityID(); - void RecycleEntityID(EntityID id) - { - m_RecycledEntityIDs.push(id); - } + void RecycleEntityID(EntityID id); }; #endif // World_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/logging.h b/Escape-the-Dawn/logging.h index e2a7b7f..e23be53 100644 --- a/Escape-the-Dawn/logging.h +++ b/Escape-the-Dawn/logging.h @@ -49,7 +49,7 @@ static void _LOG(_LOG_LEVEL logLevel, char* file, char* func, unsigned int line, char message[512]; va_list args; va_start(args, format); - vsnprintf(message, 512, format, args); + vsnprintf_s(message, 512, format, args); va_end(args); if (logLevel == LOG_LEVEL_ERROR) diff --git a/Escape-the-Dawn/main.cpp b/Escape-the-Dawn/main.cpp index e67053c..c9bc467 100644 --- a/Escape-the-Dawn/main.cpp +++ b/Escape-the-Dawn/main.cpp @@ -9,6 +9,8 @@ #include "logging.h" #include "glerror.h" +#include "World.h" + GLFWwindow* window; GLint glVersion[2]; GLchar* glVendor; diff --git a/Tests/Tests.vcxproj b/Tests/Tests.vcxproj index c013dba..b6294b2 100644 --- a/Tests/Tests.vcxproj +++ b/Tests/Tests.vcxproj @@ -80,6 +80,16 @@ + + + {fe405cfa-8fce-4867-92cf-797e73b36482} + true + true + false + true + false + + diff --git a/Tests/main.cpp b/Tests/main.cpp index 6a335d1..bc0a4f0 100644 --- a/Tests/main.cpp +++ b/Tests/main.cpp @@ -20,6 +20,27 @@ BOOST_AUTO_TEST_CASE(Parenting) BOOST_CHECK(world.GetEntityParent(ent2) == ent1); } +BOOST_AUTO_TEST_CASE(SceneGraphTraversal) +{ + World world; + + EntityID ent1 = world.CreateEntity(); + auto t1 = world.AddComponent(ent1, "Transform"); + t1->Position[0] = 1.0f; + t1->Position[1] = 1.0f; + t1->Position[2] = 1.0f; + EntityID ent2 = world.CreateEntity(ent1); + auto t2 = world.AddComponent(ent2, "Transform"); + t2->Position[0] = 1.0f; + t2->Position[1] = 1.0f; + t2->Position[2] = 1.0f; + + world.Update(0.0); + + LOG_INFO("ent1: %f %f %f", t1->Position[0], t1->Position[1], t1->Position[2]); + LOG_INFO("ent2: %f %f %f", t2->Position[0], t2->Position[1], t2->Position[2]); +} + BOOST_AUTO_TEST_CASE(Recycling) { World world;