Lely core libraries 2.3.4
loop_driver.hpp
Go to the documentation of this file.
1
22#ifndef LELY_COAPP_LOOP_DRIVER_HPP_
23#define LELY_COAPP_LOOP_DRIVER_HPP_
24
25#include <lely/coapp/driver.hpp>
26#include <lely/ev/loop.hpp>
27#include <lely/ev/strand.hpp>
28
29#include <memory>
30#include <utility>
31
32namespace lely {
33
34namespace canopen {
35
36namespace detail {
37
43 protected:
44 ev::Loop loop{};
45 ev::Strand strand{loop.get_executor()};
46};
47
48} // namespace detail
49
52 public:
62 explicit LoopDriver(AsyncMaster& master, uint8_t id);
63
71
75 return loop;
76 }
77
81 return strand;
82 }
83
94 void Join();
95
101
109 void
110 Defer(F&& f, Args&&... args) {
111 GetStrand().post(::std::forward<F>(f), ::std::forward<Args>(args)...);
112 }
113
126 template <class T>
127 T
129 GetLoop().wait(f);
130 try {
131 return f.get().value();
132 } catch (const ev::future_not_ready& e) {
133 util::throw_error_code("Wait", ::std::errc::operation_canceled);
134 }
135 }
136
149 template <class T>
150 typename ::std::enable_if<!::std::is_void<T>::value, T>::type
151 Wait(SdoFuture<T> f, ::std::error_code& ec) {
152 GetLoop().wait(f, ec);
153 try {
154 return f.get().value();
155 } catch (const ::std::system_error& e) {
156 ec = e.code();
157 } catch (const ev::future_not_ready& e) {
158 ec = ::std::make_error_code(::std::errc::operation_canceled);
159 }
160 return T{};
161 }
162
174 void Wait(SdoFuture<void> f, ::std::error_code& ec);
175
181
186 void USleep(uint_least64_t usec, ::std::error_code& ec);
187
193 template <class T>
194 T
195 RunRead(uint16_t idx, uint8_t subidx) {
196 return Wait(AsyncRead<T>(idx, subidx));
197 }
198
205 template <class T>
206 T
207 RunRead(uint16_t idx, uint8_t subidx, ::std::error_code& ec) {
208 return Wait(AsyncRead<T>(idx, subidx), ec);
209 }
210
216 template <class T>
217 T
219 const ::std::chrono::milliseconds& timeout) {
220 return Wait(AsyncRead<T>(idx, subidx, timeout));
221 }
222
238 template <class T>
239 T
241 const ::std::chrono::milliseconds& timeout, ::std::error_code& ec) {
242 return Wait(AsyncRead<T>(idx, subidx, timeout), ec);
243 }
244
250 template <class T>
251 void
252 RunWrite(uint16_t idx, uint8_t subidx, T&& value) {
253 Wait(AsyncWrite(idx, subidx, ::std::forward<T>(value)));
254 }
255
262 template <class T>
263 void
264 RunWrite(uint16_t idx, uint8_t subidx, T&& value, ::std::error_code& ec) {
265 Wait(AsyncWrite(idx, subidx, ::std::forward<T>(value)), ec);
266 }
267
273 template <class T>
274 void
275 RunWrite(uint16_t idx, uint8_t subidx, T&& value,
276 const ::std::chrono::milliseconds& timeout) {
277 Wait(AsyncWrite(idx, subidx, ::std::forward<T>(value), timeout));
278 }
279
294 template <class T>
295 void
296 RunWrite(uint16_t idx, uint8_t subidx, T&& value,
297 const ::std::chrono::milliseconds& timeout, ::std::error_code& ec) {
298 Wait(AsyncWrite(idx, subidx, ::std::forward<T>(value), timeout), ec);
299 }
300
301 private:
302 struct Impl_;
303 ::std::unique_ptr<Impl_> impl_;
304};
305
306} // namespace canopen
307
308} // namespace lely
309
310#endif // LELY_COAPP_LOOP_DRIVER_HPP_
A CANopen value.
Definition val.hpp:42
An asynchronous CANopen master.
Definition master.hpp:1957
The base class for drivers for remote CANopen nodes.
Definition driver.hpp:279
SdoFuture< void > AsyncWrite(uint16_t idx, uint8_t subidx, T &&value)
Equivalent to AsyncWrite(uint16_t idx, uint8_t subidx, T&& value, const ::std::chrono::milliseconds& ...
Definition driver.hpp:937
BasicMaster & master
A reference to the master with which this driver is registered.
Definition driver.hpp:1097
A CANopen driver running its own dedicated event loop in a separate thread.
void USleep(uint_least64_t usec)
Runs the event loop for usec microseconds.
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, ::std::error_code &ec)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, const ::std::chrono::milliseconds& ti...
T RunRead(uint16_t idx, uint8_t subidx)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, ::std::error_code& ec), except that it throws lel...
typename::std::enable_if<!::std::is_void< T >::value, T >::type Wait(SdoFuture< T > f, ::std::error_code &ec)
Waits for the specified future to become ready by running pending tasks on the dedicated event loop o...
T RunRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous read (SDO upload) operation and runs the event loop until the operation is com...
void RunWrite(uint16_t idx, uint8_t subidx, T &&value)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, ::std::error_code& ec),...
T RunRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds &timeout)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout,...
T Wait(SdoFuture< T > f)
Waits for the specified future to become ready by running pending tasks on the dedicated event loop o...
T RunRead(uint16_t idx, uint8_t subidx, ::std::error_code &ec)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout,...
void Join()
Stops the dedicated event loop of the driver and waits until the thread running the event loop finish...
void Defer(F &&f, Args &&... args)
Schedules the specified Callable object for execution by the event loop for this driver.
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, const ::std::chrono::milliseconds &timeout)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, const ::std::chrono::milliseconds& ti...
ev::Executor GetStrand() const noexcept
Returns the strand executor associated with the event loop of the driver.
ev::Future< void, void > AsyncStoppped() noexcept
Returns a future which becomes ready once the dedicated event loop of the driver is stopped and the t...
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous write (SDO download) operation and runs the event loop until the operation is ...
ev::Loop & GetLoop() noexcept
Returns a reference to the dedicated event loop of the driver.
~LoopDriver()
Stops the event loop and terminates the thread in which it was running before destroying the driver.
A base class for lely::canopen::LoopDriver, containing an event loop and the associated executor.
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition exec.hpp:38
void post(ev_task &task) noexcept
Definition exec.hpp:75
A future.
Definition future.hpp:384
A polling event loop.
Definition loop.hpp:41
Executor get_executor() const noexcept
Definition loop.hpp:80
::std::size_t wait(ev_future_t *future)
Definition loop.hpp:104
A strand executor.
Definition strand.hpp:37
The exception thrown when retrieving the result of a future which is not ready or does not contain a ...
Definition future.hpp:45
This header file is part of the C++ CANopen application library; it contains the remote node driver i...
This header file is part of the event library; it contains the C++ interface for the polling event lo...
This header file is part of the event library; it contains the C++ interface for the strand executor.