aboutsummaryrefslogtreecommitdiff
path: root/src/ui/routed_event_dispatch.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/routed_event_dispatch.hpp')
-rw-r--r--src/ui/routed_event_dispatch.hpp61
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