more clean up

This commit is contained in:
bailehuni 2024-07-29 18:58:33 +01:00
parent 2cf93def50
commit 30317ba5be
12 changed files with 130 additions and 77 deletions

View File

@ -4,6 +4,9 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# options # options
option(ENGINE_BUILD_TEST "Compile the test program" ON) 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") 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_STANDARD_REQUIRED ON)
set_property(TARGET ${PROJECT_NAME} PROPERTY C_EXTENSIONS OFF) set_property(TARGET ${PROJECT_NAME} PROPERTY C_EXTENSIONS OFF)
# compiler warnings
if (MSVC) if (MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /W3) target_compile_options(${PROJECT_NAME} PRIVATE /W3)
target_compile_options(${PROJECT_NAME} PRIVATE /MP) target_compile_options(${PROJECT_NAME} PRIVATE /MP)
@ -123,6 +127,11 @@ else()
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -pedantic) target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -pedantic)
endif() 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} PUBLIC include)
target_include_directories(${PROJECT_NAME} PRIVATE src) target_include_directories(${PROJECT_NAME} PRIVATE src)

View File

@ -21,7 +21,7 @@
{ {
"name": "x64-debug", "name": "x64-debug",
"displayName": "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", "inherits": "windows-base",
"architecture": { "architecture": {
"value": "x64", "value": "x64",
@ -29,17 +29,30 @@
}, },
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug", "CMAKE_BUILD_TYPE": "Debug",
"ENGINETEST_BUILD_WIN32_APP": "OFF" "ENGINETEST_BUILD_WIN32_APP": "OFF",
"ENGINE_HOT_RELOAD": "ON"
} }
}, },
{ {
"name": "x64-release", "name": "x64-release",
"displayName": "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", "inherits": "x64-debug",
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "Release", "CMAKE_BUILD_TYPE": "Release",
"ENGINETEST_BUILD_WIN32_APP": "ON" "ENGINETEST_BUILD_WIN32_APP": "ON",
"ENGINE_HOT_RELOAD": "OFF"
} }
} }
] ]

View File

@ -1,12 +1,36 @@
#pragma once #pragma once
#include <functional> #include <functional>
#include <memory>
#include "entity.h"
namespace engine { 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 { struct CustomComponent {
std::function<void(void)> on_init; // void on_init(void); std::unique_ptr<ComponentCustomImpl> impl;
std::function<void(float)> on_update; // void on_update(float ts);
}; };
} // namespace engine } // namespace engine

View File

