26 #if !LELY_NO_COAPP_MASTER
42 rpdo_mapped(master.RpdoMapped(id)),
43 tpdo_mapped(master.TpdoMapped(id)),
44 tpdo_event_mutex(master.tpdo_event_mutex),
45 exec_(exec ? exec : static_cast<
ev_exec_t*>(master.GetExecutor())),
50 BasicDriver::~BasicDriver() {
master.
Erase(*
this); }
55 throw ::std::out_of_range(
"invalid logical device number: " +
56 ::std::to_string(driver.
Number()));
57 if (find(driver.
id()) != end())
58 throw ::std::out_of_range(
"logical device number " +
59 ::std::to_string(driver.
Number()) +
60 " already registered");
62 MapType::operator[](driver.
Number()) = &driver;
67 auto it = find(driver.
Number());
68 if (it != end() && it->second == &driver) erase(it);
75 if (it != end())
return it->second->AsyncConfig();
76 }
else if (size() == 1) {
78 return begin()->second->AsyncConfig();
79 }
else if (!empty()) {
80 ::std::array<SdoFuture<void>, 8> futures;
83 for (
const auto& it : *
this) futures[n++] = it.second->AsyncConfig();
86 ::std::array<ev_future_t*, 8> tmp;
87 ::std::copy(futures.begin(), futures.end(), tmp.begin());
93 for (
const auto& it : futures) {
95 if (it) it.get().value();
106 if (it != end())
return it->second->AsyncDeconfig();
107 }
else if (size() == 1) {
109 return begin()->second->AsyncDeconfig();
110 }
else if (!empty()) {
111 ::std::array<SdoFuture<void>, 8> futures;
114 for (
const auto& it : *
this) futures[n++] = it.second->AsyncDeconfig();
118 ::std::array<ev_future_t*, 8> tmp;
119 ::std::copy(futures.begin(), futures.end(), tmp.begin());
125 for (
const auto& it : futures) {
127 if (it) it.get().value();
137 for (
const auto& it : *
this) it.second->OnCanState(new_state, old_state);
142 for (
const auto& it : *
this) it.second->OnCanError(
error);
147 if (idx >= 0x6000 && idx <= 0x9fff) {
148 int num = (idx - 0x6000) / 0x800 + 1;
150 if (it != end()) it->second->OnRpdoWrite(idx - (num - 1) * 0x800, subidx);
152 for (
const auto& it : *
this) it.second->OnRpdoWrite(idx, subidx);
158 for (
const auto& it : *
this) it.second->OnCommand(cs);
163 for (
const auto& it : *
this) it.second->OnHeartbeat(occurred);
168 for (
const auto& it : *
this) it.second->OnState(st);
173 for (
const auto& it : *
this) it.second->OnSync(cnt, t);
178 for (
const auto& it : *
this) it.second->OnSyncError(eec, er);
183 const ::std::chrono::system_clock::time_point& abs_time) noexcept {
184 for (
const auto& it : *
this) it.second->OnTime(abs_time);
189 for (
const auto& it : *
this) it.second->OnEmcy(eec, er, msef);
194 for (
const auto& it : *
this) it.second->OnNodeGuarding(occurred);
199 for (
const auto& it : *
this) it.second->OnBoot(st, es, what);
204 ::std::function<
void(::std::error_code ec)> res) noexcept {
207 res(::std::error_code{});
210 auto f = AsyncConfig();
212 f.submit(GetExecutor(), [res, f] {
214 ::std::error_code ec;
215 auto& result = f.get();
216 if (result.has_error()) {
218 ::std::rethrow_exception(result.error());
219 } catch (const ::std::system_error& e) {
227 }
catch (::std::system_error& e) {
234 BasicDriver::OnDeconfig(
235 ::std::function<
void(::std::error_code ec)> res) noexcept {
238 res(::std::error_code{});
241 auto f = AsyncDeconfig();
243 f.submit(GetExecutor(), [res, f] {
245 ::std::error_code ec;
246 auto& result = f.get();
247 if (result.has_error()) {
249 ::std::rethrow_exception(result.error());
250 } catch (const ::std::system_error& e) {
258 }
catch (::std::system_error& e) {
268 #endif // !LELY_NO_COAPP_MASTER