| 344 | |
| 345 | template<class Sig> |
| 346 | bool registerMethod(const char* name, RpcFn<Sig> fn, |
| 347 | const fl::vector<fl::string>& paramNames, |
| 348 | const fl::string& description, |
| 349 | const fl::vector<fl::string>& tags, |
| 350 | fl::RpcMode mode = fl::RpcMode::SYNC) { |
| 351 | fl::string key(name); |
| 352 | auto it = mRegistry.find(key); |
| 353 | if (it != mRegistry.end()) { |
| 354 | if (it->second.mTypeTag != detail::TypeTag<Sig>::id()) { |
| 355 | return false; |
| 356 | } |
| 357 | } |
| 358 | |
| 359 | detail::RpcEntry entry; |
| 360 | entry.mTypeTag = detail::TypeTag<Sig>::id(); |
| 361 | entry.mInvoker = fl::make_shared<detail::TypedInvoker<Sig>>(fn); |
| 362 | entry.mTypedCallable = fl::make_shared<detail::TypedCallableHolder<Sig>>(fn); |
| 363 | #if FL_PLATFORM_HAS_LARGE_MEMORY |
| 364 | // Schema generator construction gated on Low-memory targets per |
| 365 | // FastLED #3081 / #3079. The schema generator is only consumed by |
| 366 | // `rpc.discover` (also gated). Skipping it on Low-memory drops |
| 367 | // `TypedSchemaGenerator<Sig>::params()` (~800 B per signature). |
| 368 | entry.mSchemaGenerator = fl::make_shared<detail::TypedSchemaGenerator<Sig>>(); |
| 369 | #endif |
| 370 | entry.mDescription = description; |
| 371 | entry.mTags = tags; |
| 372 | entry.mMode = mode; |
| 373 | |
| 374 | #if FL_PLATFORM_HAS_LARGE_MEMORY |
| 375 | if (!paramNames.empty()) { |
| 376 | entry.mSchemaGenerator->setParamNames(paramNames); |
| 377 | } |
| 378 | #else |
| 379 | (void)paramNames; |
| 380 | #endif |
| 381 | |
| 382 | mRegistry[key] = fl::move(entry); |
| 383 | return true; |
| 384 | } |
| 385 | |
| 386 | private: |
| 387 | fl::unordered_map<fl::string, detail::RpcEntry> mRegistry; |
nothing calls this directly
no test coverage detected