summaryrefslogtreecommitdiff
path: root/modules/codec/c++/rpc.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/codec/c++/rpc.hpp')
-rw-r--r--modules/codec/c++/rpc.hpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/modules/codec/c++/rpc.hpp b/modules/codec/c++/rpc.hpp
new file mode 100644
index 0000000..2c97d6b
--- /dev/null
+++ b/modules/codec/c++/rpc.hpp
@@ -0,0 +1,169 @@
+#pragma once
+
+#include <forstio/id.hpp>
+#include <forstio/codec/data.hpp>
+#include <forstio/async/async.hpp>
+
+#include <forstio/codec/interface.hpp>
+
+#include <variant>
+
+namespace saw {
+
+/**
+ * This class acts as a helper for rpc calls and representing data on the remote.
+ */
+template<typename T, typename Encoding, typename Storage>
+class data_or_id {
+private:
+ /**
+ * Variant representing the either id or data class.
+ */
+ std::variant<id<T>, data<T,Encoding, Storage>> doi_;
+public:
+ /**
+ * Constructor for instantiating.
+ */
+ data_or_id(const id<T>& val):
+ doi_{val}
+ {}
+
+ /**
+ * Constructor for instantiating.
+ */
+ data_or_id(data<T,Encoding, Storage> val):
+ doi_{std::move(val)}
+ {}
+
+ /**
+ * Check if this class holds an id.
+ */
+ bool is_id() const {
+ return std::holds_alternative<id<T>>(doi_);
+ }
+
+ /**
+ * Check if this class holds data.
+ */
+ bool is_data() const {
+ return std::holds_alternative<data<T,Encoding,Storage>>(doi_);
+ }
+
+ /**
+ * Returns the id.
+ */
+ id<T> get_id() const {
+ return std::get<id<T>>(doi_);
+ }
+
+ /**
+ * Return a data reference.
+ */
+ data<T,Encoding, Storage>& get_data(){
+ return std::get<data<T,Encoding, Storage>>(doi_);
+ }
+
+ /**
+ * Return a data reference.
+ */
+ const data<T,Encoding,Storage>& get_data() const {
+ return std::get<data<T,Encoding,Storage>>(doi_);
+ }
+};
+
+/**
+ * Representing data on the remote
+ */
+template<typename T, typename Encoding, typename Storage, typename Remote>
+class remote_data {
+private:
+ id<T> id_;
+public:
+ remote_data(const id<T>& id):
+ id_{id}
+ {}
+
+ /**
+ * Wait until data arrives
+ */
+ error_or<data<T, Encoding, Storage>> wait(wait_scope& wait);
+
+ /**
+ * Asynchronously wait for a result
+ */
+ conveyor<data<T, Encoding, Storage>> on_receive();
+};
+
+/**
+ * Client RPC reference structure
+ */
+template<typename Iface, typename Encoding, typename Storage, typename Remote>
+class rpc_client {
+ /**
+ * request the data from the remote
+ */
+ template<typename IdT>
+ remote_data<IdT, Encoding, Storage, Remote> request_data(id<IdT> data);
+
+ /** @todo
+ * Determine type based on Name
+ */
+ /*
+ template<string_literal Name>
+ error_or<
+ id<
+ typename schema_member_type<Name, Iface>::type
+ >
+ > call(data_or_id<Input> inp);
+ */
+};
+
+/**
+ * Implementation of a remote server on the backend
+ */
+template<typename Iface, typename Encoding, typename Storage, typename Remote>
+class rpc_server {
+private:
+ interface<Iface, Encoding, Storage> iface_;
+public:
+ rpc_server(interface<Iface, Encoding, Storage> iface):
+ iface_{std::move(iface)}
+ {}
+};
+
+/**
+ * Representation of a remote.
+ * Partially similar to a network address
+ */
+template<typename Remote>
+class remote_address {
+ static_assert(always_false<Remote>, "Type of remote not supported");
+
+
+};
+
+/**
+ * Reference Backend structure
+ */
+template<typename Remote>
+class remote {
+ static_assert(always_false<Remote>, "Type of backend not supported");
+
+ /**
+ * Resolves an address for the remote
+ */
+ conveyor<remote_address<Remote>> resolve_address();
+
+ /**
+ * Connect to a remote
+ */
+ template<typename Iface, typename Encode, typename Storage>
+ conveyor<rpc_client<Iface, Encode, Storage, Remote>> connect(const remote_address<Remote>& addr);
+
+ /**
+ * Start listening
+ */
+ template<typename Iface, typename Encode, typename Storage>
+ rpc_server<Iface, Encode, Storage, Remote> listen();
+};
+}