| 378 | } |
| 379 | |
| 380 | fl::shared_ptr<IChannelDriver> ChannelManager::selectDriverForChannel(const ChannelDataPtr& data, const fl::string& affinity) { |
| 381 | if (!data) { |
| 382 | FL_ERROR("ChannelManager::selectDriverForChannel() - Null channel data"); |
| 383 | return fl::shared_ptr<IChannelDriver>(); |
| 384 | } |
| 385 | |
| 386 | // If affinity is specified, look up by name. Misses fall through to |
| 387 | // priority dispatch below — per-frame logging is intentionally silent |
| 388 | // here because `Channel::showPixels` now emits a one-shot, actionable |
| 389 | // FL_ERROR with the enableDrivers<...>() / enableAllDrivers() hint |
| 390 | // (#2455). Use `findDriverByName` (silent) rather than `getDriverByName` |
| 391 | // (logs on miss) so the silent fall-through actually IS silent. |
| 392 | do { |
| 393 | if (affinity.empty()) { |
| 394 | break; |
| 395 | } |
| 396 | auto driver = findDriverByName(affinity); |
| 397 | if (!driver) { |
| 398 | break; // diagnostic emitted at the channel layer |
| 399 | } |
| 400 | if (!driver->canHandle(data)) { |
| 401 | FL_WARN_ONCE("ChannelManager: Affinity driver '" << affinity |
| 402 | << "' cannot handle channel data (chipset/bus mismatch). " |
| 403 | << "Falling back to AUTO/priority dispatch."); |
| 404 | break; |
| 405 | } |
| 406 | return driver; |
| 407 | } while (false); |
| 408 | |
| 409 | |
| 410 | // No affinity: iterate drivers by priority (already sorted descending) |
| 411 | for (const auto& entry : mDrivers) { |
| 412 | if (!entry.enabled) continue; |
| 413 | if (entry.driver->canHandle(data)) { |
| 414 | return entry.driver; // Return shared_ptr |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | FL_ERROR("ChannelManager: No compatible driver found for channel data"); |
| 419 | return fl::shared_ptr<IChannelDriver>(); |
| 420 | } |
| 421 | |
| 422 | |
| 423 | template<typename Condition> |
no test coverage detected