blob: 99450a3111d6f1d895270e2e58855ddd744dd6aa [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#ifndef AOS_EVENTS_SIMULATED_EVENT_LOOP_H_
2#define AOS_EVENTS_SIMULATED_EVENT_LOOP_H_
3
4#include <algorithm>
5#include <map>
6#include <memory>
Austin Schuh5f1cc5c2019-12-01 18:01:11 -08007#include <string_view>
Alex Perrycb7da4b2019-08-28 19:35:56 -07008#include <unordered_set>
9#include <utility>
10#include <vector>
11
12#include "absl/container/btree_map.h"
13#include "aos/events/event_loop.h"
14#include "aos/events/event_scheduler.h"
15#include "aos/flatbuffer_merge.h"
16#include "aos/flatbuffers.h"
17#include "aos/ipc_lib/index.h"
18#include "glog/logging.h"
19
20namespace aos {
21
22// Class for simulated fetchers.
23class SimulatedChannel;
24
25struct SimpleChannel {
26 SimpleChannel(const Channel *channel);
27 std::string name;
28 std::string type;
29
30 std::string DebugString() const {
31 return std::string("{ ") + name + ", " + type + "}";
32 }
33
34 bool operator==(const SimpleChannel &other) const {
35 return name == other.name && type == other.type;
36 }
37 bool operator<(const SimpleChannel &other) const {
38 int name_compare = other.name.compare(name);
39 if (name_compare == 0) {
40 return other.type < type;
41 } else if (name_compare < 0) {
42 return true;
43 } else {
44 return false;
45 }
46 }
47};
48
49class SimulatedEventLoopFactory {
50 public:
51 // Constructs a SimulatedEventLoopFactory with the provided configuration.
52 // This configuration must remain in scope for the lifetime of the factory and
53 // all sub-objects.
54 SimulatedEventLoopFactory(const Configuration *configuration);
Austin Schuh217a9782019-12-21 23:02:50 -080055 SimulatedEventLoopFactory(const Configuration *configuration,
56 std::string_view node_name);
Austin Schuh15649d62019-12-28 16:36:38 -080057 SimulatedEventLoopFactory(const Configuration *configuration,
58 const Node *node);
Alex Perrycb7da4b2019-08-28 19:35:56 -070059 ~SimulatedEventLoopFactory();
60
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080061 ::std::unique_ptr<EventLoop> MakeEventLoop(std::string_view name);
Alex Perrycb7da4b2019-08-28 19:35:56 -070062
63 // Starts executing the event loops unconditionally.
64 void Run();
65 // Executes the event loops for a duration.
66 void RunFor(monotonic_clock::duration duration);
67
68 // Stops executing all event loops. Meant to be called from within an event
69 // loop handler.
70 void Exit() { scheduler_.Exit(); }
71
Austin Schuh7d87b672019-12-01 20:23:49 -080072 // Sets the simulated send delay for the factory.
73 void set_send_delay(std::chrono::nanoseconds send_delay);
James Kuszmaul314f1672020-01-03 20:02:08 -080074 std::chrono::nanoseconds send_delay() const;
Austin Schuh7d87b672019-12-01 20:23:49 -080075
Austin Schuh217a9782019-12-21 23:02:50 -080076 // Returns the node that this factory is running as, or nullptr if this is a
77 // single node setup.
78 const Node *node() const { return node_; }
79
Alex Perrycb7da4b2019-08-28 19:35:56 -070080 monotonic_clock::time_point monotonic_now() const {
81 return scheduler_.monotonic_now();
82 }
83 realtime_clock::time_point realtime_now() const {
84 return scheduler_.realtime_now();
85 }
86
Austin Schuh92547522019-12-28 14:33:43 -080087 // Sets realtime clock to realtime_now for a given monotonic clock.
88 void SetRealtimeOffset(monotonic_clock::time_point monotonic_now,
89 realtime_clock::time_point realtime_now) {
90 scheduler_.SetRealtimeOffset(monotonic_now, realtime_now);
91 }
92
Alex Perrycb7da4b2019-08-28 19:35:56 -070093 private:
Austin Schuh217a9782019-12-21 23:02:50 -080094 const Configuration *const configuration_;
Alex Perrycb7da4b2019-08-28 19:35:56 -070095 EventScheduler scheduler_;
96 // Map from name, type to queue.
97 absl::btree_map<SimpleChannel, std::unique_ptr<SimulatedChannel>> channels_;
98 // List of event loops to manage running and not running for.
99 std::vector<std::pair<EventLoop *, std::function<void(bool)>>>
100 raw_event_loops_;
Austin Schuh39788ff2019-12-01 18:22:57 -0800101
Austin Schuh7d87b672019-12-01 20:23:49 -0800102 std::chrono::nanoseconds send_delay_ = std::chrono::microseconds(50);
103
Austin Schuh217a9782019-12-21 23:02:50 -0800104 const Node *const node_;
105
Austin Schuh39788ff2019-12-01 18:22:57 -0800106 pid_t tid_ = 0;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700107};
108
109} // namespace aos
110
111#endif // AOS_EVENTS_SIMULATED_EVENT_LOOP_H_