Add an API for watchers without an argument
I'm going to give ShmEventLoop a specialized implementation, which
avoids copying the actual message data.
Change-Id: Ica7beba9835286d80adcab92e8d1d300fbeaedfc
diff --git a/aos/events/event_loop.h b/aos/events/event_loop.h
index d0ca196..a74e65b 100644
--- a/aos/events/event_loop.h
+++ b/aos/events/event_loop.h
@@ -302,9 +302,7 @@
// Returns the name of the underlying queue.
const Channel *channel() const { return sender_->channel(); }
- operator bool() {
- return sender_ ? true : false;
- }
+ operator bool() { return sender_ ? true : false; }
// Returns the time_points that the last message was sent at.
aos::monotonic_clock::time_point monotonic_sent_time() const {
@@ -464,13 +462,32 @@
// This will watch messages sent to the provided channel.
//
- // Watch is a functor that have a call signature like so:
- // void Event(const MessageType& type);
+ // w must have a non-polymorphic operator() (aka it can only be called with a
+ // single set of arguments; no overloading or templates). It must be callable
+ // with this signature:
+ // void(const MessageType &);
//
- // TODO(parker): Need to support ::std::bind. For now, use lambdas.
- // TODO(austin): Do we need a functor? Or is a std::function good enough?
+ // Lambdas are a common form for w. A std::function will work too.
+ //
+ // Note that bind expressions have polymorphic call operators, so they are not
+ // allowed.
+ //
+ // We template Watch as a whole instead of using std::function<void(const T
+ // &)> to allow deducing MessageType from lambdas and other things which are
+ // implicitly convertible to std::function, but not actually std::function
+ // instantiations. Template deduction guides might allow solving this
+ // differently in newer versions of C++, but those have their own corner
+ // cases.
template <typename Watch>
- void MakeWatcher(const std::string_view name, Watch &&w);
+ void MakeWatcher(const std::string_view channel_name, Watch &&w);
+
+ // Like MakeWatcher, but doesn't have access to the message data. This may be
+ // implemented to use less resources than an equivalent MakeWatcher.
+ //
+ // The function will still have access to context().
+ template <typename MessageType>
+ void MakeNoArgWatcher(const std::string_view channel_name,
+ std::function<void()> w);
// The passed in function will be called when the event loop starts.
// Use this to run code once the thread goes into "real-time-mode",
@@ -518,6 +535,16 @@
std::function<void(const Context &context, const void *message)>
watcher) = 0;
+ // Watches channel (name, type) for new messages, without needing to extract
+ // the message contents. Default implementation simply re-uses MakeRawWatcher.
+ virtual void MakeRawNoArgWatcher(
+ const Channel *channel,
+ std::function<void(const Context &context)> watcher) {
+ MakeRawWatcher(channel, [watcher](const Context &context, const void *) {
+ watcher(context);
+ });
+ }
+
// Creates a raw sender for the provided channel. This is used for reflection
// based sending.
// Note: this ignores any node constraints. Ignore at your own peril.