diff options
| author | Claudius "keldu" Holeksa <mail@keldu.de> | 2026-11-07 17:30:41 +0100 |
|---|---|---|
| committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2026-11-07 17:30:41 +0100 |
| commit | 55fb3a9221ea91453573453288ecedb6ea79b7ba (patch) | |
| tree | 128945e3e15ae03a11c46f9e490f4dbaafa5de67 /modules/remote/c++/remote.hpp | |
| parent | c90823bde9aea6b8f4c9737a0d8d5cd17560e8b9 (diff) | |
| download | forstio-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.hpp | 56 |
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: |
