From 532df0ac7ffaaee037dbb22985e29aeca605d088 Mon Sep 17 00:00:00 2001 From: "Alejandro W. Sior" Date: Thu, 2 Feb 2023 11:05:01 +0100 Subject: chisel: initial commit --- socket/readme | 6 +++++ socket/socket.hpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 socket/readme create mode 100644 socket/socket.hpp (limited to 'socket') diff --git a/socket/readme b/socket/readme new file mode 100644 index 0000000..0046460 --- /dev/null +++ b/socket/readme @@ -0,0 +1,6 @@ +The [[socket]] module introduces a structure +called a socket, whose purpose is to be able +to dispatch a function call to an arbitrary +number of handlers. Those handlers can be +connected and disconnected from the socket +dynamically. 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 +#include + +namespace socket { + /* Allows casting R(Args...) */ + template + 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 + class Socket { + /* The type of handler function or methods */ + using HandlerType = std::function; + + + /* 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 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 + 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...); + } + }; +} -- cgit v1.2.3