blob: d3cbf3fffa434e560f2dacddf85b35b7390f12c2 [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>
5#include "aos/common/queue.h"
6#include "aos/common/time.h"
7#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() {}
16 // Fetches the most recent message. Returns whether it fetched a new message.
17 bool Fetch() { return fetcher_->Fetch(); }
18
19 const T *get() const {
20 return reinterpret_cast<const T *>(fetcher_->most_recent());
21 }
22 const T &operator*() const { return *get(); }
23 const T *operator->() const { return get(); }
24
25 private:
26 friend class EventLoop;
27 Fetcher(std::unique_ptr<RawFetcher> fetcher) : fetcher_(std::move(fetcher)) {}
28 std::unique_ptr<RawFetcher> fetcher_;
29};
30
31// Sends messages to a queue.
32template <typename T>
33class Sender {
34 public:
35 Sender() {}
36
37 // Represents a single message about to be sent to the queue.
38 // The lifecycle goes:
39 //
40 // Message msg = sender.MakeMessage();
41 // Populate(msg.get());
42 // msg.Send();
43 //
44 // Or:
45 //
46 // Message msg = sender.MakeMessage();
47 // PopulateOrNot(msg.get());
48 class Message {
49 public:
50 Message(RawSender *sender)
51 : msg_(reinterpret_cast<T *>(sender->GetContext()), *sender) {
52 msg_->Zero();
53 }
54
55 T *get() { return msg_.get(); }
56 const T *get() const { return msg_.get(); }
57 T &operator*() { return *get(); }
58 T *operator->() { return get(); }
59 const T &operator*() const { return *get(); }
60 const T *operator->() const { return get(); }
61
62 // Sends the message to the queue. Should only be called once.
63 void Send() {
64 RawSender *sender = &msg_.get_deleter();
65 msg_->SetTimeToNow();
66 sender->Send(reinterpret_cast<RawSender::SendContext *>(msg_.release()));
67 }
68
69 private:
70 std::unique_ptr<T, RawSender &> msg_;
71 };
72
73 // Constructs an above message.
74 Message MakeMessage();
75
76 private:
77 friend class EventLoop;
78 Sender(std::unique_ptr<RawSender> sender) : sender_(std::move(sender)) {}
79 std::unique_ptr<RawSender> sender_;
80};
81
82// TODO(parker): Consider making EventLoop wrap a RawEventLoop rather than
83// inheriting.
84class EventLoop : public RawEventLoop {
85 public:
86 virtual ~EventLoop() {}
87
88 // Current time.
89 virtual monotonic_clock::time_point monotonic_now() = 0;
90
91 // Makes a class that will always fetch the most recent value
92 // sent to path.
93 template <typename T>
94 Fetcher<T> MakeFetcher(const std::string &path) {
95 return Fetcher<T>(MakeRawFetcher(path, QueueTypeInfo::Get<T>()));
96 }
97
98 // Makes class that allows constructing and sending messages to
99 // address path.
100 template <typename T>
101 Sender<T> MakeSender(const std::string &path) {
102 return Sender<T>(MakeRawSender(path, QueueTypeInfo::Get<T>()));
103 }
104
105 // Watch is a functor that have a call signature like so:
106 // void Event(const MessageType& type);
107 //
108 // This will watch messages sent to path.
109 // Note that T needs to match both send and recv side.
110 template <typename Watch>
111 void MakeWatcher(const std::string &path, Watch &&w);
112
113 // The passed in function will be called when the event loop starts.
114 // Use this to run code once the thread goes into "real-time-mode",
115 virtual void OnRun(std::function<void()>) = 0;
116
117 // Starts receiving events.
118 virtual void Run() = 0;
119
120 // TODO(austin): Sort out how to switch to realtime on run.
121 // virtual void RunRealtime() = 0;
122
123 // Stops receiving events
124 virtual void Exit() = 0;
125};
126
127} // namespace aos
128
129#include "aos/events/event-loop-tmpl.h"
130
131#endif // _AOS_EVENTS_EVENT_LOOP_H