blob: c827c468ca88118aeda931cbc755b3a81e86a931 [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)
55 : msg_(reinterpret_cast<T *>(sender->GetContext()), *sender) {
56 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();
70 msg_->SetTimeToNow();
Austin Schuh81fc9cc2019-02-02 23:25:47 -080071 return sender->Send(
72 reinterpret_cast<RawSender::SendContext *>(msg_.release()));
Parker Schuhe4a70d62017-12-27 20:10:20 -080073 }
74
75 private:
76 std::unique_ptr<T, RawSender &> msg_;
77 };
78
79 // Constructs an above message.
80 Message MakeMessage();
81
Austin Schuhd681bbd2019-02-02 12:03:32 -080082 // Returns the name of the underlying queue.
83 const char *name() const { return sender_->name(); }
84
Parker Schuhe4a70d62017-12-27 20:10:20 -080085 private:
86 friend class EventLoop;
87 Sender(std::unique_ptr<RawSender> sender) : sender_(std::move(sender)) {}
88 std::unique_ptr<RawSender> sender_;
89};
90
91// TODO(parker): Consider making EventLoop wrap a RawEventLoop rather than
92// inheriting.
93class EventLoop : public RawEventLoop {
94 public:
95 virtual ~EventLoop() {}
96
97 // Current time.
98 virtual monotonic_clock::time_point monotonic_now() = 0;
99
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800100 // Note, it is supported to create:
101 // multiple fetchers, and (one sender or one watcher) per <path, type>
102 // tuple.
103
Parker Schuhe4a70d62017-12-27 20:10:20 -0800104 // Makes a class that will always fetch the most recent value
105 // sent to path.
106 template <typename T>
107 Fetcher<T> MakeFetcher(const std::string &path) {
108 return Fetcher<T>(MakeRawFetcher(path, QueueTypeInfo::Get<T>()));
109 }
110
111 // Makes class that allows constructing and sending messages to
112 // address path.
113 template <typename T>
114 Sender<T> MakeSender(const std::string &path) {
115 return Sender<T>(MakeRawSender(path, QueueTypeInfo::Get<T>()));
116 }
117
118 // Watch is a functor that have a call signature like so:
119 // void Event(const MessageType& type);
120 //
121 // This will watch messages sent to path.
122 // Note that T needs to match both send and recv side.
Austin Schuha1654ed2019-01-27 17:24:54 -0800123 // TODO(parker): Need to support ::std::bind. For now, use lambdas.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800124 template <typename Watch>
125 void MakeWatcher(const std::string &path, Watch &&w);
126
127 // The passed in function will be called when the event loop starts.
128 // Use this to run code once the thread goes into "real-time-mode",
129 virtual void OnRun(std::function<void()>) = 0;
130
131 // Starts receiving events.
132 virtual void Run() = 0;
133
134 // TODO(austin): Sort out how to switch to realtime on run.
135 // virtual void RunRealtime() = 0;
136
137 // Stops receiving events
138 virtual void Exit() = 0;
139};
140
141} // namespace aos
142
143#include "aos/events/event-loop-tmpl.h"
144
145#endif // _AOS_EVENTS_EVENT_LOOP_H