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->OnNodeGuarding(occurred);
168 for (
const auto& it : *
this) it.second->OnHeartbeat(occurred);
173 for (
const auto& it : *
this) it.second->OnState(st);
178 for (
const auto& it : *
this) it.second->OnBoot(st, es, what);
183 ::std::function<
void(::std::error_code ec)> res) noexcept {
186 res(::std::error_code{});
189 auto f = AsyncConfig();
191 f.submit(GetExecutor(), [res, f] {
193 ::std::error_code ec;
194 auto& result = f.get();
195 if (result.has_error()) {
197 ::std::rethrow_exception(result.error());
198 } catch (const ::std::system_error& e) {
206 }
catch (::std::system_error& e) {
213 BasicDriver::OnDeconfig(
214 ::std::function<
void(::std::error_code ec)> res) noexcept {
217 res(::std::error_code{});
220 auto f = AsyncDeconfig();
222 f.submit(GetExecutor(), [res, f] {
224 ::std::error_code ec;
225 auto& result = f.get();
226 if (result.has_error()) {
228 ::std::rethrow_exception(result.error());
229 } catch (const ::std::system_error& e) {
237 }
catch (::std::system_error& e) {
244 BasicDriver::OnSync(uint8_t cnt,
const time_point& t) noexcept {
245 for (
const auto& it : *
this) it.second->OnSync(cnt, t);
249 BasicDriver::OnSyncError(uint16_t eec, uint8_t er) noexcept {
250 for (
const auto& it : *
this) it.second->OnSyncError(eec, er);
255 const ::std::chrono::system_clock::time_point& abs_time) noexcept {
256 for (
const auto& it : *
this) it.second->OnTime(abs_time);
260 BasicDriver::OnEmcy(uint16_t eec, uint8_t er, uint8_t msef[5]) noexcept {
261 for (
const auto& it : *
this) it.second->OnEmcy(eec, er, msef);
268 #endif // !LELY_NO_COAPP_MASTER