blob: be605e966895420523aff4e6b9731c1c50b0245d [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:
22 class FetchValue;
23 RawFetcher() {}
24 virtual ~RawFetcher() {}
25
James Kuszmaulc79768b2019-02-18 15:08:44 -080026 // Non-blocking fetch of the next message in the queue. Returns true if there
27 // was a new message and we got it.
28 virtual bool FetchNext() = 0;
29 // Non-blocking fetch of the latest message:
Parker Schuhe4a70d62017-12-27 20:10:20 -080030 virtual bool Fetch() = 0;
31
32 const FetchValue *most_recent() { return most_recent_; }
33
34 protected:
35 RawFetcher(const RawFetcher &) = delete;
36 RawFetcher &operator=(const RawFetcher &) = delete;
37 void set_most_recent(const FetchValue *most_recent) {
38 most_recent_ = most_recent;
39 }
40
41 private:
42 const FetchValue *most_recent_ = nullptr;
43};
44
45// Raw version of sender. Sending a message is a 3 part process. Fetch an opaque
46// token, cast that token to the message type, populate and then calling one of
47// Send() or Free().
48class RawSender {
49 public:
Parker Schuhe4a70d62017-12-27 20:10:20 -080050 RawSender() {}
51 virtual ~RawSender() {}
52
James Kuszmaulcd1db352019-05-26 16:42:29 -070053 virtual aos::Message *GetMessage() = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -080054
James Kuszmaulcd1db352019-05-26 16:42:29 -070055 virtual void Free(aos::Message *msg) = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -080056
James Kuszmaulcd1db352019-05-26 16:42:29 -070057 virtual bool Send(aos::Message *msg) = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -080058
59 // Call operator that calls Free().
60 template <typename T>
61 void operator()(T *t) {
James Kuszmaulcd1db352019-05-26 16:42:29 -070062 Free(t);
Parker Schuhe4a70d62017-12-27 20:10:20 -080063 }
64
Austin Schuhd681bbd2019-02-02 12:03:32 -080065 virtual const char *name() const = 0;
66
Parker Schuhe4a70d62017-12-27 20:10:20 -080067 protected:
68 RawSender(const RawSender &) = delete;
69 RawSender &operator=(const RawSender &) = delete;
70};
71
72// Opaque Information extracted from a particular type passed to the underlying
73// system so that it knows how much memory to allocate etc.
74struct QueueTypeInfo {
75 // Message size:
76 size_t size;
77 // This should be a globally unique identifier for the type.
78 int hash;
79 // Config parameter for how long the queue should be.
80 int queue_length;
81
82 template <typename T>
83 static QueueTypeInfo Get() {
84 QueueTypeInfo info;
85 info.size = sizeof(T);
86 info.hash = T::kHash;
87 info.queue_length = T::kQueueLength;
88 return info;
89 }
Neil Balchc8f41ed2018-01-20 22:06:53 -080090
91 // Necessary for the comparison of QueueTypeInfo objects in the
92 // SimulatedEventLoop.
93 bool operator<(const QueueTypeInfo &other) const {
94 if (size != other.size) return size < other.size;
95 if (hash != other.hash) return hash < other.hash;
96 return queue_length < other.queue_length;
97 }
Parker Schuhe4a70d62017-12-27 20:10:20 -080098};
99
Neil Balch229001a2018-01-07 18:22:52 -0800100// Interface for timers
101class TimerHandler {
102 public:
103 virtual ~TimerHandler() {}
104
105 // Timer should sleep until base, base + offset, base + offset * 2, ...
106 // If repeat_offset isn't set, the timer only expires once.
107 virtual void Setup(monotonic_clock::time_point base,
108 monotonic_clock::duration repeat_offset =
109 ::aos::monotonic_clock::zero()) = 0;
110
111 // Stop future calls to callback().
112 virtual void Disable() = 0;
113};
114
Austin Schuh44019f92019-05-19 19:58:27 -0700115class EventScheduler;
116
Parker Schuhe4a70d62017-12-27 20:10:20 -0800117// Virtual base class for all event queue-types.
118class RawEventLoop {
119 public:
120 virtual ~RawEventLoop() {}
121
122 // Current time.
123 virtual monotonic_clock::time_point monotonic_now() = 0;
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",
Austin Schuh44019f92019-05-19 19:58:27 -0700127 virtual void OnRun(::std::function<void()> on_run) = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800128
129 bool is_running() const { return is_running_.load(); }
130
Neil Balch229001a2018-01-07 18:22:52 -0800131 // Creates a timer that executes callback when the timer expires
132 // Returns a TimerHandle for configuration of the timer
133 virtual TimerHandler *AddTimer(::std::function<void()> callback) = 0;
134
Parker Schuhe4a70d62017-12-27 20:10:20 -0800135 // Stops receiving events.
136 virtual void Exit() = 0;
137
Austin Schuh44019f92019-05-19 19:58:27 -0700138 // TODO(austin): This shouldn't belong.
139 virtual void Run() = 0;
140
Parker Schuhe4a70d62017-12-27 20:10:20 -0800141 protected:
Austin Schuh44019f92019-05-19 19:58:27 -0700142 friend class EventScheduler;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800143 void set_is_running(bool value) { is_running_.store(value); }
144
145 // Will send new messages from (path, type).
146 virtual std::unique_ptr<RawSender> MakeRawSender(
147 const std::string &path, const QueueTypeInfo &type) = 0;
148
149 // Will fetch new messages from (path, type).
150 virtual std::unique_ptr<RawFetcher> MakeRawFetcher(
151 const std::string &path, const QueueTypeInfo &type) = 0;
152
153 // Will watch (path, type) for new messages
154 virtual void MakeRawWatcher(
155 const std::string &path, const QueueTypeInfo &type,
156 std::function<void(const Message *message)> watcher) = 0;
157
158 private:
Austin Schuh44019f92019-05-19 19:58:27 -0700159 ::std::atomic<bool> is_running_{false};
Parker Schuhe4a70d62017-12-27 20:10:20 -0800160};
161
162} // namespace aos
163
164#endif // _AOS_EVENTS_RAW_EVENT_LOOP_H_