diff --git a/Escape-the-Dawn/Component.h b/Escape-the-Dawn/Component.h index 221108c..21d59f6 100644 --- a/Escape-the-Dawn/Component.h +++ b/Escape-the-Dawn/Component.h @@ -9,6 +9,6 @@ struct Component EntityID Entity; }; -//&static ComponentFactory componentFactory; +class ComponentFactory : public Factory { }; #endif // Component_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/Components/Input.h b/Escape-the-Dawn/Components/Input.h index d278aa7..a565d47 100644 --- a/Escape-the-Dawn/Components/Input.h +++ b/Escape-the-Dawn/Components/Input.h @@ -12,10 +12,10 @@ namespace Components struct Input : Component { - std::array KeyState; - std::array LastKeyState; - std::array MouseState; - std::array LastMouseState; + std::array KeyState; + std::array LastKeyState; + std::array MouseState; + std::array LastMouseState; float dX, dY; }; diff --git a/Escape-the-Dawn/Engine.h b/Escape-the-Dawn/Engine.h index 99f037a..968dfed 100644 --- a/Escape-the-Dawn/Engine.h +++ b/Escape-the-Dawn/Engine.h @@ -9,20 +9,24 @@ #include "logging.h" #include "glerror.h" -#include "World.h" - - +#include "Renderer.h" +#include "GameWorld.h" class Engine { public: Engine(int argc, char* argv[]) { - renderer.Initialize(); + m_Renderer = std::make_shared(); + m_Renderer->Initialize(); + + m_World = std::make_shared(m_Renderer); + m_World->Initialize(); + m_LastTime = glfwGetTime(); } - bool Running() const { return !glfwWindowShouldClose(renderer.GetWindow()); } + bool Running() const { return !glfwWindowShouldClose(m_Renderer->GetWindow()); } void Tick() { @@ -30,13 +34,16 @@ public: double dt = currentTime - m_LastTime; m_LastTime = currentTime; - //World.Update(dt); - renderer.Draw(dt); + m_World->Update(dt); + m_Renderer->Draw(dt); glfwPollEvents(); } private: - Renderer renderer; + std::shared_ptr m_Renderer; + // TODO: This should ultimately live in GameFrame + std::shared_ptr m_World; + double m_LastTime; }; \ 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 35f180a..4fbe3f4 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj @@ -137,6 +137,7 @@ + diff --git a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters index c628454..ca2171c 100644 --- a/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters +++ b/Escape-the-Dawn/Escape-the-Dawn.vcxproj.filters @@ -27,21 +27,21 @@ - Gui + GUI - Gui + GUI - Gui + GUI - Gui + GUI - Gui + GUI @@ -125,20 +125,21 @@ - Gui + GUI - Gui + GUI - Gui + GUI - Gui + GUI - Gui + GUI + @@ -161,7 +162,7 @@ {d985d7a7-c041-46fe-ae03-aa40295a7aad} - + {7bdb0f69-049e-4f16-b271-2495e02e4b28} diff --git a/Escape-the-Dawn/Factory.h b/Escape-the-Dawn/Factory.h index 1a82f5b..01429bd 100644 --- a/Escape-the-Dawn/Factory.h +++ b/Escape-the-Dawn/Factory.h @@ -29,7 +29,4 @@ private: std::map> m_FactoryFunctions; }; -struct Component; -class ComponentFactory : public Factory { }; - #endif // ComponentFactory_h__ \ No newline at end of file diff --git a/Escape-the-Dawn/GameWorld.h b/Escape-the-Dawn/GameWorld.h new file mode 100644 index 0000000..d8f26b1 --- /dev/null +++ b/Escape-the-Dawn/GameWorld.h @@ -0,0 +1,92 @@ +#ifndef GameWorld_h__ +#define GameWorld_h__ + +#include "World.h" +#include "Renderer.h" + +#include "Systems/CollisionSystem.h" +#include "Systems/InputSystem.h" +#include "Systems/LevelGenerationSystem.h" +#include "Systems/ParticleSystem.h" +#include "Systems/PlayerSystem.h" +#include "Systems/RenderSystem.h" +#include "Systems/SoundSystem.h" + +#include "Components/Bounds.h" +#include "Components/Camera.h" +#include "Components/Collision.h" +#include "Components/DirectionalLight.h" +#include "Components/Input.h" +#include "Components/Model.h" +#include "Components/ParticleEmitter.h" +#include "Components/PointLight.h" +#include "Components/PowerUp.h" +#include "Components/SoundEmitter.h" +#include "Components/Sprite.h" +#include "Components/Stat.h" +#include "Components/Template.h" +#include "Components/Transform.h" + +class GameWorld : public World +{ +public: + GameWorld(std::shared_ptr renderer); + void Initialize() override; + + void RegisterSystems() override; + void RegisterComponents() override; + + void Update(double dt) override; + +private: + std::shared_ptr m_Renderer; +}; + +GameWorld::GameWorld(std::shared_ptr renderer) + : m_Renderer(renderer), World() +{ + +} + +void GameWorld::Initialize() +{ + World::Initialize(); + + AddSystem("InputSystem"); +} + +void GameWorld::RegisterSystems() +{ + //m_SystemFactory.Register("LevelGenerationSystem", [this]() { return new Systems::LevelGenerationSystem(this); }); + m_SystemFactory.Register("InputSystem", [this]() { return new Systems::InputSystem(this, m_Renderer); }); + //m_SystemFactory.Register("CollisionSystem", [this]() { return new Systems::CollisionSystem(this); }); + //m_SystemFactory.Register("ParticleSystem", [this]() { return new Systems::ParticleSystem(this); }); + //m_SystemFactory.Register("PlayerSystem", [this]() { return new Systems::PlayerSystem(this); }); + //m_SystemFactory.Register("SoundSystem", [this]() { return new Systems::SoundSystem(this); }); + //m_SystemFactory.Register("RenderSystem", [this]() { return new Systems::RenderSystem(this, m_Renderer); }); +} + +void GameWorld::RegisterComponents() +{ + m_ComponentFactory.Register("Bounds", []() { return new Components::Bounds(); }); + m_ComponentFactory.Register("Camera", []() { return new Components::Camera(); }); + m_ComponentFactory.Register("Collision", []() { return new Components::Collision(); }); + m_ComponentFactory.Register("DirectionalLight", []() { return new Components::DirectionalLight(); }); + m_ComponentFactory.Register("Input", []() { return new Components::Input(); }); + m_ComponentFactory.Register("Model", []() { return new Components::Model(); }); + m_ComponentFactory.Register("ParticleEmitter", []() { return new Components::ParticleEmitter(); }); + m_ComponentFactory.Register("PointLight", []() { return new Components::PointLight(); }); + m_ComponentFactory.Register("PowerUp", []() { return new Components::PowerUp(); }); + m_ComponentFactory.Register("SoundEmitter", []() { return new Components::SoundEmitter(); }); + m_ComponentFactory.Register("Sprite", []() { return new Components::Sprite(); }); + m_ComponentFactory.Register("Stat", []() { return new Components::Stat(); }); + m_ComponentFactory.Register("Template", []() { return new Components::Template(); }); + m_ComponentFactory.Register("Transform", []() { return new Components::Transform(); }); +} + +void GameWorld::Update(double dt) +{ + World::Update(dt); +} + +#endif // GameWorld_h__ diff --git a/Escape-the-Dawn/System.h b/Escape-the-Dawn/System.h index 3ad42db..f295857 100644 --- a/Escape-the-Dawn/System.h +++ b/Escape-the-Dawn/System.h @@ -1,6 +1,7 @@ #ifndef System_h__ #define System_h__ +#include "Factory.h" #include "Entity.h" #include "Component.h" @@ -15,13 +16,15 @@ public: // Called once per system every tick virtual void Update(double dt) { } // Called once for every entity in the world every tick - virtual void Update(double dt, EntityID entity, EntityID parent) { } + virtual void UpdateEntity(double dt, EntityID entity, EntityID parent) { } // Called when a component is created - virtual void OnComponentCreated(std::string type, std:: shared_ptr component); + virtual void OnComponentCreated(std::string type, std:: shared_ptr component) { } protected: World* m_World; }; +class SystemFactory : public Factory { }; + #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 5670652..f9c5a8a 100644 --- a/Escape-the-Dawn/Systems/CollisionSystem.cpp +++ b/Escape-the-Dawn/Systems/CollisionSystem.cpp @@ -1,7 +1,7 @@ #include "CollisionSystem.h" #include "World.h" -void Systems::Collision::Update(double dt, EntityID entity, EntityID parent) +void Systems::CollisionSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) { if (parent != 0) { diff --git a/Escape-the-Dawn/Systems/CollisionSystem.h b/Escape-the-Dawn/Systems/CollisionSystem.h index 2648e70..5c4c448 100644 --- a/Escape-the-Dawn/Systems/CollisionSystem.h +++ b/Escape-the-Dawn/Systems/CollisionSystem.h @@ -9,12 +9,13 @@ namespace Systems { -class Collision : public System +class CollisionSystem : public System { public: - Collision(World* world) : System(world) { } + CollisionSystem(World* world) + : System(world) { } - void Update(double dt, EntityID entity, EntityID parent) override; + void UpdateEntity(double dt, EntityID entity, EntityID parent) override; }; } diff --git a/Escape-the-Dawn/Systems/InputSystem.cpp b/Escape-the-Dawn/Systems/InputSystem.cpp index 278a2d0..fc29849 100644 --- a/Escape-the-Dawn/Systems/InputSystem.cpp +++ b/Escape-the-Dawn/Systems/InputSystem.cpp @@ -13,7 +13,7 @@ void Systems::InputSystem::Update(double dt) // Mouse buttons for (int i = 0; i <= GLFW_MOUSE_BUTTON_LAST; ++i) { - m_CurrentKeyState[i] = glfwGetMouseButton(m_Renderer->GetWindow(), i); + m_CurrentMouseState[i] = glfwGetMouseButton(m_Renderer->GetWindow(), i); } // Cursor position @@ -25,7 +25,7 @@ void Systems::InputSystem::Update(double dt) m_LastMouseY = ypos; } -void Systems::InputSystem::Update(double dt, EntityID entity, EntityID parent) +void Systems::InputSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) { auto input = m_World->GetComponent(entity, "Input"); if (input == nullptr) diff --git a/Escape-the-Dawn/Systems/InputSystem.h b/Escape-the-Dawn/Systems/InputSystem.h index 2c0e521..73a5946 100644 --- a/Escape-the-Dawn/Systems/InputSystem.h +++ b/Escape-the-Dawn/Systems/InputSystem.h @@ -13,19 +13,19 @@ namespace Systems class InputSystem : public System { public: - InputSystem(World* world, Renderer* renderer) + InputSystem(World* world, std::shared_ptr renderer) : System(world), m_Renderer(renderer) { } void Update(double dt) override; - void Update(double dt, EntityID entity, EntityID parent) override; + void UpdateEntity(double dt, EntityID entity, EntityID parent) override; private: - Renderer* m_Renderer; + std::shared_ptr m_Renderer; - std::array m_CurrentKeyState; - std::array m_LastKeyState; - std::array m_CurrentMouseState; - std::array m_LastMouseState; + std::array m_CurrentKeyState; + std::array m_LastKeyState; + std::array m_CurrentMouseState; + std::array m_LastMouseState; float m_CurrentMouseDeltaX, m_CurrentMouseDeltaY; float m_LastMouseX, m_LastMouseY; }; diff --git a/Escape-the-Dawn/World.cpp b/Escape-the-Dawn/World.cpp index ae5a7d8..cda58ae 100644 --- a/Escape-the-Dawn/World.cpp +++ b/Escape-the-Dawn/World.cpp @@ -23,7 +23,7 @@ void World::RecursiveUpdate(std::shared_ptr system, double dt, EntityID EntityID parent = pair.second; if (parent == parentEntity) { - system->Update(dt, child, parent); + system->UpdateEntity(dt, child, parent); RecursiveUpdate(system, dt, child); } } @@ -31,17 +31,13 @@ void World::RecursiveUpdate(std::shared_ptr system, double dt, EntityID void World::Update(double dt) { - for (auto system : m_Systems) { + for (auto pair : m_Systems) { + auto system = pair.second; system->Update(dt); RecursiveUpdate(system, dt, 0); } } -void World::AddSystem(System* system) -{ - -} - //std::vector GetEntityChildren(EntityID entity); //{ // std::vector children; @@ -83,21 +79,30 @@ World::~World() World::World() { m_LastEntityID = 0; - - m_Systems.push_back(std::make_shared(this)); - - RegisterComponents(); - RegisterSystems(); } -void World::RegisterComponents() +void World::Initialize() { - m_ComponentFactory.Register("Transform", []() { return new Components::Transform(); }); - m_ComponentFactory.Register("Input", []() { return new Components::Input(); }); - m_ComponentFactory.Register("DirectionalLight", []() { return new Components::DirectionalLight(); }); + RegisterSystems(); + RegisterComponents(); } void World::RegisterSystems() { } + +void World::RegisterComponents() +{ + +} + +std::shared_ptr World::AddComponent(EntityID entity, std::string componentType) +{ + return AddComponent(entity, componentType); +} + +void World::AddSystem(std::string systemType) +{ + m_Systems[systemType] = std::shared_ptr(m_SystemFactory.Create(systemType)); +} diff --git a/Escape-the-Dawn/World.h b/Escape-the-Dawn/World.h index 6d6b2a5..c8803e5 100644 --- a/Escape-the-Dawn/World.h +++ b/Escape-the-Dawn/World.h @@ -6,17 +6,12 @@ #include #include -#include "Renderer.h" +#include "logging.h" +#include "Factory.h" #include "Entity.h" #include "Component.h" -#include "Factory.h" -#include "Components/Transform.h" -#include "Components/Input.h" -#include "Components/DirectionalLight.h" - #include "System.h" -#include "Systems/CollisionSystem.h" class World { @@ -24,9 +19,15 @@ public: World(); ~World(); + virtual void Initialize(); + virtual void RegisterComponents(); virtual void RegisterSystems(); + void AddSystem(std::string systemType); + template + std::shared_ptr GetSystem(std::string systemType); + EntityID CreateEntity(EntityID parent = 0); void RemoveEntity(EntityID entity); @@ -36,56 +37,66 @@ public: EntityID GetEntityParent(EntityID entity); template - std::shared_ptr AddComponent(EntityID entity, std::string componentType) - { - std::shared_ptr component = std::shared_ptr(static_cast(m_ComponentFactory.Create(componentType))); - if (component == nullptr) { - LOG_ERROR("Failed to attach invalid component \"%s\" to entity #%i", componentType.c_str(), entity); - return nullptr; - } - - component->Entity = entity; - m_ComponentsOfType[componentType].push_back(component); - m_EntityComponents[entity][componentType] = component; - for (auto system : m_Systems) { - system->OnComponentCreated(componentType, component); - } - return component; - } - - std::shared_ptr AddComponent(EntityID entity, std::string componentType) - { - return AddComponent(entity, componentType); - } - + std::shared_ptr AddComponent(EntityID entity, std::string componentType); + std::shared_ptr AddComponent(EntityID entity, std::string componentType); template - std::shared_ptr GetComponent(EntityID entity, std::string componentType) - { - return std::static_pointer_cast(m_EntityComponents[entity][componentType]); - } + std::shared_ptr GetComponent(EntityID entity, std::string componentType); /*std::vector GetEntityChildren(EntityID entity);*/ - void AddSystem(System* system); - - void Update(double dt); + virtual void Update(double dt); // Recursively update through the scene graph void RecursiveUpdate(std::shared_ptr system, double dt, EntityID parentEntity); -private: +protected: + SystemFactory m_SystemFactory; + ComponentFactory m_ComponentFactory; + + std::unordered_map> m_Systems; + EntityID m_LastEntityID; std::stack m_RecycledEntityIDs; // A bottom to top tree. A map of child entities to parent entities. std::unordered_map m_EntityParents; - - ComponentFactory m_ComponentFactory; + std::unordered_map>> m_ComponentsOfType; std::unordered_map>> m_EntityComponents; - std::vector> m_Systems; EntityID GenerateEntityID(); void RecycleEntityID(EntityID id); }; +template +std::shared_ptr World::GetSystem(std::string systemType) +{ + return std::static_pointer_cast(m_Systems[systemType]); +} + +template +std::shared_ptr World::AddComponent(EntityID entity, std::string componentType) +{ + std::shared_ptr component = std::shared_ptr(static_cast(m_ComponentFactory.Create(componentType))); + if (component == nullptr) { + LOG_ERROR("Failed to attach invalid component \"%s\" to entity #%i", componentType.c_str(), entity); + return nullptr; + } + + component->Entity = entity; + m_ComponentsOfType[componentType].push_back(component); + m_EntityComponents[entity][componentType] = component; + for (auto pair : m_Systems) { + auto system = pair.second; + system->OnComponentCreated(componentType, component); + } + return component; +} + + +template +std::shared_ptr World::GetComponent(EntityID entity, std::string componentType) +{ + return std::static_pointer_cast(m_EntityComponents[entity][componentType]); +} + #endif // World_h__ \ No newline at end of file diff --git a/Tests/Tests.vcxproj b/Tests/Tests.vcxproj index 88269ea..1f1fed7 100644 --- a/Tests/Tests.vcxproj +++ b/Tests/Tests.vcxproj @@ -39,13 +39,13 @@ - $(SolutionDir)\Escape-the-Dawn;$(SolutionDir)\Libraries\SOIL\src;\Libraries\SOIL\src;$(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) + $(BOOST_ROOT);$(SolutionDir)\Escape-the-Dawn;$(SolutionDir)\Libraries\SOIL\src;\Libraries\SOIL\src;$(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) $(BOOST_ROOT)\lib32-msvc-11.0;$(LibraryPath) $(ProjectDir)$(Configuration)\ $(SolutionDir)obj\$(ProjectName)\ - $(SolutionDir)\Escape-the-Dawn;$(SolutionDir)\Libraries\SOIL\src;\Libraries\SOIL\src;$(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) + $(BOOST_ROOT);$(SolutionDir)\Escape-the-Dawn;$(SolutionDir)\Libraries\SOIL\src;\Libraries\SOIL\src;$(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) $(BOOST_ROOT)\lib32-msvc-11.0;$(LibraryPath) $(ProjectDir)$(Configuration)\ $(SolutionDir)obj\$(ProjectName)\