Loading...
Searching...
No Matches
ExecutionContext.hpp
1#pragma once
2#include <Process/ExecutionCommand.hpp>
3#include <Process/TimeValue.hpp>
4
5#include <ossia/detail/lockfree_queue.hpp>
6#include <ossia/detail/thread.hpp>
7#include <ossia/editor/scenario/time_value.hpp>
8
9#include <score_lib_process_export.h>
10
11#include <atomic>
12#include <memory>
13namespace ossia
14{
15class graph_node;
16class graph_interface;
17struct execution_state;
18
19#if __cplusplus > 201703L
20// TODO moveme
21static const constexpr struct disable_init_key_t
22{
23} disable_init;
24struct disable_init_t
25{
26 disable_init_t(disable_init_key_t) { }
27 disable_init_t() = delete;
28 disable_init_t(const disable_init_t&) = delete;
29 disable_init_t(disable_init_t&&) = delete;
30 disable_init_t& operator=(const disable_init_t&) = delete;
31 disable_init_t& operator=(disable_init_t&&) = delete;
32};
33#endif
34
35namespace net
36{
37class node_base;
38}
39}
40namespace score
41{
42struct DocumentContext;
43template <typename T, typename U, typename V>
44class GenericComponentFactoryList;
45}
46namespace State
47{
48struct Address;
49}
50namespace Process
51{
52class ProcessModel;
53}
54namespace Execution
55{
56struct Transaction;
57class ProcessComponent;
58class ProcessComponentFactory;
59class ProcessComponentFactoryList;
60struct SetupContext;
61namespace Settings
62{
63class Model;
64}
65
66using time_function = smallfun::function<ossia::time_value(const TimeVal&)>;
67using reverse_time_function = smallfun::function<TimeVal(const ossia::time_value&)>;
68
69// ossia::spsc_queue is moodycamel::ReaderWriterQueue, except under TSan where
70// ossia swaps in ConcurrentQueue (TSan does not model its standalone fences)
71// and does not include readerwriterqueue.h at all.
72struct ExecutionCommandQueue : private ossia::spsc_queue<ExecutionCommand>
73{
74 using base_type = ossia::spsc_queue<ExecutionCommand>;
75
76public:
77 using base_type::base_type;
78 template <typename... Args>
79 inline auto enqueue(Args&&... args) -> decltype(auto)
80 {
81 OSSIA_ENSURE_CURRENT_THREAD(ossia::thread_type::Ui);
82 return base_type::enqueue(std::forward<Args>(args)...);
83 }
84 template <typename... Args>
85 inline auto enqueue_bulk(Args&&... args) -> decltype(auto)
86 {
87 OSSIA_ENSURE_CURRENT_THREAD(ossia::thread_type::Ui);
88 return base_type::enqueue(std::forward<Args>(args)...);
89 }
90 template <typename... Args>
91 inline auto try_enqueue(Args&&... args) -> decltype(auto)
92 {
93 OSSIA_ENSURE_CURRENT_THREAD(ossia::thread_type::Ui);
94 return base_type::enqueue(std::forward<Args>(args)...);
95 }
96 template <typename... Args>
97 inline auto try_enqueue_bulk(Args&&... args) -> decltype(auto)
98 {
99 OSSIA_ENSURE_CURRENT_THREAD(ossia::thread_type::Ui);
100 return base_type::enqueue(std::forward<Args>(args)...);
101 }
102
103 template <typename... Args>
104 inline auto try_dequeue(Args&&... args) -> decltype(auto)
105 {
106 OSSIA_ENSURE_CURRENT_THREAD(ossia::thread_type::Audio);
107 return base_type::try_dequeue(std::forward<Args>(args)...);
108 }
109};
110
111struct EditionCommandQueue : private moodycamel::ConcurrentQueue<ExecutionCommand>
112{
113public:
114 using ConcurrentQueue<ExecutionCommand>::ConcurrentQueue;
115 template <typename... Args>
116 inline auto enqueue(Args&&... args) -> decltype(auto)
117 {
118 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Audio);
119 return ConcurrentQueue<ExecutionCommand>::enqueue(std::forward<Args>(args)...);
120 }
121 template <typename... Args>
122 inline auto enqueue_bulk(Args&&... args) -> decltype(auto)
123 {
124 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Audio);
125 return ConcurrentQueue<ExecutionCommand>::enqueue(std::forward<Args>(args)...);
126 }
127 template <typename... Args>
128 inline auto try_enqueue(Args&&... args) -> decltype(auto)
129 {
130 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Audio);
131 return ConcurrentQueue<ExecutionCommand>::enqueue(std::forward<Args>(args)...);
132 }
133 template <typename... Args>
134 inline auto try_enqueue_bulk(Args&&... args) -> decltype(auto)
135 {
136 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Audio);
137 return ConcurrentQueue<ExecutionCommand>::enqueue(std::forward<Args>(args)...);
138 }
139
140 template <typename... Args>
141 inline auto try_dequeue(Args&&... args) -> decltype(auto)
142 {
143 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Ui);
144 return ConcurrentQueue<ExecutionCommand>::try_dequeue(std::forward<Args>(args)...);
145 }
146 template <typename... Args>
147 inline auto try_dequeue_bulk(Args&&... args) -> decltype(auto)
148 {
149 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Ui);
150 return ConcurrentQueue<ExecutionCommand>::try_dequeue_bulk(
151 std::forward<Args>(args)...);
152 }
153};
154
155struct GCCommandQueue : private moodycamel::ConcurrentQueue<GCCommand>
156{
157public:
158 using ConcurrentQueue<GCCommand>::ConcurrentQueue;
159 template <typename... Args>
160 inline auto enqueue(Args&&... args) -> decltype(auto)
161 {
162 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Audio);
163 return ConcurrentQueue<GCCommand>::enqueue(std::forward<Args>(args)...);
164 }
165 template <typename... Args>
166 inline auto enqueue_bulk(Args&&... args) -> decltype(auto)
167 {
168 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Audio);
169 return ConcurrentQueue<GCCommand>::enqueue(std::forward<Args>(args)...);
170 }
171 template <typename... Args>
172 inline auto try_enqueue(Args&&... args) -> decltype(auto)
173 {
174 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Audio);
175 return ConcurrentQueue<GCCommand>::enqueue(std::forward<Args>(args)...);
176 }
177 template <typename... Args>
178 inline auto try_enqueue_bulk(Args&&... args) -> decltype(auto)
179 {
180 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Audio);
181 return ConcurrentQueue<GCCommand>::enqueue(std::forward<Args>(args)...);
182 }
183
184 template <typename... Args>
185 inline auto try_dequeue(Args&&... args) -> decltype(auto)
186 {
187 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Ui);
188 return ConcurrentQueue<GCCommand>::try_dequeue(std::forward<Args>(args)...);
189 }
190 template <typename... Args>
191 inline auto try_dequeue_bulk(Args&&... args) -> decltype(auto)
192 {
193 OSSIA_ENSURE_CURRENT_THREAD_KIND(ossia::thread_type::Ui);
194 return ConcurrentQueue<GCCommand>::try_dequeue_bulk(std::forward<Args>(args)...);
195 }
196};
197
200struct SCORE_LIB_PROCESS_EXPORT Context
201{
202 std::weak_ptr<void> alias;
203
204 auto acquireExecutionQueue() const noexcept
205 {
206 return std::shared_ptr<Execution::ExecutionCommandQueue>(
207 alias.lock(), &executionQueue);
208 }
209 auto acquireEditionQueue() const noexcept
210 {
211 return std::shared_ptr<Execution::EditionCommandQueue>(alias.lock(), &editionQueue);
212 }
213 auto acquireGCQueue() const noexcept
214 {
215 return std::shared_ptr<Execution::GCCommandQueue>(alias.lock(), &gcQueue);
216 }
217 std::weak_ptr<const Context> weakSelf() const noexcept
218 {
219 return std::shared_ptr<const Context>(alias.lock(), this);
220 }
221 std::weak_ptr<Execution::ExecutionCommandQueue> weakExecutionQueue() const noexcept
222 {
223 return std::shared_ptr<Execution::ExecutionCommandQueue>(
224 alias.lock(), &executionQueue);
225 }
226 std::weak_ptr<Execution::EditionCommandQueue> weakEditionQueue() const noexcept
227 {
228 return std::shared_ptr<Execution::EditionCommandQueue>(alias.lock(), &editionQueue);
229 }
230 std::weak_ptr<Execution::GCCommandQueue> weakGCQueue() const noexcept
231 {
232 return std::shared_ptr<Execution::GCCommandQueue>(alias.lock(), &gcQueue);
233 }
234
235 const score::DocumentContext& doc;
236 const std::atomic_bool& created;
237
244 Execution::reverse_time_function reverseTime;
245
248 EditionCommandQueue& editionQueue;
249 GCCommandQueue& gcQueue;
250 SetupContext& setup;
251
252 const std::shared_ptr<ossia::graph_interface>& execGraph;
253 const std::shared_ptr<ossia::execution_state>& execState;
254
255 auto& context() const { return *this; }
256
257#if !defined(_MSC_VER)
258#if __cplusplus > 201703L
259#pragma clang diagnostic push
260#pragma clang diagnostic ignored "-Wunknown-attributes"
261 [[no_unique_address]] ossia::disable_init_t disable_copy;
262#pragma clang diagnostic pop
263#else
264 Context() = delete;
265 Context(const Context&) = delete;
266 Context& operator=(const Context&) = delete;
267 Context(Context&&) = delete;
268 Context& operator=(Context&&) = delete;
269#endif
270#endif
271
281 bool retired = false;
282};
283
284}
285
286#define in_exec this->system().executionQueue.enqueue
287#define in_edit this->system().editionQueue.enqueue
288#define weak_exec this->system().weakExecutionQueue()
289#define weak_edit this->system().weakEditionQueue()
290#define weak_gc this->system().weakGCQueue()
Components used for the execution of a score.
Definition ProcessComponent.cpp:14
smallfun::function< ossia::time_value(const TimeVal &)> time_function
Sets-up and manages the main execution clock.
Definition ExecutionContext.hpp:66
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
Utilities for OSSIA data structures.
Definition DeviceInterface.hpp:35
Base toolkit upon which the software is built.
Definition Application.cpp:83
Definition ExecutionContext.hpp:201
ExecutionCommandQueue & executionQueue
Definition ExecutionContext.hpp:247
Execution::time_function time
Definition ExecutionContext.hpp:243
Definition ExecutionContext.hpp:112
Definition ExecutionContext.hpp:73
Definition ExecutionContext.hpp:156
Definition ExecutionSetup.hpp:38
Definition TimeValue.hpp:21
Definition DocumentContext.hpp:18