Loading...
Searching...
No Matches
CableCopy.hpp
1#pragma once
2#include <Process/Dataflow/Cable.hpp>
3#include <Process/Dataflow/Port.hpp>
4
5#include <ossia/detail/ptr_set.hpp>
6
7namespace Dataflow
8{
9using SerializedCables = std::vector<std::pair<Id<Process::Cable>, Process::CableData>>;
10}
11namespace Process
12{
13
14inline bool verifyAndUpdateIfChildOf(ObjectPath& path, const ObjectPath& parent)
15{
16 auto parent_n = parent.vec().size();
17 auto path_n = path.vec().size();
18 if(parent_n >= path_n)
19 return false;
20 for(std::size_t i = 0; i < parent_n; i++)
21 {
22 if(!(path.vec()[i] == parent.vec()[i]))
23 return false;
24 }
25
26 SCORE_ASSERT(parent_n > 1);
27 path.vec().erase(path.vec().begin(), path.vec().begin() + parent_n - 1);
28 return true;
29}
30
31template <typename T>
32bool verifyAndUpdateIfChildOf(Process::CableData& path, const std::vector<Path<T>>& vec)
33{
34 bool source_ok = false;
35 for(const auto& parent : vec)
36 {
37 if(verifyAndUpdateIfChildOf(path.source.unsafePath(), parent.unsafePath()))
38 {
39 source_ok = true;
40 break;
41 }
42 }
43 if(!source_ok)
44 return false;
45
46 for(const auto& parent : vec)
47 {
48 if(verifyAndUpdateIfChildOf(path.sink.unsafePath(), parent.unsafePath()))
49 {
50 return true;
51 }
52 }
53 // must not happen: the sink is already guaranteed to be a child of an
54 // interval since we look for all the inlets
55 SCORE_ABORT;
56}
57
58template <typename T>
59Dataflow::SerializedCables cablesToCopy(
60 const std::vector<T*>& array,
61 const std::vector<Path<std::remove_const_t<T>>>& siblings,
62 const score::DocumentContext& ctx)
63{
64 // For every cable, if both ends are in one of the elements or child elements
65 // currently selected, we copy them.
66 // Note: ids / cable paths have to be updated of course.
67 Dataflow::SerializedCables copiedCables;
68 ossia::ptr_set<Process::Inlet*> ins;
69 for(auto itv : array)
70 {
71 auto child_ins = itv->template findChildren<Process::Inlet*>();
72 ins.insert(child_ins.begin(), child_ins.end());
73 }
74
75 for(auto inl : ins)
76 {
77 for(const auto& c_inl : inl->cables())
78 {
79 if(Process::Cable* cable = c_inl.try_find(ctx))
80 {
81 auto cd = cable->toCableData();
82 if(verifyAndUpdateIfChildOf(cd, siblings))
83 {
84 copiedCables.push_back({cable->id(), cd});
85 }
86 }
87 }
88 }
89
90 return copiedCables;
91}
92
93template <typename T>
94Dataflow::SerializedCables
95cablesToCopy(const std::vector<T*>& array, const score::DocumentContext& ctx)
96{
97 std::vector<Path<std::remove_const_t<T>>> siblings;
98 siblings.reserve(array.size());
99 for(auto ptr : array)
100 {
101 siblings.emplace_back(*ptr);
102 }
103 return cablesToCopy(array, siblings, ctx);
104}
105}
The ObjectPath class.
Definition ObjectPath.hpp:37
The Path class is a typesafe wrapper around ObjectPath.
Definition Path.hpp:52
Definition Cable.hpp:38
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1324
Definition CableData.hpp:18
Definition DocumentContext.hpp:18