PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
event_routing.h
1#pragma once
2
3#include "pixelbullet/application/event.h"
4#include "pixelbullet/application/layer.h"
5
6#include <array>
7#include <memory>
8#include <utility>
9#include <vector>
10
11namespace pixelbullet::application_internal
12{
14{
15 bool block_events = true;
16 bool want_capture_mouse = false;
17 bool want_capture_keyboard = false;
18};
19
20constexpr EventResult MergeEventResults(const EventResult current, const EventResult next) noexcept
21{
22 if (current == EventResult::Consumed || next == EventResult::Consumed)
23 {
24 return EventResult::Consumed;
25 }
26
27 if (current == EventResult::Handled || next == EventResult::Handled)
28 {
29 return EventResult::Handled;
30 }
31
32 return EventResult::Ignored;
33}
34
35constexpr bool IsConsumed(const EventResult result) noexcept
36{
37 return result == EventResult::Consumed;
38}
39
40inline EventResult GetImGuiCaptureResult(const Event& event, const ImGuiCaptureState& capture_state) noexcept
41{
42 if (!capture_state.block_events)
43 {
44 return EventResult::Ignored;
45 }
46
47 if (event.IsInCategory(EventCategoryMouse) && capture_state.want_capture_mouse)
48 {
49 return EventResult::Consumed;
50 }
51
52 if (event.IsInCategory(EventCategoryKeyboard) && capture_state.want_capture_keyboard)
53 {
54 return EventResult::Consumed;
55 }
56
57 return EventResult::Ignored;
58}
59
60template <typename BuiltInHandler>
61EventResult RouteEvent(Event& event, const std::vector<std::unique_ptr<Layer>>& layers, BuiltInHandler&& built_in_handler)
62{
63 EventResult result = std::forward<BuiltInHandler>(built_in_handler)(event);
64 if (IsConsumed(result))
65 {
66 return result;
67 }
68
69 constexpr std::array<EventPhase, 2> k_event_phases = { EventPhase::Early, EventPhase::Normal };
70 for (const EventPhase phase : k_event_phases)
71 {
72 for (auto it = layers.rbegin(); it != layers.rend(); ++it)
73 {
74 if ((*it)->GetEventPhase() != phase)
75 {
76 continue;
77 }
78
79 result = MergeEventResults(result, (*it)->OnEvent(event));
80 if (IsConsumed(result))
81 {
82 return result;
83 }
84 }
85 }
86
87 return result;
88}
89} // namespace pixelbullet::application_internal