@ -28,13 +28,13 @@ private:
std::vector<T> m_component_array{}; std::vector<T> m_component_array{};
public: public:
void insertData(Entity entity, const T& component) void insertData(Entity entity, T&& component)
{ {
if (m_component_array.size() < entity + 1) { if (m_component_array.size() < entity + 1) {
m_component_array.resize(entity + 1); m_component_array.resize(entity + 1);
} }
// bounds checking here as not performance critical // 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) void removeData(Entity entity)
@ -59,7 +59,7 @@ public:
System(Scene* scene, std::set<size_t> required_component_hashes); System(Scene* scene, std::set<size_t> required_component_hashes);
System(const System&) = delete; System(const System&) = delete;
virtual ~System() {}; virtual ~System() {}
System& operator=(const System&) = delete; System& operator=(const System&) = delete;

View File

@ -2,6 +2,7 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <queue> #include <queue>
#include <unordered_map> #include <unordered_map>
@ -23,12 +24,21 @@ class EventHandler {
class IEventQueue { class IEventQueue {
public: public:
virtual ~IEventQueue() {} virtual ~IEventQueue() {}
virtual void despatchEvents() = 0; virtual void despatchEvents() = 0;
}; };
// holds events of type T and subscribers to those events
template <typename T> template <typename T>
class EventQueue : public IEventQueue { class EventQueue : public IEventQueue {
// holds events of type T and subscribers to those events private:
std::unordered_map<uint32_t, EventHandler<T>*> m_subscribers;
struct QueuedEvent {
EventHandler<T>* handler;
T event;
};
std::queue<QueuedEvent> m_event_queue{};
public: public:
void subscribe(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler) void subscribe(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler)
@ -56,24 +66,20 @@ class EventQueue : public IEventQueue {
m_event_queue.pop(); m_event_queue.pop();
} }
} }
private:
std::unordered_map<uint32_t, EventHandler<T>*> m_subscribers;
struct QueuedEvent {
EventHandler<T>* handler;
T event;
};
std::queue<QueuedEvent> m_event_queue{};
}; };
class EventSystem { class EventSystem {
private:
std::unordered_map<size_t, std::unique_ptr<IEventQueue>> m_event_queues{};
public: public:
EventSystem() {} EventSystem() {}
EventSystem(const EventSystem&) = delete; EventSystem(const EventSystem&) = delete;
EventSystem& operator=(const EventSystem&) = delete;
~EventSystem() {} ~EventSystem() {}
EventSystem& operator=(const EventSystem&) = delete;
template <typename T> template <typename T>
void registerEventType() void registerEventType()
{ {
@ -108,9 +114,6 @@ class EventSystem {
queue->despatchEvents(); queue->despatchEvents();
} }
} }
private:
std::unordered_map<size_t, std::unique_ptr<IEventQueue>> m_event_queues{};
}; };
} // namespace engine } // namespace engine

View File

@ -17,9 +17,8 @@ class InputManager {
public: public:
/* The Window object here is stored for the duration of the InputManager. /* The Window object here is stored for the duration of the InputManager.
* 'win' must point to a valid Window object. */ * '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); enabled_devices_.fill(true);
} }
InputManager(const InputManager&) = delete; InputManager(const InputManager&) = delete;
@ -86,7 +85,7 @@ class InputManager {
int low; int low;
}; };
const Window* win_; const Window& m_win;
std::vector<struct ButtonEntry> button_entries_; std::vector<struct ButtonEntry> button_entries_;
std::vector<struct AxisEntry> axis_entries_; std::vector<struct AxisEntry> axis_entries_;

View File

