feat: engine class impl + IApplication interface

This commit is contained in:
2025-10-05 16:27:58 +02:00
parent 9d56515fe5
commit 431d723afc
10 changed files with 318 additions and 263 deletions

View File

@ -3,11 +3,12 @@
#include <functional>
#include <algorithm>
#include <typeindex>
#include <unordered_map>
#include <vector>
#include <typeindex>
class EventBus {
class EventDispatcher {
using Type = std::type_index;
using RawFn = std::function<void(const void*)>;
@ -24,7 +25,7 @@ public:
};
template<class E, class F>
Handle subscribe(F&& f) {
Handle Subscribe(F&& f) {
auto& vec = subs_[Type(typeid(E))];
Handle h{ Type(typeid(E)), next_id_++ };
// Wrap strongly typed callback into type-erased RawFn
@ -36,7 +37,7 @@ public:
}
// Unsubscribe with handle
void unsubscribe(const Handle& h) {
void Unsubscribe(const Handle& h) {
auto it = subs_.find(h.type);
if (it == subs_.end()) return;
auto& vec = it->second;
@ -47,26 +48,11 @@ public:
// Publish immediately
template<class E>
void publish(const E& e) const {
void Dispatch(const E& e) const {
auto it = subs_.find(Type(typeid(E)));
if (it == subs_.end()) return;
for (auto& slot : it->second) slot.fn(&e);
}
};
// Optional RAII helper
struct ScopedSub {
EventBus* bus{};
EventBus::Handle h{};
ScopedSub() = default;
ScopedSub(EventBus& b, EventBus::Handle hh) : bus(&b), h(hh) {}
ScopedSub(ScopedSub&& o) noexcept { *this = std::move(o); }
ScopedSub& operator=(ScopedSub&& o) noexcept {
if (this != &o) { reset(); bus = o.bus; h = o.h; o.bus = nullptr; }
return *this;
}
~ScopedSub(){ reset(); }
void reset(){ if (bus && h) bus->unsubscribe(h); bus=nullptr; h={}; }
};
#endif // EVENT_H_

View File

@ -1,8 +1,9 @@
#ifndef WINDOW_H_
#define WINDOW_H_
#include <SDL3/SDL.h>
#include <memory>
#include "event.hpp"
#include "event.h"
#define ENGINE_GL_MAJOR_VERSION 4
#define ENGINE_GL_MINOR_VERSION 6
@ -12,35 +13,39 @@
#define DEFAULT_WIDTH 1024
#define DEFAULT_HEIGHT 768
class Window : public EventBus {
class Window : public EventDispatcher {
friend class Engine;
private:
SDL_Window *m_handle;
SDL_GLContext m_context;
int m_width;
int m_height;
bool m_is_open;
public:
Window();
Window(const char* title, int width, int height);
~Window();
struct WindowDeleter {
void operator()(Window* w) const { delete w; };
};
public:
static std::shared_ptr<Window> GetInstance();
Window(Window&& window) noexcept;
Window& operator=(Window&& window) noexcept;
Window(const Window& window) noexcept = delete;
Window& operator=(const Window& window) noexcept = delete;
public:
[[nodiscard]] inline int GetWidth() const { return m_width; }
[[nodiscard]] inline int GetHeight() const { return m_height; }
[[nodiscard]] inline bool IsOpen() const { return m_is_open; }
public:
[[nodiscard]] static inline int GetWidth() { return Window::GetInstance()->m_width; }
[[nodiscard]] static inline int GetHeight() { return Window::GetInstance()->m_height; }
private:
void ProcessEvents();
public:
void SwapBuffers() const;
public:
void Destroy() const;
private:
static std::shared_ptr<Window> s_instance;
SDL_Window *m_handle;
SDL_GLContext m_context;
int m_width;
int m_height;
};
#endif //WINDOW_H_