|
@@ -452,475 +452,3 @@ int main() {
|
|
|
std::cout << "\n";
|
|
std::cout << "\n";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-// This code is a more complex version of the EventDispatcher, which allows for different types of events and handlers.
|
|
|
|
|
-#if 0
|
|
|
|
|
-/*
|
|
|
|
|
-Certainly!Here’s how you can improve the code by :
|
|
|
|
|
-
|
|
|
|
|
-1. * *Using an enum for event types** instead of string names.
|
|
|
|
|
-2. * *Using `Args...` for arguments** in `invokeAll`, `invokeById`, etc., so you don’t need to repeat the argument list everywhere.
|
|
|
|
|
-
|
|
|
|
|
-Below is a complete, working code example with these improvements :
|
|
|
|
|
-*/
|
|
|
|
|
-
|
|
|
|
|
-// 1. Define event types as enum
|
|
|
|
|
-enum class EventType {
|
|
|
|
|
- ButtonClick,
|
|
|
|
|
- Redraw,
|
|
|
|
|
- Hover
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// Helper for unique handler IDs
|
|
|
|
|
-class IdGen {
|
|
|
|
|
- size_t current = 0;
|
|
|
|
|
-public:
|
|
|
|
|
- size_t next() { return ++current; }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// Type-erased base for handler lists
|
|
|
|
|
-struct IEventHandlerList {
|
|
|
|
|
- virtual ~IEventHandlerList() {}
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// Templated handler list for a given signature
|
|
|
|
|
-template<typename Ret, typename... Args>
|
|
|
|
|
-class EventHandlerList : public IEventHandlerList {
|
|
|
|
|
-public:
|
|
|
|
|
- using HandlerType = std::function<Ret(Args...)>;
|
|
|
|
|
- struct HandlerEntry {
|
|
|
|
|
- size_t id;
|
|
|
|
|
- HandlerType handler;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- size_t addHandler(const HandlerType& h) {
|
|
|
|
|
- size_t id = idGen.next();
|
|
|
|
|
- handlers.push_back({ id, h });
|
|
|
|
|
- return id;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void removeHandler(size_t id) {
|
|
|
|
|
- handlers.erase(std::remove_if(handlers.begin(), handlers.end(),
|
|
|
|
|
- [id](const HandlerEntry& e) { return e.id == id; }), handlers.end());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- std::vector<Ret> invokeAll(Args... args) {
|
|
|
|
|
- std::vector<Ret> results;
|
|
|
|
|
- for (auto& entry : handlers) {
|
|
|
|
|
- results.push_back(entry.handler(args...));
|
|
|
|
|
- }
|
|
|
|
|
- return results;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Ret invokeById(size_t id, Args... args) {
|
|
|
|
|
- for (auto& entry : handlers) {
|
|
|
|
|
- if (entry.id == id)
|
|
|
|
|
- return entry.handler(args...);
|
|
|
|
|
- }
|
|
|
|
|
- throw std::runtime_error("Handler ID not found");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-private:
|
|
|
|
|
- std::vector<HandlerEntry> handlers;
|
|
|
|
|
- IdGen idGen;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// The main dispatcher
|
|
|
|
|
-class EventDispatcher {
|
|
|
|
|
-public:
|
|
|
|
|
- // Main template: add handler as std::function
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- size_t addHandler(EventType eventType, std::function<Ret(Args...)> handler) {
|
|
|
|
|
- auto key = std::make_pair(eventType, std::type_index(typeid(EventHandlerList<Ret, Args...>)));
|
|
|
|
|
- auto& ptr = handlers[key];
|
|
|
|
|
- if (!ptr) {
|
|
|
|
|
- ptr.reset(new EventHandlerList<Ret, Args...>());
|
|
|
|
|
- }
|
|
|
|
|
- auto* list = static_cast<EventHandlerList<Ret, Args...>*>(ptr.get());
|
|
|
|
|
- return list->addHandler(handler);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Overload for free functions
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- size_t addHandler(EventType eventType, Ret(*func)(Args...)) {
|
|
|
|
|
- return addHandler<Ret, Args...>(eventType, std::function<Ret(Args...)>(func));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Overload for non-const member functions
|
|
|
|
|
- template<typename Ret, typename Class, typename... Args>
|
|
|
|
|
- size_t addHandler(EventType eventType, Class* obj, Ret(Class::* memFn)(Args...)) {
|
|
|
|
|
- auto wrapper = [obj, memFn](Args... args) -> Ret {
|
|
|
|
|
- return (obj->*memFn)(args...);
|
|
|
|
|
- };
|
|
|
|
|
- return addHandler<Ret, Args...>(eventType, wrapper);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Overload for const member functions
|
|
|
|
|
- template<typename Ret, typename Class, typename... Args>
|
|
|
|
|
- size_t addHandler(EventType eventType, Class* obj, Ret(Class::* memFn)(Args...) const) {
|
|
|
|
|
- auto wrapper = [obj, memFn](Args... args) -> Ret {
|
|
|
|
|
- return (obj->*memFn)(args...);
|
|
|
|
|
- };
|
|
|
|
|
- return addHandler<Ret, Args...>(eventType, wrapper);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Remove handler by ID
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- void removeHandler(EventType eventType, size_t id) {
|
|
|
|
|
- auto key = std::make_pair(eventType, std::type_index(typeid(EventHandlerList<Ret, Args...>)));
|
|
|
|
|
- auto it = handlers.find(key);
|
|
|
|
|
- if (it != handlers.end()) {
|
|
|
|
|
- auto* list = static_cast<EventHandlerList<Ret, Args...>*>(it->second.get());
|
|
|
|
|
- if (list) list->removeHandler(id);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Invoke all handlers for an event
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- std::vector<Ret> invokeAll(EventType eventType, Args&&... args) {
|
|
|
|
|
- auto key = std::make_pair(eventType, std::type_index(typeid(EventHandlerList<Ret, Args...>)));
|
|
|
|
|
- auto it = handlers.find(key);
|
|
|
|
|
- // auto it = handlers.find(eventType);
|
|
|
|
|
- if (it != handlers.end()) {
|
|
|
|
|
- auto* list = static_cast<EventHandlerList<Ret, Args...>*>(it->second.get());
|
|
|
|
|
- if (list) return list->invokeAll(std::forward<Args>(args)...);
|
|
|
|
|
- }
|
|
|
|
|
- return {};
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Invoke a handler by ID
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- Ret invokeById(EventType eventType, size_t id, Args&&... args) {
|
|
|
|
|
- auto key = std::make_pair(eventType, std::type_index(typeid(EventHandlerList<Ret, Args...>)));
|
|
|
|
|
- auto it = handlers.find(key);
|
|
|
|
|
- if (it != handlers.end()) {
|
|
|
|
|
- auto* list = static_cast<EventHandlerList<Ret, Args...>*>(it->second.get());
|
|
|
|
|
- if (list) return list->invokeById(id, std::forward<Args>(args)...);
|
|
|
|
|
- }
|
|
|
|
|
- throw std::runtime_error("Handler or event not found");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-private:
|
|
|
|
|
- using HandlerKey = std::pair<EventType, std::type_index>;
|
|
|
|
|
- std::map<HandlerKey, std::unique_ptr<IEventHandlerList>> handlers;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// Example class for reference parameter/return
|
|
|
|
|
-struct MyWidget {
|
|
|
|
|
- int value = 42;
|
|
|
|
|
- int memberFunc(int a, bool b, const char* s, MyWidget& ref) {
|
|
|
|
|
- std::cout << "MyWidget::memberFunc called: " << a << ", " << b << ", " << s << ", ref.value=" << ref.value << std::endl;
|
|
|
|
|
- return value + a;
|
|
|
|
|
- }
|
|
|
|
|
- bool onRedraw(int a, bool b, const char* s, MyWidget& ref) {
|
|
|
|
|
- std::cout << "Redraw: " << a << ", " << b << ", " << s << ", ref.value=" << ref.value << std::endl;
|
|
|
|
|
- return b;
|
|
|
|
|
- }
|
|
|
|
|
- int constMember(int a, bool, const char*, MyWidget&) const {
|
|
|
|
|
- std::cout << "constMember: " << a << std::endl;
|
|
|
|
|
- return a + 100;
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-bool freeHandler(int a, bool b, const char* s, MyWidget& ref) {
|
|
|
|
|
- ref.value = 32;
|
|
|
|
|
- std::cout << "freeHandler: " << a << ", " << b << ", " << s << ", ref.value=" << ref.value << std::endl;
|
|
|
|
|
- return a > 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-int main() {
|
|
|
|
|
- EventDispatcher dispatcher;
|
|
|
|
|
- MyWidget widget, refWidget;
|
|
|
|
|
-
|
|
|
|
|
- // Lambda handler returning bool
|
|
|
|
|
- auto id1 = dispatcher.addHandler<bool, int, bool, const char*, MyWidget&>(
|
|
|
|
|
- EventType::ButtonClick,
|
|
|
|
|
- [](int a, bool b, const char* s, MyWidget& ref) {
|
|
|
|
|
- std::cout << "Lambda handler: " << a << ", " << b << ", " << s << ", ref.value=" << ref.value << std::endl;
|
|
|
|
|
- return b;
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Free function handler
|
|
|
|
|
- auto id2 = dispatcher.addHandler(EventType::ButtonClick, freeHandler);
|
|
|
|
|
-
|
|
|
|
|
- // Member function handler (non-const)
|
|
|
|
|
- auto id3 = dispatcher.addHandler(EventType::ButtonClick, &widget, &MyWidget::onRedraw);
|
|
|
|
|
-
|
|
|
|
|
- // Member function handler (const)
|
|
|
|
|
- auto id4 = dispatcher.addHandler(EventType::Hover, &widget, &MyWidget::constMember);
|
|
|
|
|
-
|
|
|
|
|
- // Lambda handler returning int
|
|
|
|
|
- auto id5 = dispatcher.addHandler<int, int, bool, const char*,
|
|
|
|
|
- MyWidget&>(EventType::Hover, [](int a, bool, const char*, MyWidget&) {
|
|
|
|
|
- std::cout << "Hover handler: " << a << std::endl;
|
|
|
|
|
- return a + 10;
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Member function handler returning int (non-const)
|
|
|
|
|
- auto id6 = dispatcher.addHandler(EventType::Hover, &widget, &MyWidget::memberFunc);
|
|
|
|
|
-
|
|
|
|
|
- // Lambda handler returning const char*
|
|
|
|
|
- auto id7 = dispatcher.addHandler<const char*, int, bool, const char*, MyWidget&>(
|
|
|
|
|
- EventType::Redraw,
|
|
|
|
|
- [](int, bool, const char*, MyWidget&) {
|
|
|
|
|
- return "Redraw done";
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Call all buttonClick handlers
|
|
|
|
|
- std::cout << "\nInvoking all buttonClick with return bool and argument (int, bool, const char*) handlers:\n";
|
|
|
|
|
- auto results = dispatcher.invokeAll<bool>(
|
|
|
|
|
- EventType::ButtonClick, 5, true, "OK", refWidget);
|
|
|
|
|
- for (auto r : results) std::cout << "Result: " << std::boolalpha << r << std::endl;
|
|
|
|
|
-
|
|
|
|
|
- std::cout << "\nInvoking all with return int and argument (int bool const char*) handlers:\n";
|
|
|
|
|
- auto hoverResults = dispatcher.invokeAll<int, int, bool, const char*, MyWidget&>(EventType::Hover, 7, true, "Hovering", refWidget);
|
|
|
|
|
- for (auto r : hoverResults) std::cout << "Hover result: " << r << std::endl;
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // Call a specific handler by ID
|
|
|
|
|
- std::cout << "\nInvoke buttonClick by id3:\n";
|
|
|
|
|
- bool res = dispatcher.invokeById<bool, int, bool, const char*, MyWidget&>(EventType::ButtonClick, id3, 2, false, "Cancel", refWidget);
|
|
|
|
|
- std::cout << "Result: " << std::boolalpha << res << std::endl;
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // Call redraw handler (returns const char*)
|
|
|
|
|
- std::cout << "\nInvoking all redraw handlers:\n";
|
|
|
|
|
- auto redrawResults = dispatcher.invokeAll<const char*, int, bool, const char*, MyWidget&>(EventType::Redraw, 1, false, "Redraw", refWidget);
|
|
|
|
|
- for (auto r : redrawResults) std::cout << "Redraw result: " << r << std::endl;
|
|
|
|
|
-
|
|
|
|
|
- // Remove a handler and show it's gone
|
|
|
|
|
- dispatcher.removeHandler<bool, int, bool, const char*, MyWidget&>(EventType::ButtonClick, id1);
|
|
|
|
|
- std::cout << "\nAfter removing lambda handler (id1):\n";
|
|
|
|
|
- auto results2 = dispatcher.invokeAll<bool, int, bool, const char*, MyWidget&>(EventType::ButtonClick, 9, false, "Bye", refWidget);
|
|
|
|
|
- for (auto r : results2) std::cout << "Result: " << std::boolalpha << r << std::endl;
|
|
|
|
|
-
|
|
|
|
|
- return 0;
|
|
|
|
|
-};
|
|
|
|
|
-#endif
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-#if 0
|
|
|
|
|
-
|
|
|
|
|
-// Helper for unique handler IDs
|
|
|
|
|
-class IdGen {
|
|
|
|
|
- size_t current = 0;
|
|
|
|
|
-public:
|
|
|
|
|
- size_t next() { return ++current; }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// Type-erased base for handler lists
|
|
|
|
|
-struct IEventHandlerList {
|
|
|
|
|
- virtual ~IEventHandlerList() {}
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// Templated handler list for a given signature
|
|
|
|
|
-template<typename Ret, typename... Args>
|
|
|
|
|
-class EventHandlerList : public IEventHandlerList {
|
|
|
|
|
-public:
|
|
|
|
|
- using HandlerType = std::function<Ret(Args...)>;
|
|
|
|
|
- struct HandlerEntry {
|
|
|
|
|
- size_t id;
|
|
|
|
|
- HandlerType handler;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- size_t addHandler(const HandlerType& h) {
|
|
|
|
|
- size_t id = idGen.next();
|
|
|
|
|
- handlers.push_back({ id, h });
|
|
|
|
|
- return id;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void removeHandler(size_t id) {
|
|
|
|
|
- handlers.erase(std::remove_if(handlers.begin(), handlers.end(),
|
|
|
|
|
- [id](const HandlerEntry& e) { return e.id == id; }), handlers.end());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- std::vector<Ret> invokeAll(Args... args) {
|
|
|
|
|
- std::vector<Ret> results;
|
|
|
|
|
- for (auto& entry : handlers) {
|
|
|
|
|
- results.push_back(entry.handler(args...));
|
|
|
|
|
- }
|
|
|
|
|
- return results;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Ret invokeById(size_t id, Args... args) {
|
|
|
|
|
- for (auto& entry : handlers) {
|
|
|
|
|
- if (entry.id == id)
|
|
|
|
|
- return entry.handler(args...);
|
|
|
|
|
- }
|
|
|
|
|
- throw std::runtime_error("Handler ID not found");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-private:
|
|
|
|
|
- std::vector<HandlerEntry> handlers;
|
|
|
|
|
- IdGen idGen;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// The main dispatcher
|
|
|
|
|
-class EventDispatcher {
|
|
|
|
|
-public:
|
|
|
|
|
- // Main template: add handler as std::function
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- size_t addHandler(const std::string& eventName, std::function<Ret(Args...)> handler) {
|
|
|
|
|
- auto& ptr = handlers[eventName];
|
|
|
|
|
- if (!ptr) {
|
|
|
|
|
- ptr.reset(new EventHandlerList<Ret, Args...>());
|
|
|
|
|
- }
|
|
|
|
|
- auto* list = dynamic_cast<EventHandlerList<Ret, Args...>*>(ptr.get());
|
|
|
|
|
- if (!list) throw std::runtime_error("Event signature mismatch");
|
|
|
|
|
- return list->addHandler(handler);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Overload for free functions
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- size_t addHandler(const std::string& eventName, Ret(*func)(Args...)) {
|
|
|
|
|
- return addHandler<Ret, Args...>(eventName, std::function<Ret(Args...)>(func));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Overload for non-const member functions
|
|
|
|
|
- template<typename Ret, typename Class, typename... Args>
|
|
|
|
|
- size_t addHandler(const std::string& eventName, Class* obj, Ret(Class::* memFn)(Args...)) {
|
|
|
|
|
- auto wrapper = [obj, memFn](Args... args) -> Ret {
|
|
|
|
|
- return (obj->*memFn)(args...);
|
|
|
|
|
- };
|
|
|
|
|
- return addHandler<Ret, Args...>(eventName, wrapper);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Overload for const member functions
|
|
|
|
|
- template<typename Ret, typename Class, typename... Args>
|
|
|
|
|
- size_t addHandler(const std::string& eventName, Class* obj, Ret(Class::* memFn)(Args...) const) {
|
|
|
|
|
- auto wrapper = [obj, memFn](Args... args) -> Ret {
|
|
|
|
|
- return (obj->*memFn)(args...);
|
|
|
|
|
- };
|
|
|
|
|
- return addHandler<Ret, Args...>(eventName, wrapper);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Remove handler by ID
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- void removeHandler(const std::string& eventName, size_t id) {
|
|
|
|
|
- auto it = handlers.find(eventName);
|
|
|
|
|
- if (it != handlers.end()) {
|
|
|
|
|
- auto* list = dynamic_cast<EventHandlerList<Ret, Args...>*>(it->second.get());
|
|
|
|
|
- if (list) list->removeHandler(id);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Invoke all handlers for an event
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- std::vector<Ret> invokeAll(const std::string& eventName, Args... args) {
|
|
|
|
|
- auto it = handlers.find(eventName);
|
|
|
|
|
- if (it != handlers.end()) {
|
|
|
|
|
- auto* list = dynamic_cast<EventHandlerList<Ret, Args...>*>(it->second.get());
|
|
|
|
|
- if (list) return list->invokeAll(args...);
|
|
|
|
|
- }
|
|
|
|
|
- return {};
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Invoke a handler by ID
|
|
|
|
|
- template<typename Ret, typename... Args>
|
|
|
|
|
- Ret invokeById(const std::string& eventName, size_t id, Args... args) {
|
|
|
|
|
- auto it = handlers.find(eventName);
|
|
|
|
|
- if (it != handlers.end()) {
|
|
|
|
|
- auto* list = dynamic_cast<EventHandlerList<Ret, Args...>*>(it->second.get());
|
|
|
|
|
- if (list) return list->invokeById(id, args...);
|
|
|
|
|
- }
|
|
|
|
|
- throw std::runtime_error("Handler or event not found");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-private:
|
|
|
|
|
- std::map<std::string, std::unique_ptr<IEventHandlerList>> handlers;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// Example class for reference parameter/return
|
|
|
|
|
-struct MyWidget {
|
|
|
|
|
- int value = 42;
|
|
|
|
|
- int memberFunc(int a, bool b, const char* s, MyWidget& ref) {
|
|
|
|
|
- std::cout << "MyWidget::memberFunc called: " << a << ", " << b << ", " << s << ", ref.value=" << ref.value << std::endl;
|
|
|
|
|
- return value + a;
|
|
|
|
|
- }
|
|
|
|
|
- bool onRedraw(int a, bool b, const char* s, MyWidget& ref) {
|
|
|
|
|
- std::cout << "Redraw: " << a << ", " << b << ", " << s << ", ref.value=" << ref.value << std::endl;
|
|
|
|
|
- return b;
|
|
|
|
|
- }
|
|
|
|
|
- int constMember(int a, bool, const char*, MyWidget&) const {
|
|
|
|
|
- std::cout << "constMember: " << a << std::endl;
|
|
|
|
|
- return a + 100;
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-bool freeHandler(int a, bool b, const char* s, MyWidget& ref) {
|
|
|
|
|
- std::cout << "freeHandler: " << a << ", " << b << ", " << s << ", ref.value=" << ref.value << std::endl;
|
|
|
|
|
- return a > 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-int main() {
|
|
|
|
|
- EventDispatcher dispatcher;
|
|
|
|
|
- MyWidget widget, refWidget;
|
|
|
|
|
-
|
|
|
|
|
- // Lambda handler returning bool
|
|
|
|
|
- auto id1 = dispatcher.addHandler<bool, int, bool, const char*, MyWidget&>(
|
|
|
|
|
- "buttonClick",
|
|
|
|
|
- [](int a, bool b, const char* s, MyWidget& ref) {
|
|
|
|
|
- std::cout << "Lambda handler: " << a << ", " << b << ", " << s << ", ref.value=" << ref.value << std::endl;
|
|
|
|
|
- return b;
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Free function handler
|
|
|
|
|
- auto id2 = dispatcher.addHandler("buttonClick", freeHandler);
|
|
|
|
|
-
|
|
|
|
|
- // Member function handler (non-const)
|
|
|
|
|
- auto id3 = dispatcher.addHandler("buttonClick", &widget, &MyWidget::onRedraw);
|
|
|
|
|
-
|
|
|
|
|
- // Member function handler (const)
|
|
|
|
|
- auto id4 = dispatcher.addHandler("hover", &widget, &MyWidget::constMember);
|
|
|
|
|
-
|
|
|
|
|
- // Lambda handler returning int
|
|
|
|
|
- auto id5 = dispatcher.addHandler<int, int, bool, const char*, MyWidget&>(
|
|
|
|
|
- "hover",
|
|
|
|
|
- [](int a, bool, const char*, MyWidget&) {
|
|
|
|
|
- std::cout << "Hover handler: " << a << std::endl;
|
|
|
|
|
- return a + 10;
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Member function handler returning int (non-const)
|
|
|
|
|
- auto id6 = dispatcher.addHandler("hover", &widget, &MyWidget::memberFunc);
|
|
|
|
|
-
|
|
|
|
|
- // Lambda handler returning const char*
|
|
|
|
|
- auto id7 = dispatcher.addHandler<const char*, int, bool, const char*, MyWidget&>(
|
|
|
|
|
- "redraw",
|
|
|
|
|
- [](int, bool, const char*, MyWidget&) {
|
|
|
|
|
- return "Redraw done";
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Call all buttonClick handlers
|
|
|
|
|
- std::cout << "\nInvoking all buttonClick handlers:\n";
|
|
|
|
|
- auto results = dispatcher.invokeAll<bool, int, bool, const char*, MyWidget&>("buttonClick", 5, true, "OK", refWidget);
|
|
|
|
|
- for (auto r : results) std::cout << "Result: " << std::boolalpha << r << std::endl;
|
|
|
|
|
-
|
|
|
|
|
- // Call a specific handler by ID
|
|
|
|
|
- std::cout << "\nInvoke buttonClick by id3:\n";
|
|
|
|
|
- bool res = dispatcher.invokeById<bool, int, bool, const char*, MyWidget&>("buttonClick", id3, 2, false, "Cancel", refWidget);
|
|
|
|
|
- std::cout << "Result: " << std::boolalpha << res << std::endl;
|
|
|
|
|
-
|
|
|
|
|
- auto hoverResults = dispatcher.invokeAll<int, int, bool, const char*, MyWidget&>("hover", 7, true, "Hovering", refWidget);
|
|
|
|
|
- for (auto r : hoverResults) std::cout << "Hover result: " << r << std::endl;
|
|
|
|
|
-
|
|
|
|
|
- // Call redraw handler (returns const char*)
|
|
|
|
|
- std::cout << "\nInvoking all redraw handlers:\n";
|
|
|
|
|
- auto redrawResults = dispatcher.invokeAll<const char*, int, bool, const char*, MyWidget&>("redraw", 1, false, "Redraw", refWidget);
|
|
|
|
|
- for (auto r : redrawResults) std::cout << "Redraw result: " << r << std::endl;
|
|
|
|
|
-
|
|
|
|
|
- // Remove a handler and show it's gone
|
|
|
|
|
- dispatcher.removeHandler<bool, int, bool, const char*, MyWidget&>("buttonClick", id1);
|
|
|
|
|
- std::cout << "\nAfter removing lambda handler (id1):\n";
|
|
|
|
|
- auto results2 = dispatcher.invokeAll<bool, int, bool, const char*, MyWidget&>("buttonClick", 9, false, "Bye", refWidget);
|
|
|
|
|
- for (auto r : results2) std::cout << "Result: " << std::boolalpha << r << std::endl;
|
|
|
|
|
-
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-#endif
|
|
|