@use itertools::Itertools; @use crate::data::RPC; @use crate::generators::cpp_s::*; @(rpc: &RPC) #pragma once #ifndef MRPC_GEN_H #define MRPC_GEN_H #include #include #include #include #include #include #include #define RAPIDJSON_HAS_STDSTRING 1 #include #include #include namespace mrpc @{ using MRPCJWriter = rapidjson::Writer; @for e in &rpc.enums { enum struct @e.name : std::uint64_t @{ @e.values.iter().map(|(k,v)| format!("{k} = {v}")).join(",\n ") @}; } @for s in &rpc.structs { struct @s.name; } @for s in &rpc.structs { struct @s.name @{ @for f in &s.fields { @ty_to_str(&f.ty) @f.name; } MRPCJWriter& operator >>(MRPCJWriter&) const; @(s.name)& operator <<(const rapidjson::Value&); @}; } struct MRPCStreamImpl @{ virtual void close() noexcept final; virtual void abort() noexcept final; virtual bool is_open() noexcept final; protected: MRPCStreamImpl(crow::websocket::connection *conn, uint64_t id) : conn(conn), id(id) @{@} crow::websocket::connection* conn; std::uint64_t id; @}; template struct MRPCStream final : MRPCStreamImpl @{ MRPCStream(crow::websocket::connection *conn, uint64_t id) : MRPCStreamImpl(conn, id) @{@} bool send(const T &v) noexcept @{ if (!conn) return false; try @{ rapidjson::StringBuffer s; mrpc::MRPCJWriter writer@{s@}; writer.StartObject(); writer.Key("id"); writer.Uint64(id); writer.Key("data"); v >> writer; writer.EndObject(); conn->send_text(s.GetString()); @} catch (const std::exception &_) @{ abort(); return false; @} return true; @} @}; struct MRPCServer @{ virtual void install(crow::SimpleApp &app, std::string &&route) final; private: @for s in &rpc.services {@for m in &s.methods { virtual @method_ret(m) @(s.name)_@(m.name)(@method_args(m)) = 0; }} virtual void msg_handler(crow::websocket::connection&, std::string, bool) final; std::mutex __streams_mutex; std::unordered_multimap> __streams; @}; @} #endif // MRPC_GEN_H