From 30317ba5be36162b65fbfb368e5d5c5676926df5 Mon Sep 17 00:00:00 2001 From: bailehuni Date: Mon, 29 Jul 2024 18:58:33 +0100 Subject: [PATCH] more clean up --- CMakeLists.txt | 9 +++++++ CMakePresets.json | 21 +++++++++++++--- include/component_custom.h | 28 +++++++++++++++++++-- include/ecs.h | 6 ++--- include/event_system.h | 39 +++++++++++++++------------- include/input_manager.h | 5 ++-- include/scene.h | 4 +-- include/system_custom_behaviour.h | 9 ++++--- src/application.cpp | 4 +-- src/input_manager.cpp | 20 +++++++-------- src/system_custom_behaviour.cpp | 42 +++++++++++++++---------------- test/src/game.cpp | 20 +++++++++------ 12 files changed, 130 insertions(+), 77 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b88c2c..bea3790 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,9 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON) # options option(ENGINE_BUILD_TEST "Compile the test program" ON) +if (MSVC) + option(ENGINE_HOT_RELOAD "Enable VS hot reload" OFF) +endif() set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo") @@ -115,6 +118,7 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 11) set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD_REQUIRED ON) set_property(TARGET ${PROJECT_NAME} PROPERTY C_EXTENSIONS OFF) +# compiler warnings if (MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W3) target_compile_options(${PROJECT_NAME} PRIVATE /MP) @@ -123,6 +127,11 @@ else() target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -pedantic) endif() +if (MSVC AND ENGINE_HOT_RELOAD) + target_compile_options(${PROJECT_NAME} PRIVATE /ZI) + target_link_options(${PROJECT_NAME} PRIVATE /INCREMENTAL) +endif() + target_include_directories(${PROJECT_NAME} PUBLIC include) target_include_directories(${PROJECT_NAME} PRIVATE src) diff --git a/CMakePresets.json b/CMakePresets.json index e8c83d1..3d4a7ad 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -21,7 +21,7 @@ { "name": "x64-debug", "displayName": "x64 Debug", - "description": "Target Windows (64-bit) with the Visual Studio development environment. (Debug)", + "description": "No optimisation, hot reloading enabled, generate debug symbols", "inherits": "windows-base", "architecture": { "value": "x64", @@ -29,17 +29,30 @@ }, "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", - "ENGINETEST_BUILD_WIN32_APP": "OFF" + "ENGINETEST_BUILD_WIN32_APP": "OFF", + "ENGINE_HOT_RELOAD": "ON" } }, { "name": "x64-release", "displayName": "x64 Release", - "description": "Target Windows (64-bit) with the Visual Studio development environment. (RelWithDebInfo)", + "description": "Optimisation on, hot reloading enabled, generate debug symbols", + "inherits": "x64-debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "ENGINETEST_BUILD_WIN32_APP": "OFF", + "ENGINE_HOT_RELOAD": "ON" + } + }, + { + "name": "x64-dist", + "displayName": "x64 Distribution Build", + "description": "Optimisation on, hot reloading disabled, no symbols", "inherits": "x64-debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", - "ENGINETEST_BUILD_WIN32_APP": "ON" + "ENGINETEST_BUILD_WIN32_APP": "ON", + "ENGINE_HOT_RELOAD": "OFF" } } ] diff --git a/include/component_custom.h b/include/component_custom.h index f60d260..7377c70 100644 --- a/include/component_custom.h +++ b/include/component_custom.h @@ -1,12 +1,36 @@ #pragma once #include +#include + +#include "entity.h" namespace engine { +class CustomBehaviourSystem; // foward-dec +class Scene; // forward-dec + +class ComponentCustomImpl { + friend CustomBehaviourSystem; // to set scene and entity on init + +protected: + Scene* m_scene = nullptr; + Entity m_entity = 0u; + +public: + ComponentCustomImpl() = default; + ComponentCustomImpl(const ComponentCustomImpl&) = delete; + + virtual ~ComponentCustomImpl() = 0; + + virtual void init() {} + virtual void update(float dt) {} +}; + +inline ComponentCustomImpl::~ComponentCustomImpl() {} + struct CustomComponent { - std::function on_init; // void on_init(void); - std::function on_update; // void on_update(float ts); + std::unique_ptr impl; }; } // namespace engine \ No newline at end of file diff --git a/include/ecs.h b/include/ecs.h index 0760fae..6d5fd3a 100644 --- a/include/ecs.h +++ b/include/ecs.h @@ -28,13 +28,13 @@ private: std::vector m_component_array{}; public: - void insertData(Entity entity, const T& component) + void insertData(Entity entity, T&& component) { if (m_component_array.size() < entity + 1) { m_component_array.resize(entity + 1); } // bounds checking here as not performance critical - m_component_array.at(entity) = component; + m_component_array.at(entity) = std::move(component); } void removeData(Entity entity) @@ -59,7 +59,7 @@ public: System(Scene* scene, std::set required_component_hashes); System(const System&) = delete; - virtual ~System() {}; + virtual ~System() {} System& operator=(const System&) = delete; diff --git a/include/event_system.h b/include/event_system.h index 3ad16fe..ecaeda2 100644 --- a/include/event_system.h +++ b/include/event_system.h @@ -2,6 +2,7 @@ #include #include + #include #include #include @@ -15,22 +16,31 @@ enum class EventSubscriberKind { // Event handler base-class template class EventHandler { - public: +public: virtual void onEvent(T data) = 0; }; // Event queue interface to allow for different type queues to be in the map class IEventQueue { - public: +public: virtual ~IEventQueue() {} + virtual void despatchEvents() = 0; }; +// holds events of type T and subscribers to those events template class EventQueue : public IEventQueue { - // holds events of type T and subscribers to those events +private: + std::unordered_map*> m_subscribers; - public: + struct QueuedEvent { + EventHandler* handler; + T event; + }; + std::queue m_event_queue{}; + +public: void subscribe(EventSubscriberKind kind, uint32_t id, EventHandler* handler) { // For the time being, ignore kind (TODO) @@ -56,24 +66,20 @@ class EventQueue : public IEventQueue { m_event_queue.pop(); } } - - private: - std::unordered_map*> m_subscribers; - - struct QueuedEvent { - EventHandler* handler; - T event; - }; - std::queue m_event_queue{}; }; class EventSystem { - public: +private: + std::unordered_map> m_event_queues{}; + +public: EventSystem() {} EventSystem(const EventSystem&) = delete; - EventSystem& operator=(const EventSystem&) = delete; + ~EventSystem() {} + EventSystem& operator=(const EventSystem&) = delete; + template void registerEventType() { @@ -108,9 +114,6 @@ class EventSystem { queue->despatchEvents(); } } - - private: - std::unordered_map> m_event_queues{}; }; } // namespace engine \ No newline at end of file diff --git a/include/input_manager.h b/include/input_manager.h index d8e1484..b65b1b4 100644 --- a/include/input_manager.h +++ b/include/input_manager.h @@ -17,9 +17,8 @@ class InputManager { public: /* The Window object here is stored for the duration of the InputManager. * 'win' must point to a valid Window object. */ - InputManager(const Window* win) : win_(win) + InputManager(const Window& win) : m_win(win) { - assert(win != nullptr); enabled_devices_.fill(true); } InputManager(const InputManager&) = delete; @@ -86,7 +85,7 @@ class InputManager { int low; }; - const Window* win_; + const Window& m_win; std::vector button_entries_; std::vector axis_entries_; diff --git a/include/scene.h b/include/scene.h index a49f847..81bac76 100644 --- a/include/scene.h +++ b/include/scene.h @@ -78,12 +78,12 @@ class Scene { glm::vec3& GetScale(Entity entity) { return GetTransform(entity)->scale; } template - T* AddComponent(Entity entity, const T& comp = T{}) + T* AddComponent(Entity entity, T&& comp = T{}) { size_t hash = typeid(T).hash_code(); auto array = GetComponentArray(); - array->insertData(entity, comp); // errors if entity already exists in array + array->insertData(entity, std::move(comp)); // errors if entity already exists in array // set the component bit for this entity size_t signature_position = component_signature_positions_.at(hash); diff --git a/include/system_custom_behaviour.h b/include/system_custom_behaviour.h index 44cbbe1..6b212cf 100644 --- a/include/system_custom_behaviour.h +++ b/include/system_custom_behaviour.h @@ -10,15 +10,16 @@ namespace engine { class CustomBehaviourSystem : public System { - public: +private: + std::unordered_map m_entity_is_initialised{}; + +public: CustomBehaviourSystem(Scene* scene); + ~CustomBehaviourSystem(); void onUpdate(float ts) override; void onComponentInsert(Entity entity) override; - - private: - std::unordered_map entity_is_initialised_{}; }; } // namespace engine \ No newline at end of file diff --git a/src/application.cpp b/src/application.cpp index 8da91a2..b125157 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -59,7 +59,7 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph : app_name(appName), app_version(appVersion), m_configuration(configuration) { m_window = std::make_unique(appName, true, false); - m_input_manager = std::make_unique(m_window.get()); + m_input_manager = std::make_unique(*m_window); m_scene_manager = std::make_unique(this); // get base path for resources @@ -235,7 +235,7 @@ void Application::gameLoop() m_input_manager->SetDeviceActive(InputDevice::kMouse, !debug_menu_state.menu_active); if (debug_menu_state.menu_active) { - if (ImGui::Begin("Settings", 0)) { + if (ImGui::Begin("Settings Deez! lol", 0)) { ImGui::Text("FPS: %.3f", std::roundf(avg_fps)); ImGui::Checkbox("Enable FPS limiter", &debug_menu_state.enable_frame_limiter); if (debug_menu_state.enable_frame_limiter) { diff --git a/src/input_manager.cpp b/src/input_manager.cpp index 84573c4..79a3f80 100644 --- a/src/input_manager.cpp +++ b/src/input_manager.cpp @@ -81,13 +81,13 @@ float InputManager::GetDeviceAxis(enum InputDevice device, int axis) const case InputDevice::kMouse: switch (static_cast(axis)) { case inputs::MouseAxis::X: - return static_cast(win_->GetMouseDX()); + return static_cast(m_win.GetMouseDX()); case inputs::MouseAxis::Y: - return static_cast(win_->GetMouseDY()); + return static_cast(m_win.GetMouseDY()); case inputs::MouseAxis::X_SCR: - return win_->GetMouseScrollX(); + return m_win.GetMouseScrollX(); case inputs::MouseAxis::Y_SCR: - return win_->GetMouseScrollY(); + return m_win.GetMouseScrollY(); default: break; } break; @@ -104,9 +104,9 @@ bool InputManager::GetDeviceButton(enum InputDevice device, int button) const { switch (device) { case InputDevice::kMouse: - return win_->GetButton(static_cast(button)); + return m_win.GetButton(static_cast(button)); case InputDevice::kKeyboard: - return win_->GetKey(static_cast(button)); + return m_win.GetKey(static_cast(button)); case InputDevice::kController: break; default: break; @@ -118,9 +118,9 @@ bool InputManager::getDeviceButtonDown(enum InputDevice device, int button) cons { switch (device) { case InputDevice::kMouse: - return win_->GetButtonPress(static_cast(button)); + return m_win.GetButtonPress(static_cast(button)); case InputDevice::kKeyboard: - return win_->GetKeyPress(static_cast(button)); + return m_win.GetKeyPress(static_cast(button)); case InputDevice::kController: break; default: break; @@ -132,9 +132,9 @@ bool InputManager::GetDeviceButtonUp(enum InputDevice device, int button) const { switch (device) { case InputDevice::kMouse: - return win_->GetButtonRelease(static_cast(button)); + return m_win.GetButtonRelease(static_cast(button)); case InputDevice::kKeyboard: - return win_->GetKeyRelease(static_cast(button)); + return m_win.GetKeyRelease(static_cast(button)); case InputDevice::kController: break; default: break; diff --git a/src/system_custom_behaviour.cpp b/src/system_custom_behaviour.cpp index 71c3ca8..a457955 100644 --- a/src/system_custom_behaviour.cpp +++ b/src/system_custom_behaviour.cpp @@ -8,32 +8,30 @@ namespace engine { -CustomBehaviourSystem::CustomBehaviourSystem(Scene* scene) - : System(scene, {typeid(TransformComponent).hash_code(), - typeid(CustomComponent).hash_code()}) { - // constructor here +CustomBehaviourSystem::CustomBehaviourSystem(Scene* scene) : System(scene, {typeid(TransformComponent).hash_code(), typeid(CustomComponent).hash_code()}) +{ + // constructor here } CustomBehaviourSystem::~CustomBehaviourSystem() {} -void CustomBehaviourSystem::onUpdate(float ts) { - for (Entity entity : m_entities) { - auto c = m_scene->GetComponent(entity); - assert(c != nullptr); - bool& entity_initialised = entity_is_initialised_.at(entity); - if (entity_initialised == false) { - if (c->on_init == nullptr) throw std::runtime_error("CustomComponent::on_init not set! Entity: " + std::to_string(entity)); - if (c->on_update == nullptr) throw std::runtime_error("CustomComponent::on_update not set! Entity: " + std::to_string(entity)); - c->on_init(); - entity_initialised = true; - } - c->on_update(ts); - } -} - -void CustomBehaviourSystem::onComponentInsert(Entity entity) +void CustomBehaviourSystem::onUpdate(float ts) { - entity_is_initialised_.emplace(entity, false); + for (Entity entity : m_entities) { + auto c = m_scene->GetComponent(entity); + assert(c != nullptr); + assert(c->impl != nullptr); + bool& entity_initialised = m_entity_is_initialised.at(entity); + if (entity_initialised == false) { + c->impl->m_entity = entity; + c->impl->m_scene = m_scene; + c->impl->init(); + entity_initialised = true; + } + c->impl->update(ts); + } } -} // namespace engine \ No newline at end of file +void CustomBehaviourSystem::onComponentInsert(Entity entity) { m_entity_is_initialised.emplace(entity, false); } + +} // namespace engine \ No newline at end of file diff --git a/test/src/game.cpp b/test/src/game.cpp index ef691d8..bf3c2e1 100644 --- a/test/src/game.cpp +++ b/test/src/game.cpp @@ -142,14 +142,20 @@ void PlayGame(GameSettings settings) cube_ren->mesh = GenCuboidMesh(app.getRenderer()->GetDevice(), 1.0f, 1.0f, 1.0f); cube_ren->visible = true; auto cubeCustom = main_scene->AddComponent(cube); - cubeCustom->on_init = [] {}; - cubeCustom->on_update = [&main_scene, cube](float dt) { - static float yaw = 0.0f; - yaw += dt; - main_scene->GetRotation(cube) = glm::angleAxis(yaw, glm::vec3{0.0f, 0.0f, 1.0f}); - main_scene->GetRotation(cube) *= glm::angleAxis(glm::half_pi(), glm::vec3{ 1.0f, 0.0f, 0.0f }); - }; + class Spinner : public engine::ComponentCustomImpl { + private: + float yaw = 0.0f; + public: + void init() override { + } + void update(float dt) override { + yaw += dt; + m_scene->GetRotation(m_entity) = glm::angleAxis(yaw, glm::vec3{0.0f, 0.0f, 1.0f}); + m_scene->GetRotation(m_entity) *= glm::angleAxis(glm::half_pi(), glm::vec3{1.0f, 0.0f, 0.0f}); + } + }; + cubeCustom->impl = std::make_unique(); engine::Entity teapot = engine::loadGLTF(*main_scene, app.getResourcePath("models/teapot.glb"), true); main_scene->GetPosition(teapot).y += 5.0f;