diff options
Diffstat (limited to 'docs_oos')
21 files changed, 1652 insertions, 6 deletions
diff --git a/docs_oos/data/error.json b/docs_oos/data/error.json deleted file mode 100644 index 55d5e51..0000000 --- a/docs_oos/data/error.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - members = [ - ], - methods = [ - ] -} diff --git a/docs_oos/data/remote/data_client.json b/docs_oos/data/remote/data_client.json new file mode 100644 index 0000000..fc717b6 --- /dev/null +++ b/docs_oos/data/remote/data_client.json @@ -0,0 +1,31 @@ +{ + "format": 1, + "id": "saw-data_client", + "kind": "class", + "name": "data_client", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer.hpp", + "brief_description": "Handle on a data server of one schema.", + "detailed_description": [ + [ + "The caller side of the transport layer. Values are sent and received through it, and ids are what comes back, since the data itself stays on the", + {"name": "data_server", "id": "saw-data_server"} + ], + [ + "Only declared by the primary template and defined per backend." + ] + ], + "templates": [ + {"name": "Schema", "kind": "type", "brief_description": "Schema of the transported data."}, + {"name": "Encoding", "kind": "type", "brief_description": "Encoding of the transported data."}, + {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} + ], + "specializations": [ + { + "name": "data_client< Schema, Encoding, rmt::Loopback >", + "id": "saw-data_client-loopback", + "brief_description": "Talks to a server in the same process, so nothing is serialized." + } + ] +} diff --git a/docs_oos/data/remote/data_client.loopback.json b/docs_oos/data/remote/data_client.loopback.json new file mode 100644 index 0000000..515209d --- /dev/null +++ b/docs_oos/data/remote/data_client.loopback.json @@ -0,0 +1,112 @@ +{ + "format": 1, + "id": "saw-data_client-loopback", + "kind": "class", + "name": "data_client", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer_loopback.hpp", + "is_special": true, + "specializes": "saw-data_client", + "arguments": ["Schema", "Encoding", "rmt::Loopback"], + "brief_description": "Talks to a data server in the same process.", + "detailed_description": [ + [ + "Every call forwards straight to the server, so nothing is serialized and nothing can fail on the way. Ids are asked for rather than guessed, because the server is the only instance which knows about every client." + ] + ], + "templates": [ + {"name": "Schema", "kind": "type"}, + {"name": "Encoding", "kind": "type"} + ], + "attributes": { + "saw-data_client-loopback-srv_": { + "id": "saw-data_client-loopback-srv_", + "name": "srv_", + "type": ["ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< Schema, Encoding, rmt::Loopback > >"], + "visibility": "private" + } + }, + "functions": { + "saw-data_client-loopback-next_free_id": { + "id": "saw-data_client-loopback-next_free_id", + "name": "next_free_id", + "type": ["error_or< id< Schema > >"], + "brief_description": "Asks the remote for an id which is not in use yet.", + "detailed_description": [ + [ + "Free here, a roundtrip on a backend which is not in process. Worth avoiding when the server can pick the id itself." + ] + ] + }, + "saw-data_client-loopback-send-1": { + "id": "saw-data_client-loopback-send-1", + "name": "send", + "type": ["error_or< id< Schema > >"], + "brief_description": "Sends data to the remote and returns the id it was stored under.", + "parameters": [ + {"name": "dat", "type": ["const data< Schema, Encoding > &"]} + ] + }, + "saw-data_client-loopback-send-2": { + "id": "saw-data_client-loopback-send-2", + "name": "send", + "type": ["error_or< void >"], + "brief_description": "Sends data to the remote and stores it under a specific id.", + "parameters": [ + {"name": "dat", "type": ["const data< Schema, Encoding > &"]}, + {"name": "dat_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_client-loopback-allocate": { + "id": "saw-data_client-loopback-allocate", + "name": "allocate", + "type": ["error_or< id< Schema > >"], + "brief_description": "Preallocates data on the remote without sending a value.", + "parameters": [ + { + "name": "meta", + "type": ["const data< typename meta_schema< Schema >::MetaSchema, Encoding > &"], + "brief_description": "Dimensions and whatever else the schema needs to exist." + } + ] + }, + "saw-data_client-loopback-receive": { + "id": "saw-data_client-loopback-receive", + "name": "receive", + "type": ["conveyor< data< Schema, Encoding > >"], + "brief_description": "Receives the data stored under an id.", + "detailed_description": [ + [ + "A conveyor even though this backend answers immediately, so code written against it keeps working on a backend which has to wait." + ] + ], + "parameters": [ + {"name": "dat_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_client-loopback-erase": { + "id": "saw-data_client-loopback-erase", + "name": "erase", + "type": ["error_or< void >"], + "brief_description": "Erases the data stored under an id.", + "parameters": [ + {"name": "dat_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_client-loopback-find": { + "id": "saw-data_client-loopback-find", + "name": "find", + "type": ["error_or< ptr< data< Schema, Encoding > > >"], + "brief_description": "Returns a pointer to the stored data itself.", + "detailed_description": [ + [ + "An exception for this backend. Here it is safe to use find from the client side, because the data never left the process." + ] + ], + "parameters": [ + {"name": "dat_id", "type": ["id< Schema >"]} + ] + } + } +} diff --git a/docs_oos/data/remote/data_or_id.json b/docs_oos/data/remote/data_or_id.json new file mode 100644 index 0000000..c3152e9 --- /dev/null +++ b/docs_oos/data/remote/data_or_id.json @@ -0,0 +1,78 @@ +{ + "format": 1, + "id": "saw-data_or_id", + "kind": "class", + "name": "data_or_id", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Helper for rpc calls. Either a value or its place on the remote.", + "detailed_description": [ + [ + "A parameter is in one of two states: still here, or already on the remote from an earlier call. This carries both so a call site doesn't have to branch, and so a result can be fed into the next call without a roundtrip." + ], + [ + "Both constructors are implicit, which is what lets a plain value be passed where a call expects one of these." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "Schema of the data."}, + {"name": "Encoding", "kind": "type"} + ], + "attributes": { + "saw-data_or_id-doi_": { + "id": "saw-data_or_id-doi_", + "name": "doi_", + "type": ["std::variant< id< T >, data< T, Encoding > >"], + "visibility": "private", + "brief_description": "Variant representing either the id or the data class." + } + }, + "functions": { + "saw-data_or_id-ctor-1": { + "id": "saw-data_or_id-ctor-1", + "name": "data_or_id", + "type": [], + "brief_description": "Refers to data already on the remote.", + "parameters": [ + {"name": "val", "type": ["const id< T > &"]} + ] + }, + "saw-data_or_id-ctor-2": { + "id": "saw-data_or_id-ctor-2", + "name": "data_or_id", + "type": [], + "brief_description": "Carries data which still has to be sent.", + "parameters": [ + {"name": "val", "type": ["data< T, Encoding >"]} + ] + }, + "saw-data_or_id-is_id": { + "id": "saw-data_or_id-is_id", + "name": "is_id", + "type": ["bool"], + "const": true, + "brief_description": "Checks if this class holds an id." + }, + "saw-data_or_id-is_data": { + "id": "saw-data_or_id-is_data", + "name": "is_data", + "type": ["bool"], + "const": true, + "brief_description": "Checks if this class holds data." + }, + "saw-data_or_id-get_id": { + "id": "saw-data_or_id-get_id", + "name": "get_id", + "type": ["id< T >"], + "const": true, + "brief_description": "Returns the id." + }, + "saw-data_or_id-get_data": { + "id": "saw-data_or_id-get_data", + "name": "get_data", + "type": ["data< T, Encoding > &"], + "brief_description": "Returns a data reference." + } + } +} diff --git a/docs_oos/data/remote/data_server.json b/docs_oos/data/remote/data_server.json new file mode 100644 index 0000000..1be7c93 --- /dev/null +++ b/docs_oos/data/remote/data_server.json @@ -0,0 +1,44 @@ +{ + "format": 1, + "id": "saw-data_server", + "kind": "class", + "name": "data_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer.hpp", + "brief_description": "Owns the data of one schema on one backend.", + "detailed_description": [ + [ + "The transport layer. A data server stores values under ids and is the only thing which knows where they physically live." + ], + [ + "The", + {"name": "rpc_server", "id": "saw-rpc_server"}, + "is an overlay on top of it and never touches the data itself, only the ids. That split is what lets the same interface run against memory, a file or a device." + ] + ], + "templates": [ + { + "name": "Schema", + "kind": "type", + "brief_description": "Schema of the stored data." + }, + { + "name": "Encoding", + "kind": "type", + "brief_description": "Encoding the data is stored in." + }, + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "specializations": [ + { + "name": "data_server< Schema, Encoding, rmt::Loopback >", + "id": "saw-data_server-loopback", + "brief_description": "Keeps the values in a map in this process." + } + ] +} diff --git a/docs_oos/data/remote/data_server.loopback.json b/docs_oos/data/remote/data_server.loopback.json new file mode 100644 index 0000000..daca8e0 --- /dev/null +++ b/docs_oos/data/remote/data_server.loopback.json @@ -0,0 +1,165 @@ +{ + "format": 1, + "id": "saw-data_server-loopback", + "kind": "class", + "name": "data_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer_loopback.hpp", + "is_special": true, + "specializes": "saw-data_server", + "arguments": ["Schema", "Encoding", "rmt::Loopback"], + "brief_description": "Keeps the values of one schema in a map in this process.", + "detailed_description": [ + [ + "Registers itself with its", + {"name": "remote", "id": "saw-remote-loopback"}, + "on construction and deregisters on destruction, so its lifetime is what a client sees as the server being reachable." + ], + [ + "Ids are owned by the server, since it is the only instance which knows about every client." + ] + ], + "templates": [ + {"name": "Schema", "kind": "type"}, + {"name": "Encoding", "kind": "type"} + ], + "attributes": { + "saw-data_server-loopback-class_id": { + "id": "saw-data_server-loopback-class_id", + "name": "class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "{schema_hash<Schema>::apply(), schema_hash<Encoding>::apply()}", + "brief_description": "Unique key for identifying an underlying data type without using typeid." + }, + "saw-data_server-loopback-values_": { + "id": "saw-data_server-loopback-values_", + "name": "values_", + "type": ["std::unordered_map< uint64_t, data< Schema, Encoding > >"], + "visibility": "private" + }, + "saw-data_server-loopback-next_id_": { + "id": "saw-data_server-loopback-next_id_", + "name": "next_id_", + "type": ["uint64_t"], + "visibility": "private", + "initializer": "0u", + "brief_description": "Counter for handing out ids." + } + }, + "functions": { + "saw-data_server-loopback-get_class_id": { + "id": "saw-data_server-loopback-get_class_id", + "name": "get_class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "const": true, + "override": true, + "brief_description": "Returns the schema id." + }, + "saw-data_server-loopback-next_free_id": { + "id": "saw-data_server-loopback-next_free_id", + "name": "next_free_id", + "type": ["id< Schema >"], + "brief_description": "Hands out the next id which is not in use yet.", + "detailed_description": [ + [ + "The id is not reserved by this call. It is only in use once something is stored under it, so two calls without a store in between return the same id." + ] + ] + }, + "saw-data_server-loopback-send-1": { + "id": "saw-data_server-loopback-send-1", + "name": "send", + "type": ["error_or< void >"], + "brief_description": "Stores a value under an id without taking over the source.", + "detailed_description": [ + ["Fails with already_exists if the id is taken."] + ], + "parameters": [ + {"name": "dat", "type": ["ref< data< Schema, Encoding > >"]}, + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-send-2": { + "id": "saw-data_server-loopback-send-2", + "name": "send", + "type": ["error_or< void >"], + "brief_description": "Stores a value under an id, taking it over.", + "detailed_description": [ + ["Fails with already_exists if the id is taken."] + ], + "parameters": [ + {"name": "dat", "type": ["data< Schema, Encoding >"]}, + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-allocate": { + "id": "saw-data_server-loopback-allocate", + "name": "allocate", + "type": ["error_or< void >"], + "brief_description": "Reserves storage described by the meta schema without sending a value.", + "detailed_description": [ + [ + "The counterpart to sending for backends where the output has to exist before it is written, such as a device buffer." + ] + ], + "parameters": [ + { + "name": "meta", + "type": ["data< typename meta_schema< Schema >::MetaSchema, Encoding >"], + "brief_description": "Dimensions and whatever else the schema needs to exist." + }, + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-receive": { + "id": "saw-data_server-loopback-receive", + "name": "receive", + "type": ["error_or< data< Schema, Encoding > >"], + "brief_description": "Returns a copy of the value stored under an id.", + "detailed_description": [ + ["Fails with not_found if nothing is stored under that id."] + ], + "parameters": [ + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-erase": { + "id": "saw-data_server-loopback-erase", + "name": "erase", + "type": ["error_or< void >"], + "brief_description": "Drops the value stored under an id.", + "detailed_description": [ + ["Fails with not_found if nothing is stored under that id."] + ], + "parameters": [ + {"name": "store_id", "type": ["id< Schema >"]} + ] + }, + "saw-data_server-loopback-find": { + "id": "saw-data_server-loopback-find", + "name": "find", + "type": ["error_or< ptr< data< Schema, Encoding > > >"], + "brief_description": "Returns a pointer to the stored value itself.", + "detailed_description": [ + [ + "An exception for this backend. Only meaningful because the data is in process, and a store may invalidate the pointer." + ], + [ + "The", + {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, + "uses it to hand a parameter to an interface function without copying it out of the server first." + ] + ], + "parameters": [ + {"name": "store_id", "type": ["id< Schema >"]} + ] + } + }, + "notes": [ + "Copy and move are forbidden, because the remote holds a pointer to this object while it is registered." + ] +} diff --git a/docs_oos/data/remote/i_data_server.json b/docs_oos/data/remote/i_data_server.json new file mode 100644 index 0000000..ecde59c --- /dev/null +++ b/docs_oos/data/remote/i_data_server.json @@ -0,0 +1,53 @@ +{ + "format": 1, + "id": "saw-i_data_server", + "kind": "class", + "name": "i_data_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/transfer.hpp", + "brief_description": "Registry handle for a data server of unknown schema.", + "detailed_description": [ + [ + "The one place the library erases a type. A", + {"name": "remote", "id": "saw-remote"}, + "holds servers for many schemas in one map, which is only possible if they share a type. The class id recovers what was erased: a caller which knows the schema it wants asks for exactly that one and gets an error if the stored server is a different one." + ], + [ + "The destructor is protected, so nothing can be deleted through this handle." + ] + ], + "templates": [ + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "functions": { + "saw-i_data_server-get_class_id": { + "id": "saw-i_data_server-get_class_id", + "name": "get_class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "const": true, + "virtual": true, + "brief_description": "Schema hash and encoding hash of the server behind this handle." + }, + "saw-i_data_server-cast_to": { + "id": "saw-i_data_server-cast_to", + "name": "cast_to", + "type": ["error_or< ptr< To > >"], + "brief_description": "Recovers the concrete server.", + "detailed_description": [ + ["Fails with invalid_state if the class ids don't match, which is what keeps the erasure honest."] + ], + "templates": [ + { + "name": "To", + "kind": "type", + "brief_description": "The concrete data server expected behind this handle." + } + ] + } + } +} diff --git a/docs_oos/data/remote/i_rpc_server.json b/docs_oos/data/remote/i_rpc_server.json new file mode 100644 index 0000000..b648f4c --- /dev/null +++ b/docs_oos/data/remote/i_rpc_server.json @@ -0,0 +1,53 @@ +{ + "format": 1, + "id": "saw-i_rpc_server", + "kind": "class", + "name": "i_rpc_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Registry handle for an rpc server of unknown interface.", + "detailed_description": [ + [ + "The counterpart of", + {"name": "i_data_server", "id": "saw-i_data_server"}, + "for the rpc layer. It exists so a remote can keep servers of different interfaces in one map and hand back the right one when a client requests it." + ], + [ + "Here the class id is the interface hash together with the encoding hash, so connecting with a different interface than the one being served fails instead of reinterpreting the server." + ] + ], + "templates": [ + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "functions": { + "saw-i_rpc_server-get_class_id": { + "id": "saw-i_rpc_server-get_class_id", + "name": "get_class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "const": true, + "virtual": true, + "brief_description": "Interface hash and encoding hash of the server behind this handle." + }, + "saw-i_rpc_server-cast_to": { + "id": "saw-i_rpc_server-cast_to", + "name": "cast_to", + "type": ["error_or< ptr< To > >"], + "brief_description": "Recovers the concrete server.", + "detailed_description": [ + ["Fails with invalid_state if the class ids don't match."] + ], + "templates": [ + { + "name": "To", + "kind": "type", + "brief_description": "The concrete rpc server expected behind this handle." + } + ] + } + } +} diff --git a/docs_oos/data/remote/loopback.json b/docs_oos/data/remote/loopback.json new file mode 100644 index 0000000..e0d150e --- /dev/null +++ b/docs_oos/data/remote/loopback.json @@ -0,0 +1,15 @@ +{ + "format": 1, + "id": "saw-rmt-loopback", + "kind": "struct", + "name": "Loopback", + "namespace": "saw::rmt", + "module": "remote", + "header": "modules/remote/c++/remote_loopback_base.hpp", + "brief_description": "Tag of the in process backend.", + "detailed_description": [ + [ + "An empty type. It carries no state and is never instantiated; it exists to select the specializations which make up a backend, and it is the argument every class in the remote module is specialized on." + ] + ] +} diff --git a/docs_oos/data/remote/remote.json b/docs_oos/data/remote/remote.json new file mode 100644 index 0000000..3c9e1a6 --- /dev/null +++ b/docs_oos/data/remote/remote.json @@ -0,0 +1,36 @@ +{ + "format": 1, + "id": "saw-remote", + "kind": "class", + "name": "remote", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Reference backend structure.", + "detailed_description": [ + [ + "The primary template is never defined. A backend is added by specializing this class on its tag type, which is the only place the backend itself appears in the public api. An unsupported tag fails with a static_assert instead of a linker error." + ], + [ + "Every", + {"name": "data_server", "id": "saw-data_server"}, + "and", + {"name": "rpc_server", "id": "saw-rpc_server"}, + "of a backend is owned and handed out by its remote, which is also the registry a client searches when it connects." + ] + ], + "templates": [ + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend, e.g. rmt::Loopback." + } + ], + "specializations": [ + { + "name": "remote< rmt::Loopback >", + "id": "saw-remote-loopback", + "brief_description": "In process backend. Data stays where it is and calls are answered inline." + } + ] +} diff --git a/docs_oos/data/remote/remote.loopback.json b/docs_oos/data/remote/remote.loopback.json new file mode 100644 index 0000000..83c2ee8 --- /dev/null +++ b/docs_oos/data/remote/remote.loopback.json @@ -0,0 +1,182 @@ +{ + "format": 1, + "id": "saw-remote-loopback", + "kind": "class", + "name": "remote", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback_base.hpp", + "is_special": true, + "specializes": "saw-remote", + "arguments": ["rmt::Loopback"], + "brief_description": "In process backend.", + "detailed_description": [ + [ + "The reference implementation every other backend is measured against. Nothing is serialized and nothing is copied across a boundary, so what remains is the bookkeeping every backend has to do." + ], + [ + "Servers are registered under the address they listen on together with their class id, so a client asking for a schema on an address finds the one server which owns it." + ] + ], + "examples": [ + { + "title": "Serving an interface and calling it", + "description": [ + [ + "The whole flow on one address: bring up the data servers, bind an interface to them, connect, call. Error handling is left out, but note that every error_or is kept in a named variable, because get_value hands back a reference into it." + ], + [ + "The data servers have to exist before", + {"name": "rpc_listen", "id": "saw-remote-loopback-rpc_listen"}, + "is called, since that is where the parameter and the answer live." + ] + ], + "language": "cpp", + "code": "using TestInterface = schema::Interface<\n\tschema::Member<schema::Function<schema::UInt32, schema::Int64>, \"foo\">\n>;\n\nevent_loop loop;\nwait_scope wait{loop};\n\nremote<rmt::Loopback> rmt;\n\nauto eo_addr = rmt.parse_address(0u);\nauto& addr = eo_addr.get_value();\n\n/// The transport layer, one server per schema the interface mentions.\nauto eo_u32_srv = rmt.data_listen<schema::UInt32, encode::Native>(*addr);\nauto eo_i64_srv = rmt.data_listen<schema::Int64, encode::Native>(*addr);\n\nauto iface = interface_factory<TestInterface, encode::Native>::create(\n\t[](data<schema::UInt32, encode::Native> input)\n\t\t-> error_or<data<schema::Int64, encode::Native>>\n\t{\n\t\tdata<schema::Int64, encode::Native> rv;\n\t\trv.set(input.get() * 2);\n\t\treturn rv;\n\t});\n\nauto eo_rpc_srv = rmt.rpc_listen<TestInterface, encode::Native>(*addr, std::move(iface));\n\n/// The overlay on top of it.\nauto cvr_client = rmt.rpc_connect<TestInterface, encode::Native>(*addr);\nauto eo_client = cvr_client.take();\nauto& client = eo_client.get_value();\n\ndata<schema::UInt32, encode::Native> inp{21};\n\nauto cvr_result = client.call<\"foo\">(std::move(inp));\nauto eo_result = cvr_result.take();\nauto& result = eo_result.get_value();\n\n/// The answer never left the server. result only knows the id it picked.\nauto eo_value = result.wait(wait);\n/// eo_value.get_value().get() == 42\n" + } + ], + "attributes": { + "saw-remote-loopback-registered_data_servers_": { + "id": "saw-remote-loopback-registered_data_servers_", + "name": "registered_data_servers_", + "type": ["std::map< key_t, ptr<", {"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > > >"], + "visibility": "private", + "brief_description": "Keyed by address id, schema hash and encoding hash." + }, + "saw-remote-loopback-registered_rpc_servers_": { + "id": "saw-remote-loopback-registered_rpc_servers_", + "name": "registered_rpc_servers_", + "type": ["std::map< key_t, ptr<", {"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > > >"], + "visibility": "private", + "brief_description": "Keyed by address id, interface hash and encoding hash." + } + }, + "functions": { + "saw-remote-loopback-parse_address": { + "id": "saw-remote-loopback-parse_address", + "name": "parse_address", + "type": ["error_or< own<", {"name": "remote_address", "id": "saw-remote_address-loopback"}, "< rmt::Loopback > > >"], + "brief_description": "Resolves an address for the remote.", + "parameters": [ + { + "name": "id", + "type": ["data< schema::UInt64 >"], + "brief_description": "Identifier standing in for what a network address would be." + } + ] + }, + "saw-remote-loopback-data_listen": { + "id": "saw-remote-loopback-data_listen", + "name": "data_listen", + "type": ["error_or< own<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< Schema, Encode, rmt::Loopback > > >"], + "brief_description": "Starts a data server for one schema on an address.", + "detailed_description": [ + [ + "Fails with already_exists if a server for the same schema and encoding is already bound to that address. The returned server registers itself and stays reachable until it is destroyed." + ] + ], + "templates": [ + {"name": "Schema", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-data_connect": { + "id": "saw-remote-loopback-data_connect", + "name": "data_connect", + "type": ["conveyor<", {"name": "data_client", "id": "saw-data_client-loopback"}, "< Schema, Encode, rmt::Loopback > >"], + "brief_description": "Connects to a data server.", + "detailed_description": [ + ["Fails with not_found if nothing listens for that schema on that address."] + ], + "templates": [ + {"name": "Schema", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-rpc_listen": { + "id": "saw-remote-loopback-rpc_listen", + "name": "rpc_listen", + "type": ["error_or< own<", {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, "< Iface, Encode, rmt::Loopback > > >"], + "brief_description": "Starts an rpc server for an interface on an address.", + "detailed_description": [ + [ + "Every schema the interface mentions needs a data server on the same address beforehand, since that is where parameters and responses live. A missing one fails the call with not_found." + ] + ], + "templates": [ + {"name": "Iface", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "parameters": [ + {"name": "addr", "type": ["remote_address< rmt::Loopback > &"]}, + { + "name": "iface", + "type": ["typename rpc_server< Iface, Encode, rmt::Loopback >::InterfaceT"], + "brief_description": "The implementations backing the interface." + } + ] + }, + "saw-remote-loopback-rpc_connect": { + "id": "saw-remote-loopback-rpc_connect", + "name": "rpc_connect", + "type": ["conveyor<", {"name": "rpc_client", "id": "saw-rpc_client-loopback"}, "< Iface, Encode, rmt::Loopback > >"], + "brief_description": "Connects to an rpc server.", + "detailed_description": [ + ["Defined in remote_loopback.hpp, since the client has to be a complete type at that point."] + ], + "templates": [ + {"name": "Iface", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-register_data_server": { + "id": "saw-remote-loopback-register_data_server", + "name": "register_data_server", + "type": ["error_or< void >"], + "brief_description": "Internal. Called by a data server on construction.", + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, + {"name": "srv", "type": [{"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-deregister_data_server": { + "id": "saw-remote-loopback-deregister_data_server", + "name": "deregister_data_server", + "type": ["error_or< void >"], + "brief_description": "Internal. Called by a data server on destruction.", + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, + {"name": "srv", "type": [{"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-register_rpc_server": { + "id": "saw-remote-loopback-register_rpc_server", + "name": "register_rpc_server", + "type": ["error_or< void >"], + "brief_description": "Internal. Called by an rpc server on construction.", + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, + {"name": "srv", "type": [{"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > &"]} + ] + }, + "saw-remote-loopback-deregister_rpc_server": { + "id": "saw-remote-loopback-deregister_rpc_server", + "name": "deregister_rpc_server", + "type": ["error_or< void >"], + "brief_description": "Internal. Called by an rpc server on destruction.", + "parameters": [ + {"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}, + {"name": "srv", "type": [{"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > &"]} + ] + } + } +} diff --git a/docs_oos/data/remote/remote_address.json b/docs_oos/data/remote/remote_address.json new file mode 100644 index 0000000..783527c --- /dev/null +++ b/docs_oos/data/remote/remote_address.json @@ -0,0 +1,34 @@ +{ + "format": 1, + "id": "saw-remote_address", + "kind": "class", + "name": "remote_address", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Representation of a remote. Partially similar to a network address.", + "detailed_description": [ + [ + "What an address is depends entirely on the backend. A loopback address is a number, a file address is a path, a socket address is host and port." + ], + [ + "Addresses are produced by the parse_address of their own", + {"name": "remote", "id": "saw-remote"}, + "and are meaningless to any other backend." + ] + ], + "templates": [ + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "specializations": [ + { + "name": "remote_address< rmt::Loopback >", + "id": "saw-remote_address-loopback", + "brief_description": "A plain identifier, since there is nothing to address but the process itself." + } + ] +} diff --git a/docs_oos/data/remote/remote_address.loopback.json b/docs_oos/data/remote/remote_address.loopback.json new file mode 100644 index 0000000..ec7d5e4 --- /dev/null +++ b/docs_oos/data/remote/remote_address.loopback.json @@ -0,0 +1,43 @@ +{ + "format": 1, + "id": "saw-remote_address-loopback", + "kind": "class", + "name": "remote_address", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback_base.hpp", + "is_special": true, + "specializes": "saw-remote_address", + "arguments": ["rmt::Loopback"], + "brief_description": "Address of an in process endpoint.", + "detailed_description": [ + [ + "There is nothing to address but the process itself, so the address is a plain number. It still has to exist, because it is the component which separates two endpoints serving the same schema." + ] + ], + "attributes": { + "saw-remote_address-loopback-addr_id_": { + "id": "saw-remote_address-loopback-addr_id_", + "name": "addr_id_", + "type": ["data< schema::UInt64 >"], + "visibility": "private" + } + }, + "functions": { + "saw-remote_address-loopback-ctor": { + "id": "saw-remote_address-loopback-ctor", + "name": "remote_address", + "type": [], + "parameters": [ + {"name": "addr_id__", "type": ["data< schema::UInt64 >"]} + ] + }, + "saw-remote_address-loopback-get_address_id": { + "id": "saw-remote_address-loopback-get_address_id", + "name": "get_address_id", + "type": ["const data< schema::UInt64 > &"], + "const": true, + "brief_description": "The identifier this address stands for." + } + } +} diff --git a/docs_oos/data/remote/remote_data.json b/docs_oos/data/remote/remote_data.json new file mode 100644 index 0000000..1086ca4 --- /dev/null +++ b/docs_oos/data/remote/remote_data.json @@ -0,0 +1,30 @@ +{ + "format": 1, + "id": "saw-remote_data", + "kind": "class", + "name": "remote_data", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Representing data on the remote.", + "detailed_description": [ + [ + "What an rpc call hands back. It is an id plus a way to resolve it, not the value, so a result can be passed into the next call without ever being pulled across." + ], + [ + "Only declared by the primary template and defined per backend." + ] + ], + "templates": [ + {"name": "T", "kind": "type", "brief_description": "Schema of the data on the remote."}, + {"name": "Encoding", "kind": "type"}, + {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} + ], + "specializations": [ + { + "name": "remote_data< T, Encoding, rmt::Loopback >", + "id": "saw-remote_data-loopback", + "brief_description": "Resolves immediately, since the call it came from was answered inline." + } + ] +} diff --git a/docs_oos/data/remote/remote_data.loopback.json b/docs_oos/data/remote/remote_data.loopback.json new file mode 100644 index 0000000..32786aa --- /dev/null +++ b/docs_oos/data/remote/remote_data.loopback.json @@ -0,0 +1,70 @@ +{ + "format": 1, + "id": "saw-remote_data-loopback", + "kind": "class", + "name": "remote_data", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback.hpp", + "is_special": true, + "specializes": "saw-remote_data", + "arguments": ["T", "Encoding", "rmt::Loopback"], + "brief_description": "Handle for data which is stored on an in process remote.", + "detailed_description": [ + [ + "The result of an rpc call. Resolving it goes back through the data layer rather than through the rpc layer, which is why the handle carries the data server and not the rpc server." + ], + [ + "This backend answers calls inline, so the data is already present whenever the call succeeded and waiting costs nothing." + ] + ], + "templates": [ + {"name": "T", "kind": "type"}, + {"name": "Encoding", "kind": "type"} + ], + "attributes": { + "saw-remote_data-loopback-id_": { + "id": "saw-remote_data-loopback-id_", + "name": "id_", + "type": ["id< T >"], + "visibility": "private" + }, + "saw-remote_data-loopback-srv_": { + "id": "saw-remote_data-loopback-srv_", + "name": "srv_", + "type": ["ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< T, Encoding, rmt::Loopback > >"], + "visibility": "private" + } + }, + "functions": { + "saw-remote_data-loopback-get_id": { + "id": "saw-remote_data-loopback-get_id", + "name": "get_id", + "type": ["const id< T > &"], + "const": true, + "brief_description": "Id of the data on the remote.", + "detailed_description": [ + ["Hand this to the next call to keep a result where it is instead of pulling it across."] + ] + }, + "saw-remote_data-loopback-wait": { + "id": "saw-remote_data-loopback-wait", + "name": "wait", + "type": ["error_or< data< T, Encoding > >"], + "brief_description": "Waits until the data arrives.", + "parameters": [ + { + "name": "wait", + "type": ["wait_scope &"], + "brief_description": "Unused here, since there is nothing to wait for." + } + ] + }, + "saw-remote_data-loopback-on_receive": { + "id": "saw-remote_data-loopback-on_receive", + "name": "on_receive", + "type": ["conveyor< data< T, Encoding > >"], + "brief_description": "Asynchronously waits for the result." + } + } +} diff --git a/docs_oos/data/remote/rpc_client.json b/docs_oos/data/remote/rpc_client.json new file mode 100644 index 0000000..b9dd5ca --- /dev/null +++ b/docs_oos/data/remote/rpc_client.json @@ -0,0 +1,30 @@ +{ + "format": 1, + "id": "saw-rpc_client", + "kind": "class", + "name": "rpc_client", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Client RPC reference structure.", + "detailed_description": [ + [ + "The caller side of the overlay. Parameters and return values are moved by the data clients; the rpc layer only ties ids to a function call on the remote." + ], + [ + "Only declared by the primary template and defined per backend." + ] + ], + "templates": [ + {"name": "Iface", "kind": "type", "brief_description": "Interface schema being called."}, + {"name": "Encoding", "kind": "type", "brief_description": "Encoding of the parameters and responses."}, + {"name": "Remote", "kind": "type", "brief_description": "Tag type of the backend."} + ], + "specializations": [ + { + "name": "rpc_client< Iface, Encoding, rmt::Loopback >", + "id": "saw-rpc_client-loopback", + "brief_description": "Calls a server in the same process, which answers before the call returns." + } + ] +} diff --git a/docs_oos/data/remote/rpc_client.loopback.json b/docs_oos/data/remote/rpc_client.loopback.json new file mode 100644 index 0000000..c305255 --- /dev/null +++ b/docs_oos/data/remote/rpc_client.loopback.json @@ -0,0 +1,136 @@ +{ + "format": 1, + "id": "saw-rpc_client-loopback", + "kind": "class", + "name": "rpc_client", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback.hpp", + "is_special": true, + "specializes": "saw-rpc_client", + "arguments": ["Iface", "Encoding", "rmt::Loopback"], + "brief_description": "Calls an rpc server in the same process.", + "detailed_description": [ + [ + "Holds one", + {"name": "data_client", "id": "saw-data_client-loopback"}, + "per schema the interface mentions, all of them handles on the data servers the server is already bound to. A parameter which is not on the remote yet goes through the data layer first, and only its id reaches the rpc layer." + ] + ], + "templates": [ + {"name": "Iface", "kind": "type"}, + {"name": "Encoding", "kind": "type"} + ], + "aliases": { + "saw-rpc_client-loopback-ServerT": { + "id": "saw-rpc_client-loopback-ServerT", + "name": "ServerT", + "type": [{"name": "rpc_server", "id": "saw-rpc_server-loopback"}, "< Iface, Encoding, rmt::Loopback >"] + }, + "saw-rpc_client-loopback-TypeGroup": { + "id": "saw-rpc_client-loopback-TypeGroup", + "name": "TypeGroup", + "type": ["typename schema_iface_type_group< Iface >::Type"], + "brief_description": "Every schema the interface mentions, reduced to unique types." + }, + "saw-rpc_client-loopback-DataClients": { + "id": "saw-rpc_client-loopback-DataClients", + "name": "DataClients", + "type": ["std::tuple<", {"name": "data_client", "id": "saw-data_client-loopback"}, "< T, Encoding, rmt::Loopback >... >"], + "brief_description": "One data client per schema in the type group." + } + }, + "functions": { + "saw-rpc_client-loopback-get_data_client": { + "id": "saw-rpc_client-loopback-get_data_client", + "name": "get_data_client", + "type": [{"name": "data_client", "id": "saw-data_client-loopback"}, "< IdT, Encoding, rmt::Loopback > &"], + "brief_description": "The data client of one of the interface types.", + "detailed_description": [ + ["Useful when a parameter is meant to be sent once and reused in several calls."] + ], + "templates": [ + {"name": "IdT", "kind": "type", "brief_description": "One of the schemas the interface mentions."} + ], + "examples": [ + { + "title": "Sending a parameter once and calling with it twice", + "description": [ + [ + "Handing a value to call sends it every time. Sending it once and passing the id instead keeps it on the remote, which is the point of", + {"name": "data_or_id", "id": "saw-data_or_id"} + ] + ], + "language": "cpp", + "code": "data<schema::UInt32, encode::Native> inp{21};\n\nauto& u32_client = client.get_data_client<schema::UInt32>();\nauto eo_param = u32_client.send(inp);\nauto param = eo_param.get_value();\n\n/// Both calls refer to the same value on the remote.\nauto first = client.call<\"foo\">(param).take();\nauto second = client.call<\"foo\">(param).take();\n" + } + ] + }, + "saw-rpc_client-loopback-request_data": { + "id": "saw-rpc_client-loopback-request_data", + "name": "request_data", + "type": [{"name": "remote_data", "id": "saw-remote_data-loopback"}, "< IdT, Encoding, rmt::Loopback >"], + "brief_description": "Requests the data from the remote.", + "templates": [ + {"name": "IdT", "kind": "type"} + ], + "parameters": [ + {"name": "dat_id", "type": ["id< IdT >"]} + ] + }, + "saw-rpc_client-loopback-call-1": { + "id": "saw-rpc_client-loopback-call-1", + "name": "call", + "type": ["conveyor<", {"name": "remote_data", "id": "saw-remote_data-loopback"}, "< ResponseT, Encoding, rmt::Loopback > >"], + "brief_description": "Calls a function on the remote.", + "detailed_description": [ + [ + "The parameter is either already present on the remote, in which case only its id is handed over, or it is sent through the data layer first." + ], + [ + "The id of the response is picked by the server and travels back with the answer, so this is asynchronous in the id as well, not only in the data." + ] + ], + "templates": [ + { + "name": "Name", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member to call." + } + ], + "parameters": [ + { + "name": "input", + "type": [{"name": "data_or_id", "id": "saw-data_or_id"}, "< RequestT, Encoding >"], + "brief_description": "The parameter, or the id of one already on the remote." + } + ] + }, + "saw-rpc_client-loopback-call-2": { + "id": "saw-rpc_client-loopback-call-2", + "name": "call", + "type": ["conveyor<", {"name": "remote_data", "id": "saw-remote_data-loopback"}, "< ResponseT, Encoding, rmt::Loopback > >"], + "brief_description": "Calls a function and stores the response in a slot allocated beforehand.", + "templates": [ + { + "name": "Name", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member to call." + } + ], + "parameters": [ + { + "name": "input", + "type": [{"name": "data_or_id", "id": "saw-data_or_id"}, "< RequestT, Encoding >"] + }, + { + "name": "resp_id", + "type": ["id< ResponseT >"], + "brief_description": "Slot the answer has to end up in." + } + ] + } + } +} diff --git a/docs_oos/data/remote/rpc_function_id.json b/docs_oos/data/remote/rpc_function_id.json new file mode 100644 index 0000000..b5788f4 --- /dev/null +++ b/docs_oos/data/remote/rpc_function_id.json @@ -0,0 +1,40 @@ +{ + "format": 1, + "id": "saw-rpc_function_id", + "kind": "struct", + "name": "rpc_function_id", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Identifier of an interface function on the wire.", + "detailed_description": [ + [ + "Keyed on the member name rather than on its index, so reordering an interface doesn't silently rebind calls between two versions." + ], + [ + "This is the number a backend hands to call_by_id of the", + {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, + "when the called function arrives as data instead of as a template argument." + ] + ], + "templates": [ + { + "name": "Lit", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member." + } + ], + "attributes": { + "saw-rpc_function_id-value": { + "id": "saw-rpc_function_id-value", + "name": "value", + "type": ["uint32_t"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "hash_literal<Lit>::apply(0u)", + "brief_description": "crc32 of the member name." + } + } +} diff --git a/docs_oos/data/remote/rpc_server.json b/docs_oos/data/remote/rpc_server.json new file mode 100644 index 0000000..eb21128 --- /dev/null +++ b/docs_oos/data/remote/rpc_server.json @@ -0,0 +1,66 @@ +{ + "format": 1, + "id": "saw-rpc_server", + "kind": "class", + "name": "rpc_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote.hpp", + "brief_description": "Implementation of a remote server on the backend.", + "detailed_description": [ + [ + "Holds the interface whose functions clients call." + ], + [ + "The server never receives a parameter as data, only the id of a value already sitting in the matching", + {"name": "data_server", "id": "saw-data_server"}, + "which is what keeps the rpc layer an overlay on the transport layer." + ] + ], + "templates": [ + { + "name": "Iface", + "kind": "type", + "brief_description": "Interface schema the server provides." + }, + { + "name": "Encoding", + "kind": "type", + "brief_description": "Encoding of the parameters and responses." + }, + { + "name": "Remote", + "kind": "type", + "brief_description": "Tag type of the backend." + } + ], + "attributes": { + "saw-rpc_server-iface_": { + "id": "saw-rpc_server-iface_", + "name": "iface_", + "type": ["interface< Iface, Encoding >"], + "visibility": "private" + } + }, + "functions": { + "saw-rpc_server-ctor": { + "id": "saw-rpc_server-ctor", + "name": "rpc_server", + "type": [], + "parameters": [ + { + "name": "iface", + "type": ["interface< Iface, Encoding >"], + "brief_description": "The functions this server answers with." + } + ] + } + }, + "specializations": [ + { + "name": "rpc_server< Iface, Encode, rmt::Loopback >", + "id": "saw-rpc_server-loopback", + "brief_description": "Answers calls inline, resolving ids against the data servers of the same address." + } + ] +} diff --git a/docs_oos/data/remote/rpc_server.loopback.json b/docs_oos/data/remote/rpc_server.loopback.json new file mode 100644 index 0000000..3f43ab2 --- /dev/null +++ b/docs_oos/data/remote/rpc_server.loopback.json @@ -0,0 +1,180 @@ +{ + "format": 1, + "id": "saw-rpc_server-loopback", + "kind": "class", + "name": "rpc_server", + "namespace": "saw", + "module": "remote", + "header": "modules/remote/c++/remote_loopback.hpp", + "is_special": true, + "specializes": "saw-rpc_server", + "arguments": ["Iface", "Encode", "rmt::Loopback"], + "brief_description": "Answers calls inline against the data servers of its address.", + "detailed_description": [ + [ + "Translates a call on an id into a call on the local interface: it looks the parameter up in the data server of the request schema, calls the function, and stores the answer in the data server of the response schema." + ], + [ + "The data itself never passes through the rpc layer. Registering with its", + {"name": "remote", "id": "saw-remote-loopback"}, + "on construction is what makes rpc_connect able to find it." + ] + ], + "templates": [ + {"name": "Iface", "kind": "type"}, + {"name": "Encode", "kind": "type"} + ], + "aliases": { + "saw-rpc_server-loopback-InterfaceT": { + "id": "saw-rpc_server-loopback-InterfaceT", + "name": "InterfaceT", + "type": ["interface< Iface, Encode >"], + "brief_description": "The implementations backing the interface." + }, + "saw-rpc_server-loopback-TypeGroup": { + "id": "saw-rpc_server-loopback-TypeGroup", + "name": "TypeGroup", + "type": ["typename schema_iface_type_group< Iface >::Type"], + "brief_description": "Every schema the interface mentions, reduced to unique types." + }, + "saw-rpc_server-loopback-DataServers": { + "id": "saw-rpc_server-loopback-DataServers", + "name": "DataServers", + "type": ["std::tuple< ptr<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< T, Encode, rmt::Loopback > >... >"], + "brief_description": "One data server pointer per schema in the type group." + } + }, + "attributes": { + "saw-rpc_server-loopback-class_id": { + "id": "saw-rpc_server-loopback-class_id", + "name": "class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "visibility": "public", + "static": true, + "constexpr": true, + "initializer": "{schema_hash<Iface>::apply(), schema_hash<Encode>::apply()}", + "brief_description": "Identifies which interface this server provides." + }, + "saw-rpc_server-loopback-iface_": { + "id": "saw-rpc_server-loopback-iface_", + "name": "iface_", + "type": ["InterfaceT"], + "visibility": "private" + }, + "saw-rpc_server-loopback-dat_srvs_": { + "id": "saw-rpc_server-loopback-dat_srvs_", + "name": "dat_srvs_", + "type": ["DataServers"], + "visibility": "private" + } + }, + "functions": { + "saw-rpc_server-loopback-get_class_id": { + "id": "saw-rpc_server-loopback-get_class_id", + "name": "get_class_id", + "type": ["std::pair< uint32_t, uint32_t >"], + "const": true, + "override": true, + "brief_description": "Returns the interface id." + }, + "saw-rpc_server-loopback-get_data_servers": { + "id": "saw-rpc_server-loopback-get_data_servers", + "name": "get_data_servers", + "type": ["const DataServers &"], + "const": true, + "brief_description": "The data servers this rpc server moves its parameters and responses through." + }, + "saw-rpc_server-loopback-call-1": { + "id": "saw-rpc_server-loopback-call-1", + "name": "call", + "type": ["error_or< id< ResponseT > >"], + "brief_description": "Calls a function and lets the server decide where the response is stored.", + "detailed_description": [ + [ + "A client cannot know which ids are free without asking, so this is the variant which costs no roundtrip beforehand." + ], + [ + "The slot is picked after the function returned, which is the latest and therefore most accurate moment." + ] + ], + "templates": [ + { + "name": "Lit", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member to call." + } + ], + "parameters": [ + { + "name": "id_param", + "type": ["id< typename schema_member_type< Lit, Iface >::type::RequestT >"], + "brief_description": "Id of a value already sitting in the request data server." + } + ] + }, + "saw-rpc_server-loopback-call-2": { + "id": "saw-rpc_server-loopback-call-2", + "name": "call", + "type": ["error_or< void >"], + "brief_description": "Calls a function and stores the response in a slot allocated beforehand.", + "detailed_description": [ + [ + "Meant for backends where the output exists before the call, such as a device buffer allocated on the remote." + ] + ], + "templates": [ + { + "name": "Lit", + "kind": "non_type", + "type": "string_literal", + "brief_description": "Name of the interface member to call." + } + ], + "parameters": [ + {"name": "id_param", "type": ["id< typename schema_member_type< Lit, Iface >::type::RequestT >"]}, + { + "name": "id_resp", + "type": ["id< typename schema_member_type< Lit, Iface >::type::ResponseT >"], + "brief_description": "Slot the answer has to end up in." + } + ] + }, + "saw-rpc_server-loopback-call_by_id-1": { + "id": "saw-rpc_server-loopback-call_by_id-1", + "name": "call_by_id", + "type": ["error_or< uint64_t >"], + "brief_description": "Calls a function which is only known at runtime.", + "detailed_description": [ + [ + "The entry point for every backend which transports the call itself. The ids are untyped here, since such a backend only knows the function id and a number." + ], + [ + "The id the response ended up in is meant to travel back in the reply. Fails with not_found if no interface member carries that function id." + ] + ], + "parameters": [ + { + "name": "func_id", + "type": ["uint32_t"], + "brief_description": "rpc_function_id of the member name." + }, + {"name": "id_param", "type": ["uint64_t"]} + ] + }, + "saw-rpc_server-loopback-call_by_id-2": { + "id": "saw-rpc_server-loopback-call_by_id-2", + "name": "call_by_id", + "type": ["error_or< void >"], + "brief_description": "Runtime call into a slot the caller allocated beforehand.", + "parameters": [ + {"name": "func_id", "type": ["uint32_t"]}, + {"name": "id_param", "type": ["uint64_t"]}, + {"name": "id_resp", "type": ["uint64_t"]} + ] + } + }, + "notes": [ + "Copy and move are forbidden, because the remote holds a pointer to this object while it is registered." + ] +} diff --git a/docs_oos/entity.schema.json b/docs_oos/entity.schema.json new file mode 100644 index 0000000..73011a7 --- /dev/null +++ b/docs_oos/entity.schema.json @@ -0,0 +1,254 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "forstio/docs_oos/entity.schema.json", + "title": "forstio out of source api entity", + "description": "One file per entity, written by hand instead of derived from doxygen. A primary template and each of its specializations are separate files with their own id; the primary links the specializations, which the tree renders as a sublist underneath it. The generator collects every file under docs_oos/data into one map keyed by id, which is the shape the rst templates consume.", + "type": "object", + "required": ["format", "id", "kind", "name", "namespace", "header"], + "additionalProperties": false, + "properties": { + "format": { + "const": 1 + }, + "id": { + "type": "string", + "pattern": "^[a-z0-9_]+(-[a-z0-9_]+)*$", + "description": "Stable identifier. Becomes the rst file name, the label and the :ref: target, so it replaces the doxygen refid. Convention: namespace and name joined by a dash, with a slug for a specialization, e.g. saw-data_server and saw-data_server-loopback." + }, + "kind": { + "enum": ["class", "struct", "alias", "function", "variable", "enum", "concept", "namespace"] + }, + "name": { + "type": "string", + "description": "Unqualified name without namespace and without template arguments. A specialization carries the same name as its primary." + }, + "namespace": { + "type": "string", + "description": "Where it lives, e.g. saw or saw::rmt. Kept apart from the name so the heading stays readable and the namespace can still be shown." + }, + "module": { + "type": "string", + "description": "Module directory, e.g. remote." + }, + "header": { + "type": "string", + "description": "Declaring header, relative to the repository root." + }, + "brief_description": { + "type": "string" + }, + "detailed_description": { + "$ref": "#/$defs/paragraphs" + }, + "templates": { + "type": "array", + "description": "Template parameters. A partial specialization lists the parameters it introduces, not the ones it binds.", + "items": {"$ref": "#/$defs/template_parameter"} + }, + "is_special": { + "type": "boolean", + "default": false, + "description": "True on a specialization. The index skips these; they are reachable through their primary." + }, + "specializes": { + "type": "string", + "description": "Only on a specialization: id of the primary." + }, + "arguments": { + "type": "array", + "description": "Only on a specialization: the arguments it binds, in order, as written.", + "items": {"type": "string"} + }, + "specializations": { + "type": "array", + "description": "Only on a primary. Rendered as the sublist under the entity.", + "items": {"$ref": "#/$defs/specialization_link"} + }, + "aliases": { + "type": "object", + "description": "Member type aliases keyed by id. These carry weight here, e.g. DataServers or InterfaceT.", + "additionalProperties": {"$ref": "#/$defs/alias"} + }, + "attributes": { + "type": "object", + "description": "Data members keyed by id.", + "additionalProperties": {"$ref": "#/$defs/attribute"} + }, + "functions": { + "type": "object", + "description": "Member functions keyed by id. Overloads get distinct ids.", + "additionalProperties": {"$ref": "#/$defs/function"} + }, + "examples": { + "type": "array", + "description": "Usage examples for the entity as a whole.", + "items": {"$ref": "#/$defs/example"} + }, + "notes": { + "type": "array", + "description": "Remarks which don't belong to a single member.", + "items": {"type": "string"} + } + }, + "$defs": { + "example": { + "type": "object", + "required": ["code"], + "additionalProperties": false, + "properties": { + "title": {"type": "string"}, + "language": { + "type": "string", + "default": "cpp", + "description": "Rendered as the code block language." + }, + "description": {"$ref": "#/$defs/paragraphs"}, + "code": { + "type": "string", + "description": "Source as a single string with newlines. Error handling may be left out for readability, but then the description has to say so." + } + } + }, + "paragraphs": { + "type": "array", + "description": "A list of paragraphs. Each paragraph is a list of fragments: plain strings, or a reference object which renders as a link to another entity.", + "items": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + {"$ref": "#/$defs/type_ref"} + ] + } + } + }, + "type_ref": { + "type": "object", + "required": ["name", "id"], + "additionalProperties": false, + "properties": { + "name": {"type": "string", "description": "Text to display."}, + "id": {"type": "string", "description": "id of the entity being linked."} + } + }, + "type_tuple": { + "type": "array", + "description": "A type as a sequence of fragments, so the parts which are entities link and the rest stays text.", + "items": { + "oneOf": [ + {"type": "string"}, + {"$ref": "#/$defs/type_ref"} + ] + } + }, + "template_parameter": { + "type": "object", + "required": ["name", "kind"], + "additionalProperties": false, + "properties": { + "name": {"type": "string"}, + "kind": { + "enum": ["type", "non_type", "template"], + "description": "type for class/typename, non_type for a value parameter such as uint64_t N or string_literal Lit." + }, + "type": { + "type": "string", + "description": "Required for non_type, e.g. uint64_t or string_literal." + }, + "pack": {"type": "boolean", "default": false}, + "default": {"type": "string", "description": "Default argument as written."}, + "brief_description": {"type": "string"} + } + }, + "specialization_link": { + "type": "object", + "required": ["name", "id"], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "Specialized name as it should read in the sublist, e.g. data_server< Schema, Encoding, rmt::Loopback >." + }, + "id": {"type": "string"}, + "brief_description": { + "type": "string", + "description": "One line, so the sublist says what the specialization is for without opening it." + } + } + }, + "alias": { + "type": "object", + "required": ["id", "name", "type"], + "additionalProperties": false, + "properties": { + "id": {"type": "string"}, + "name": {"type": "string"}, + "type": {"$ref": "#/$defs/type_tuple"}, + "visibility": {"enum": ["public", "protected", "private"], "default": "public"}, + "brief_description": {"type": "string"}, + "detailed_description": {"$ref": "#/$defs/paragraphs"} + } + }, + "attribute": { + "type": "object", + "required": ["id", "name", "type"], + "additionalProperties": false, + "properties": { + "id": {"type": "string"}, + "name": {"type": "string"}, + "type": {"$ref": "#/$defs/type_tuple"}, + "visibility": {"enum": ["public", "protected", "private"], "default": "private"}, + "static": {"type": "boolean", "default": false}, + "const": {"type": "boolean", "default": false}, + "constexpr": {"type": "boolean", "default": false}, + "initializer": {"type": "string", "default": ""}, + "brief_description": {"type": "string"}, + "detailed_description": {"$ref": "#/$defs/paragraphs"} + } + }, + "function": { + "type": "object", + "required": ["id", "name", "type"], + "additionalProperties": false, + "properties": { + "id": {"type": "string"}, + "name": {"type": "string"}, + "type": { + "$ref": "#/$defs/type_tuple", + "description": "Return type. Empty for constructors and destructors." + }, + "templates": { + "type": "array", + "description": "Template parameters of the function itself, e.g. the string_literal naming an interface member.", + "items": {"$ref": "#/$defs/template_parameter"} + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "type"], + "additionalProperties": false, + "properties": { + "name": {"type": "string"}, + "type": {"$ref": "#/$defs/type_tuple"}, + "default": {"type": "string"}, + "brief_description": {"type": "string"} + } + } + }, + "visibility": {"enum": ["public", "protected", "private"], "default": "public"}, + "static": {"type": "boolean", "default": false}, + "const": {"type": "boolean", "default": false}, + "virtual": {"type": "boolean", "default": false}, + "override": {"type": "boolean", "default": false}, + "brief_description": {"type": "string"}, + "detailed_description": {"$ref": "#/$defs/paragraphs"}, + "examples": { + "type": "array", + "description": "Usage examples for this member.", + "items": {"$ref": "#/$defs/example"} + } + } + } + } +} |
