summaryrefslogtreecommitdiff
path: root/modules/remote/c++/remote.hpp
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2026-11-07 17:30:41 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2026-11-07 17:30:41 +0100
commit55fb3a9221ea91453573453288ecedb6ea79b7ba (patch)
tree128945e3e15ae03a11c46f9e490f4dbaafa5de67 /modules/remote/c++/remote.hpp
parentc90823bde9aea6b8f4c9737a0d8d5cd17560e8b9 (diff)
downloadforstio-forstio-55fb3a9221ea91453573453288ecedb6ea79b7ba.tar.gz
Creating out of source doc files
Diffstat (limited to 'modules/remote/c++/remote.hpp')
-rw-r--r--modules/remote/c++/remote.hpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/modules/remote/c++/remote.hpp b/modules/remote/c++/remote.hpp
index 83e6042..62d79c9 100644
--- a/modules/remote/c++/remote.hpp
+++ b/modules/remote/c++/remote.hpp
@@ -5,6 +5,7 @@
#include <forstio/codec/data.hpp>
#include <forstio/codec/interface.hpp>
+#include <forstio/codec/schema_hash.hpp>
#include <variant>
@@ -99,6 +100,61 @@ struct tmpl_group_to_data_client_std_tuple<tmpl_group<T...>, Encoding, Remote> {
using type = std::tuple<data_client<T,Encoding,Remote>...>;
};
}
+/**
+ * Identifier of an interface function on the wire.
+ *
+ * Keyed on the member name instead of the member index, so reordering an
+ * interface doesn't silently rebind calls between versions.
+ */
+template<string_literal Lit>
+struct rpc_function_id {
+ static constexpr uint32_t value = hash_literal<Lit>::apply(0u);
+};
+
+namespace impl {
+/**
+ * Translates a runtime function id back into the compile time member name
+ * of an interface.
+ *
+ * Needed by every backend where the called function arrives as data instead
+ * of as a template argument.
+ */
+template<typename Iface>
+struct iface_dispatch {
+ static_assert(always_false<Iface>, "Expecting an Interface Type");
+};
+
+template<typename... T, string_literal... Names>
+struct iface_dispatch<schema::Interface<schema::Member<T,Names>...>> {
+ template<typename Ret, uint64_t i, typename Func>
+ static Ret apply_ele(uint32_t func_id, Func& func){
+ if constexpr ( i < sizeof...(Names) ){
+ constexpr string_literal Lit = parameter_key_pack_type<i, Names...>::literal;
+
+ if(func_id == rpc_function_id<Lit>::value){
+ return func.template operator()<Lit>();
+ }
+
+ return apply_ele<Ret, i+1u>(func_id, func);
+ } else {
+ (void) func_id;
+ (void) func;
+ return make_error<err::not_found>("No interface member with this function id");
+ }
+ }
+
+ /**
+ * Calls func.operator()<Name>() for the member matching the id.
+ * The return type has to be provided, since there is no member to
+ * deduce it from if the id doesn't match anything.
+ */
+ template<typename Ret, typename Func>
+ static Ret apply(uint32_t func_id, Func&& func){
+ return apply_ele<Ret, 0u>(func_id, func);
+ }
+};
+}
+
template<typename Remote>
class i_rpc_server {
protected: