Selaa lähdekoodia

Update on chatGPT - EventDispatcher C++14/cEventDispatcher.h *.cpp

sfreundel@gmx.de 8 kuukautta sitten
vanhempi
sitoutus
d418660184
28 muutettua tiedostoa jossa 837 lisäystä ja 12 poistoa
  1. BIN
      chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/FileContentIndex/1f1fb049-88b9-4af3-8b27-e203536c99ca.vsidx
  2. BIN
      chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/FileContentIndex/4ac4fd17-e44f-46b6-880c-611034cc8156.vsidx
  3. BIN
      chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/FileContentIndex/e51b6591-474d-47ce-88fb-c9e0cf33b7ad.vsidx
  4. BIN
      chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/copilot-chat/48988cf4/sessions/e776ec02-c0e0-4cf7-9680-3ede483d761e
  5. BIN
      chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/v17/ipch/AutoPCH/a2cde6afa019edcf/CEVENTDISPATCHER.ipch
  6. BIN
      chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/v17/ipch/AutoPCH/e0ad0a4baa56806a/CEVENTDISPATCHER.ipch
  7. 417 0
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/cEventDispatcher.cpp
  8. 405 0
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/cEventDispatcher.h
  9. 4 2
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14.vcxproj
  10. 6 4
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14.vcxproj.filters
  11. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/cEventDispatcher.obj
  12. 1 1
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.Build.CppClean.log
  13. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.ilk
  14. 1 1
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.log
  15. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.obj
  16. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/CL.command.1.tlog
  17. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/CL.read.1.tlog
  18. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/CL.write.1.tlog
  19. 1 2
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/Cl.items.tlog
  20. 1 1
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/chatGPT - EventDispatcher C++14.lastbuildstate
  21. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/link.command.1.tlog
  22. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/link.read.1.tlog
  23. 1 1
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/link.secondary.1.tlog
  24. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/link.write.1.tlog
  25. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/vc143.idb
  26. BIN
      chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/vc143.pdb
  27. BIN
      chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.exe
  28. BIN
      chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.pdb

BIN
chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/FileContentIndex/1f1fb049-88b9-4af3-8b27-e203536c99ca.vsidx


BIN
chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/FileContentIndex/4ac4fd17-e44f-46b6-880c-611034cc8156.vsidx


BIN
chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/FileContentIndex/e51b6591-474d-47ce-88fb-c9e0cf33b7ad.vsidx


BIN
chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/copilot-chat/48988cf4/sessions/e776ec02-c0e0-4cf7-9680-3ede483d761e


BIN
chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/v17/ipch/AutoPCH/a2cde6afa019edcf/CEVENTDISPATCHER.ipch


BIN
chatGPT - EventDispatcher C++14/.vs/chatGPT - EventDispatcher C++14/v17/ipch/AutoPCH/e0ad0a4baa56806a/CEVENTDISPATCHER.ipch


+ 417 - 0
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/cEventDispatcher.cpp

