diff options
Diffstat (limited to 'src/ui/routed_event_dispatch.hpp')
-rw-r--r-- | src/ui/routed_event_dispatch.hpp | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/src/ui/routed_event_dispatch.hpp b/src/ui/routed_event_dispatch.hpp index 83702005..b032c0a3 100644 --- a/src/ui/routed_event_dispatch.hpp +++ b/src/ui/routed_event_dispatch.hpp @@ -1,6 +1,8 @@ #pragma once #include "cru/ui/control.hpp" +#include "cru/common/logger.hpp" + #include <list> namespace cru::ui { @@ -18,9 +20,20 @@ namespace cru::ui { // "original_sender", which is unchanged. And "args" will be perfectly forwarded // as the rest arguments. template <typename EventArgs, typename... Args> -void DispatchEvent(Control* const original_sender, +void DispatchEvent(const std::wstring_view& event_name, + Control* const original_sender, event::RoutedEvent<EventArgs>* (Control::*event_ptr)(), Control* const last_receiver, Args&&... args) { + if (original_sender == last_receiver) { +#ifdef CRU_DEBUG + log::Debug( + L"Routed event {} no need to dispatch (original_sender == " + L"last_receiver). Original sender is {}.", + event_name, original_sender->GetControlType()); +#endif + return; + } + std::list<Control*> receive_list; auto parent = original_sender; @@ -29,15 +42,44 @@ void DispatchEvent(Control* const original_sender, parent = parent->GetParent(); } +#ifdef CRU_DEBUG + { + std::wstring log = L"Dispatch routed event "; + log += event_name; + log += L". Path (parent first): "; + auto i = receive_list.crbegin(); + const auto end = --receive_list.crend(); + for (; i != end; ++i) { + log += (*i)->GetControlType(); + log += L" -> "; + } + log += (*i)->GetControlType(); + log::Debug(log); + } +#endif + auto handled = false; +#ifdef CRU_DEBUG + int count = 0; +#endif + // tunnel for (auto i = receive_list.crbegin(); i != receive_list.crend(); ++i) { +#ifdef CRU_DEBUG + count++; +#endif EventArgs event_args(*i, original_sender, std::forward<Args>(args)...); static_cast<Event<EventArgs&>*>(((*i)->*event_ptr)()->Tunnel()) ->Raise(event_args); if (event_args.IsHandled()) { handled = true; +#ifdef CRU_DEBUG + log::Debug( + L"Routed event is short-circuit in TUNNEL at {}-st control (count " + L"from parent).", + count); +#endif break; } } @@ -45,10 +87,21 @@ void DispatchEvent(Control* const original_sender, // bubble if (!handled) { for (auto i : receive_list) { +#ifdef CRU_DEBUG + count--; +#endif EventArgs event_args(i, original_sender, std::forward<Args>(args)...); static_cast<Event<EventArgs&>*>((i->*event_ptr)()->Bubble()) ->Raise(event_args); - if (event_args.IsHandled()) break; + if (event_args.IsHandled()) { +#ifdef CRU_DEBUG + log::Debug( + L"Routed event is short-circuit in BUBBLE at {}-st control (count " + L"from parent).", + count); +#endif + break; + } } } @@ -58,5 +111,9 @@ void DispatchEvent(Control* const original_sender, static_cast<Event<EventArgs&>*>((i->*event_ptr)()->Direct()) ->Raise(event_args); } + +#ifdef CRU_DEBUG + log::Debug(L"Routed event dispatch finished."); +#endif } } // namespace cru::ui |