35class RPC :
public Plugin{
46 void begin(Stream *target_stream);
51 void begin(usb_serial_class *target_usb_serial);
58 void begin(HardwareSerialIMXRT *target_serial, uint32_t baud, uint16_t format = 0);
61 template<
typename Ret,
typename... Args>
62 void enroll(
const String& name, Ret(*func)(Args...)){
63 add_to_registry(name, [func,
this](JsonArray args){
64 this->call_and_respond(func, args, std::index_sequence_for<Args...>{});
66 rpc_index[name] =
"function";
69 template<
typename Obj,
typename Ret,
typename... Args>
70 void enroll(
const String& instance_name,
const String& name, Obj& instance, Ret(Obj::*method)(Args...)){
71 add_to_registry(instance_name +
"." + name, [&instance, method,
this](JsonArray args){
72 this->call_and_respond(instance, method, args, std::index_sequence_for<Args...>{});
74 rpc_index[instance_name +
"." + name] =
"function";
77 void enroll(
const String& name, Plugin& instance){
78 instance.enroll(
this, name);
81 template<
typename T,
typename = std::enable_if_t<!std::is_base_of_v<Plugin, T>>>
82 void enroll(
const String& name, T& parameter){
83 add_to_registry(name, [¶meter,
this](JsonArray args){
84 if(!args.isNull() && args.size() > 0){
85 parameter = args[0].as<T>();
86 reset_outbound_state();
87 outbound_json_doc[
"result"] =
"ok";
88 serializeJson(outbound_json_doc, *rpc_stream);
89 rpc_stream->println();
91 reset_outbound_state();
92 outbound_json_doc[
"result"] =
"ok";
93 outbound_json_doc[
"return"] = parameter;
94 serializeJson(outbound_json_doc, *rpc_stream);
95 rpc_stream->println();
98 rpc_index[name] =
"parameter";
102 template<
typename... Args,
size_t... I>
103 void call_and_respond(
void(*func)(Args...), JsonArray args, std::index_sequence<I...>){
104 func(args[I].as<Args>()...);
105 reset_outbound_state();
106 outbound_json_doc[
"result"] =
"ok";
107 serializeJson(outbound_json_doc, *rpc_stream);
108 rpc_stream->println();
111 template<
typename Obj,
typename... Args,
size_t... I>
112 void call_and_respond(Obj& instance,
void(Obj::*method)(Args...), JsonArray args, std::index_sequence<I...>){
113 (instance.*method)(args[I].as<Args>()...);
114 reset_outbound_state();
115 outbound_json_doc[
"result"] =
"ok";
116 serializeJson(outbound_json_doc, *rpc_stream);
117 rpc_stream->println();
120 template<
typename Ret,
typename... Args,
size_t... I>
121 void call_and_respond(Ret(*func)(Args...), JsonArray args, std::index_sequence<I...>){
122 Ret ret = func(args[I].as<Args>()...);
123 reset_outbound_state();
124 outbound_json_doc[
"result"] =
"ok";
125 outbound_json_doc[
"return"] = ret;
126 serializeJson(outbound_json_doc, *rpc_stream);
127 rpc_stream->println();
130 template<
typename Obj,
typename Ret,
typename... Args,
size_t... I>
131 void call_and_respond(Obj& instance, Ret(Obj::*method)(Args...), JsonArray args, std::index_sequence<I...>){
132 Ret ret = (instance.*method)(args[I].as<Args>()...);
133 reset_outbound_state();
134 outbound_json_doc[
"result"] =
"ok";
135 outbound_json_doc[
"return"] = ret;
136 serializeJson(outbound_json_doc, *rpc_stream);
137 rpc_stream->println();
141 void reset_inbound_state();
142 void reset_outbound_state();
145 String inbound_string;
146 JsonDocument inbound_json_doc;
147 JsonDocument outbound_json_doc;
149 using RPCFunction = std::function<void(JsonArray)>;
150 std::map<String, RPCFunction> rpc_registry;
151 std::map<String, String> rpc_index;
153 inline void add_to_registry(
const String& name, RPCFunction rpc_function){
154 rpc_registry[name] = rpc_function;
157 void rpc_call(
const String& name, JsonArray args);