@@ -0,0 +1,417 @@
+#include "cEventDispatcher.h"
+
+// Specializations for common types
+
+/**
+ * Specialization of getTypeName for int.
+ *
+ * @return The name of the type ("int")
+ */
+template <>
+const char* cEventDispatcher::getTypeName<void>()
+{
+    return "void";
+}
+
+
+/**
+ * Specialization of getTypeName for int.
+ *
+ * @return The name of the type ("int")
+ */
+template <>
+const char* cEventDispatcher::getTypeName<int>()
+{
+    return "int";
+}
+
+/**
+ * Specialization of getTypeName for float.
+ *
+ * @return The name of the type ("float")
+ */
+template <>
+const char* cEventDispatcher::getTypeName<float>()
+{
+    return "float";
+}
+
+/**
+ * Specialization of getTypeName for double.
+ *
+ * @return The name of the type ("double")
+ */
+template <>
+const char* cEventDispatcher::getTypeName<double>()
+{
+    return "double";
+}
+
+/**
+ * Specialization of getTypeName for const char*.
+ *
+ * @return The name of the type ("const char*")
+ */
+template <>
+const char* cEventDispatcher::getTypeName<const char*>()
+{
+    return "const char*";
+}
+
+/**
+ * Specialization of getTypeName for bool.
+ *
+ * @return The name of the type ("bool")
+ */
+template <>
+const char* cEventDispatcher::getTypeName<bool>()
+{
+    return "bool";
+}
+
+/**
+ * Prints the names of all types in Args to std::cout, separated by spaces.
+ * The output is not terminated by a newline.
+ *
+ * This is mostly useful for debugging purposes.
+ */
+template <typename... Args>
+void cEventDispatcher::printArgs()
+{
+    using expander = int[];
+    (void)expander {
+        0, (std::cout << getTypeName<Args>() << " ", 0)...
+    };
+}
+
+// For const member function pointers
+/**
+ * Specialization of FunctionTraits for const call operator.
+ * This specialization is used to extract the return type and argument types
+ * from a const call operator.
+ *
+ * @tparam C The class type.
+ * @tparam R The return type of the const call operator.
+ * @tparam Args The argument types of the const call operator.
+ */
+template <typename C, typename R, typename... Args>
+struct cEventDispatcher::FunctionTraits<R(C::*)(Args...) const>
+{
+    using ReturnType = R;
+    using ArgsTuple = std::tuple<Args...>;
+};
+
+// For member function pointers
+/**
+ * Specialization of FunctionTraits for member functions.
+ * This specialization is used to extract the return type and argument types
+ * from a member function pointer.
+ *
+ * @tparam C The class type.
+ * @tparam R The return type of the member function.
+ * @tparam Args The argument types of the member function.
+ */
+template <typename C, typename R, typename... Args>
+struct cEventDispatcher::FunctionTraits<R(C::*)(Args...)>
+{
+    using ReturnType = R;
+    using ArgsTuple = std::tuple<Args...>;
+};
+
+/**
+ * Specialization of FunctionTraits for function pointers.
+ * This specialization is used to extract the return type and argument types
+ * from a function pointer.
+ *
+ * @tparam R The return type of the function.
+ * @tparam Args The argument types of the function.
+ */
+template <typename R, typename... Args>
+struct cEventDispatcher::FunctionTraits<R(*)(Args...)>
+{
+    using ReturnType = R;
+    using ArgsTuple = std::tuple<Args...>;
+};
+
+
+#if 1
+struct Button
+{
+    int onClick(int x)
+    {
+        std::cout << "Button::onClick(" << x << ")\n";
+        return x;
+    }
+    int onClick_1(int x)
+    {
+        std::cout << "Button::onClick_1(" << x << ")\n";
+        return x * 2;
+    }
+    int onClick_2(int x)
+    {
+        std::cout << "Button::onClick_2(" << x << ")\n";
+        return x;
+    }
+    int onClick_3(int x)
+    {
+        std::cout << "Button::onClick_2(" << x << ")\n";
+        return x;
+    }
+};
+
+struct Widget
+{
+    void update()
+    {
+        std::cout << "Widget::update()\n";
+    }
+
+    bool draw()
+    {
+        std::cout << "Widget::draw()\n";
+        return true;
+    }
+
+    bool onClick_1(int x)
+    {
+        std::cout << "Widget::onClick_1(" << x << ")\n";
+        return true;
+    }
+
+    bool onClick_2(int x)
+    {
+        std::cout << "Widget::onClick_2(" << x << ")\n";
+        return false;
+    }
+
+    bool onClick_3(int x)
+    {
+        std::cout << "Widget::onClick_3(" << x << ")\n";
+        return true;
+    }
+
+    bool onClick_4(int x)
+    {
+        std::cout << "Widget::onClick_4(" << x << ")\n";
+        return false;
+    }
+
+    const char* onHover(const char* msg)
+    {
+        std::cout << "Widget::onHover_3(" << msg << ")\n";
+        return msg;
+    }
+
+    int onClick_5(int x)
+    {
+        std::cout << "Widget::onHover_4(" << x << ")\n";
+        return x * 2;
+    }
+
+    int globalIntHandler(int x, int y)
+    {
+        std::cout << "Widget::globalIntHandler(" << x << "," << y << ") return: " << x * y << std::endl;
+        return x * y;
+    }
+};
+
+bool globalHandler(int x)
+{
+    std::cout << "free standing globalHandler(" << x << ") return: true" << std::endl;
+    return x > 0;
+}
+
+bool globalHandler1(int x)
+{
+    std::cout << "free standing globalHandler_1(" << x << ") return: false" << std::endl;
+    return x < 0;
+}
+
+int globalIntHandler(int x, int y)
+{
+    std::cout << "free standing globalIntHandler(" << x << "," << y <<") return: " << x*y << std::endl;
+    return x * y;
+}
+
+
+int main()
+{
+    cEventDispatcher dispatcher;
+    Widget w;
+    Button b;
+
+    // Register handlers and keep their IDs for removal
+    std::cout << "-------------------------  void foo()  --------------------------------" << std::endl;
+    std::cout << ">> addHandler(EventTypeDisp::Down, [&w]() -> void { w.update(); });" << std::endl;
+    auto id1_1 = dispatcher.addHandler(EventTypeDisp::Down, [&w]() -> void { w.update(); });
+    std::cout << ">> emit(EventTypeDisp::Down);" << std::endl;
+    dispatcher.emit(EventTypeDisp::Down);
+
+    // Register handlers and keep their IDs for removal
+    std::cout << "-------------------------  bool foo()  --------------------------------" << std::endl;
+    std::cout << ">> addHandler(EventTypeDisp::Down, [&w]() -> bool { w.update(); });" << std::endl;
+    auto id1_2 = dispatcher.addHandler(EventTypeDisp::Down, [&w]() -> bool { return w.draw(); });
+    std::cout << ">> emit<bool>(EventTypeDisp::Down);" << std::endl;
+    auto id1_2_results = dispatcher.emit<bool>(EventTypeDisp::Down);
+
+    std::cout << "Down results: "; 
+    for (bool b : id1_2_results)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    // Register handlers and keep their IDs for removal
+    std::cout << "-------------------------  bool foo(int)  --------------------------------" << std::endl;
+    std::cout << "Click Handler registered ...(globalHandler, globalHandler1, lambda)" << std::endl;
+    std::cout << ">> addHandler(EventTypeDisp::Click, globalHandler) - Free Function" << std::endl;
+    auto id2_1 = dispatcher.addHandler(EventTypeDisp::Click, globalHandler);
+    std::cout << ">> addHandler(EventTypeDisp::Click, globalHandler1) - Free Function" << std::endl;
+    auto id2_2 = dispatcher.addHandler(EventTypeDisp::Click, globalHandler1);
+    std::cout << ">> addHandler(EventTypeDisp::Click, [](int x) -> bool {} - Lambda Function" << std::endl;
+    auto id2_3 = dispatcher.addHandler(EventTypeDisp::Click, [](int x) -> bool
+        {
+            std::cout << "function lambda(" << x << ") return true\n";
+            return x % 2 == 0; 
+        });
+
+    std::cout << "\n--------- emit<bool>(EventTypeDisp::Click, 42) --------" << std::endl;
+    std::cout << "---------- supposely 3 functions ----------" << std::endl;
+    auto id2_results = dispatcher.emit<bool>(EventTypeDisp::Click, 42);
+    std::cout << "-----------------" << std::endl;
+    std::cout << "Click results: ";
+    for (bool b : id2_results)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    std::cout << "-----------------------------------------------------------------------" << std::endl;
+    std::cout << "          Remove Handler globalHandler and Lambda Function" << std::endl;
+    dispatcher.removeHandler(EventTypeDisp::Click, id2_1);
+    dispatcher.removeHandler(EventTypeDisp::Click, id2_3);
+    // dispatcher.removeHandler(EventTypeDisp::Click, id1_1);
+
+    std::cout << "\n--------- emit<bool>(EventTypeDisp::Click, 27) --------" << std::endl;
+    std::cout << "---------- supposely 1 functions ----------" << std::endl;
+    id2_results = dispatcher.emit<bool>(EventTypeDisp::Click, 27);
+    std::cout << "-----------------" << std::endl;
+    std::cout << "Click results: ";
+    for (bool b : id2_results)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    std::cout << "------------------------------------------------------------" << std::endl;
+    std::cout << "New Click Handler registered ... (onClick, onClick_1, onClick_2, onClick_3)" << std::endl;
+    std::cout << "\n>> addHandler(EventTypeDisp::Click, [&w](int x) -> bool { return w.onClick_1(x); }" << std::ends;
+    auto id3_1 = dispatcher.addHandler(EventTypeDisp::Click, [&w](int x) -> bool
+        { return w.onClick_1(x); });
+    std::cout << "\n>> addHandler(EventTypeDisp::Click, [&w](int x) -> bool { return w.onClick_2(x); }" << std::ends;
+    auto id3_2 = dispatcher.addHandler(EventTypeDisp::Click, [&w](int x) -> bool
+        { return w.onClick_2(x); });
+    std::cout << "\n>> addHandler(EventTypeDisp::Click, [&w](int x) -> bool { return w.onClick_3(x); }" << std::ends;
+    auto id3_3 = dispatcher.addHandler(EventTypeDisp::Click, [&w](int x) -> bool
+        { return w.onClick_3(x); });
+    std::cout << "\n>> addHandler(EventTypeDisp::Click, [&w](int x) -> bool { return w.onClick_4(x); }" << std::ends;
+    auto id3_4 = dispatcher.addHandler(EventTypeDisp::Click, [&w](int x) -> bool
+        { return w.onClick_4(x); });
+
+    std::cout << "\n--------- dispatcher.emit<bool>(EventTypeDisp::Click, 24) --------" << std::ends;
+    std::cout << "\n--------- supposely 5 functions --------\n"
+        << std::ends;
+    // Emit events; collect return values if any
+    auto clickResults_3 = dispatcher.emit<bool>(EventTypeDisp::Click, 24);
+    std::cout << "-----------------" << std::endl;
+    std::cout << "Click results: ";
+    if (clickResults_3.size() == 0)
+        std::cout << "Error" << std::endl;
+    for (bool b : clickResults_3)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    std::cout << "------------------  const char* foo(const char*)  ---------------------" << std::endl;
+    std::cout << "New Hover Handler registered ... (onHover)" << std::endl;
+    std::cout << ">> addHandler(EventTypeDisp::Hover, [&w](const char* msg) -> const char* { return w.onHover(msg); })" << std::endl;
+
+    auto id4_1 = dispatcher.addHandler(EventTypeDisp::Hover, [&w](const char* msg) -> const char*
+        { return w.onHover(msg); });
+    auto id4_1_results_a = dispatcher.emit<const char*>(EventTypeDisp::Hover, static_cast<const char*>("hello"));
+    auto id4_1_results_b = dispatcher.emit<const char*>(EventTypeDisp::Hover, static_cast<const char*>("Thank you"));
+    std::copy(id4_1_results_b.begin(), id4_1_results_b.end(), std::back_inserter(id4_1_results_a));
+
+    std::cout << "-----------------" << std::endl;
+    std::cout << "Hover results: ";
+    for (const char* b : id4_1_results_a)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    std::cout << "------------------------------------------------------------" << std::endl;
+    std::cout << "New Click Handler registered ... (lambda)" << std::endl;
+    std::cout << ">> addHandler(EventTypeDisp::Click, [&w,&b](int x) -> int { return b.onClick_1(w.onClick_4(x)); }" << std::endl;
+    dispatcher.addHandler(EventTypeDisp::Click, [&w, &b](int x) -> int
+        { return b.onClick_1(w.onClick_5(x)); });
+    auto clickResultsInt = dispatcher.emit<int>(EventTypeDisp::Click, 7);
+    std::cout << "-----------------" << std::endl;
+    std::cout << "Click results: ";
+    for (int b : clickResultsInt)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    // Remove a handler and emit again
+    std::cout << "------------------------------------------------------------" << std::endl;
+    std::cout << "------------------------------------------------------------" << std::endl;
+    std::cout << "Remove Handler Click ID 1 ...\n"
+        << std::endl;
+
+    dispatcher.removeHandler(EventTypeDisp::Click, id2_2);
+    auto clickResults_4 = dispatcher.emit<bool>(EventTypeDisp::Click, 7);
+    std::cout << "Click results after removal: ";
+    for (bool b : clickResults_4)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    std::cout << "-------------------------  int foo(int, int)  -------------------------" << std::endl;
+    std::cout << ">> addHandler(EventTypeDisp::Click, globalIntHandler1) - Free Function" << std::endl;
+    // dispatcher.addHandler(EventTypeDisp::Hover, [](int x, int y) -> int { return x + y; });
+    auto id5_1 = dispatcher.addHandler(EventTypeDisp::Hover, globalIntHandler);
+    std::cout << ">> addHandler(EventTypeDisp::Hover, [](int x, int y) -> int { return x + y; }); - Lambda" << std::endl;
+    auto id5_2 = dispatcher.addHandler(EventTypeDisp::Hover, [](int x, int y) -> int { std::cout << "Lambda Function: " << x+y << std::endl; return x + y; });
+    std::cout << ">> addHandler(EventTypeDisp::Hover, [&w](int x, int y) { return w.globalIntHandler(x, y); }); - Call class member" << std::endl;
+    auto id5_3 = dispatcher.addHandler(EventTypeDisp::Hover, [&w](int x, int y) { return w.globalIntHandler(x, y); });
+
+    clickResultsInt = dispatcher.emit<int>(EventTypeDisp::Hover, 7,8);
+    std::cout << "Hover results: ";
+    for (int b : clickResultsInt)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    std::cout << "-------------------------  float foo(int, int)  -------------------------" << std::endl;
+    std::cout << ">> addHandler(EventTypeDisp::Hover, [](int x, int y) -> float { return x / y; }); - Lambda" << std::endl;
+    auto id5_4 = dispatcher.addHandler(EventTypeDisp::Hover, [](int x, int y) -> float { 
+        float result = float(x) / float(y);
+        std::cout << "Lambda Function: " << result << std::endl;
+        return result; 
+        });
+
+    auto id5_4_result = dispatcher.emit<float>(EventTypeDisp::Hover, 7, 8);
+    std::cout << "Hover results: "; 
+    for (float b : id5_4_result)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+    std::cout << "-------------------------  float foo(float, float)  -------------------------" << std::endl;
+    std::cout << ">> addHandler(EventTypeDisp::Hover, [](float x, float y) -> float { return y / x; }); - Lambda" << std::endl;
+    auto id5_5 = dispatcher.addHandler(EventTypeDisp::Hover, [](float x, float y) -> float {
+        float result = y / x;
+        std::cout << "Lambda Function: " << result << std::endl;
+        return result;
+        });
+
+    auto id5_5_result = dispatcher.emit<float>(EventTypeDisp::Hover, (float) 7.0, (float) 8.0);
+    std::cout << "Hover results: ";
+    for (float b : id5_5_result)
+        std::cout << b << " ";
+    std::cout << "\n";
+
+
+
+
+    return 0;
+}
+#endif

