aboutsummaryrefslogtreecommitdiff
path: root/src/Core/Event.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Core/Event.h')
-rw-r--r--src/Core/Event.h338
1 files changed, 338 insertions, 0 deletions
diff --git a/src/Core/Event.h b/src/Core/Event.h
new file mode 100644
index 0000000..32cdde4
--- /dev/null
+++ b/src/Core/Event.h
@@ -0,0 +1,338 @@
+#pragma once
+
+#include <functional>
+#include <unordered_map>
+#include <vector>
+#include <string>
+#include <sstream>
+
+namespace Donut
+{
+ class Event;
+ class EventDispatcher;
+
+ enum class EventType
+ {
+ None = 0,
+
+ WindowClose,
+ WindowResize,
+ WindowFocus,
+ WindowLostFocus,
+ WindowMoved,
+
+ KeyPressed,
+ KeyReleased,
+ KeyTyped,
+
+ MouseButtonPressed,
+ MouseButtonReleased,
+ MouseMoved,
+ MouseScrolled
+ };
+
+ enum EventCategory
+ {
+ None = 0,
+ EventCategoryApplication = 1 << 0,
+ EventCategoryInput = 1 << 1,
+ EventCategoryKeyboard = 1 << 2,
+ EventCategoryMouse = 1 << 3,
+ EventCategoryMouseButton = 1 << 4
+ };
+
+ class Event
+ {
+ public:
+ virtual ~Event() = default;
+
+ bool Handled = false;
+
+ virtual EventType GetEventType() const = 0;
+ virtual const char* GetName() const = 0;
+ virtual int GetCategoryFlags() const = 0;
+ virtual std::string ToString() const { return GetName(); }
+
+ bool IsInCategory(EventCategory category) { return GetCategoryFlags() & category; }
+ };
+
+ #define EVENT_CLASS_TYPE(type) \
+ static EventType GetStaticType() { return EventType::type; } \
+ virtual EventType GetEventType() const override { return GetStaticType(); } \
+ virtual const char* GetName() const override { return #type; }
+
+ #define APPLICATION_EVENT_CLASS_TYPE(type) \
+ EVENT_CLASS_TYPE(type) \
+ virtual int GetCategoryFlags() const override { return EventCategoryApplication; }
+
+ #define MOUSE_EVENT_CLASS_TYPE(type) \
+ EVENT_CLASS_TYPE(type) \
+ virtual int GetCategoryFlags() const override { return EventCategoryMouse | \
+ EventCategoryInput; }
+
+ #define MOUSE_BUTTON_EVENT_CLASS_TYPE(type) \
+ EVENT_CLASS_TYPE(type) \
+ virtual int GetCategoryFlags() const override { return EventCategoryMouseButton | \
+ EventCategoryMouse | \
+ EventCategoryInput; }
+
+ #define KEYBOARD_EVENT_CLASS_TYPE(type) \
+ EVENT_CLASS_TYPE(type) \
+ virtual int GetCategoryFlags() const override { return EventCategoryKeyboard | \
+ EventCategoryInput; }
+
+ class WindowResizeEvent : public Event
+ {
+ public:
+ WindowResizeEvent(unsigned int width, unsigned int height)
+ : m_Width(width), m_Height(height) { }
+
+ unsigned int GetWidth() const { return m_Width; }
+ unsigned int GetHeight() const { return m_Height; }
+
+ std::string ToString() const override
+ {
+ return "WindowResizeEvent: " + std::to_string(m_Width) + ", " + std::to_string(m_Height);
+ }
+
+ APPLICATION_EVENT_CLASS_TYPE(WindowResize)
+
+ private:
+ unsigned int m_Width, m_Height;
+ };
+
+ class WindowCloseEvent : public Event
+ {
+ public:
+ WindowCloseEvent() = default;
+ APPLICATION_EVENT_CLASS_TYPE(WindowClose)
+ };
+
+ class WindowFocusEvent : public Event
+ {
+ public:
+ WindowFocusEvent() = default;
+ APPLICATION_EVENT_CLASS_TYPE(WindowFocus)
+ };
+
+ class WindowLostFocusEvent : public Event
+ {
+ public:
+ WindowLostFocusEvent() = default;
+ APPLICATION_EVENT_CLASS_TYPE(WindowLostFocus)
+ };
+
+ class WindowMovedEvent : public Event
+ {
+ public:
+ WindowMovedEvent(int x, int y)
+ : m_X(x), m_Y(y) { }
+
+ int GetX() const { return m_X; }
+ int GetY() const { return m_Y; }
+
+ std::string ToString() const override
+ {
+ return "WindowMovedEvent: " + std::to_string(m_X) + ", " + std::to_string(m_Y);
+ }
+
+ APPLICATION_EVENT_CLASS_TYPE(WindowMoved)
+
+ private:
+ int m_X, m_Y;
+ };
+
+ class KeyEvent : public Event
+ {
+ public:
+ int GetKeyCode() const { return m_KeyCode; }
+ virtual int GetCategoryFlags() const override { return EventCategoryKeyboard |
+ EventCategoryInput; }
+
+ protected:
+ KeyEvent(int keycode) : m_KeyCode(keycode) { }
+ int m_KeyCode;
+ };
+
+ class KeyPressedEvent : public KeyEvent
+ {
+ public:
+ KeyPressedEvent(int keycode, bool isRepeat = false)
+ : KeyEvent(keycode), m_IsRepeat(isRepeat) { }
+
+ bool IsRepeat() const { return m_IsRepeat; }
+
+ std::string ToString() const override
+ {
+ return "KeyPressedEvent: " + std::to_string(m_KeyCode) +
+ " (repeat = " + std::to_string(m_IsRepeat) + ")";
+ }
+
+ KEYBOARD_EVENT_CLASS_TYPE(KeyPressed)
+
+ private:
+ bool m_IsRepeat;
+ };
+
+ class KeyReleasedEvent : public KeyEvent
+ {
+ public:
+ KeyReleasedEvent(int keycode) : KeyEvent(keycode) { }
+
+ std::string ToString() const override
+ {
+ return "KeyReleasedEvent: " + std::to_string(m_KeyCode);
+ }
+
+ KEYBOARD_EVENT_CLASS_TYPE(KeyReleased)
+ };
+
+ class KeyTypedEvent : public KeyEvent
+ {
+ public:
+ KeyTypedEvent(int keycode) : KeyEvent(keycode) { }
+
+ std::string ToString() const override
+ {
+ return "KeyTypedEvent: " + std::to_string(m_KeyCode);
+ }
+
+ KEYBOARD_EVENT_CLASS_TYPE(KeyTyped)
+ };
+
+ class MouseMovedEvent : public Event
+ {
+ public:
+ MouseMovedEvent(float x, float y)
+ : m_MouseX(x), m_MouseY(y) { }
+
+ float GetX() const { return m_MouseX; }
+ float GetY() const { return m_MouseY; }
+
+ std::string ToString() const override
+ {
+ return "MouseMovedEvent: " + std::to_string(m_MouseX) + ", " + std::to_string(m_MouseY);
+ }
+
+ MOUSE_EVENT_CLASS_TYPE(MouseMoved)
+
+ private:
+ float m_MouseX, m_MouseY;
+ };
+
+ class MouseScrolledEvent : public Event
+ {
+ public:
+ MouseScrolledEvent(float xOffset, float yOffset)
+ : m_XOffset(xOffset), m_YOffset(yOffset) { }
+
+ float GetXOffset() const { return m_XOffset; }
+ float GetYOffset() const { return m_YOffset; }
+
+ std::string ToString() const override
+ {
+ return "MouseScrolledEvent: " + std::to_string(m_XOffset) +
+ ", " + std::to_string(m_YOffset);
+ }
+
+ MOUSE_EVENT_CLASS_TYPE(MouseScrolled)
+
+ private:
+ float m_XOffset, m_YOffset;
+ };
+
+ class MouseButtonEvent : public Event
+ {
+ public:
+ int GetMouseButton() const { return m_Button; }
+ virtual int GetCategoryFlags() const override { return EventCategoryMouseButton |
+ EventCategoryMouse |
+ EventCategoryInput; }
+
+ protected:
+ MouseButtonEvent(int button) : m_Button(button) { }
+ int m_Button;
+ };
+
+ class MouseButtonPressedEvent : public MouseButtonEvent
+ {
+ public:
+ MouseButtonPressedEvent(int button) : MouseButtonEvent(button) { }
+
+ std::string ToString() const override
+ {
+ return "MouseButtonPressedEvent: " + std::to_string(m_Button);
+ }
+
+ MOUSE_BUTTON_EVENT_CLASS_TYPE(MouseButtonPressed)
+ };
+
+ class MouseButtonReleasedEvent : public MouseButtonEvent
+ {
+ public:
+ MouseButtonReleasedEvent(int button) : MouseButtonEvent(button) { }
+
+ std::string ToString() const override
+ {
+ return "MouseButtonReleasedEvent: " + std::to_string(m_Button);
+ }
+
+ MOUSE_BUTTON_EVENT_CLASS_TYPE(MouseButtonReleased)
+ };
+
+ class EventDispatcher
+ {
+ public:
+ EventDispatcher(Event& event) : m_Event(event) { }
+
+ template<typename T, typename F>
+ bool Dispatch(const F& func)
+ {
+ if (m_Event.GetEventType() == T::GetStaticType())
+ {
+ m_Event.Handled = func(static_cast<T&>(m_Event));
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ Event& m_Event;
+ };
+
+ class EventHandler
+ {
+ public:
+ using EventCallbackFn = std::function<void(Event&)>;
+
+ EventHandler() = default;
+ ~EventHandler() = default;
+
+ void SetEventCallback(const EventCallbackFn& callback) { m_EventCallback = callback; }
+
+ void OnEvent(Event& event)
+ {
+ if (m_EventCallback)
+ m_EventCallback(event);
+ }
+
+ template<typename T>
+ void BindEvent(const std::function<void(T&)>& callback)
+ {
+ m_EventCallback = [callback](Event& event)
+ {
+ if (event.GetEventType() == T::GetStaticType())
+ callback(static_cast<T&>(event));
+ };
+ }
+
+ private:
+ EventCallbackFn m_EventCallback;
+ };
+
+ #undef EVENT_CLASS_TYPE
+ #undef APPLICATION_EVENT_CLASS_TYPE
+ #undef MOUSE_EVENT_CLASS_TYPE
+ #undef MOUSE_BUTTON_EVENT_CLASS_TYPE
+ #undef KEYBOARD_EVENT_CLASS_TYPE
+} \ No newline at end of file