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