blob: a605cf2ba4eebdc17659921dc6695968f8f7316a [file] [log] [blame]
Parker Schuhe4a70d62017-12-27 20:10:20 -08001#ifndef _AOS_EVENTS_EVENT_LOOP_H_
2#define _AOS_EVENTS_EVENT_LOOP_H_
3
4#include <string>
John Park33858a32018-09-28 23:05:48 -07005#include "aos/queue.h"
6#include "aos/time/time.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -08007#include "aos/events/raw-event-loop.h"
8
9namespace aos {
10
11// Fetches the newest message from a queue.
12template <typename T>
13class Fetcher {
14 public:
15 Fetcher() {}
James Kuszmaulc79768b2019-02-18 15:08:44 -080016 // Fetches the next message. Returns whether it fetched a new message.
17 bool FetchNext() { return fetcher_->FetchNext(); }
Parker Schuhe4a70d62017-12-27 20:10:20 -080018 // Fetches the most recent message. Returns whether it fetched a new message.
19 bool Fetch() { return fetcher_->Fetch(); }
20
21 const T *get() const {
22 return reinterpret_cast<const T *>(fetcher_->most_recent());
23 }
24 const T &operator*() const { return *get(); }
25 const T *operator->() const { return get(); }
26
27 private:
28 friend class EventLoop;
29 Fetcher(std::unique_ptr<RawFetcher> fetcher) : fetcher_(std::move(fetcher)) {}
30 std::unique_ptr<RawFetcher> fetcher_;
31};
32
33// Sends messages to a queue.
34template <typename T>
35class Sender {
36 public:
Austin Schuhdf6cbb12019-02-02 13:46:52 -080037 typedef T Type;
38
Parker Schuhe4a70d62017-12-27 20:10:20 -080039 Sender() {}
40
41 // Represents a single message about to be sent to the queue.
42 // The lifecycle goes:
43 //
44 // Message msg = sender.MakeMessage();
45 // Populate(msg.get());
46 // msg.Send();
47 //
48 // Or:
49 //
50 // Message msg = sender.MakeMessage();
51 // PopulateOrNot(msg.get());
52 class Message {
53 public:
54 Message(RawSender *sender)
James Kuszmaulcd1db352019-05-26 16:42:29 -070055 : msg_(reinterpret_cast<T *>(sender->GetMessage()), *sender) {
Parker Schuhe4a70d62017-12-27 20:10:20 -080056 msg_->Zero();
57 }
58
59 T *get() { return msg_.get(); }
60 const T *get() const { return msg_.get(); }
61 T &operator*() { return *get(); }
62 T *operator->() { return get(); }
63 const T &operator*() const { return *get(); }
64 const T *operator->() const { return get(); }
65
Austin Schuh81fc9cc2019-02-02 23:25:47 -080066 // Sends the message to the queue. Should only be called once. Returns true
67 // if the message was successfully sent, and false otherwise.
68 bool Send() {
Parker Schuhe4a70d62017-12-27 20:10:20 -080069 RawSender *sender = &msg_.get_deleter();
James Kuszmaulcd1db352019-05-26 16:42:29 -070070 return sender->Send(msg_.release());
Parker Schuhe4a70d62017-12-27 20:10:20 -080071 }
72
73 private:
74 std::unique_ptr<T, RawSender &> msg_;
75 };
76
77 // Constructs an above message.
78 Message MakeMessage();
79
Austin Schuhd681bbd2019-02-02 12:03:32 -080080 // Returns the name of the underlying queue.
81 const char *name() const { return sender_->name(); }
82
Parker Schuhe4a70d62017-12-27 20:10:20 -080083 private:
84 friend class EventLoop;
85 Sender(std::unique_ptr<RawSender> sender) : sender_(std::move(sender)) {}
86 std::unique_ptr<RawSender> sender_;
87};
88
89// TODO(parker): Consider making EventLoop wrap a RawEventLoop rather than
90// inheriting.
91class EventLoop : public RawEventLoop {
92 public:
93 virtual ~EventLoop() {}
94
95 // Current time.
96 virtual monotonic_clock::time_point monotonic_now() = 0;
97
Austin Schuh81fc9cc2019-02-02 23:25:47 -080098 // Note, it is supported to create:
99 // multiple fetchers, and (one sender or one watcher) per <path, type>
100 // tuple.
101
Parker Schuhe4a70d62017-12-27 20:10:20 -0800102 // Makes a class that will always fetch the most recent value
103 // sent to path.
104 template <typename T>
105 Fetcher<T> MakeFetcher(const std::string &path) {
106 return Fetcher<T>(MakeRawFetcher(path, QueueTypeInfo::Get<T>()));
107 }
108
109 // Makes class that allows constructing and sending messages to
110 // address path.
111 template <typename T>
112 Sender<T> MakeSender(const std::string &path) {
113 return Sender<T>(MakeRawSender(path, QueueTypeInfo::Get<T>()));
114 }
115
116 // Watch is a functor that have a call signature like so:
117 // void Event(const MessageType& type);
118 //
119 // This will watch messages sent to path.
120 // Note that T needs to match both send and recv side.
Austin Schuha1654ed2019-01-27 17:24:54 -0800121 // TODO(parker): Need to support ::std::bind. For now, use lambdas.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800122 template <typename Watch>
123 void MakeWatcher(const std::string &path, Watch &&w);
124
125 // The passed in function will be called when the event loop starts.
126 // Use this to run code once the thread goes into "real-time-mode",
127 virtual void OnRun(std::function<void()>) = 0;
128
Parker Schuhe4a70d62017-12-27 20:10:20 -0800129 // TODO(austin): Sort out how to switch to realtime on run.
130 // virtual void RunRealtime() = 0;
131
132 // Stops receiving events
133 virtual void Exit() = 0;
134};
135
136} // namespace aos
137
138#include "aos/events/event-loop-tmpl.h"
139
140#endif // _AOS_EVENTS_EVENT_LOOP_H