+ 405 - 0
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/cEventDispatcher.h

@@ -0,0 +1,405 @@
+#pragma once
+// #include "Arduino.h"
+//     EVDISP      = 0x00001000,  // Log Info cEventDispatcher
+//     EVDISPERR   = 0x00002000,  // Log Info cEventDispatcher Error
+/// #include "DebugHdl.h" 
+
+#include <vector>
+#include <memory>
+#include <unordered_map>
+#include <functional>
+#include <iostream>
+
+// extern void testEventDispatcher();
+
+enum class EventTypeDisp
+{
+    Up,
+    Down,
+    Press,
+    Click,
+    Hover
+};
+
+// Definition of HandlerBase
+struct HandlerBase {
+    using TypeID = std::size_t;
+
+    HandlerBase() = default;
+    virtual ~HandlerBase() = default;
+
+    virtual TypeID getTypeID() const = 0;
+};
+
+using HandlerID = std::size_t;
+
+class cEventDispatcher
+{
+public:
+
+    /**
+     * Prints the names of all types in Args to std::cout, separated by spaces.
+     * The output is not terminated by a newline.
+     *
+     * This is mostly useful for debugging purposes.
+     */
+    template <typename... Args>
+    void printArgs();
+
+    /**
+     * Returns the name of the type as a string. This is mostly useful for
+     * debugging purposes. If the type is not one of the supported types (see
+     * below), this function returns "Unknown".
+     *
+     * Supported types are:
+     *   - int
+     *   - bool
+     *   - const char*
+     *
+     * @return The name of the type as a string.
+     */
+    template <typename T> const char* getTypeName() { return "Unknown"; }
+
+    /**
+     * Creates a std::unique_ptr to a new instance of type T, using the given arguments
+     * to initialize the new object. This function is equivalent to
+     * std::make_unique, but is provided so that the dependency on C++14 can be
+     * avoided.
+     *
+     * @param args the arguments to use when initializing the new object.
+     * @return a std::unique_ptr to the newly created object.
+     */
+    template <typename T, typename... Args>
+    std::unique_ptr<T> make_unique(Args &&...args)
+    {
+        return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+    }
+
+    /**
+     * Add a handler for the specified event type. The handler must be a std::function
+     * that takes the correct arguments for the given event type.
+     *
+     * @param type The type of event to handle.
+     * @param func The handler to add. The handler must be a callable object that
+     * takes the correct arguments for the given event type.
+     *
+     * @return The ID of the added handler. This ID can be used to remove the handler
+     * later.
+     */
+#if 0
+    template <typename R, typename... Args>
+    HandlerID addHandler(EventTypeDisp type, std::function<R(Args...)> func)
+    {
+        auto handler = make_unique<Handler<R, Args...>>(std::move(func));
+        HandlerID id = nextHandlerID++;
+        handlerMap[id] = handler.get(); // Map HandlerID to the handler
+        handlers[type].emplace_back(std::move(handler));
+        return id;
+    }
+#else
+    template <typename R, typename... Args>
+    HandlerID addHandler(EventTypeDisp type, std::function<R(Args...)> func)
+    {
+        auto handler = make_unique<Handler<R, Args...>>(nextHandlerID, std::move(func));
+        handlerMap[nextHandlerID] = handler.get();
+        handlers[type].emplace_back(std::move(handler));
+        return nextHandlerID++;
+    }
+#endif
+
+
+    HandlerID addHandler(EventTypeDisp type, std::function<void()> func)
+    {
+        auto handler = make_unique<Handler<void>>(nextHandlerID, std::move(func));
+        handlerMap[nextHandlerID] = handler.get();
+        handlers[type].emplace_back(std::move(handler));
+        return nextHandlerID++;
+    }
+
+    /**
+     * Add a handler for the specified event type. The handler can be a std::function, a functor, or a member function.
+     *
+     * @param type The type of event to handle.
+     * @param f The handler to add. The handler must be a callable object that takes the correct arguments for the given event type.
+     *
+     * @return The ID of the added handler. This ID can be used to remove the handler later.
+     */
+    template <typename F>
+    HandlerID addHandler(EventTypeDisp type, F&& f)
+    {
+        using Traits = FunctionTraits<typename std::decay<F>::type>;
+        using R = typename Traits::ReturnType;
+        using Tuple = typename Traits::ArgsTuple;
+        return addHandlerImpl<R>(type, std::forward<F>(f), static_cast<Tuple*>(nullptr));
+    }
+
+    /**
+     * Removes a handler associated with a specific event type and handler ID.
+     *
+     * @param type The type of event for which the handler should be removed.
+     * @param id The unique identifier of the handler to be removed.
+     *
+     * This function removes the handler from both the handler map and the
+     * handlers vector corresponding to the specified event type. If the
+     * handler ID is found, it is erased from both data structures.
+     */
+    void removeHandler(EventTypeDisp type, HandlerID id)
+    {
+        auto it = handlerMap.find(id);
+        if (it != handlerMap.end())
+        {
+            // Remove the handler from the handlers map
+            auto& vec = handlers[type];
+            vec.erase(std::remove_if(vec.begin(), vec.end(),
+                [id, this](const HandlerBasePtr& h)
+                {
+                    return h.get() == handlerMap[id];
+                }),
+                vec.end());
+
+            // Remove the handler from the handlerMap
+            handlerMap.erase(it);
+        }
+    }
+
+
+
+
+    /**
+     * Emits an event of the specified type, calling all registered handlers
+     * for that event type. The handlers are called with the provided arguments.
+     *
+     * @param type The type of event to emit.
+     * @param args The arguments to pass to the handlers.
+     *
+     * @return A vector containing the return values from all handlers that
+     * were called.
+     */
+    template <typename R, typename... Args>
+    std::vector<R> emit(EventTypeDisp type, Args... args)
+    {
+        std::vector<R> results;
+        auto it = handlers.find(type);
+        if (it != handlers.end())
+        {
+            for (const auto& handlerBase : it->second)
+            {
+                // std::cout << "Emitting for handler type: " << typeid(*handlerBase).name() << std::endl;
+                auto handler = castHandler<R, Args...>(handlerBase.get());
+                if (handler)
+                {
+                    results.push_back(handler->func(args...));
+                }
+            }
+        }
+        return results;
+    }
+
+    void emit(EventTypeDisp type)
+    {
+        auto it = handlers.find(type);
+        if (it != handlers.end())
+        {
+            for (const auto& handlerBase : it->second)
+            {
+                auto handler = castHandler<void>(handlerBase.get());
+                if (handler)
+                {
+                    (handler->func)();
+                }
+            }
+        }
+        return;
+    }
+
+#if 0
+    void emit(EventTypeDisp type)
+    {
+        auto it = handlers.find(type);
+        if (it != handlers.end())
+        {
+            for (const auto& handlerBase : it->second)
+            {
+                auto handler = castHandler<void, void>(handlerBase.get());
+                if (handler)
+                {
+                    //handler->func();
+                    handler->id = handler->id;
+                }
+            }
+        }
+        return;
+    }
+#endif
+private:
+    // Base class for handlers
+    /**
+     * HandlerBase is an abstract base class that represents a generic handler.
+     * It provides a pure virtual function getTypeID() that must be implemented
+     * by derived classes to return the type ID of the handler.
+     *
+     * This class is used to store the handler function and its type information.
+     */
+    struct HandlerBase
+    {
+        using TypeID = std::size_t;
+
+        HandlerBase() = default;
+        virtual ~HandlerBase() = default;
+
+        virtual TypeID getTypeID() const = 0;
+    };
+
+    /**
+     * Handler is a template class that represents a handler for a specific event type.
+     * It stores a std::function that can be called with the specified arguments.
+     * It also provides a way to get the type ID of the handler.
+     *
+     * @tparam R The return type of the handler.
+     * @tparam Args The argument types of the handler.
+     *
+     * This class is used to store the handler function and its type information.
+     */
+    template <typename R, typename... Args>
+    struct Handler : public HandlerBase
+    {
+        using FuncType = std::function<R(Args...)>;
+
+        FuncType func;
+        HandlerID id; // Add a member to store the HandlerID
+
+        Handler(HandlerID handlerID, FuncType f) : id(handlerID), func(std::move(f)) {}
+        TypeID getTypeID() const override { return getStaticTypeID(); }
+
+        /**
+         * Returns a unique type ID for the specified handler type.
+         *
+         * The type ID is generated using a static local variable and the
+         * address-of operator (&). This ensures that each handler type has
+         * a unique type ID, even if the handler type is instantiated multiple
+         * times with different template arguments.
+         *
+         * @return A unique type ID for the handler type.
+         */
+        static TypeID getStaticTypeID()
+        {
+            static const TypeID id = reinterpret_cast<TypeID>(&getStaticTypeID);
+            return id;
+        }
+    };
+
+    /**
+     * Casts a HandlerBase pointer to a specific Handler type.
+     *
+     * @param base A pointer to a HandlerBase object.
+     * @tparam R The return type of the handler.
+     * @tparam Args The argument types of the handler.
+     *
+     * @return A pointer to the casted Handler object, or nullptr if the cast fails.
+     */
+
+
+    template <typename R, typename... Args>
+    Handler<R, Args...>* castHandler(HandlerBase* base)
+    {
+        if (base->getTypeID() == Handler<R, Args...>::getStaticTypeID())
+        {
+            return static_cast<Handler<R, Args...>*>(base);
+        }
+        return nullptr;
+    }
+    // FunctionTraits to deduce argument and return types
+    /**
+     * FunctionTraits is a template struct that extracts the return type and
+     * argument types from a callable object (function pointer, member function
+     * pointer, or functor).
+     *
+     * @tparam T The type of the callable object.
+     */
+    template <typename T>
+    struct FunctionTraits : public FunctionTraits<decltype(&T::operator())>
+    {
+    };
+
+    // For std::function
+    template <typename R, typename... Args>
+    struct FunctionTraits<std::function<R(Args...)>> {
+        using ReturnType = R;
+        using ArgsTuple = std::tuple<Args...>;
+    };
+
+
+    /**
+     * Adds a handler for a specific event type, creating a unique Handler object
+     * and storing it in the handler map. This function constructs a std::function
+     * with the specified return type and arguments, and associates it with a unique
+     * HandlerID. It checks for errors during std::function construction and logs
+     * detailed information if the Handler object creation is unsuccessful.
+     *
+     * @tparam R The return type of the handler function.
+     * @tparam F The type of the handler function or callable object.
+     * @tparam Args The argument types expected by the handler function.
+     * @param type The type of event to associate with the handler.
+     * @param f The handler function or callable object to add.
+     * @param A tuple representing the argument types for the handler function.
+     * @return A unique HandlerID for the added handler.
+     */
+    template <typename R, typename F, typename... Args>
+    HandlerID addHandlerImpl(EventTypeDisp type, F&& f, std::tuple<Args...>*)
+    {
+        // Explicitly construct std::function with the correct return type
+        auto func = std::function<R(Args...)>(std::forward<F>(f));
+        if (!func)
+        {
+            std::cerr << "Error: std::function construction failed!" << std::endl;
+        }
+
+        auto handler = make_unique<Handler<R, Args...>>(nextHandlerID, func);
+        if (!handler)
+        {
+            std::cout << "\n-------------------- AddHandlerImp --------------------" << std::endl;
+            std::cout << "Registering handler type: " << typeid(Handler<R, Args...>).name() << std::endl;
+            std::cout << "Args... types: "; printArgs<Args...>(); std::cout << std::endl;
+            std::cerr << "Expected Handler type: " << getTypeName<Handler<R, Args...>>() << std::endl;
+            std::cerr << "Actual HandlerBase type: " << handler->getTypeID() << std::endl;
+            std::cerr << "HandlerBase pointer: " << handler.get() << std::endl;
+        }
+        // Add the handler to the handlerMap
+        handlerMap[nextHandlerID] = handler.get();
+        // Add the handler to the handlers map
+        handlers[type].emplace_back(std::move(handler));
+        return nextHandlerID++;
+    }
+
+    template <typename F>
+    HandlerID addHandlerImpl(EventTypeDisp type, F&& f)
+    {
+        // Explicitly construct std::function with the correct return type
+        auto func = std::function<void>(std::forward<F>(f));
+        if (!func)
+        {
+            std::cerr << "Error: std::function construction failed!" << std::endl;
+        }
+
+        auto handler = make_unique<Handler<void>>(nextHandlerID, func);
+        if (!handler)
+        {
+            std::cout << "\n-------------------- AddHandlerImp --------------------" << std::endl;
+            std::cout << std::endl;
+           // std::cerr << "Expected Handler type: " << getTypeName<Handler<R, Args...>>() << std::endl;
+            std::cerr << "Actual HandlerBase type: " << handler->getTypeID() << std::endl;
+            std::cerr << "HandlerBase pointer: " << handler.get() << std::endl;
+        }
+        // Add the handler to the handlerMap
+        handlerMap[nextHandlerID] = handler.get();
+        // Add the handler to the handlers map
+        handlers[type].emplace_back(std::move(handler));
+        return nextHandlerID++;
+    }
+
+private:
+    using HandlerBasePtr = std::unique_ptr<HandlerBase>;
+    std::unordered_map<EventTypeDisp, std::vector<HandlerBasePtr>> handlers;
+    std::unordered_map<HandlerID, HandlerBase*> handlerMap; // Map HandlerID to handlers
+    HandlerID nextHandlerID;
+};

