|
|
@@ -4,6 +4,139 @@
|
|
|
#include <functional>
|
|
|
#include <unordered_map>
|
|
|
#include <vector>
|
|
|
+#include <sstream>
|
|
|
+#include <type_traits>
|
|
|
+#include <variant>
|
|
|
+
|
|
|
+
|
|
|
+// Enum for Event Types
|
|
|
+enum class EventType {
|
|
|
+ Click,
|
|
|
+ Hover,
|
|
|
+ KeyPress
|
|
|
+};
|
|
|
+
|
|
|
+// Utility function to convert various types to a string
|
|
|
+template <typename T>
|
|
|
+std::string toString(const T& value) {
|
|
|
+ if constexpr (std::is_same_v<T, const char*> || std::is_same_v<T, char*>) {
|
|
|
+ return std::string(value);
|
|
|
+ }
|
|
|
+ else if constexpr (std::is_same_v<T, bool>) {
|
|
|
+ return value ? "true" : "false";
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ std::ostringstream oss;
|
|
|
+ oss << value;
|
|
|
+ return oss.str();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Specialization for void
|
|
|
+inline std::string toString() {
|
|
|
+ return "void";
|
|
|
+}
|
|
|
+
|
|
|
+// EventManager class to manage event handlers
|
|
|
+class EventManager {
|
|
|
+public:
|
|
|
+
|
|
|
+ // Add a handler for a specific event type (void return type)
|
|
|
+ void addHandler(EventType type, const std::function<void()>& handler) {
|
|
|
+ auto& handlersForType = handlers[static_cast<int>(type)];
|
|
|
+ handlersForType.push_back(handler);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add a handler for a specific event type (non-void return type)
|
|
|
+// Add a handler for a specific event type
|
|
|
+ template <typename ReturnType>
|
|
|
+ void addHandler(EventType type, const std::function<ReturnType()>& handler) {
|
|
|
+ auto& handlersForType = handlers[static_cast<int>(type)];
|
|
|
+ handlersForType.push_back(handler);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Emit an event of a specific type
|
|
|
+ template <typename ReturnType, typename = typename std::enable_if<!std::is_same<ReturnType, void>::value>::type>
|
|
|
+ ReturnType emit(EventType type) {
|
|
|
+ auto it = handlers.find(static_cast<int>(type));
|
|
|
+ if (it != handlers.end()) {
|
|
|
+ for (const auto& callback : it->second) {
|
|
|
+ // Check the type of the callback and invoke it
|
|
|
+ if (auto func = std::get_if<std::function<ReturnType()>>(&callback)) {
|
|
|
+ return (*func)(); // Call the callback and return the result
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Emit an event of a specific type
|
|
|
+ void emit(EventType type) {
|
|
|
+ auto it = handlers.find(static_cast<int>(type));
|
|
|
+ if (it != handlers.end()) {
|
|
|
+ for (const auto& callback : it->second) {
|
|
|
+ // Check the type of the callback and invoke it
|
|
|
+ if (auto func = std::get_if<std::function<void()>>(&callback)) {
|
|
|
+ (*func)(); // Call the callback and return the result
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return; // Explicit return for clarity
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+private:
|
|
|
+
|
|
|
+ // Define a variant type for supported callback return types
|
|
|
+ using CallbackVariant = std::variant<
|
|
|
+ std::function<void()>,
|
|
|
+ std::function<int()>,
|
|
|
+ std::function<bool()>,
|
|
|
+ std::function<std::string()>,
|
|
|
+ std::function<const char* ()>>;
|
|
|
+
|
|
|
+ // Update the handlers map to use the variant
|
|
|
+ std::unordered_map<int, std::vector<CallbackVariant>> handlers;
|
|
|
+ // std::unordered_map<int, std::vector<std::function<std::string()>>> handlers; // Map of event type to handlers
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+int main() {
|
|
|
+ EventManager eventManager;
|
|
|
+
|
|
|
+ // Add handlers for different event types with various return types
|
|
|
+ eventManager.addHandler(EventType::Click, []() {
|
|
|
+ std::cout << "Click event triggered!" << std::endl;
|
|
|
+ });
|
|
|
+
|
|
|
+ eventManager.addHandler<const char*>(EventType::Hover, []() -> const char* {
|
|
|
+ return "Hover event triggered!";
|
|
|
+ });
|
|
|
+
|
|
|
+ eventManager.addHandler<bool>(EventType::KeyPress, []() -> bool {
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ eventManager.addHandler<int>(EventType::Click, []() -> int {
|
|
|
+ return 42;
|
|
|
+ });
|
|
|
+
|
|
|
+ // Emit events
|
|
|
+ std::cout << "Emitting Click event:" << std::endl;
|
|
|
+ eventManager.emit(EventType::Click);
|
|
|
+
|
|
|
+ std::cout << "Emitting Hover event:" << std::endl;
|
|
|
+ // eventManager.emit<const char*>(EventType::Hover);
|
|
|
+ const char* hoverResult = eventManager.emit<const char*>(EventType::Hover);
|
|
|
+ std::cout << "Hover event result: " << hoverResult << std::endl;
|
|
|
+
|
|
|
+ std::cout << "Emitting KeyPress event:" << std::endl;
|
|
|
+ bool KeyPressResult = eventManager.emit<bool>(EventType::KeyPress);
|
|
|
+ std::cout << "KeyPress event result: " << KeyPressResult << std::endl;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
@@ -306,152 +439,3 @@ int main() {
|
|
|
|
|
|
#endif
|
|
|
|
|
|
-
|
|
|
-#include <iostream>
|
|
|
-#include <functional>
|
|
|
-#include <unordered_map>
|
|
|
-#include <vector>
|
|
|
-#include <sstream>
|
|
|
-#include <type_traits>
|
|
|
-
|
|
|
-// Enum for Event Types
|
|
|
-enum class EventType {
|
|
|
- Click,
|
|
|
- Hover,
|
|
|
- KeyPress
|
|
|
-};
|
|
|
-
|
|
|
-// Utility function to convert various types to a string
|
|
|
-template <typename T>
|
|
|
-std::string toString(const T& value) {
|
|
|
- if constexpr (std::is_same_v<T, const char*> || std::is_same_v<T, char*>) {
|
|
|
- return std::string(value);
|
|
|
- }
|
|
|
- else if constexpr (std::is_same_v<T, bool>) {
|
|
|
- return value ? "true" : "false";
|
|
|
- }
|
|
|
- else {
|
|
|
- std::ostringstream oss;
|
|
|
- oss << value;
|
|
|
- return oss.str();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Specialization for void
|
|
|
-inline std::string toString() {
|
|
|
- return "void";
|
|
|
-}
|
|
|
-
|
|
|
-// EventManager class to manage event handlers
|
|
|
-class EventManager {
|
|
|
-public:
|
|
|
-
|
|
|
- // Add a handler for a specific event type (void return type)
|
|
|
- void addHandler(EventType type, const std::function<void()>& handler) {
|
|
|
- auto& handlersForType = handlers[static_cast<int>(type)];
|
|
|
- handlersForType.push_back([handler]() ->std::string {
|
|
|
- handler();
|
|
|
- return "";
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // Add a handler for a specific event type (non-void return type)
|
|
|
- template <typename ReturnType >
|
|
|
- void addHandler(EventType type, const std::function<ReturnType()>& handler) {
|
|
|
- auto& handlersForType = handlers[static_cast<int>(type)];
|
|
|
- handlersForType.push_back([handler]() -> std::string {
|
|
|
- ReturnType result = handler(); // Call the handler
|
|
|
- return toString(result);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // Emit an event of a specific type
|
|
|
- template <typename ReturnType, typename = typename std::enable_if<!std::is_same<ReturnType, void>::value>::type>
|
|
|
- ReturnType emit(EventType type) {
|
|
|
- auto it = handlers.find(static_cast<int>(type));
|
|
|
- if (it != handlers.end()) {
|
|
|
- for (const auto& handler : it->second) {
|
|
|
- std::string result = handler(); // Call each handler and get the result
|
|
|
- auto handlerResult = handler(); // Call each handler and get the result
|
|
|
- // ReturnType result = handler(); // Call each handler and get the result
|
|
|
-
|
|
|
- // Convert handlerResult to ReturnType if necessary
|
|
|
- if constexpr (std::is_same<ReturnType, const char*>::value) {
|
|
|
- // Convert std::string to const char*
|
|
|
- return static_cast<ReturnType>(handlerResult.c_str());
|
|
|
- }
|
|
|
- else if constexpr (std::is_same<ReturnType, std::string>::value) {
|
|
|
- return static_cast<ReturnType>(handlerResult);
|
|
|
- }
|
|
|
- else if constexpr (std::is_same<ReturnType, int>::value) {
|
|
|
- return static_cast<ReturnType>(std::stoi(handlerResult));
|
|
|
- }
|
|
|
- else if constexpr (std::is_same<ReturnType, bool>::value) {
|
|
|
- return static_cast<ReturnType>(handlerResult == "true");
|
|
|
- }
|
|
|
- else {
|
|
|
- throw std::runtime_error("Unsupported ReturnType");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // Return default value for non-void types if no handler is found
|
|
|
- if (!std::is_same<ReturnType, void>::value) {
|
|
|
- return ReturnType();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Emit an event of a specific type
|
|
|
-// Emit an event of a specific type
|
|
|
- void emit(EventType type) {
|
|
|
- auto it = handlers.find(static_cast<int>(type));
|
|
|
- if (it != handlers.end()) {
|
|
|
- for (const auto& handler : it->second) {
|
|
|
- handler(); // Call each handler
|
|
|
- }
|
|
|
- }
|
|
|
- return; // Explicit return for clarity
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-private:
|
|
|
- std::unordered_map<int, std::vector<std::function<std::string()>>> handlers; // Map of event type to handlers
|
|
|
-};
|
|
|
-
|
|
|
-int main() {
|
|
|
- EventManager eventManager;
|
|
|
-
|
|
|
- // Add handlers for different event types with various return types
|
|
|
- eventManager.addHandler(EventType::Click, []() {
|
|
|
- std::cout << "Click event triggered!" << std::endl;
|
|
|
- });
|
|
|
-
|
|
|
- eventManager.addHandler<const char*>(EventType::Hover, []() -> const char* {
|
|
|
- return "Hover event triggered!";
|
|
|
- });
|
|
|
-
|
|
|
- eventManager.addHandler<bool>(EventType::KeyPress, []() -> bool {
|
|
|
- return true;
|
|
|
- });
|
|
|
-
|
|
|
- eventManager.addHandler<int>(EventType::Click, []() -> int {
|
|
|
- return 42;
|
|
|
- });
|
|
|
-
|
|
|
- // Emit events
|
|
|
- std::cout << "Emitting Click event:" << std::endl;
|
|
|
- eventManager.emit(EventType::Click);
|
|
|
-
|
|
|
- std::cout << "Emitting Hover event:" << std::endl;
|
|
|
- // eventManager.emit<const char*>(EventType::Hover);
|
|
|
- const char* hoverResult = eventManager.emit<const char*>(EventType::Hover);
|
|
|
- std::cout << "Hover event result: " << hoverResult << std::endl;
|
|
|
-
|
|
|
- std::cout << "Emitting KeyPress event:" << std::endl;
|
|
|
- eventManager.emit<bool>(EventType::KeyPress);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|