blob: 9b1408db745836976b4219629de647d930c34bf1 [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>
7#include "aos/common/queue.h"
8#include "aos/common/time.h"
9
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
26 virtual bool Fetch() = 0;
27
28 const FetchValue *most_recent() { return most_recent_; }
29
30 protected:
31 RawFetcher(const RawFetcher &) = delete;
32 RawFetcher &operator=(const RawFetcher &) = delete;
33 void set_most_recent(const FetchValue *most_recent) {
34 most_recent_ = most_recent;
35 }
36
37 private:
38 const FetchValue *most_recent_ = nullptr;
39};
40
41// Raw version of sender. Sending a message is a 3 part process. Fetch an opaque
42// token, cast that token to the message type, populate and then calling one of
43// Send() or Free().
44class RawSender {
45 public:
46 class SendContext;
47
48 RawSender() {}
49 virtual ~RawSender() {}
50
51 virtual SendContext *GetContext() = 0;
52
53 virtual void Free(SendContext *context) = 0;
54
55 virtual bool Send(SendContext *context) = 0;
56
57 // Call operator that calls Free().
58 template <typename T>
59 void operator()(T *t) {
60 Free(reinterpret_cast<SendContext *>(t));
61 }
62
63 protected:
64 RawSender(const RawSender &) = delete;
65 RawSender &operator=(const RawSender &) = delete;
66};
67
68// Opaque Information extracted from a particular type passed to the underlying
69// system so that it knows how much memory to allocate etc.
70struct QueueTypeInfo {
71 // Message size:
72 size_t size;
73 // This should be a globally unique identifier for the type.
74 int hash;
75 // Config parameter for how long the queue should be.
76 int queue_length;
77
78 template <typename T>
79 static QueueTypeInfo Get() {
80 QueueTypeInfo info;
81 info.size = sizeof(T);
82 info.hash = T::kHash;
83 info.queue_length = T::kQueueLength;
84 return info;
85 }
Neil Balchc8f41ed2018-01-20 22:06:53 -080086
87 // Necessary for the comparison of QueueTypeInfo objects in the
88 // SimulatedEventLoop.
89 bool operator<(const QueueTypeInfo &other) const {
90 if (size != other.size) return size < other.size;
91 if (hash != other.hash) return hash < other.hash;
92 return queue_length < other.queue_length;
93 }
Parker Schuhe4a70d62017-12-27 20:10:20 -080094};
95
Neil Balch229001a2018-01-07 18:22:52 -080096// Interface for timers
97class TimerHandler {
98 public:
99 virtual ~TimerHandler() {}
100
101 // Timer should sleep until base, base + offset, base + offset * 2, ...
102 // If repeat_offset isn't set, the timer only expires once.
103 virtual void Setup(monotonic_clock::time_point base,
104 monotonic_clock::duration repeat_offset =
105 ::aos::monotonic_clock::zero()) = 0;
106
107 // Stop future calls to callback().
108 virtual void Disable() = 0;
109};
110
Parker Schuhe4a70d62017-12-27 20:10:20 -0800111// Virtual base class for all event queue-types.
112class RawEventLoop {
113 public:
114 virtual ~RawEventLoop() {}
115
116 // Current time.
117 virtual monotonic_clock::time_point monotonic_now() = 0;
118
119 // The passed in function will be called when the event loop starts.
120 // Use this to run code once the thread goes into "real-time-mode",
121 virtual void OnRun(std::function<void()> on_run) = 0;
122
123 bool is_running() const { return is_running_.load(); }
124
Neil Balch229001a2018-01-07 18:22:52 -0800125 // Creates a timer that executes callback when the timer expires
126 // Returns a TimerHandle for configuration of the timer
127 virtual TimerHandler *AddTimer(::std::function<void()> callback) = 0;
128
Parker Schuhe4a70d62017-12-27 20:10:20 -0800129 // Starts receiving events.
130 virtual void Run() = 0;
131
132 // Stops receiving events.
133 virtual void Exit() = 0;
134
135 protected:
136 void set_is_running(bool value) { is_running_.store(value); }
137
138 // Will send new messages from (path, type).
139 virtual std::unique_ptr<RawSender> MakeRawSender(
140 const std::string &path, const QueueTypeInfo &type) = 0;
141
142 // Will fetch new messages from (path, type).
143 virtual std::unique_ptr<RawFetcher> MakeRawFetcher(
144 const std::string &path, const QueueTypeInfo &type) = 0;
145
146 // Will watch (path, type) for new messages
147 virtual void MakeRawWatcher(
148 const std::string &path, const QueueTypeInfo &type,
149 std::function<void(const Message *message)> watcher) = 0;
150
151 private:
152 std::atomic<bool> is_running_{false};
153};
154
155} // namespace aos
156
157#endif // _AOS_EVENTS_RAW_EVENT_LOOP_H_