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
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)

View File

@ -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"
}
}
]

View File

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

View File

@ -28,13 +28,13 @@ private:
std::vector<T> 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<size_t> required_component_hashes);
System(const System&) = delete;
virtual ~System() {};
virtual ~System() {}
System& operator=(const System&) = delete;

View File

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

View File

@ -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<struct ButtonEntry> button_entries_;
std::vector<struct AxisEntry> axis_entries_;

View File

@ -78,12 +78,12 @@ class Scene {
glm::vec3& GetScale(Entity entity) { return GetTransform(entity)->scale; }
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();
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
size_t signature_position = component_signature_positions_.at(hash);

View File

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

View File

@ -81,13 +81,13 @@ float InputManager::GetDeviceAxis(enum InputDevice device, int axis) const
case InputDevice::kMouse:
switch (static_cast<inputs::MouseAxis>(axis)) {
case inputs::MouseAxis::X:
return static_cast<float>(win_->GetMouseDX());
return static_cast<float>(m_win.GetMouseDX());
case inputs::MouseAxis::Y:
return static_cast<float>(win_->GetMouseDY());
return static_cast<float>(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<inputs::MouseButton>(button));
return m_win.GetButton(static_cast<inputs::MouseButton>(button));
case InputDevice::kKeyboard:
return win_->GetKey(static_cast<inputs::Key>(button));
return m_win.GetKey(static_cast<inputs::Key>(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<enum inputs::MouseButton>(button));
return m_win.GetButtonPress(static_cast<enum inputs::MouseButton>(button));
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:
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<enum inputs::MouseButton>(button));
return m_win.GetButtonRelease(static_cast<enum inputs::MouseButton>(button));
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:
break;
default: break;

View File

@ -8,32 +8,30 @@
namespace engine {
CustomBehaviourSystem::CustomBehaviourSystem(Scene* scene)
: System(scene, {typeid(TransformComponent).hash_code(),
typeid(CustomComponent).hash_code()}) {
CustomBehaviourSystem::CustomBehaviourSystem(Scene* scene) : System(scene, {typeid(TransformComponent).hash_code(), typeid(CustomComponent).hash_code()})
{
// constructor here
}
CustomBehaviourSystem::~CustomBehaviourSystem() {}
void CustomBehaviourSystem::onUpdate(float ts) {
void CustomBehaviourSystem::onUpdate(float ts)
{
for (Entity entity : m_entities) {
auto c = m_scene->GetComponent<CustomComponent>(entity);
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 (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();
c->impl->m_entity = entity;
c->impl->m_scene = m_scene;
c->impl->init();
entity_initialised = true;
}
c->on_update(ts);
c->impl->update(ts);
}
}
void CustomBehaviourSystem::onComponentInsert(Entity entity)
{
entity_is_initialised_.emplace(entity, false);
}
void CustomBehaviourSystem::onComponentInsert(Entity entity) { m_entity_is_initialised.emplace(entity, false); }
} // 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->visible = true;
auto cubeCustom = main_scene->AddComponent<engine::CustomComponent>(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<float>(), 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<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);
main_scene->GetPosition(teapot).y += 5.0f;