+ 4 - 2
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14.vcxproj

@@ -127,10 +127,12 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClCompile Include="chatGPT - EventDispatcher C++ - ESP32.cpp" />
-    <ClCompile Include="chatGPT - EventDispatcher C++ NoRTTI.cpp" />
+    <ClCompile Include="cEventDispatcher.cpp" />
     <ClCompile Include="chatGPT - EventDispatcher C++14.cpp" />
   </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="cEventDispatcher.h" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>

+ 6 - 4
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14.vcxproj.filters

@@ -18,11 +18,13 @@
     <ClCompile Include="chatGPT - EventDispatcher C++14.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="chatGPT - EventDispatcher C++ NoRTTI.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="chatGPT - EventDispatcher C++ - ESP32.cpp">
+    <ClCompile Include="cEventDispatcher.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="cEventDispatcher.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
 </Project>

BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/cEventDispatcher.obj


+ 1 - 1
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.Build.CppClean.log

@@ -1,10 +1,10 @@
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\vc143.pdb
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\vc143.idb
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\chatgpt - eventdispatcher c++14.obj
+c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\ceventdispatcher.obj
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\x64\debug\chatgpt - eventdispatcher c++14.exe
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\x64\debug\chatgpt - eventdispatcher c++14.pdb
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\chatgpt - eventdispatcher c++14.ilk
-c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\chatgpt - eventdispatcher c++14.obj.enc
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\chatgpt .742afb35.tlog\cl.command.1.tlog
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\chatgpt .742afb35.tlog\cl.items.tlog
 c:\users\sfreunde\source\repos\chatgpt - eventdispatcher c++14\chatgpt - eventdispatcher c++14\x64\debug\chatgpt .742afb35.tlog\cl.read.1.tlog

BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.ilk


+ 1 - 1
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.log

@@ -1,2 +1,2 @@
-  chatGPT - EventDispatcher C++ - ESP32.cpp
+  cEventDispatcher.cpp
   chatGPT - EventDispatcher C++14.vcxproj -> C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\x64\Debug\chatGPT - EventDispatcher C++14.exe

BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.obj


BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/CL.command.1.tlog


BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/CL.read.1.tlog


BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/CL.write.1.tlog


+ 1 - 2
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/Cl.items.tlog

@@ -1,3 +1,2 @@
-C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++ - ESP32.cpp;C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\x64\Debug\chatGPT - EventDispatcher C++ - ESP32.obj
-C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++ NoRTTI.cpp;C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\x64\Debug\chatGPT - EventDispatcher C++ NoRTTI.obj
+C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\cEventDispatcher.cpp;C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\x64\Debug\cEventDispatcher.obj
 C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14.cpp;C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\x64\Debug\chatGPT - EventDispatcher C++14.obj

+ 1 - 1
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/chatGPT - EventDispatcher C++14.lastbuildstate

@@ -1,2 +1,2 @@
-PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.43.34808:TargetPlatformVersion=10.0.22621.0:
+PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.43.34808:TargetPlatformVersion=10.0.26100.0:
 Debug|x64|C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\|

BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/link.command.1.tlog


BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/link.read.1.tlog


+ 1 - 1
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/link.secondary.1.tlog

@@ -1,2 +1,2 @@
-^C:\USERS\SFREUNDE\SOURCE\REPOS\CHATGPT - EVENTDISPATCHER C++14\CHATGPT - EVENTDISPATCHER C++14\X64\DEBUG\CHATGPT - EVENTDISPATCHER C++ - ESP32.OBJ|C:\USERS\SFREUNDE\SOURCE\REPOS\CHATGPT - EVENTDISPATCHER C++14\CHATGPT - EVENTDISPATCHER C++14\X64\DEBUG\CHATGPT - EVENTDISPATCHER C++ NORTTI.OBJ|C:\USERS\SFREUNDE\SOURCE\REPOS\CHATGPT - EVENTDISPATCHER C++14\CHATGPT - EVENTDISPATCHER C++14\X64\DEBUG\CHATGPT - EVENTDISPATCHER C++14.OBJ
+^C:\USERS\SFREUNDE\SOURCE\REPOS\CHATGPT - EVENTDISPATCHER C++14\CHATGPT - EVENTDISPATCHER C++14\X64\DEBUG\CEVENTDISPATCHER.OBJ|C:\USERS\SFREUNDE\SOURCE\REPOS\CHATGPT - EVENTDISPATCHER C++14\CHATGPT - EVENTDISPATCHER C++14\X64\DEBUG\CHATGPT - EVENTDISPATCHER C++14.OBJ
 C:\Users\sfreunde\source\repos\chatGPT - EventDispatcher C++14\chatGPT - EventDispatcher C++14\x64\Debug\chatGPT - EventDispatcher C++14.ilk

BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/chatGPT .742afb35.tlog/link.write.1.tlog


BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/vc143.idb


BIN
chatGPT - EventDispatcher C++14/chatGPT - EventDispatcher C++14/x64/Debug/vc143.pdb


BIN
chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.exe


BIN
chatGPT - EventDispatcher C++14/x64/Debug/chatGPT - EventDispatcher C++14.pdb