2 #include <Process/Process.hpp>
4 #include <Crousti/File.hpp>
5 #include <Crousti/ProcessModel.hpp>
7 #include <avnd/binding/ossia/node.hpp>
12 template <
typename Node,
typename Field, std::
size_t NPred, std::
size_t NField>
15 using ExecNode = safe_node<Node>;
17 std::weak_ptr<ExecNode> weak_node;
19 void operator()(
const ossia::value& val)
21 using control_value_type = std::decay_t<decltype(Field::value)>;
23 if(
auto node = weak_node.lock())
26 node->from_ossia_value(field, val, v, avnd::field_index<NField>{});
27 ctx.
executionQueue.enqueue([weak_node = weak_node, v = std::move(v)]()
mutable {
28 if(
auto n = weak_node.lock())
30 n->template control_updated_from_ui<control_value_type, NPred>(std::move(v));
37 template <
typename Node,
typename Field, std::
size_t NPred, std::
size_t NField>
40 using ExecNode = safe_node<Node>;
42 std::weak_ptr<ExecNode> weak_node;
45 void operator()(
const ossia::value& val)
47 using control_value_type = std::decay_t<decltype(Field::value)>;
49 if(
auto node = weak_node.lock())
52 node->from_ossia_value(field, val, v, avnd::field_index<NField>{});
54 [weak_node = weak_node, port_index = port_index, v = std::move(v)]()
mutable {
55 if(
auto n = weak_node.lock())
57 n->template control_updated_from_ui<control_value_type, NPred>(
58 std::move(v), port_index);
65 template <
typename Node,
typename Field>
68 using ExecNode = safe_node<Node>;
73 const std::shared_ptr<ExecNode>& node_ptr;
76 void invoke_update(Field& param)
78 avnd::effect_container<Node>& eff = node_ptr->impl;
80 for(
auto state : eff.full_state())
83 if_possible(param.update(state.effect));
88 template <
typename Node,
typename Field, std::
size_t N, std::
size_t NField>
91 template <
typename Node,
typename Field, std::
size_t N, std::
size_t NField>
94 using ExecNode = safe_node<Node>;
100 if constexpr(avnd::dynamic_ports_port<Field>)
102 if constexpr(!requires { param.ports[0].value.reset(); })
104 this->node_ptr->from_ossia_value(
105 param, inlet->value(), param.ports[k].value, avnd::field_index<NField>{});
110 if constexpr(!requires { param.value.reset(); })
112 this->node_ptr->from_ossia_value(
113 param, inlet->value(), param.value, avnd::field_index<NField>{});
121 if constexpr(requires { param.update_controller; })
123 param.update_controller
124 = [inlet = QPointer{inlet},
self = QPointer{&this->element}](
auto&& value) {
132 static thread_local
const Field field;
133 ossia::qt::run_async(
134 qApp, [
self, inlet, val = oscr::to_ossia_value(field, value)] {
137 inlet->setValue(val);
146 std::weak_ptr<ExecNode> weak_node = this->node_ptr;
147 if constexpr(avnd::dynamic_ports_port<Field>)
149 using port_type = avnd::dynamic_port_type<Field>;
151 inlet, &Process::ControlInlet::valueChanged, this->parent,
153 this->ctx, weak_node, param.ports[k], k});
155 this->update_controller(param, inlet);
160 inlet, &Process::ControlInlet::valueChanged, this->parent,
163 this->update_controller(param, inlet);
168 template <
typename Node, avnd::soundfile_port Field, std::
size_t N, std::
size_t NField>
172 using ExecNode = safe_node<Node>;
179 if(
auto hdl = loadSoundfile(inlet->value(), this->ctx.doc, this->ctx.execState))
180 this->node_ptr->soundfile_loaded(
181 hdl, avnd::predicate_index<N>{}, avnd::field_index<NField>{});
187 std::weak_ptr<ExecNode> weak_node = this->node_ptr;
188 std::weak_ptr<ossia::execution_state> weak_st = this->ctx.execState;
190 inlet, &Process::ControlInlet::valueChanged, this->parent,
191 [&ctx = this->ctx, weak_node = std::move(weak_node),
192 weak_st = std::move(weak_st)](
const ossia::value& v) {
193 if(
auto n = weak_node.lock())
194 if(
auto st = weak_st.lock())
195 if(
auto file = loadSoundfile(v, ctx.doc, st))
197 ctx.executionQueue.enqueue([f = std::move(file), weak_node]() mutable {
198 auto n = weak_node.lock();
205 f, avnd::predicate_index<N>{}, avnd::field_index<NField>{});
212 template <
typename Node, avnd::m
idifile_port Field, std::
size_t N, std::
size_t NField>
213 struct setup_control_for_exec<Node, Field, N, NField>
214 : setup_control_for_exec_base<Node, Field>
216 using ExecNode = safe_node<Node>;
217 using Model = ProcessModel<Node>;
224 if(
auto hdl = loadMidifile(inlet->value(), this->ctx.doc))
225 this->node_ptr->midifile_loaded(
226 hdl, avnd::predicate_index<N>{}, avnd::field_index<NField>{});
232 std::weak_ptr<ExecNode> weak_node = this->node_ptr;
233 std::weak_ptr<ossia::execution_state> weak_st = this->ctx.execState;
235 inlet, &Process::ControlInlet::valueChanged, this->parent,
236 [inlet, &ctx = this->ctx,
237 weak_node = std::move(weak_node)](
const ossia::value& v) {
238 if(
auto n = weak_node.lock())
239 if(
auto file = loadMidifile(v, ctx.doc))
241 ctx.executionQueue.enqueue([f = std::move(file), weak_node]() mutable {
242 auto n = weak_node.lock();
249 f, avnd::predicate_index<N>{}, avnd::field_index<NField>{});
256 template <
typename Node, avnd::raw_file_port Field, std::
size_t N, std::
size_t NField>
257 struct setup_control_for_exec<
Node, Field, N, NField>
258 : setup_control_for_exec_base<Node, Field>
260 using ExecNode = safe_node<Node>;
261 using Model = ProcessModel<Node>;
263 static constexpr
bool has_text = requires { decltype(Field::file)::text; };
264 static constexpr
bool has_mmap = requires { decltype(Field::file)::mmap; };
271 if(
auto hdl = loadRawfile(inlet->value(), this->ctx.doc, has_text, has_mmap))
273 if constexpr(avnd::port_can_process<Field>)
277 auto func = executePortPreprocess<Field>(*hdl);
278 this->node_ptr->file_loaded(
279 hdl, avnd::predicate_index<N>{}, avnd::field_index<NField>{});
281 func(this->node_ptr->impl.effect);
285 this->node_ptr->file_loaded(
286 hdl, avnd::predicate_index<N>{}, avnd::field_index<NField>{});
294 std::weak_ptr<ExecNode> weak_node = this->node_ptr;
295 std::weak_ptr<ossia::execution_state> weak_st = this->ctx.execState;
297 inlet, &Process::ControlInlet::valueChanged, this->parent,
298 [inlet, &ctx = this->ctx, weak_node = std::move(weak_node)] {
299 if(
auto n = weak_node.lock())
300 if(
auto file = loadRawfile(inlet->value(), ctx.doc, has_text, has_mmap))
302 if constexpr(avnd::port_can_process<Field>)
304 auto func = executePortPreprocess<Field>(*file);
305 ctx.executionQueue.enqueue(
306 [f = std::move(file), weak_node, ff = std::move(func)]() mutable {
307 auto n = weak_node.lock();
313 n->file_loaded(f, avnd::predicate_index<N>{}, avnd::field_index<NField>{});
320 ctx.executionQueue.enqueue([f = std::move(file), weak_node]() mutable {
321 auto n = weak_node.lock();
327 n->file_loaded(f, avnd::predicate_index<N>{}, avnd::field_index<NField>{});
335 template <
typename Node>
338 using ExecNode = safe_node<Node>;
343 const std::shared_ptr<ExecNode>& node_ptr;
347 template <
typename Field, std::
size_t N, std::
size_t NField>
349 operator()(Field& param, avnd::predicate_index<N> np, avnd::field_index<NField> nf)
351 const auto ports = element.avnd_input_idx_to_model_ports(NField);
353 if constexpr(avnd::dynamic_ports_port<Field>)
355 param.ports.resize(ports.size());
361 if(
auto inlet = qobject_cast<Process::ControlInlet*>(p))
364 element, ctx, node_ptr, parent};
366 setup.initialize_control(param, inlet, k);
368 setup.invoke_update(param);
370 setup.connect_control_to_ui(param, inlet, k);
Definition: score-plugin-avnd/Crousti/ProcessModel.hpp:77
TreeNode< DeviceExplorerNode > Node
Definition: DeviceNode.hpp:74
Definition: Factories.hpp:19
Definition: ExecutionContext.hpp:76
ExecutionCommandQueue & executionQueue
Definition: ExecutionContext.hpp:91
Definition: ExecutorPortSetup.hpp:39
Definition: ExecutorPortSetup.hpp:14
Definition: ExecutorPortSetup.hpp:337
Definition: ExecutorPortSetup.hpp:171
Definition: ExecutorPortSetup.hpp:67
Definition: ExecutorPortSetup.hpp:93