Virtual Testbed
Ship dynamics simulator for extreme conditions
TestbedPipeline.hh
1 #ifndef VTESTBED_GUI_TESTBEDPIPELINE_HH
2 #define VTESTBED_GUI_TESTBEDPIPELINE_HH
3 
4 #include <atomic>
5 #include <chrono>
6 #include <mutex>
7 #include <thread>
8 
9 #include <vtestbed/core/testbed.hh>
10 #include <vtestbed/gui/types.hh>
11 
12 namespace vtb {
13 
14  namespace gui {
15 
16  template <class T>
18 
19  public:
23  using time_point = clock_type::time_point;
24  using duration = clock_type::duration;
27  using thread_type = std::thread;
29  using Record = typename statistics_type::Record;
35 
36  private:
37  enum class state_type {initial, started, stopped};
38 
39  private:
40  testbed_type _testbed;
41  testbed_gui_type* _testbed_gui;
42  callback_array _callbacks;
43  gui_callback_array _gui_callbacks;
44  thread_type _thread;
45  mutex_type _mutex;
46  std::atomic<state_type> _state{state_type::initial};
47  T _min_time_step{T{1} / T{60}};
48  T _max_time_step{T{1} / T{5}};
49  T _speed{1};
50  T _dt_accumulator;
51  std::atomic<bool> _fixed_time_step{false};
52 
53  public:
54 
55  TestbedPipeline() = default;
56  ~TestbedPipeline() = default;
57 
58  void
59  start();
60 
61  inline void stop() { this->_state = state_type::stopped; }
62  void reset();
63 
64  inline void
65  wait() {
66  if (this->_thread.joinable()) {
67  this->_thread.join();
68  }
69  }
70 
71  inline bool initial() const { return this->_state == state_type::initial; }
72  inline bool stopped() const { return this->_state == state_type::stopped; }
73  inline bool started() const { return this->_state == state_type::started; }
74 
75  inline void testbed_gui(testbed_gui_type* rhs) { this->_testbed_gui = rhs; }
76  inline testbed_gui_type* testbed_gui() { return this->_testbed_gui; }
77  void testbed(testbed_type&& rhs);
78  inline testbed_type* testbed() { return &this->_testbed; }
79 
80  inline T min_time_step() const { return this->_min_time_step; }
81  inline void min_time_step(T rhs) { this->_min_time_step = rhs; }
82  inline T max_time_step() const { return this->_max_time_step; }
83  inline void max_time_step(T rhs) { this->_max_time_step = rhs; }
84  inline T speed() const { return this->_speed; }
85  inline void speed(T rhs) { this->_speed = rhs; }
86  inline T time_step() const { return this->_dt_accumulator; }
87  inline void fixed_time_step(bool rhs) { this->_fixed_time_step = rhs; }
88  inline bool fixed_time_step() const { return this->_fixed_time_step; }
89 
90  inline T
91  frame_rate() const {
92  auto len = time_step();
93  return len == T{} ? T{0} : (T{1} / len);
94  }
95 
97  inline void
98  accumulate_dt(T dt) {
99  const T w1 = 0.25;
100  const T w2 = T{1} - w1;
101  _dt_accumulator = w1*dt + w2*_dt_accumulator;
102  }
103 
114  template <class Callback>
115  inline void
116  call(Callback&& cb) {
117  lock_type lock(this->_mutex);
118  this->_callbacks.emplace_back(std::move(cb));
119  }
120 
130  template <class Callback>
131  inline void
132  gui_call(Callback&& cb) {
133  this->_gui_callbacks.emplace_back(std::move(cb));
134  }
135 
136  void do_gui_callbacks();
137 
138  private:
139 
140  void do_callbacks();
141  void loop();
142 
143  };
144 
145  }
146 
147 }
148 
149 #endif // vim:filetype=cpp
void call(Callback &&cb)
Insert computational callback.
void gui_call(Callback &&cb)
Insert computational and graphical callbacks.
Main namespace.
Definition: convert.hh:9
Main class for interacting with virtual testbed via GUI.
Definition: TestbedGUI.hh:30
void accumulate_dt(T dt)
Accumulate FPS using exponential moving average.