MCPcopy Create free account
hub / github.com/FastLED/FastLED / resolveDynamicDriver

Method resolveDynamicDriver

src/fl/channels/channel.cpp.hpp:390–447  ·  view source on GitHub ↗

@brief Cold fallback for the non-pre-bound driver path. Handles dynamic `ChannelManager::selectDriverForChannel` lookup AND the bus-key-miss diagnostic chain. Hoisted out of `showPixels` so the hot legacy `addLeds<>` path stays compact — see #2773 item 2.1. Marked `noinline` (via `FL_NOINLINE`) so the compiler doesn't fold the cold body back into `showPixels`. The whole helper is reachable only w

Source from the content-addressed store, hash-verified

388/// LTO can use that across the call site to keep the cold body off the
389/// hot icache line.
390FL_NO_INLINE
391fl::shared_ptr<IChannelDriver> Channel::resolveDynamicDriver() {
392#if defined(FASTLED_DISABLE_DYNAMIC_DRIVER) && FASTLED_DISABLE_DYNAMIC_DRIVER
393 // Body excluded via FASTLED_DISABLE_DYNAMIC_DRIVER (#2926). The
394 // showPixels call site is also gated so this is unreachable; the
395 // empty body lets the linker dead-strip ChannelManager::findDriverByName
396 // and selectDriverForChannel along with this symbol.
397 return {};
398#else
399 // Build busKey only when we actually need it (mBus != AUTO).
400 fl::string busKey;
401 if (mBus != Bus::AUTO) {
402 busKey = fl::string::from_literal(busName(mBus));
403 }
404
405 fl::shared_ptr<IChannelDriver> driver =
406 ChannelManager::instance().selectDriverForChannel(mChannelData, busKey);
407 mDriver = driver;
408
409 // #2455 / #2459: one-shot diagnostic when a typed-Bus miss happens.
410 // Probe via `findDriverByName` (silent) to distinguish "driver wasn't
411 // instantiated" from "driver exists but canHandle() rejected this
412 // chipset" — resolution paths differ. The mBusWarned guard suppresses
413 // duplicate logs on subsequent shows of the same channel.
414#if FASTLED_LOG_RUNTIME_ENABLED
415 if (mBus != Bus::AUTO && !mBusWarned &&
416 (!driver || driver->getName() != busKey)) {
417 auto busDriver = ChannelManager::instance().findDriverByName(busKey);
418 if (!busDriver) {
419 // Typed Bus miss — emit the actionable hint with the three
420 // currently-shipping remediations (option 3 added in #2460).
421 FL_ERROR("Channel '" << mName << "': Driver '" << busKey
422 << "' wasn't instantiated. Resolve with: "
423 << "(1) fl::enableDrivers<fl::Bus::" << busKey << ">() "
424 << "(links only this driver), "
425 << "(2) FastLED.enableAllDrivers() (links every driver), or "
426 << "(3) FastLED.addLeds<..., fl::Bus::" << busKey << ">(...) "
427 << "(legacy API; pins Bus + triggers linker keep-alive). "
428 << "Defaulting to AUTO/priority dispatch.");
429 } else {
430 // Registered, but canHandle() said no — bus/chipset mismatch.
431 FL_ERROR("Channel '" << mName << "': Driver '" << busKey
432 << "' is registered but cannot handle this channel's chipset "
433 << "(bus/chipset mismatch). Defaulting to AUTO/priority dispatch.");
434 }
435 mBusWarned = true;
436 }
437 if (!driver) {
438 FL_ERROR("Channel '" << mName << "': No compatible driver found - cannot transmit");
439 }
440#endif // FASTLED_LOG_RUNTIME_ENABLED — release skips the per-frame
441 // driver->getName() != busKey compare + the silent
442 // findDriverByName probe (used only to differentiate the
443 // FL_ERROR message). The functional return value below is
444 // preserved in both builds. See #2952.
445 return driver;
446#endif // !FASTLED_DISABLE_DYNAMIC_DRIVER
447}

Callers

nothing calls this directly

Calls 4

busNameFunction · 0.85
findDriverByNameMethod · 0.80
getNameMethod · 0.45

Tested by

no test coverage detected