OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
scenario.hpp
1#pragma once
2#include <ossia/detail/config.hpp>
3
4#include <ossia/dataflow/graph/small_graph.hpp>
5#include <ossia/detail/flat_map.hpp>
6#include <ossia/detail/flat_set.hpp>
7#include <ossia/detail/pod_vector.hpp>
9#include <ossia/detail/ptr_set.hpp>
10#include <ossia/detail/small_vector.hpp>
13
14#include <boost/graph/adjacency_list.hpp>
15
16#include <ankerl/unordered_dense.h>
17
18namespace ossia
19{
20class time_event;
21class time_interval;
22class time_sync;
23using interval_set = ossia::flat_set<time_interval*>;
24using sync_set = ossia::flat_set<time_sync*>;
25using small_sync_vec = ossia::small_vector<time_sync*, 4>;
26using small_event_vec = std::vector<time_event*>;
27struct overtick
28{
29 ossia::time_value min;
30 ossia::time_value max;
31 ossia::time_value offset;
32
35 int32_t start_sample{-1};
36};
37using overtick_map = ossia::flat_map<time_sync*, overtick>;
38
39class scenario;
40using scenario_graph_vertex = time_sync*;
41using scenario_graph_edge = time_interval*;
42
43using scenario_graph_t = boost::adjacency_list<
44 boost::smallvecS, boost::smallvecS, boost::undirectedS, scenario_graph_vertex,
45 scenario_graph_edge>;
46
47inline void
48remove_vertex(typename scenario_graph_t::vertex_descriptor v, scenario_graph_t& g)
49{
50 typedef typename scenario_graph_t::directed_category Cat;
51 g.removing_vertex(v, boost::graph_detail::iterator_stability(g.m_vertices));
52 boost::detail::remove_vertex_dispatch(g, v, Cat());
53}
54
55/*
56template <typename T, typename V>
57using dense_ptr_map = ankerl::unordered_dense::map<
58 T, V, EgurHash<std::remove_pointer_t<T>>, std::equal_to<T>,
59 ossia::small_vector<std::pair<T, V>, 1024>>;
60struct scenario_graph
61{
62 scenario& scenar;
63
64 scenario_graph(scenario& sc);
65
66 void add_vertice(scenario_graph_vertex timeSync);
67 void add_edge(scenario_graph_edge itv);
68 void remove_vertice(scenario_graph_vertex timeSync);
69 void remove_edge(scenario_graph_edge itv);
70
71 void reset_component(ossia::time_sync& sync) const;
72
73private:
74 void recompute_maps();
75 void update_components_cache() const;
76 scenario_graph_t graph;
77 mutable ossia::int_vector m_components_cache;
78 mutable bool dirty = false;
79 ossia::dense_ptr_map<const time_sync*, scenario_graph_t::vertex_descriptor> vertices;
80 ossia::dense_ptr_map<const time_interval*, scenario_graph_t::edge_descriptor> edges;
81
82 std::vector<std::shared_ptr<ossia::time_sync>> to_disable_sync;
83 std::vector<std::shared_ptr<ossia::time_interval>> to_disable_itv;
84}; */
85
86class OSSIA_EXPORT scenario final : public looping_process<scenario>
87{
88 friend class looping_process<scenario>;
89
90public:
91 scenario();
92 ~scenario() override;
93
98 void add_time_interval(std::shared_ptr<time_interval>);
99
103 void remove_time_interval(const std::shared_ptr<time_interval>&);
104
107 void add_time_sync(std::shared_ptr<time_sync>);
108
111 void remove_time_sync(const std::shared_ptr<time_sync>&);
112
115 const std::shared_ptr<time_sync>& get_start_time_sync() const;
116
119 const ptr_container<time_sync>& get_time_syncs() const;
120
123 const ptr_container<time_interval>& get_time_intervals() const;
124
125 friend struct scenario_graph;
126 void offset_impl(ossia::time_value) override;
127
128 void state_impl(const ossia::token_request& req);
129
130 void start() override;
131 void stop() override;
132 void pause() override;
133 void resume() override;
134
135 void transport_impl(ossia::time_value offset) override;
136 void mute_impl(bool) override;
137
144 void request_start_interval(
145 ossia::time_interval&, double ratio = 0.0, ossia::time_value from = {});
151 void request_stop_interval(ossia::time_interval&, double ratio = 0.0);
152
153 small_sync_vec get_roots() const noexcept;
154
155 void reset_subgraph(
156 const ptr_container<time_sync>&, const ptr_container<time_interval>&,
157 time_sync& root);
158
159 ossia::time_value last_date() const noexcept { return m_last_date; }
160
161 void set_exclusive(bool excl) noexcept;
162 bool exclusive(bool excl) const noexcept;
163
164private:
165 void stop_all_intervals();
166 void prepare_offset();
167 void make_rigid(time_interval& itv, time_value min, time_value max);
168 void restore_durations();
169 ossia::time_value m_last_date{ossia::Infinite};
170
172 struct saved_durations
173 {
174 time_value min;
175 time_value max;
176 };
177 ossia::flat_map<time_interval*, saved_durations> m_offset_durations;
178
179 ptr_container<time_interval> m_intervals;
180 ptr_container<time_sync> m_nodes; // list of all TimeSyncs of the scenario
181 // (the first is the start node)
182
183 interval_set m_runningIntervals;
184 sync_set m_waitingNodes;
185 small_sync_vec m_rootNodes;
186 small_event_vec m_pendingEvents;
187 small_event_vec m_maxReachedEvents;
188 overtick_map m_overticks; // used as cache
189 ossia::flat_map<time_interval*, time_value> m_itv_end_map;
190 sync_set m_retry_syncs; // used as cache
191 sync_set m_endNodes; // used as cache
192
193 // Backward playback support
194 overtick_map m_backward_overticks;
195 sync_set m_startNodes;
196 // scenario_graph m_sg; // used as cache
197
198 sync_set m_component_visit_cache;
199 std::vector<ossia::time_sync*> m_component_visit_stack;
200
201 bool m_exclusive{};
202
203 // Used to start intervals off-time
204 struct quantized_interval
205 {
206 ossia::time_interval* interval{};
207 double quantization_ratio{};
208 ossia::time_value from{};
209 operator ossia::time_interval*() const noexcept { return interval; }
210 };
211
212 ossia::small_vector<quantized_interval, 2> m_itv_to_start;
213 ossia::small_vector<quantized_interval, 2> m_itv_to_stop;
214
215 static void make_happen(
216 time_event& event, interval_set& started, interval_set& stopped,
217 ossia::time_value tick_offset, const ossia::token_request& tok);
218
219 static void make_dispose(time_event& event, interval_set& stopped);
220
221 sync_status process_this(
222 time_sync& node, small_event_vec& pendingEvents, small_event_vec& maxReachedEvents,
223 interval_set& started, interval_set& stopped, ossia::time_value tick_offset,
224 const token_request& tok);
225
226 sync_status trigger_sync(
227 time_sync& node, small_event_vec& pending, small_event_vec& maxReachedEv,
228 interval_set& started, interval_set& stopped, ossia::time_value tick_offset,
229 const token_request& req, bool maxReached);
230
231 sync_status process_this_musical(
232 time_sync& node, small_event_vec& pendingEvents, small_event_vec& maxReachedEvents,
233 ossia::time_value tick_offset, const token_request& tok) noexcept;
234
235 sync_status trigger_sync_musical(
236 time_sync& node, small_event_vec& maxReachedEvents, ossia::time_value tick_offset,
237 const token_request& req, bool maxReached) noexcept;
238
239 sync_status
240 quantify_time_sync(time_sync& sync, const ossia::token_request& tk) noexcept;
241
242 sync_status
243 trigger_quantified_time_sync(time_sync& sync, bool& maximalDurationReached) noexcept;
244
248 void run_interval(
249 ossia::time_interval& interval, const ossia::token_request& tk,
250 const time_value& tick_ms, ossia::time_value tick, ossia::time_value offset,
251 int32_t start_sample, int32_t end_sample);
252
253 void stop_interval(ossia::time_interval& itv);
254 void reset_component(ossia::time_sync& n);
255 void reset_all_components_except(ossia::time_sync& n);
256
257 void state_impl_backward(const ossia::token_request& tk, time_value tick_amount);
258 void run_interval_backward(
259 ossia::time_interval& interval, const ossia::token_request& tk,
260 const time_value& tick_ms, ossia::time_value tick, ossia::time_value offset,
261 int32_t start_sample, int32_t end_sample);
262};
263}
The time_event class.
Definition time_event.hpp:34
The time_interval class.
Definition time_interval.hpp:49
time_sync is use to describe temporal structure to synchronize each attached time_event evaluation.
Definition time_sync.hpp:103
Definition git_info.h:7
OSSIA_INLINE constexpr auto min(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
min function tailored for values
Definition math.hpp:125
OSSIA_INLINE constexpr auto max(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
max function tailored for values
Definition math.hpp:96