87 {
88 if (!driver) {
89 FL_WARN(
"ChannelManager::addDriver() - Null driver provided");
90 return;
91 }
92
93
94 fl::string engineName = driver->getName();
95
96
97 if (engineName.
empty()) {
98 FL_WARN(
"ChannelManager::addDriver() - Engine has empty name (driver->getName() returned empty string)");
99 return;
100 }
101
102
103 bool replacing = false;
104 for (
const auto& entry :
mDrivers) {
105 if (entry.name == engineName) {
106
107
108
109
110
111 if (entry.driver == driver && entry.priority == priority) {
112 FL_DBG(
"ChannelManager::addDriver() - '" << engineName.
c_str()
113 << "' already registered at priority " << priority
114 << " (idempotent no-op)");
115 return;
116 }
117 replacing = true;
118 FL_WARN(
"ChannelManager::addDriver() - Replacing existing driver '" << engineName.
c_str() <<
"'");
119 break;
120 }
121 }
122
123
124 if (replacing) {
125 FL_DBG(
"ChannelManager: Waiting for all drivers to become READY before replacement");
127
128
129 for (
size_t i = 0; i <
mDrivers.size(); ++i) {
130 if (
mDrivers[i].name == engineName) {
131 FL_DBG(
"ChannelManager: Removing old driver '" << engineName.
c_str() <<
"' (shared_ptr may delete)");
133 mDrivers[i].driver->setPollNeededCallback(IChannelDriver::PollNeededCallback());
134 }
136 break;
137 }
138 }
139 }
140
141
142 bool enabled = true;
145 }
146
147 mDrivers.push_back({priority, driver, engineName, enabled});
149
150
151
152
153
154
155
156
157#if FASTLED_HAS_DBG
158 IChannelDriver::Capabilities caps = driver->getCapabilities();
159 fl::string capStr;
160 if (caps.supportsClockless) {
161 capStr += "CLOCKLESS";
162 }
163 if (caps.supportsSpi) {
164 if (!capStr.
empty()) capStr +=
"|";
165 capStr += "SPI";
166 }
167 if (capStr.
empty()) {
168 capStr = "NONE";
169 }
170
171 FL_DBG(
"ChannelManager: Added driver '" << engineName.
c_str() <<
"' (priority " << priority <<
", caps: " << capStr.
c_str() <<
")");
172#endif
173
174
175
176
177
179}
IChannelDriver::PollNeededCallback mPollNeededCallback
Shared callback installed on drivers that can signal poll-needed events.
bool waitForReady(u32 timeoutMs=1000) FL_NOEXCEPT
Wait for all drivers to become READY.
fl::vector< EngineEntry > mDrivers
Shared drivers sorted by priority descending (higher values first)
fl::string mExclusiveDriver
Exclusive driver name (empty if no exclusive mode)
bool empty() const FL_NOEXCEPT
const char * c_str() const FL_NOEXCEPT
void sort_small(Iterator first, Iterator last, Compare comp) FL_NOEXCEPT