PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
event.h
1#pragma once
2
3#include "pixelbullet/core/bits.h"
4
5#include <concepts>
6#include <cstdint>
7#include <functional>
8#include <ostream>
9#include <string>
10#include <type_traits>
11#include <utility>
12
13namespace pixelbullet::core
14{
15enum class EventType
16{
17 None = 0,
18 WindowClose,
19 WindowResize,
20 WindowFocus,
21 WindowLostFocus,
22 WindowMoved,
23 AppTick,
24 AppUpdate,
25 AppRender,
26 KeyPressed,
27 KeyReleased,
28 KeyTyped,
29 MouseButtonPressed,
30 MouseButtonReleased,
31 MouseMoved,
32 MouseScrolled
33};
34
35enum class EventCategory : std::uint32_t
36{
37 None = 0,
38 Application = bit(0),
39 Window = bit(1),
40 Input = bit(2),
41 Keyboard = bit(3),
42 Mouse = bit(4),
43 MouseButton = bit(5)
44};
45
46enum class EventResult
47{
48 Ignored,
49 Handled,
50 Consumed
51};
52
53[[nodiscard]] constexpr EventCategory operator|(const EventCategory lhs, const EventCategory rhs) noexcept
54{
55 using Underlying = std::underlying_type_t<EventCategory>;
56 return static_cast<EventCategory>(static_cast<Underlying>(lhs) | static_cast<Underlying>(rhs));
57}
58
59[[nodiscard]] constexpr EventCategory operator&(const EventCategory lhs, const EventCategory rhs) noexcept
60{
61 using Underlying = std::underlying_type_t<EventCategory>;
62 return static_cast<EventCategory>(static_cast<Underlying>(lhs) & static_cast<Underlying>(rhs));
63}
64
65constexpr EventCategory& operator|=(EventCategory& lhs, const EventCategory rhs) noexcept
66{
67 lhs = lhs | rhs;
68 return lhs;
69}
70
71[[nodiscard]] constexpr EventResult merge_event_results(const EventResult current, const EventResult next) noexcept
72{
73 if (current == EventResult::Consumed || next == EventResult::Consumed)
74 {
75 return EventResult::Consumed;
76 }
77
78 if (current == EventResult::Handled || next == EventResult::Handled)
79 {
80 return EventResult::Handled;
81 }
82
83 return EventResult::Ignored;
84}
85
86#define PB_EVENT_TYPE(event_type) \
87 [[nodiscard]] static constexpr pixelbullet::core::EventType static_type() noexcept \
88 { \
89 return pixelbullet::core::EventType::event_type; \
90 } \
91 [[nodiscard]] pixelbullet::core::EventType type() const override \
92 { \
93 return static_type(); \
94 } \
95 [[nodiscard]] const char* name() const override \
96 { \
97 return #event_type; \
98 }
99
100#define PB_EVENT_CATEGORIES(event_categories) \
101 [[nodiscard]] pixelbullet::core::EventCategory categories() const override \
102 { \
103 return event_categories; \
104 }
105
106class Event
107{
108public:
109 virtual ~Event() = default;
110
111 [[nodiscard]] virtual EventType type() const = 0;
112 [[nodiscard]] virtual const char* name() const = 0;
113 [[nodiscard]] virtual EventCategory categories() const = 0;
114 [[nodiscard]] virtual std::string to_string() const
115 {
116 return name();
117 }
118
119 [[nodiscard]] bool is_in_category(EventCategory category) const;
120
121 [[nodiscard]] EventResult result() const noexcept
122 {
123 return result_;
124 }
125
126 [[nodiscard]] bool handled() const noexcept
127 {
128 return result_ == EventResult::Handled || result_ == EventResult::Consumed;
129 }
130
131 [[nodiscard]] bool consumed() const noexcept
132 {
133 return result_ == EventResult::Consumed;
134 }
135
136 void merge_result(const EventResult result) noexcept
137 {
138 result_ = merge_event_results(result_, result);
139 }
140
141 void reset_result() noexcept
142 {
143 result_ = EventResult::Ignored;
144 }
145
146private:
147 EventResult result_ = EventResult::Ignored;
148};
149
150class EventDispatcher
151{
152public:
153 explicit EventDispatcher(Event& event);
154
155 template <typename T, typename F>
156 requires std::same_as<std::invoke_result_t<F, T&>, EventResult>
157 [[nodiscard]] EventResult dispatch(F&& func)
158 {
159 if (event_.type() == T::static_type())
160 {
161 const EventResult result = std::invoke(std::forward<F>(func), static_cast<T&>(event_));
162 event_.merge_result(result);
163 return result;
164 }
165 return EventResult::Ignored;
166 }
167
168private:
169 Event& event_;
170};
171
172std::ostream& operator<<(std::ostream& os, const Event& e);
173
174} // namespace pixelbullet::core
Definition event.h:107