3#include "CreateCurves.hpp"
5#include <State/ValueConversion.hpp>
7#include <Device/Address/AddressSettings.hpp>
8#include <Device/Node/DeviceNode.hpp>
10#include <Process/State/MessageNode.hpp>
12#include <Explorer/Explorer/DeviceExplorerModel.hpp>
14#include <Scenario/Commands/Cohesion/CreateCurveFromStates.hpp>
15#include <Scenario/Commands/Cohesion/InterpolateMacro.hpp>
16#include <Scenario/Commands/CommandAPI.hpp>
17#include <Scenario/Document/Interval/IntervalModel.hpp>
18#include <Scenario/Document/State/ItemModel/MessageItemModel.hpp>
19#include <Scenario/Document/State/StateModel.hpp>
20#include <Scenario/Process/Algorithms/Accessors.hpp>
21#include <Scenario/Process/ScenarioModel.hpp>
23#include <Automation/AutomationModel.hpp>
25#include <score/command/Dispatchers/CommandDispatcher.hpp>
26#include <score/document/DocumentContext.hpp>
27#include <score/model/IdentifiedObjectAbstract.hpp>
28#include <score/selection/Selectable.hpp>
29#include <score/selection/SelectionStack.hpp>
31#include <ossia/network/common/destination_qualifiers.hpp>
32#include <ossia/network/domain/domain.hpp>
33#include <ossia/network/value/value_conversion.hpp>
38static std::vector<Device::FullAddressSettings>
42 auto& device_explorer = Explorer::deviceExplorerFromContext(doc);
44 std::vector<Device::FullAddressSettings> addresses;
45 for(
const auto& index : device_explorer.selectedIndexes())
47 const auto& node = device_explorer.nodeFromModelIndex(index);
51 if(ossia::is_numeric(addr.value) || ossia::is_array(addr.value))
55 as.address = Device::address(node).address;
56 addresses.push_back(std::move(as));
64 const std::vector<const Scenario::IntervalModel*>& selected_intervals,
67 if(selected_intervals.empty())
72 auto& doc = score::IDocument::documentContext(*selected_intervals.front());
74 auto addresses = getSelectedAddresses(doc);
78 CreateCurvesFromAddresses(selected_intervals, addresses, stack);
88 ossia::apply_nonnull([&](
const auto& v) { (*this)(v, addr); }, addr.value.v);
105 if(addr.address.qualifiers.get().accessors.empty())
112 if(addr.address.qualifiers.get().accessors.empty())
119 if(addr.address.qualifiers.get().accessors.empty())
125 const std::vector<ossia::value>& v,
128 if(addr.address.qualifiers.get().accessors.empty())
141 int automCount() {
return count; }
150 const std::vector<Id<Process::ProcessModel>>& process_ids;
152 const std::vector<SlotPath>& slotsToUse;
153 std::vector<Process::ProcessModel*>& created;
155 void operator()(ossia::impulse) { }
157 void operator()(
bool b) { }
159 void operator()(
int v)
169 ss.messages().rootNode(), stringList(addr.address));
172 if(
auto val = s_node->value())
174 dom.start = State::convert::value<int>(*val);
175 dom.min = std::min(dom.start, dom.min);
176 dom.max = std::max(dom.start, dom.max);
185 es.messages().rootNode(), stringList(addr.address));
188 if(
auto val = e_node->value())
190 dom.end = State::convert::value<int>(*val);
191 dom.min = std::min(dom.end, dom.min);
192 dom.max = std::max(dom.end, dom.max);
197 auto& p = macro.automate(
198 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
199 created.push_back(&p);
202 void operator()(
float v)
212 ss.messages().rootNode(), stringList(addr.address));
215 if(
auto val = s_node->value())
217 dom.start = State::convert::value<double>(*val);
218 dom.min = std::min(dom.start, dom.min);
219 dom.max = std::max(dom.start, dom.max);
228 es.messages().rootNode(), stringList(addr.address));
231 if(
auto val = e_node->value())
233 dom.end = State::convert::value<double>(*val);
234 dom.min = std::min(dom.end, dom.min);
235 dom.max = std::max(dom.end, dom.max);
240 auto& p = macro.automate(
241 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
242 created.push_back(&p);
245 void operator()(
char v) { }
247 void operator()(
const std::string& v) { }
249 template <std::
size_t N>
250 void operator()(
const std::array<float, N>& v)
258 auto& acc = addr.qualifiers.get().accessors;
263 for(std::size_t c = 0; c < N; c++)
267 auto& p = macro.automate(
268 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
269 created.push_back(&p);
275 auto& p = macro.automate(
276 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
277 created.push_back(&p);
283 void operator()(
const std::vector<ossia::value>& v)
291 auto& acc = addr.qualifiers.get().accessors;
297 for(std::size_t c = 0; c < v.size(); c++)
299 const auto t = v[c].get_type();
300 if(t == ossia::val_type::FLOAT || t == ossia::val_type::INT)
304 auto& p = macro.automate(
305 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
306 created.push_back(&p);
312 auto& p = macro.automate(
313 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
314 created.push_back(&p);
318 void operator()(
const ossia::value_map_type& v) { }
320 void operator()() { }
323std::vector<Process::ProcessModel*> CreateCurvesFromAddress(
327 std::vector<Process::ProcessModel*> created;
331 const auto N = addresses.automCount();
334 auto process_ids = getStrongIdRange<Process::ProcessModel>(N, interval.
processes);
336 if(interval.smallView().empty())
338 m.createSlot(interval);
342 std::vector<SlotPath> slotsToUse{{interval, 0}};
344 const auto& ss = startState(interval, *scenar);
345 const auto& es = endState(interval, *scenar);
348 as.value.apply(AddressAccessorCurveCreator{
349 as, ss, es, interval, process_ids, m, slotsToUse, created});
351 if(created.size() > 0)
367 for(
auto& addr : addrs)
370 ossia::apply_nonnull([&](
const auto& v) { (*this)(v, addr); }, addr.value.v);
376 impulse_addr.push_back(addr);
380 bool_addr.push_back(addr);
384 int_addr.push_back(addr);
388 float_addr.push_back(addr);
392 char_addr.push_back(addr);
396 string_addr.push_back(addr);
400 vec2f_addr.push_back(addr);
404 vec3f_addr.push_back(addr);
408 vec4f_addr.push_back(addr);
415 list_addr.push_back(addr);
427 c += int_addr.size();
429 c += float_addr.size();
431 c += char_addr.size();
432 c += 2 * vec2f_addr.size();
433 c += 3 * vec3f_addr.size();
434 c += 4 * vec4f_addr.size();
436 for(
auto& addr : list_addr)
438 auto& v = addr.value.get<std::vector<ossia::value>>();
445 std::vector<Device::FullAddressSettings> impulse_addr;
446 std::vector<Device::FullAddressSettings> int_addr;
447 std::vector<Device::FullAddressSettings> bool_addr;
448 std::vector<Device::FullAddressSettings> float_addr;
449 std::vector<Device::FullAddressSettings> string_addr;
450 std::vector<Device::FullAddressSettings> char_addr;
451 std::vector<Device::FullAddressSettings> vec2f_addr;
452 std::vector<Device::FullAddressSettings> vec3f_addr;
453 std::vector<Device::FullAddressSettings> vec4f_addr;
454 std::vector<Device::FullAddressSettings> list_addr;
463 const std::vector<Id<Process::ProcessModel>>& process_ids;
465 const std::vector<SlotPath>& slotsToUse;
466 std::vector<Process::ProcessModel*>& created;
468 void operator()(ossia::impulse) { }
470 void operator()(
bool b) { }
472 void operator()(
int v)
482 ss.messages().rootNode(), stringList(as.address));
485 if(
auto val = s_node->value())
487 dom.start = State::convert::value<int>(*val);
488 dom.min = std::min(dom.start, dom.min);
489 dom.max = std::max(dom.start, dom.max);
498 es.messages().rootNode(), stringList(as.address));
501 if(
auto val = e_node->value())
503 dom.end = State::convert::value<int>(*val);
504 dom.min = std::min(dom.end, dom.min);
505 dom.max = std::max(dom.end, dom.max);
510 auto& p = macro.automate(
511 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
512 created.push_back(&p);
515 void operator()(
float v)
525 ss.messages().rootNode(), stringList(as.address));
528 if(
auto val = s_node->value())
530 dom.start = State::convert::value<double>(*val);
531 dom.min = std::min(dom.start, dom.min);
532 dom.max = std::max(dom.start, dom.max);
541 es.messages().rootNode(), stringList(as.address));
544 if(
auto val = e_node->value())
546 dom.end = State::convert::value<double>(*val);
547 dom.min = std::min(dom.end, dom.min);
548 dom.max = std::max(dom.end, dom.max);
553 auto& p = macro.automate(
554 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
555 created.push_back(&p);
558 void operator()(
char v) { }
560 void operator()(
const std::string& v) { }
562 template <std::
size_t N>
563 void operator()(
const std::array<float, N>& v)
571 auto& acc = addr.qualifiers.get().accessors;
573 for(std::size_t c = 0; c < N; c++)
577 auto& p = macro.automate(
578 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
579 created.push_back(&p);
583 void operator()(
const std::vector<ossia::value>& v)
591 auto& acc = addr.qualifiers.get().accessors;
595 for(std::size_t c = 0; c < v.size(); c++)
597 const auto t = v[c].get_type();
598 if(t == ossia::val_type::FLOAT || t == ossia::val_type::INT)
602 auto& p = macro.automate(
603 interval, slotsToUse, process_ids[created.size()], addr, dom, tween);
604 created.push_back(&p);
609 void operator()() { }
612int CreateCurvesFromAddresses(
615 std::vector<Process::ProcessModel*>& created)
618 auto process_ids = getStrongIdRange<Process::ProcessModel>(N, interval.
processes);
619 auto macro = Scenario::Command::makeAddProcessMacro(interval, N);
621 auto slots = macro->slotsToUse;
623 const auto& ss = startState(interval, scenar);
624 const auto& es = endState(interval, scenar);
638 CurveCreator{as, ss, es, interval, process_ids, m, slots, created}(
float{});
642 CurveCreator{as, ss, es, interval, process_ids, m, slots, created}(
int{});
646 CurveCreator{as, ss, es, interval, process_ids, m, slots, created}(ossia::vec2f{});
650 CurveCreator{as, ss, es, interval, process_ids, m, slots, created}(ossia::vec3f{});
654 CurveCreator{as, ss, es, interval, process_ids, m, slots, created}(ossia::vec4f{});
658 CurveCreator{as, ss, es, interval, process_ids, m, slots, created}(
659 as.value.get<std::vector<ossia::value>>());
661 return created.size();
664std::vector<Process::ProcessModel*> CreateCurvesFromAddresses(
668 std::vector<Process::ProcessModel*> created;
671 CategorizedAddresses addresses{a};
672 const auto N = addresses.automCount();
674 int count = CreateCurvesFromAddresses(interval, *scenar, addresses, N, m, created);
683std::vector<Process::ProcessModel*> CreateCurvesFromAddresses(
684 const std::vector<const Scenario::IntervalModel*>& selected_intervals,
687 std::vector<Process::ProcessModel*> created;
689 if(selected_intervals.empty())
698 bool added_processes =
false;
699 CategorizedAddresses addresses{a};
700 const auto N = addresses.automCount();
702 for(
const auto& interval_ptr : selected_intervals)
705 = CreateCurvesFromAddresses(*interval_ptr, *scenar, addresses, N, m, created);
707 added_processes =
true;
718void CreateCurvesFromAddresses(
719 const std::vector<const Scenario::IntervalModel*>& selected_intervals,
720 const std::vector<Device::FullAddressSettings>& a,
727 CreateCurvesFromAddresses(selected_intervals, a, big_macro);
Definition InterpolateMacro.hpp:19
Definition CommandAPI.hpp:28
Definition IntervalModel.hpp:50
score::EntityMap< Process::ProcessModel, true > processes
Definition IntervalModel.hpp:62
Definition ScenarioInterface.hpp:20
Definition StateModel.hpp:63
A small abstraction layer over the score::CommandStack.
Definition CommandStackFacade.hpp:20
Main plug-in of score.
Definition score-plugin-dataflow/Dataflow/PortItem.hpp:13
Definition CurveModel.hpp:104
Definition AddressSettings.hpp:24
Definition AddressSettings.hpp:49
Definition AddressSettings.hpp:131
Definition AddressSettings.hpp:62
Definition CreateCurves.cpp:145
Definition CreateCurves.cpp:84
Definition CreateCurves.cpp:364
Definition CreateCurves.cpp:458
Definition Address.hpp:108
Definition DocumentContext.hpp:18