diff --git a/src/gui/core/event/dispatcher.cpp b/src/gui/core/event/dispatcher.cpp index d2768f27272..dc472983697 100644 --- a/src/gui/core/event/dispatcher.cpp +++ b/src/gui/core/event/dispatcher.cpp @@ -70,27 +70,27 @@ bool dispatcher::fire(const ui_event event, widget& target) { assert(is_in_category(event, event_category::general)); switch(event) { - case LEFT_BUTTON_DOUBLE_CLICK: - return fire_event_double_click(this, &target); + case LEFT_BUTTON_DOUBLE_CLICK: + return fire_event_double_click(this, &target); - case MIDDLE_BUTTON_DOUBLE_CLICK: - return fire_event_double_click(this, &target); + case MIDDLE_BUTTON_DOUBLE_CLICK: + return fire_event_double_click(this, &target); - case RIGHT_BUTTON_DOUBLE_CLICK: - return fire_event_double_click(this, &target); + case RIGHT_BUTTON_DOUBLE_CLICK: + return fire_event_double_click(this, &target); - default: - return fire_event(event, this, &target); + default: + return fire_event(event, this, &target); } } bool dispatcher::fire(const ui_event event, widget& target, const point& coordinate) { assert(is_in_category(event, event_category::mouse)); - return fire_event(event, this, &target, coordinate); + return fire_event(event, this, &target, coordinate); } bool dispatcher::fire(const ui_event event, @@ -100,43 +100,43 @@ bool dispatcher::fire(const ui_event event, const std::string& unicode) { assert(is_in_category(event, event_category::keyboard)); - return fire_event(event, this, &target, key, modifier, unicode); + return fire_event(event, this, &target, key, modifier, unicode); } bool dispatcher::fire(const ui_event event, widget& target, const point& pos, const point& distance) { assert(is_in_category(event, event_category::touch_motion)); - return fire_event(event, this, &target, pos, distance); + return fire_event(event, this, &target, pos, distance); } bool dispatcher::fire(const ui_event event, widget& target, const point& center, float dTheta, float dDist, uint8_t numFingers) { assert(is_in_category(event, event_category::touch_gesture)); - return fire_event(event, this, &target, center, dTheta, dDist, numFingers); + return fire_event(event, this, &target, center, dTheta, dDist, numFingers); } bool dispatcher::fire(const ui_event event, widget& target, const SDL_Event& sdlevent) { assert(is_in_category(event, event_category::raw_event)); - return fire_event(event, this, &target, sdlevent); + return fire_event(event, this, &target, sdlevent); } bool dispatcher::fire(const ui_event event, widget& target, const std::string& text, int32_t start, int32_t len) { assert(is_in_category(event, event_category::text_input)); - return fire_event(event, this, &target, text, start, len); + return fire_event(event, this, &target, text, start, len); } bool dispatcher::fire(const ui_event event, widget& target, void*) { assert(is_in_category(event, event_category::notification)); - return fire_event(event, this, &target, nullptr); + return fire_event(event, this, &target, nullptr); } bool dispatcher::fire(const ui_event event, widget& target, const message& msg) { assert(is_in_category(event, event_category::message)); - return fire_event(event, this, &target, msg); + return fire_event(event, this, &target, msg); } void dispatcher::register_hotkey(const hotkey::HOTKEY_COMMAND id, const hotkey_function& function) diff --git a/src/gui/core/event/dispatcher_private.hpp b/src/gui/core/event/dispatcher_private.hpp index 61ca4596083..e76e7af0435 100644 --- a/src/gui/core/event/dispatcher_private.hpp +++ b/src/gui/core/event/dispatcher_private.hpp @@ -28,46 +28,19 @@ namespace gui2::event { struct dispatcher_implementation { -#define FUNCTION_QUEUE_CHECK(TYPE) \ - else if constexpr(std::is_same_v) { \ - return dispatcher.signal_##TYPE##_queue_.queue[event]; \ - } - /** - * Returns the appropriate signal queue for an event by function signature. + * Returns the appropriate signal queue for an event by category. * - * @tparam F For example, signal. + * @tparam C For example, general. * @param dispatcher The dispatcher whose signal queue is used. * @param event The event to get the signal for. * - * @returns The signal of the type dispatcher::signal_type + * @returns The signal of the type dispatcher::signal_type */ - template + template static auto& event_signal(dispatcher& dispatcher, const ui_event event) { - if constexpr(std::is_same_v) { - return dispatcher.signal_queue_.queue[event]; - } - - FUNCTION_QUEUE_CHECK(mouse) - FUNCTION_QUEUE_CHECK(keyboard) - FUNCTION_QUEUE_CHECK(touch_motion) - FUNCTION_QUEUE_CHECK(touch_gesture) - FUNCTION_QUEUE_CHECK(notification) - FUNCTION_QUEUE_CHECK(message) - FUNCTION_QUEUE_CHECK(raw_event) - FUNCTION_QUEUE_CHECK(text_input) - - else { - static_assert(utils::dependent_false_v, "No matching signal queue found for function"); - } - } - -#undef FUNCTION_QUEUE_CHECK - -#define RUNTIME_EVENT_SIGNAL_CHECK(TYPE) \ - else if(is_in_category(event, event_category::TYPE)) { \ - return queue_check(dispatcher.signal_##TYPE##_queue_); \ + return dispatcher.get_signal_queue().queue[event]; } /** @@ -85,23 +58,30 @@ struct dispatcher_implementation return !queue_set.queue[event].empty(queue_type); }; - if(is_in_category(event, event_category::general)) { + // We can't just use get_signal_queue since there's no way to know the event at compile time. + switch(get_event_category(event)) { + case event_category::general: return queue_check(dispatcher.signal_queue_); + case event_category::mouse: + return queue_check(dispatcher.signal_mouse_queue_); + case event_category::keyboard: + return queue_check(dispatcher.signal_keyboard_queue_); + case event_category::touch_motion: + return queue_check(dispatcher.signal_touch_motion_queue_); + case event_category::touch_gesture: + return queue_check(dispatcher.signal_touch_gesture_queue_); + case event_category::notification: + return queue_check(dispatcher.signal_notification_queue_);; + case event_category::message: + return queue_check(dispatcher.signal_message_queue_); + case event_category::raw_event: + return queue_check(dispatcher.signal_raw_event_queue_); + case event_category::text_input: + return queue_check(dispatcher.signal_text_input_queue_); + default: + throw std::invalid_argument("Event is not categorized"); } - - RUNTIME_EVENT_SIGNAL_CHECK(mouse) - RUNTIME_EVENT_SIGNAL_CHECK(keyboard) - RUNTIME_EVENT_SIGNAL_CHECK(touch_motion) - RUNTIME_EVENT_SIGNAL_CHECK(touch_gesture) - RUNTIME_EVENT_SIGNAL_CHECK(notification) - RUNTIME_EVENT_SIGNAL_CHECK(message) - RUNTIME_EVENT_SIGNAL_CHECK(raw_event) - RUNTIME_EVENT_SIGNAL_CHECK(text_input) - - return false; } - -#undef RUNTIME_EVENT_SIGNAL_CHECK }; namespace implementation @@ -155,7 +135,7 @@ namespace implementation * * container 1 * * dispatcher */ -template +template std::vector> build_event_chain(const ui_event event, widget* dispatcher, widget* w) { @@ -191,7 +171,7 @@ build_event_chain(const ui_event event, widget* dispatcher, widget* w) */ template<> std::vector> -build_event_chain(const ui_event event, widget* dispatcher, widget* w) +build_event_chain(const ui_event event, widget* dispatcher, widget* w) { assert(dispatcher); assert(w); @@ -220,7 +200,7 @@ build_event_chain(const ui_event event, widget* dispatcher, */ template<> std::vector> -build_event_chain(const ui_event event, widget* dispatcher, widget* w) +build_event_chain(const ui_event event, widget* dispatcher, widget* w) { assert(dispatcher); assert(w); @@ -246,7 +226,7 @@ build_event_chain(const ui_event event, widget* dispatcher, widg * This is called with the same parameters as fire_event except for the * event_chain, which contains the widgets with the events to call for them. */ -template +template bool fire_event(const ui_event event, const std::vector>& event_chain, widget* dispatcher, @@ -258,7 +238,7 @@ bool fire_event(const ui_event event, /***** ***** ***** Pre ***** ***** *****/ for(const auto& [chain_target, chain_event] : utils::reversed_view(event_chain)) { - const auto& signal = dispatcher_implementation::event_signal(*chain_target, chain_event); + const auto& signal = dispatcher_implementation::event_signal(*chain_target, chain_event); for(const auto& pre_func : signal.pre_child) { pre_func(*dispatcher, chain_event, handled, halt, std::forward(params)...); @@ -276,7 +256,7 @@ bool fire_event(const ui_event event, /***** ***** ***** Child ***** ***** *****/ if(w->has_event(event, dispatcher::child)) { - const auto& signal = dispatcher_implementation::event_signal(*w, event); + const auto& signal = dispatcher_implementation::event_signal(*w, event); for(const auto& func : signal.child) { func(*dispatcher, event, handled, halt, std::forward(params)...); @@ -294,7 +274,7 @@ bool fire_event(const ui_event event, /***** ***** ***** Post ***** ***** *****/ for(const auto& [chain_target, chain_event] : event_chain) { - const auto& signal = dispatcher_implementation::event_signal(*chain_target, chain_event); + const auto& signal = dispatcher_implementation::event_signal(*chain_target, chain_event); for(const auto& post_func : signal.post_child) { post_func(*dispatcher, chain_event, handled, halt, std::forward(params)...); @@ -326,7 +306,7 @@ bool fire_event(const ui_event event, * @pre d != nullptr * @pre w != nullptr * - * @tparam T The signal type of the event to handle. + * @tparam C The category of the event to handle. * @tparam F The parameter pack type. * * @@ -338,7 +318,7 @@ bool fire_event(const ui_event event, * * @returns Whether or not the event was handled. */ -template +template bool fire_event(const ui_event event, dispatcher* d, widget* w, F&&... params) { assert(d); @@ -347,15 +327,14 @@ bool fire_event(const ui_event event, dispatcher* d, widget* w, F&&... params) widget* dispatcher_w = dynamic_cast(d); std::vector> event_chain = - implementation::build_event_chain(event, dispatcher_w, w); + implementation::build_event_chain(event, dispatcher_w, w); - return implementation::fire_event(event, event_chain, dispatcher_w, w, std::forward(params)...); + return implementation::fire_event(event, event_chain, dispatcher_w, w, std::forward(params)...); } template bool fire_event_double_click(dispatcher* dsp, widget* wgt, F&&... params) { @@ -382,9 +361,11 @@ bool fire_event_double_click(dispatcher* dsp, widget* wgt, F&&... params) } if(std::invoke(wants_double_click, wgt)) { - return implementation::fire_event(double_click, event_chain, d, wgt, std::forward(params)...); + constexpr auto C = get_event_category(double_click); + return implementation::fire_event(double_click, event_chain, d, wgt, std::forward(params)...); } else { - return implementation::fire_event(click, event_chain, d, wgt, std::forward(params)...); + constexpr auto C = get_event_category(click); + return implementation::fire_event(click, event_chain, d, wgt, std::forward(params)...); } }