FastLED 3.10.6
Loading...
Searching...
No Matches

◆ invoke()

fl::tuple< TypeConversionResult, json > fl::detail::RuntimeRpcBinding::invoke ( const json & jsonArgs)
overridevirtual

Implements fl::detail::ErasedInvoker.

Definition at line 41 of file runtime_rpc_binding.cpp.hpp.

41 {
42 TypeConversionResult result;
43
44 if (!jsonArgs.is_array()) {
45 result.setError("arguments must be a JSON array");
46 return fl::make_tuple(result, json(nullptr));
47 }
48
49 fl::size received = jsonArgs.size();
50 if (received != mArgCount) {
51 result.setError("argument count mismatch: expected " +
52 fl::to_string(static_cast<fl::i64>(mArgCount)) +
53 ", got " + fl::to_string(static_cast<fl::i64>(received)));
54 return fl::make_tuple(result, json(nullptr));
55 }
56
57 fl::vector<unsigned char*> raw_slots;
58 fl::vector<void*> slot_ptrs;
59 raw_slots.reserve(mArgCount);
60 slot_ptrs.reserve(mArgCount);
61
62 RuntimeRpcSlotCleanup cleanup(mArgTypes, raw_slots);
63
64 for (fl::size i = 0; i < mArgCount; ++i) {
65 const RpcTypeOps* ops = mArgTypes[i];
66 // `operator new[]` on `unsigned char` returns memory aligned to at
67 // least alignof(max_align_t), which is sufficient for every type
68 // currently routable through `rpc_storage_type<T>::type`
69 // (fl::string, ints, floats, ConstCharPtrWrapper, ConstSpanWrapper).
70 // Raw byte buffer for placement-new of `T` -- ops drives lifetime.
71 unsigned char* buf = new unsigned char[ops->storage_size]; // ok bare allocation
72 raw_slots.push_back(buf);
73 slot_ptrs.push_back(buf);
74 ops->default_construct(buf);
75 cleanup.constructed = i + 1;
76
77 TypeConversionResult convResult = ops->decode(jsonArgs[i], buf);
78 for (fl::size w = 0; w < convResult.warnings().size(); ++w) {
79 result.addWarning("arg " + fl::to_string(static_cast<fl::i64>(i)) +
80 ": " + convResult.warnings()[w]);
81 }
82 if (convResult.hasError()) {
83 result.setError("arg " + fl::to_string(static_cast<fl::i64>(i)) +
84 ": " + convResult.errorMessage());
85 return fl::make_tuple(result, json(nullptr));
86 }
87 }
88
89 if (mResultType) {
90 // Raw byte buffer for placement-new of `R`; same pattern as arg slots.
91 unsigned char* result_buf = new unsigned char[mResultType->storage_size]; // ok bare allocation
92 mResultType->default_construct(result_buf);
93 mTrampoline(mUserFn, result_buf, slot_ptrs.data());
94 json jsonResult = mResultType->encode(result_buf);
95 mResultType->destroy(result_buf);
96 delete[] result_buf; // ok bare allocation
97 return fl::make_tuple(result, jsonResult);
98 }
99
100 mTrampoline(mUserFn, nullptr, slot_ptrs.data());
101 return fl::make_tuple(result, json(nullptr));
102}
const RpcTypeOps *const * mArgTypes
void reserve(fl::size n) FL_NO_EXCEPT
Definition vector.h:591
T * data() FL_NO_EXCEPT
Definition vector.h:619
void push_back(const T &value) FL_NO_EXCEPT
Definition vector.h:624
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
string to_string(T value) FL_NO_EXCEPT
Definition string.h:459
tuple< typename fl::decay< Ts >::type... > make_tuple(Ts &&... args) FL_NO_EXCEPT
Definition tuple.h:104

References fl::vector< T >::data(), fl::detail::RpcTypeOps::decode, fl::detail::RpcTypeOps::default_construct, fl::TypeConversionResult::errorMessage(), fl::FL_NO_EXCEPT, fl::TypeConversionResult::hasError(), fl::make_tuple(), mArgCount, mArgTypes, mResultType, mTrampoline, mUserFn, fl::vector< T >::push_back(), fl::vector< T >::reserve(), fl::detail::RpcTypeOps::storage_size, fl::to_string(), and fl::TypeConversionResult::warnings().

+ Here is the call graph for this function: