Parker Schuh | e4a70d6 | 2017-12-27 20:10:20 -0800 | [diff] [blame] | 1 | #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. |
| 15 | namespace 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. |
| 20 | class 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(). |
| 44 | class 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. |
| 70 | struct 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 | } |
| 86 | }; |
| 87 | |
Neil Balch | 229001a | 2018-01-07 18:22:52 -0800 | [diff] [blame^] | 88 | // Interface for timers |
| 89 | class TimerHandler { |
| 90 | public: |
| 91 | virtual ~TimerHandler() {} |
| 92 | |
| 93 | // Timer should sleep until base, base + offset, base + offset * 2, ... |
| 94 | // If repeat_offset isn't set, the timer only expires once. |
| 95 | virtual void Setup(monotonic_clock::time_point base, |
| 96 | monotonic_clock::duration repeat_offset = |
| 97 | ::aos::monotonic_clock::zero()) = 0; |
| 98 | |
| 99 | // Stop future calls to callback(). |
| 100 | virtual void Disable() = 0; |
| 101 | }; |
| 102 | |
Parker Schuh | e4a70d6 | 2017-12-27 20:10:20 -0800 | [diff] [blame] | 103 | // Virtual base class for all event queue-types. |
| 104 | class RawEventLoop { |
| 105 | public: |
| 106 | virtual ~RawEventLoop() {} |
| 107 | |
| 108 | // Current time. |
| 109 | virtual monotonic_clock::time_point monotonic_now() = 0; |
| 110 | |
| 111 | // The passed in function will be called when the event loop starts. |
| 112 | // Use this to run code once the thread goes into "real-time-mode", |
| 113 | virtual void OnRun(std::function<void()> on_run) = 0; |
| 114 | |
| 115 | bool is_running() const { return is_running_.load(); } |
| 116 | |
Neil Balch | 229001a | 2018-01-07 18:22:52 -0800 | [diff] [blame^] | 117 | // Creates a timer that executes callback when the timer expires |
| 118 | // Returns a TimerHandle for configuration of the timer |
| 119 | virtual TimerHandler *AddTimer(::std::function<void()> callback) = 0; |
| 120 | |
Parker Schuh | e4a70d6 | 2017-12-27 20:10:20 -0800 | [diff] [blame] | 121 | // Starts receiving events. |
| 122 | virtual void Run() = 0; |
| 123 | |
| 124 | // Stops receiving events. |
| 125 | virtual void Exit() = 0; |
| 126 | |
| 127 | protected: |
| 128 | void set_is_running(bool value) { is_running_.store(value); } |
| 129 | |
| 130 | // Will send new messages from (path, type). |
| 131 | virtual std::unique_ptr<RawSender> MakeRawSender( |
| 132 | const std::string &path, const QueueTypeInfo &type) = 0; |
| 133 | |
| 134 | // Will fetch new messages from (path, type). |
| 135 | virtual std::unique_ptr<RawFetcher> MakeRawFetcher( |
| 136 | const std::string &path, const QueueTypeInfo &type) = 0; |
| 137 | |
| 138 | // Will watch (path, type) for new messages |
| 139 | virtual void MakeRawWatcher( |
| 140 | const std::string &path, const QueueTypeInfo &type, |
| 141 | std::function<void(const Message *message)> watcher) = 0; |
| 142 | |
| 143 | private: |
| 144 | std::atomic<bool> is_running_{false}; |
| 145 | }; |
| 146 | |
| 147 | } // namespace aos |
| 148 | |
| 149 | #endif // _AOS_EVENTS_RAW_EVENT_LOOP_H_ |