blob: 90eb721fbf7a8d038fb9c47349a18aba6ac60f45 [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:
37 Sender() {}
38
39 // Represents a single message about to be sent to the queue.
40 // The lifecycle goes:
41 //
42 // Message msg = sender.MakeMessage();
43 // Populate(msg.get());
44 // msg.Send();
45 //
46 // Or:
47 //
48 // Message msg = sender.MakeMessage();
49 // PopulateOrNot(msg.get());
50 class Message {
51 public:
52 Message(RawSender *sender)
53 : msg_(reinterpret_cast<T *>(sender->GetContext()), *sender) {
54 msg_->Zero();
55 }
56
57 T *get() { return msg_.get(); }
58 const T *get() const { return msg_.get(); }
59 T &operator*() { return *get(); }
60 T *operator->() { return get(); }
61 const T &operator*() const { return *get(); }
62 const T *operator->() const { return get(); }
63
Austin Schuh81fc9cc2019-02-02 23:25:47 -080064 // Sends the message to the queue. Should only be called once. Returns true
65 // if the message was successfully sent, and false otherwise.
66 bool Send() {
Parker Schuhe4a70d62017-12-27 20:10:20 -080067 RawSender *sender = &msg_.get_deleter();
68 msg_->SetTimeToNow();
Austin Schuh81fc9cc2019-02-02 23:25:47 -080069 return sender->Send(
70 reinterpret_cast<RawSender::SendContext *>(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
129 // Starts receiving events.
130 virtual void Run() = 0;
131
132 // TODO(austin): Sort out how to switch to realtime on run.
133 // virtual void RunRealtime() = 0;
134
135 // Stops receiving events
136 virtual void Exit() = 0;
137};
138
139} // namespace aos
140
141#include "aos/events/event-loop-tmpl.h"
142
143#endif // _AOS_EVENTS_EVENT_LOOP_H