blob: 1435723f3a551c9b9485c802d9fe0d67c9742ba8 [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() {}
Austin Schuhbbce72d2019-05-26 15:11:46 -070016 // Fetches the next message. Returns true if it fetched a new message. This
17 // method will only return messages sent after the Fetcher was created.
James Kuszmaulc79768b2019-02-18 15:08:44 -080018 bool FetchNext() { return fetcher_->FetchNext(); }
Austin Schuhbbce72d2019-05-26 15:11:46 -070019 // Fetches the most recent message. Returns true if it fetched a new message.
20 // This will return the latest message regardless of if it was sent before or
21 // after the fetcher was created.
Parker Schuhe4a70d62017-12-27 20:10:20 -080022 bool Fetch() { return fetcher_->Fetch(); }
23
24 const T *get() const {
25 return reinterpret_cast<const T *>(fetcher_->most_recent());
26 }
27 const T &operator*() const { return *get(); }
28 const T *operator->() const { return get(); }
29
30 private:
31 friend class EventLoop;
Austin Schuh6b6dfa52019-06-12 20:16:20 -070032 Fetcher(::std::unique_ptr<RawFetcher> fetcher) : fetcher_(::std::move(fetcher)) {}
33 ::std::unique_ptr<RawFetcher> fetcher_;
Parker Schuhe4a70d62017-12-27 20:10:20 -080034};
35
36// Sends messages to a queue.
37template <typename T>
38class Sender {
39 public:
Austin Schuhdf6cbb12019-02-02 13:46:52 -080040 typedef T Type;
41
Parker Schuhe4a70d62017-12-27 20:10:20 -080042 Sender() {}
43
44 // Represents a single message about to be sent to the queue.
45 // The lifecycle goes:
46 //
47 // Message msg = sender.MakeMessage();
48 // Populate(msg.get());
49 // msg.Send();
50 //
51 // Or:
52 //
53 // Message msg = sender.MakeMessage();
54 // PopulateOrNot(msg.get());
55 class Message {
56 public:
57 Message(RawSender *sender)
James Kuszmaulcd1db352019-05-26 16:42:29 -070058 : msg_(reinterpret_cast<T *>(sender->GetMessage()), *sender) {
Parker Schuhe4a70d62017-12-27 20:10:20 -080059 msg_->Zero();
60 }
61
62 T *get() { return msg_.get(); }
63 const T *get() const { return msg_.get(); }
64 T &operator*() { return *get(); }
65 T *operator->() { return get(); }
66 const T &operator*() const { return *get(); }
67 const T *operator->() const { return get(); }
68
Austin Schuh81fc9cc2019-02-02 23:25:47 -080069 // Sends the message to the queue. Should only be called once. Returns true
70 // if the message was successfully sent, and false otherwise.
71 bool Send() {
Parker Schuhe4a70d62017-12-27 20:10:20 -080072 RawSender *sender = &msg_.get_deleter();
James Kuszmaulcd1db352019-05-26 16:42:29 -070073 return sender->Send(msg_.release());
Parker Schuhe4a70d62017-12-27 20:10:20 -080074 }
75
76 private:
77 std::unique_ptr<T, RawSender &> msg_;
78 };
79
80 // Constructs an above message.
81 Message MakeMessage();
82
Austin Schuhd681bbd2019-02-02 12:03:32 -080083 // Returns the name of the underlying queue.
84 const char *name() const { return sender_->name(); }
85
Parker Schuhe4a70d62017-12-27 20:10:20 -080086 private:
87 friend class EventLoop;
Austin Schuh6b6dfa52019-06-12 20:16:20 -070088 Sender(::std::unique_ptr<RawSender> sender) : sender_(::std::move(sender)) {}
89 ::std::unique_ptr<RawSender> sender_;
Parker Schuhe4a70d62017-12-27 20:10:20 -080090};
91
92// TODO(parker): Consider making EventLoop wrap a RawEventLoop rather than
93// inheriting.
94class EventLoop : public RawEventLoop {
95 public:
96 virtual ~EventLoop() {}
97
98 // Current time.
99 virtual monotonic_clock::time_point monotonic_now() = 0;
100
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800101 // Note, it is supported to create:
102 // multiple fetchers, and (one sender or one watcher) per <path, type>
103 // tuple.
104
Parker Schuhe4a70d62017-12-27 20:10:20 -0800105 // Makes a class that will always fetch the most recent value
106 // sent to path.
107 template <typename T>
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700108 Fetcher<T> MakeFetcher(const ::std::string &path) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800109 return Fetcher<T>(MakeRawFetcher(path, QueueTypeInfo::Get<T>()));
110 }
111
112 // Makes class that allows constructing and sending messages to
113 // address path.
114 template <typename T>
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700115 Sender<T> MakeSender(const ::std::string &path) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800116 return Sender<T>(MakeRawSender(path, QueueTypeInfo::Get<T>()));
117 }
118
119 // Watch is a functor that have a call signature like so:
120 // void Event(const MessageType& type);
121 //
122 // This will watch messages sent to path.
123 // Note that T needs to match both send and recv side.
Austin Schuha1654ed2019-01-27 17:24:54 -0800124 // TODO(parker): Need to support ::std::bind. For now, use lambdas.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800125 template <typename Watch>
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700126 void MakeWatcher(const ::std::string &path, Watch &&w);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800127
128 // The passed in function will be called when the event loop starts.
129 // Use this to run code once the thread goes into "real-time-mode",
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700130 virtual void OnRun(::std::function<void()>) = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800131
Austin Schuh3115a202019-05-27 21:02:14 -0700132 // TODO(austin): OnExit
Parker Schuhe4a70d62017-12-27 20:10:20 -0800133
134 // Stops receiving events
135 virtual void Exit() = 0;
Austin Schuh3115a202019-05-27 21:02:14 -0700136
137 // Sets the scheduler priority to run the event loop at. This may not be
138 // called after we go into "real-time-mode".
139 virtual void SetRuntimeRealtimePriority(int priority) = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800140};
141
142} // namespace aos
143
144#include "aos/events/event-loop-tmpl.h"
145
146#endif // _AOS_EVENTS_EVENT_LOOP_H