aboutsummaryrefslogtreecommitdiff
path: root/mwe/events/include
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-11-04 08:28:18 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-11-04 08:28:18 +0100
commit06f65659fc6ffde7cabd2135040cbfbf089e5a24 (patch)
treee3570bea52b87b6919550ee81d17927ccbc11cc5 /mwe/events/include
parent128969619a22dfc17a9ea35335c0d21c6ad0c954 (diff)
parent6aa8fdd04728b6a499f526de727514ae3d0490b4 (diff)
merge `origin/master` into `master`
Diffstat (limited to 'mwe/events/include')
-rw-r--r--mwe/events/include/customTypes.h38
-rw-r--r--mwe/events/include/event.h103
-rw-r--r--mwe/events/include/eventHandler.h46
-rw-r--r--mwe/events/include/eventManager.h66
-rw-r--r--mwe/events/include/keyCodes.h143
-rw-r--r--mwe/events/include/loopManager.h29
-rw-r--r--mwe/events/include/timer.h31
-rw-r--r--mwe/events/include/userevent.h0
-rw-r--r--mwe/events/include/window.h19
9 files changed, 475 insertions, 0 deletions
diff --git a/mwe/events/include/customTypes.h b/mwe/events/include/customTypes.h
new file mode 100644
index 0000000..a5d8dc9
--- /dev/null
+++ b/mwe/events/include/customTypes.h
@@ -0,0 +1,38 @@
+#pragma once
+#include <cmath>
+struct Vector2 {
+ float x; // X component of the vector
+ float y; // Y component of the vector
+
+ // Vector subtraction
+ Vector2 operator-(const Vector2 & other) const {
+ return {x - other.x, y - other.y};
+ }
+
+ // Vector addition
+ Vector2 operator+(const Vector2 & other) const {
+ return {x + other.x, y + other.y};
+ }
+
+ // Scalar multiplication
+ Vector2 operator*(float scalar) const { return {x * scalar, y * scalar}; }
+
+ // Normalize the vector
+ Vector2 normalize() const {
+ float length = std::sqrt(x * x + y * y);
+ if (length == 0) return {0, 0}; // Prevent division by zero
+ return {x / length, y / length};
+ }
+};
+struct Collision {
+ int objectIdA; // ID of the first object
+ int objectIdB; // ID of the second object
+ Vector2 contactPoint; // Point of contact
+ Vector2 contactNormal; // Normal vector at the contact point
+
+ // Constructor to initialize a Collision
+ Collision(int idA, int idB, const Vector2 & point, const Vector2 & normal,
+ float depth)
+ : objectIdA(idA), objectIdB(idB), contactPoint(point),
+ contactNormal(normal) {}
+};
diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h
new file mode 100644
index 0000000..730ee4b
--- /dev/null
+++ b/mwe/events/include/event.h
@@ -0,0 +1,103 @@
+#pragma once
+#include "customTypes.h"
+#include "keyCodes.h"
+#include <cstdint>
+#include <iostream>
+#include <string>
+#include <unordered_map>
+#include <variant>
+
+class UUIDGenerator {
+public:
+ static std::uint32_t getUniqueID() {
+ static std::uint32_t id = 0;
+ return ++id;
+ }
+};
+#define REGISTER_EVENT_TYPE(ClassName) \
+\
+public: \
+ static std::uint32_t getStaticEventType() { \
+ static std::uint32_t typeID = UUIDGenerator::getUniqueID(); \
+ return typeID; \
+ } \
+ virtual std::uint32_t getEventType() const override { \
+ return getStaticEventType(); \
+ }
+class Event {
+public:
+ Event(std::string eventType);
+ virtual ~Event() = default;
+ virtual std::uint32_t getEventType() const = 0;
+ virtual std::string toString() const;
+ void addArgument(const std::string & key,
+ const std::variant<int, std::string, float> & value);
+
+ std::variant<int, std::string, float>
+ getArgument(const std::string & key) const;
+
+ std::string getType() const;
+ bool getHandled() const;
+ void markHandled();
+
+private:
+ std::unordered_map<std::string, std::variant<int, std::string, float>>
+ eventData;
+ bool isHandled = false;
+};
+
+// KeyPressedEvent class
+class KeyPressedEvent : public Event {
+public:
+ KeyPressedEvent(int keyCode);
+
+ REGISTER_EVENT_TYPE("KeyPressedEvent");
+
+ Keycode getKeyCode() const;
+ int getRepeatCount() const;
+
+private:
+ Keycode keycode;
+
+public:
+ Keycode key = 0;
+ int repeatCount = 0;
+};
+
+// KeyReleasedEvent class
+class KeyReleasedEvent : public Event {
+public:
+ KeyReleasedEvent(int keyCode);
+
+ REGISTER_EVENT_TYPE(KeyReleasedEvent);
+
+ Keycode getKeyCode() const;
+
+private:
+ Keycode key = 0;
+};
+
+// MousePressedEvent class
+class MousePressedEvent : public Event {
+public:
+ MousePressedEvent(int mouseX, int mouseY);
+
+ REGISTER_EVENT_TYPE(MousePressedEvent)
+
+ std::pair<int, int> getMousePosition() const;
+
+private:
+ int mouseX = 0;
+ int mouseY = 0;
+};
+class CollisionEvent : public Event {
+public:
+ CollisionEvent(Collision);
+
+ REGISTER_EVENT_TYPE(CollisionEvent)
+
+ Collision getCollisionData() const;
+
+private:
+ Collision collisionData;
+};
diff --git a/mwe/events/include/eventHandler.h b/mwe/events/include/eventHandler.h
new file mode 100644
index 0000000..7414801
--- /dev/null
+++ b/mwe/events/include/eventHandler.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "event.h"
+
+#include <functional>
+#include <iostream>
+template <typename EventType>
+using EventHandler = std::function<void(const EventType & e)>;
+
+class IEventHandlerWrapper {
+public:
+ virtual ~IEventHandlerWrapper() = default;
+
+ void exec(const Event & e);
+
+ virtual std::string getType() const = 0;
+ virtual bool isDestroyOnSuccess() const = 0;
+
+private:
+ virtual void call(const Event & e) = 0;
+};
+
+template <typename EventType>
+class EventHandlerWrapper : public IEventHandlerWrapper {
+public:
+ explicit EventHandlerWrapper(const EventHandler<EventType> & handler,
+ const bool destroyOnSuccess = false)
+ : m_handler(handler), m_handlerType(m_handler.target_type().name()),
+ m_destroyOnSuccess(destroyOnSuccess) {
+ // std::cout << m_handlerType << std::endl;
+ }
+
+private:
+ void call(const Event & e) override {
+ if (e.getEventType() == EventType::getStaticEventType()) {
+ m_handler(static_cast<const EventType &>(e));
+ }
+ }
+
+ std::string getType() const override { return m_handlerType; }
+ bool isDestroyOnSuccess() const { return m_destroyOnSuccess; }
+
+ EventHandler<EventType> m_handler;
+ const std::string m_handlerType;
+ bool m_destroyOnSuccess{false};
+};
diff --git a/mwe/events/include/eventManager.h b/mwe/events/include/eventManager.h
new file mode 100644
index 0000000..508a5e2
--- /dev/null
+++ b/mwe/events/include/eventManager.h
@@ -0,0 +1,66 @@
+#pragma once
+#include "event.h"
+#include "eventHandler.h"
+#include "keyCodes.h"
+#include <memory>
+#include <unordered_map>
+#include <vector>
+// using EventType = std::uint32_t;
+// using EventId = std::uint64_t;
+
+class EventManager {
+public:
+ EventManager(const EventManager &) = delete;
+ const EventManager & operator=(const EventManager &) = delete;
+ static EventManager & getInstance() {
+ static EventManager instance;
+ return instance;
+ }
+
+ void shutdown();
+ void subscribe(int eventType,
+ std::unique_ptr<IEventHandlerWrapper> && handler,
+ int eventId);
+ void unsubscribe(int eventType, const std::string & handlerName,
+ int eventId);
+ void triggerEvent(const Event & event_, int eventId);
+ void queueEvent(std::unique_ptr<Event> && event_, int eventId);
+ void dispatchEvents();
+
+private:
+ EventManager() = default;
+ std::vector<std::pair<std::unique_ptr<Event>, int>> eventsQueue;
+ std::unordered_map<int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>
+ subscribers;
+ std::unordered_map<
+ int, std::unordered_map<
+ int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>
+ subscribersByEventId;
+};
+
+template <typename EventType>
+inline void subscribe(const EventHandler<EventType> & callback, int eventId = 0,
+ const bool unsubscribeOnSuccess = false) {
+ std::unique_ptr<IEventHandlerWrapper> handler
+ = std::make_unique<EventHandlerWrapper<EventType>>(
+ callback, unsubscribeOnSuccess);
+ EventManager::getInstance().subscribe(EventType::getStaticEventType(),
+ std::move(handler), eventId);
+}
+
+template <typename EventType>
+inline void unsubscribe(const EventHandler<EventType> & callback,
+ int eventId = 0) {
+ const std::string handlerName = callback.target_type().name();
+ EventManager::getInstance().unsubscribe(EventType::getStaticEventType(),
+ handlerName, eventId);
+}
+
+inline void triggerEvent(const Event & triggeredEvent, int eventId = 0) {
+ EventManager::getInstance().triggerEvent(triggeredEvent, eventId);
+}
+
+inline void queueEvent(std::unique_ptr<Event> && queuedEvent, int eventId = 0) {
+ EventManager::getInstance().queueEvent(
+ std::forward<std::unique_ptr<Event>>(queuedEvent), eventId);
+}
diff --git a/mwe/events/include/keyCodes.h b/mwe/events/include/keyCodes.h
new file mode 100644
index 0000000..0879efc
--- /dev/null
+++ b/mwe/events/include/keyCodes.h
@@ -0,0 +1,143 @@
+#pragma once
+#include <SDL2/SDL.h>
+#include <cstdint>
+#include <unordered_map>
+using Keycode = uint16_t;
+enum : Keycode {
+ // From glfw3.h
+ Space = 32,
+ Apostrophe = 39, /* ' */
+ Comma = 44, /* , */
+ Minus = 45, /* - */
+ Period = 46, /* . */
+ Slash = 47, /* / */
+
+ D0 = 48, /* 0 */
+ D1 = 49, /* 1 */
+ D2 = 50, /* 2 */
+ D3 = 51, /* 3 */
+ D4 = 52, /* 4 */
+ D5 = 53, /* 5 */
+ D6 = 54, /* 6 */
+ D7 = 55, /* 7 */
+ D8 = 56, /* 8 */
+ D9 = 57, /* 9 */
+
+ Semicolon = 59, /* ; */
+ Equal = 61, /* = */
+
+ A = 65,
+ B = 66,
+ C = 67,
+ D = 68,
+ E = 69,
+ F = 70,
+ G = 71,
+ H = 72,
+ I = 73,
+ J = 74,
+ K = 75,
+ L = 76,
+ M = 77,
+ N = 78,
+ O = 79,
+ P = 80,
+ Q = 81,
+ R = 82,
+ S = 83,
+ T = 84,
+ U = 85,
+ V = 86,
+ W = 87,
+ X = 88,
+ Y = 89,
+ Z = 90,
+
+ LeftBracket = 91, /* [ */
+ Backslash = 92, /* \ */
+ RightBracket = 93, /* ] */
+ GraveAccent = 96, /* ` */
+
+ World1 = 161, /* non-US #1 */
+ World2 = 162, /* non-US #2 */
+
+ /* Function keys */
+ Escape = 256,
+ Enter = 257,
+ Tab = 258,
+ Backspace = 259,
+ Insert = 260,
+ Delete = 261,
+ Right = 262,
+ Left = 263,
+ Down = 264,
+ Up = 265,
+ PageUp = 266,
+ PageDown = 267,
+ Home = 268,
+ End = 269,
+ CapsLock = 280,
+ ScrollLock = 281,
+ NumLock = 282,
+ PrintScreen = 283,
+ Pause = 284,
+ F1 = 290,
+ F2 = 291,
+ F3 = 292,
+ F4 = 293,
+ F5 = 294,
+ F6 = 295,
+ F7 = 296,
+ F8 = 297,
+ F9 = 298,
+ F10 = 299,
+ F11 = 300,
+ F12 = 301,
+ F13 = 302,
+ F14 = 303,
+ F15 = 304,
+ F16 = 305,
+ F17 = 306,
+ F18 = 307,
+ F19 = 308,
+ F20 = 309,
+ F21 = 310,
+ F22 = 311,
+ F23 = 312,
+ F24 = 313,
+ F25 = 314,
+
+ /* Keypad */
+ KP0 = 320,
+ KP1 = 321,
+ KP2 = 322,
+ KP3 = 323,
+ KP4 = 324,
+ KP5 = 325,
+ KP6 = 326,
+ KP7 = 327,
+ KP8 = 328,
+ KP9 = 329,
+ KPDecimal = 330,
+ KPDivide = 331,
+ KPMultiply = 332,
+ KPSubtract = 333,
+ KPAdd = 334,
+ KPEnter = 335,
+ KPEqual = 336,
+
+ LeftShift = 340,
+ LeftControl = 341,
+ LeftAlt = 342,
+ LeftSuper = 343,
+ RightShift = 344,
+ RightControl = 345,
+ RightAlt = 346,
+ RightSuper = 347,
+ Menu = 348
+};
+// Define the mapping
+extern const std::unordered_map<SDL_Keycode, Keycode> sdlToCustom;
+
+// Function to map SDL_Keycode to custom Keycode
+Keycode getCustomKey(SDL_Keycode sdlKey);
diff --git a/mwe/events/include/loopManager.h b/mwe/events/include/loopManager.h
new file mode 100644
index 0000000..baffb94
--- /dev/null
+++ b/mwe/events/include/loopManager.h
@@ -0,0 +1,29 @@
+#pragma once
+#include "timer.h"
+#include "window.h"
+#include <SDL2/SDL.h>
+//#include "combinedEvent.h"
+#include "eventHandler.h"
+#include "eventManager.h"
+#include "loopManager.h"
+class LoopManager {
+public:
+ LoopManager();
+ void setup();
+ void loop();
+ void setRunning(bool running);
+
+private:
+ void processInput();
+ void update();
+ void lateUpdate();
+ void fixedUpdate();
+ void render();
+ bool gameRunning = false;
+ WindowManager window;
+ int timeScale = 1;
+ float accumulator = 0.0;
+ double currentTime;
+ double t = 0.0;
+ double dt = 0.01;
+};
diff --git a/mwe/events/include/timer.h b/mwe/events/include/timer.h
new file mode 100644
index 0000000..22383b2
--- /dev/null
+++ b/mwe/events/include/timer.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <SDL2/SDL.h>
+
+class LoopTimer {
+public:
+ static LoopTimer & getInstance();
+ void start();
+ void update();
+ double getDeltaTime() const;
+ int getCurrentTime() const;
+ void advanceFixedUpdate();
+ double getFixedDeltaTime() const;
+ void setFPS(int FPS);
+ int getFPS() const;
+ void enforceFrameRate();
+ double getLag() const;
+
+private:
+ LoopTimer();
+ int FPS = 50;
+ double gameScale = 1;
+ double maximumDeltaTime = 0.25;
+ double deltaTime;
+ double frameTargetTime = FPS / 1000;
+ double fixedDeltaTime = 0.01;
+ double elapsedTime;
+ double elapsedFixedTime;
+ double time;
+ uint64_t lastFrameTime;
+};
diff --git a/mwe/events/include/userevent.h b/mwe/events/include/userevent.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mwe/events/include/userevent.h
diff --git a/mwe/events/include/window.h b/mwe/events/include/window.h
new file mode 100644
index 0000000..9020b1a
--- /dev/null
+++ b/mwe/events/include/window.h
@@ -0,0 +1,19 @@
+#pragma once
+#include <SDL2/SDL.h>
+#include <iostream>
+#include <vector>
+class WindowManager {
+public:
+ WindowManager();
+ virtual ~WindowManager();
+ bool initWindow();
+ void destroyWindow();
+
+ SDL_Renderer * getRenderer();
+
+private:
+ const int SCREEN_WIDTH = 800;
+ const int SCREEN_HEIGHT = 600;
+ SDL_Window * window = NULL;
+ SDL_Renderer * renderer = NULL;
+};