diff options
Diffstat (limited to 'socket/socket.hpp')
| -rw-r--r-- | socket/socket.hpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/socket/socket.hpp b/socket/socket.hpp new file mode 100644 index 0000000..dd9b2a3 --- /dev/null +++ b/socket/socket.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include <functional> +#include <map> + +namespace socket { + /* Allows casting R(Args...) */ + template <typename T> + class Socket; + + /* A class that represents a socket that can + be used to dispatch a function call to different + handlers. Handlers can be connected and disconnected + from the socket at runtime. */ + template <typename R, typename... Args> + class Socket<R(Args...)> { + /* The type of handler function or methods */ + using HandlerType = std::function<R(Args...)>; + + + /* The next handler descriptor to be assigned + the descriptor can be used to disconnect + a descriptor */ + int descriptor; + + /* Map between descriptors and handlers */ + std::map<int, HandlerType> handlers; + public: + /* Connect a handler to the socket + handler: the handler to connect to + Returns the handler descriptor */ + int connect(HandlerType handler) { + // Get the handler descriptor of next handler + int hd = descriptor++; + + // Store the handler + handlers[hd] = handler; + + return hd; + } + + /* Connect a handler to the socket + and bind the call to an object, this + can be useful if the handler is a method */ + template <typename T, typename V> + int connect(T *object, R (V::*handler)(Args...)) { + auto f = [=](Args... args) { + return std::invoke(handler, object, args...); + }; + + return connect(f); + } + + /* Disconnect a handler from the socket + hd: the handle descriptor of the handler + to disconnect */ + void disconnect(int hd) { + // Remove the handler from the map + handlers.erase(hd); + } + + /* Dispatch a call to all handlers */ + void operator()(Args... args) { + for (auto &handler : handlers) + handler.second(args...); + } + }; +} |