@ -78,12 +78,12 @@ class Scene {
glm::vec3& GetScale(Entity entity) { return GetTransform(entity)->scale; } glm::vec3& GetScale(Entity entity) { return GetTransform(entity)->scale; }
template <typename T> template <typename T>
T* AddComponent(Entity entity, const T& comp = T{}) T* AddComponent(Entity entity, T&& comp = T{})
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto array = GetComponentArray<T>(); auto array = GetComponentArray<T>();
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 // set the component bit for this entity
size_t signature_position = component_signature_positions_.at(hash); size_t signature_position = component_signature_positions_.at(hash);

View File

@ -10,15 +10,16 @@
namespace engine { namespace engine {
class CustomBehaviourSystem : public System { class CustomBehaviourSystem : public System {
private:
std::unordered_map<Entity, bool> m_entity_is_initialised{};
public: public:
CustomBehaviourSystem(Scene* scene); CustomBehaviourSystem(Scene* scene);
~CustomBehaviourSystem(); ~CustomBehaviourSystem();
void onUpdate(float ts) override; void onUpdate(float ts) override;
void onComponentInsert(Entity entity) override; void onComponentInsert(Entity entity) override;
private:
std::unordered_map<Entity, bool> entity_is_initialised_{};
}; };
} // namespace engine } // namespace engine

View File

@ -59,7 +59,7 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
: app_name(appName), app_version(appVersion), m_configuration(configuration) : app_name(appName), app_version(appVersion), m_configuration(configuration)
{ {
m_window = std::make_unique<Window>(appName, true, false); m_window = std::make_unique<Window>(appName, true, false);
m_input_manager = std::make_unique<InputManager>(m_window.get()); m_input_manager = std::make_unique<InputManager>(*m_window);
m_scene_manager = std::make_unique<SceneManager>(this); m_scene_manager = std::make_unique<SceneManager>(this);
// get base path for resources // get base path for resources
@ -235,7 +235,7 @@ void Application::gameLoop()
m_input_manager->SetDeviceActive(InputDevice::kMouse, !debug_menu_state.menu_active); m_input_manager->SetDeviceActive(InputDevice::kMouse, !debug_menu_state.menu_active);
if (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::Text("FPS: %.3f", std::roundf(avg_fps));
ImGui::Checkbox("Enable FPS limiter", &debug_menu_state.enable_frame_limiter); ImGui::Checkbox("Enable FPS limiter", &debug_menu_state.enable_frame_limiter);
if (debug_menu_state.enable_frame_limiter) { if (debug_menu_state.enable_frame_limiter) {

View File

@ -81,13 +81,13 @@ float InputManager::GetDeviceAxis(enum InputDevice device, int axis) const
case InputDevice::kMouse: case InputDevice::kMouse:
switch (static_cast<inputs::MouseAxis>(axis)) { switch (static_cast<inputs::MouseAxis>(axis)) {
case inputs::MouseAxis::X: case inputs::MouseAxis::X:
return static_cast<float>(win_->GetMouseDX()); return static_cast<float>(m_win.GetMouseDX());
case inputs::MouseAxis::Y: case inputs::MouseAxis::Y:
return static_cast<float>(win_->GetMouseDY()); return static_cast<float>(m_win.GetMouseDY());
case inputs::MouseAxis::X_SCR: case inputs::MouseAxis::X_SCR:
return win_->GetMouseScrollX(); return m_win.GetMouseScrollX();
case inputs::MouseAxis::Y_SCR: case inputs::MouseAxis::Y_SCR:
return win_->GetMouseScrollY(); return m_win.GetMouseScrollY();
default: break; default: break;
} }
break; break;
@ -104,9 +104,9 @@ bool InputManager::GetDeviceButton(enum InputDevice device, int button) const
{ {
switch (device) { switch (device) {
case InputDevice::kMouse: case InputDevice::kMouse:
return win_->GetButton(static_cast<inputs::MouseButton>(button)); return m_win.GetButton(static_cast<inputs::MouseButton>(button));
case InputDevice::kKeyboard: case InputDevice::kKeyboard:
return win_->GetKey(static_cast<inputs::Key>(button)); return m_win.GetKey(static_cast<inputs::Key>(button));
case InputDevice::kController: case InputDevice::kController:
break; break;
default: break; default: break;
@ -118,9 +118,9 @@ bool InputManager::getDeviceButtonDown(enum InputDevice device, int button) cons
{ {
switch (device) { switch (device) {
case InputDevice::kMouse: case InputDevice::kMouse:
return win_->GetButtonPress(static_cast<enum inputs::MouseButton>(button)); return m_win.GetButtonPress(static_cast<enum inputs::MouseButton>(button));
case InputDevice::kKeyboard: case InputDevice::kKeyboard:
return win_->GetKeyPress(static_cast<enum inputs::Key>(button)); return m_win.GetKeyPress(static_cast<enum inputs::Key>(button));
case InputDevice::kController: case InputDevice::kController:
break; break;
default: break; default: break;
@ -132,9 +132,9 @@ bool InputManager::GetDeviceButtonUp(enum InputDevice device, int button) const
{ {
switch (device) { switch (device) {
case InputDevice::kMouse: case InputDevice::kMouse:
return win_->GetButtonRelease(static_cast<enum inputs::MouseButton>(button)); return m_win.GetButtonRelease(static_cast<enum inputs::MouseButton>(button));
case InputDevice::kKeyboard: case InputDevice::kKeyboard:
return win_->GetKeyRelease(static_cast<enum inputs::Key>(button)); return m_win.GetKeyRelease(static_cast<enum inputs::Key>(button));
case InputDevice::kController: case InputDevice::kController:
break; break;
default: break; default: break;

View File

@ -8,32 +8,30 @@
namespace engine { namespace engine {
CustomBehaviourSystem::CustomBehaviourSystem(Scene* scene) CustomBehaviourSystem::CustomBehaviourSystem(Scene* scene) : System(scene, {typeid(TransformComponent).hash_code(), typeid(CustomComponent).hash_code()})
: System(scene, {typeid(TransformComponent).hash_code(), {
typeid(CustomComponent).hash_code()}) {
// constructor here // constructor here
} }
CustomBehaviourSystem::~CustomBehaviourSystem() {} CustomBehaviourSystem::~CustomBehaviourSystem() {}
void CustomBehaviourSystem::onUpdate(float ts) { void CustomBehaviourSystem::onUpdate(float ts)
{
for (Entity entity : m_entities) { for (Entity entity : m_entities) {
auto c = m_scene->GetComponent<CustomComponent>(entity); auto c = m_scene->GetComponent<CustomComponent>(entity);
assert(c != nullptr); assert(c != nullptr);
bool& entity_initialised = entity_is_initialised_.at(entity); assert(c->impl != nullptr);
bool& entity_initialised = m_entity_is_initialised.at(entity);
if (entity_initialised == false) { if (entity_initialised == false) {
if (c->on_init == nullptr) throw std::runtime_error("CustomComponent::on_init not set! Entity: " + std::to_string(entity)); c->impl->m_entity = entity;
if (c->on_update == nullptr) throw std::runtime_error("CustomComponent::on_update not set! Entity: " + std::to_string(entity)); c->impl->m_scene = m_scene;
c->on_init(); c->impl->init();
entity_initialised = true; entity_initialised = true;
} }
c->on_update(ts); c->impl->update(ts);
} }
} }
void CustomBehaviourSystem::onComponentInsert(Entity entity) void CustomBehaviourSystem::onComponentInsert(Entity entity) { m_entity_is_initialised.emplace(entity, false); }
{
entity_is_initialised_.emplace(entity, false);
}
} // namespace engine } // namespace engine

View File

@ -142,14 +142,20 @@ void PlayGame(GameSettings settings)
cube_ren->mesh = GenCuboidMesh(app.getRenderer()->GetDevice(), 1.0f, 1.0f, 1.0f); cube_ren->mesh = GenCuboidMesh(app.getRenderer()->GetDevice(), 1.0f, 1.0f, 1.0f);
cube_ren->visible = true; cube_ren->visible = true;
auto cubeCustom = main_scene->AddComponent<engine::CustomComponent>(cube); auto cubeCustom = main_scene->AddComponent<engine::CustomComponent>(cube);
cubeCustom->on_init = [] {}; class Spinner : public engine::ComponentCustomImpl {
cubeCustom->on_update = [&main_scene, cube](float dt) { private:
static float yaw = 0.0f; float yaw = 0.0f;
yaw += dt; public:
main_scene->GetRotation(cube) = glm::angleAxis(yaw, glm::vec3{0.0f, 0.0f, 1.0f}); void init() override {
main_scene->GetRotation(cube) *= glm::angleAxis(glm::half_pi<float>(), glm::vec3{ 1.0f, 0.0f, 0.0f });
};
}
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<float>(), glm::vec3{1.0f, 0.0f, 0.0f});
}
};
cubeCustom->impl = std::make_unique<Spinner>();
engine::Entity teapot = engine::loadGLTF(*main_scene, app.getResourcePath("models/teapot.glb"), true); engine::Entity teapot = engine::loadGLTF(*main_scene, app.getResourcePath("models/teapot.glb"), true);
main_scene->GetPosition(teapot).y += 5.0f; main_scene->GetPosition(teapot).y += 5.0f;