blob: 887c7abbaa0279911485830da1ea04d57f917e3b [file] [log] [blame]
Parker Schuhe4a70d62017-12-27 20:10:20 -08001#ifndef _AOS_EVENTS_RAW_EVENT_LOOP_H_
2#define _AOS_EVENTS_RAW_EVENT_LOOP_H_
3
4#include <atomic>
5#include <memory>
6#include <string>
John Park33858a32018-09-28 23:05:48 -07007#include "aos/queue.h"
8#include "aos/time/time.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -08009
10// This file contains raw versions of the classes in event-loop.h.
11//
12// Users should look exclusively at event-loop.h. Only people who wish to
13// implement a new IPC layer (like a fake layer for example) may wish to use
14// these classes.
15namespace aos {
16
17// Raw version of fetcher. Contains a local variable that the fetcher will
18// update.
19// It is the job of the typed version to cast this to the appropriate type.
20class RawFetcher {
21 public:
Parker Schuhe4a70d62017-12-27 20:10:20 -080022 RawFetcher() {}
23 virtual ~RawFetcher() {}
24
James Kuszmaulc79768b2019-02-18 15:08:44 -080025 // Non-blocking fetch of the next message in the queue. Returns true if there
26 // was a new message and we got it.
27 virtual bool FetchNext() = 0;
28 // Non-blocking fetch of the latest message:
Parker Schuhe4a70d62017-12-27 20:10:20 -080029 virtual bool Fetch() = 0;
30
James Kuszmaulaf04d732019-10-06 21:51:55 -070031 const void *most_recent() { return most_recent_; }
Parker Schuhe4a70d62017-12-27 20:10:20 -080032
33 protected:
34 RawFetcher(const RawFetcher &) = delete;
35 RawFetcher &operator=(const RawFetcher &) = delete;
James Kuszmaulaf04d732019-10-06 21:51:55 -070036 void set_most_recent(const void *most_recent) { most_recent_ = most_recent; }
Parker Schuhe4a70d62017-12-27 20:10:20 -080037
38 private:
James Kuszmaulaf04d732019-10-06 21:51:55 -070039 const void *most_recent_ = nullptr;
Parker Schuhe4a70d62017-12-27 20:10:20 -080040};
41
42// Raw version of sender. Sending a message is a 3 part process. Fetch an opaque
43// token, cast that token to the message type, populate and then calling one of
44// Send() or Free().
45class RawSender {
46 public:
Parker Schuhe4a70d62017-12-27 20:10:20 -080047 RawSender() {}
48 virtual ~RawSender() {}
49
James Kuszmaulcd1db352019-05-26 16:42:29 -070050 virtual aos::Message *GetMessage() = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -080051
James Kuszmaulcd1db352019-05-26 16:42:29 -070052 virtual void Free(aos::Message *msg) = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -080053
James Kuszmaulcd1db352019-05-26 16:42:29 -070054 virtual bool Send(aos::Message *msg) = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -080055
56 // Call operator that calls Free().
57 template <typename T>
58 void operator()(T *t) {
James Kuszmaulcd1db352019-05-26 16:42:29 -070059 Free(t);
Parker Schuhe4a70d62017-12-27 20:10:20 -080060 }
61
Austin Schuhd681bbd2019-02-02 12:03:32 -080062 virtual const char *name() const = 0;
63
Parker Schuhe4a70d62017-12-27 20:10:20 -080064 protected:
65 RawSender(const RawSender &) = delete;
66 RawSender &operator=(const RawSender &) = delete;
67};
68
69// Opaque Information extracted from a particular type passed to the underlying
70// system so that it knows how much memory to allocate etc.
71struct QueueTypeInfo {
72 // Message size:
73 size_t size;
74 // This should be a globally unique identifier for the type.
75 int hash;
76 // Config parameter for how long the queue should be.
77 int queue_length;
78
79 template <typename T>
80 static QueueTypeInfo Get() {
81 QueueTypeInfo info;
82 info.size = sizeof(T);
83 info.hash = T::kHash;
84 info.queue_length = T::kQueueLength;
85 return info;
86 }
Neil Balchc8f41ed2018-01-20 22:06:53 -080087
88 // Necessary for the comparison of QueueTypeInfo objects in the
89 // SimulatedEventLoop.
90 bool operator<(const QueueTypeInfo &other) const {
91 if (size != other.size) return size < other.size;
92 if (hash != other.hash) return hash < other.hash;
93 return queue_length < other.queue_length;
94 }
Parker Schuhe4a70d62017-12-27 20:10:20 -080095};
96
Neil Balch229001a2018-01-07 18:22:52 -080097// Interface for timers
98class TimerHandler {
99 public:
100 virtual ~TimerHandler() {}
101
102 // Timer should sleep until base, base + offset, base + offset * 2, ...
103 // If repeat_offset isn't set, the timer only expires once.
104 virtual void Setup(monotonic_clock::time_point base,
105 monotonic_clock::duration repeat_offset =
106 ::aos::monotonic_clock::zero()) = 0;
107
108 // Stop future calls to callback().
109 virtual void Disable() = 0;
110};
111
Austin Schuh52d325c2019-06-23 18:59:06 -0700112// Interface for phased loops. They are built on timers.
113class PhasedLoopHandler {
114 public:
115 virtual ~PhasedLoopHandler() {}
116
117 // Sets the interval and offset. Any changes to interval and offset only take
118 // effect when the handler finishes running.
119 virtual void set_interval_and_offset(
120 const monotonic_clock::duration interval,
121 const monotonic_clock::duration offset) = 0;
122};
123
Austin Schuh44019f92019-05-19 19:58:27 -0700124class EventScheduler;
125
Parker Schuhe4a70d62017-12-27 20:10:20 -0800126// Virtual base class for all event queue-types.
127class RawEventLoop {
128 public:
129 virtual ~RawEventLoop() {}
130
131 // Current time.
132 virtual monotonic_clock::time_point monotonic_now() = 0;
133
134 // The passed in function will be called when the event loop starts.
135 // Use this to run code once the thread goes into "real-time-mode",
Austin Schuh44019f92019-05-19 19:58:27 -0700136 virtual void OnRun(::std::function<void()> on_run) = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800137
Austin Schuh0fc3b3e2019-06-29 13:56:21 -0700138 // Sets the name of the event loop.
139 virtual void set_name(const char *name) = 0;
140
Austin Schuh52d325c2019-06-23 18:59:06 -0700141 // Threadsafe.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800142 bool is_running() const { return is_running_.load(); }
143
Neil Balch229001a2018-01-07 18:22:52 -0800144 // Creates a timer that executes callback when the timer expires
145 // Returns a TimerHandle for configuration of the timer
146 virtual TimerHandler *AddTimer(::std::function<void()> callback) = 0;
147
Austin Schuh52d325c2019-06-23 18:59:06 -0700148 // Creates a timer that executes callback periodically at the specified
149 // interval and offset. Returns a PhasedLoopHandler for interacting with the
150 // timer.
151 virtual PhasedLoopHandler *AddPhasedLoop(
152 ::std::function<void(int)> callback,
153 const monotonic_clock::duration interval,
154 const monotonic_clock::duration offset = ::std::chrono::seconds(0)) = 0;
155
Parker Schuhe4a70d62017-12-27 20:10:20 -0800156 protected:
Austin Schuh44019f92019-05-19 19:58:27 -0700157 friend class EventScheduler;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800158 void set_is_running(bool value) { is_running_.store(value); }
159
160 // Will send new messages from (path, type).
161 virtual std::unique_ptr<RawSender> MakeRawSender(
162 const std::string &path, const QueueTypeInfo &type) = 0;
163
164 // Will fetch new messages from (path, type).
165 virtual std::unique_ptr<RawFetcher> MakeRawFetcher(
166 const std::string &path, const QueueTypeInfo &type) = 0;
167
168 // Will watch (path, type) for new messages
169 virtual void MakeRawWatcher(
170 const std::string &path, const QueueTypeInfo &type,
171 std::function<void(const Message *message)> watcher) = 0;
172
173 private:
Austin Schuh44019f92019-05-19 19:58:27 -0700174 ::std::atomic<bool> is_running_{false};
Parker Schuhe4a70d62017-12-27 20:10:20 -0800175};
176
177} // namespace aos
178
179#endif // _AOS_EVENTS_RAW_EVENT_LOOP_H_