Loading...
Searching...
No Matches
ScenarioPaste.hpp
1#pragma once
2#include <Process/ProcessList.hpp>
3
4#include <Scenario/Document/ScenarioDocument/ScenarioDocumentModel.hpp>
5#include <Scenario/Process/ScenarioModel.hpp>
6
7#include <score/application/GUIApplicationContext.hpp>
8#include <score/document/DocumentContext.hpp>
9#include <score/model/EntitySerialization.hpp>
10#include <score/plugins/SerializableHelpers.hpp>
11#include <score/tools/IdentifierGeneration.hpp>
12
13#include <ossia/detail/flat_map.hpp>
14#include <ossia/detail/hash_map.hpp>
15
16namespace Scenario
17{
18
19std::vector<Process::CableData>
20cableDataFromCablesJson(const rapidjson::Document::ConstArray& arr);
21std::vector<Process::CableData>
22cableDataFromCablesJson(const rapidjson::Document::Array& arr);
23
24// e.g. IntervalModel being copied in a Scenario
25template <typename CopiedObjects, typename ParentObject>
26ossia::flat_map<Id<Process::Cable>, Process::CableData> mapCopiedCables(
27 const score::DocumentContext& ctx, std::vector<Process::CableData>& cables,
28 std::vector<CopiedObjects*>& intervals,
29 const std::vector<Id<CopiedObjects>>& interval_ids, const ParentObject& scenario)
30{
31 ossia::flat_map<Id<Process::Cable>, Process::CableData> cable_map;
32
33 {
34 ossia::hash_map<Id<CopiedObjects>, Id<CopiedObjects>> id_map;
35 {
36 int i = 0;
37 for(CopiedObjects* interval : intervals)
38 {
39 id_map[interval->id()] = interval_ids[i];
40 i++;
41 }
42 }
43
44 auto& doc = score::IDocument::modelDelegate<ScenarioDocumentModel>(ctx.document);
45 auto cable_ids = getStrongIdRange<Process::Cable>(cables.size(), doc.cables);
46
47 int i = 0;
48 Path<ParentObject> p{scenario};
49 for(Process::CableData& cd : cables)
50 {
51 auto& source_vec = cd.source.unsafePath().vec();
52 auto& sink_vec = cd.sink.unsafePath().vec();
53 SCORE_ASSERT(!source_vec.empty());
54 SCORE_ASSERT(!sink_vec.empty());
55 int32_t source_itv_id = source_vec.front().id();
56 int32_t sink_itv_id = sink_vec.front().id();
57
58 for(CopiedObjects* interval : intervals)
59 {
60 auto id = interval->id().val();
61 if(id == source_itv_id)
62 source_itv_id = id_map.at(interval->id()).val();
63 if(id == sink_itv_id)
64 sink_itv_id = id_map.at(interval->id()).val();
65 }
66 source_vec.front()
67 = ObjectIdentifier{source_vec.front().objectName(), source_itv_id};
68 sink_vec.front() = ObjectIdentifier{sink_vec.front().objectName(), sink_itv_id};
69
70 source_vec.insert(
71 source_vec.begin(), p.unsafePath().vec().begin(), p.unsafePath().vec().end());
72 sink_vec.insert(
73 sink_vec.begin(), p.unsafePath().vec().begin(), p.unsafePath().vec().end());
74
75 cable_map.insert({cable_ids[i], std::move(cd)});
76 i++;
77 }
78
79 for(CopiedObjects* interval : intervals)
80 {
81 const auto ports = interval->template findChildren<Process::Port*>();
82 for(Process::Port* port : ports)
83 {
84 while(!port->cables().empty())
85 {
86 port->removeCable(port->cables().back());
87 }
88 }
89 }
90 }
91
92 return cable_map;
93}
94
96{
98 const rapidjson::Value& obj, const Scenario::ProcessModel& scenario,
99 const score::DocumentContext& ctx)
100 {
101 // TODO this is really a bad idea... either they should be properly added,
102 // or the json should be modified without including anything in the
103 // scenario. Especially their parents aren't coherent (TimeSync must not
104 // have a parent because it tries to access the event in the scenario if it
105 // has one) We deserialize everything
106 {
107 const auto& json_arr = obj["Intervals"].GetArray();
108 intervals.reserve(json_arr.Size());
109 for(const auto& element : json_arr)
110 {
111 intervals.emplace_back(new IntervalModel{
112 JSONObject::Deserializer{element}, scenario.context(), (QObject*)&scenario});
113 }
114 }
115 {
116 const auto& json_arr = obj["TimeNodes"].GetArray();
117 timesyncs.reserve(json_arr.Size());
118 for(const auto& element : json_arr)
119 {
120 timesyncs.emplace_back(
121 new TimeSyncModel{JSONObject::Deserializer{element}, nullptr});
122 }
123 }
124 {
125 const auto& json_arr = obj["Events"].GetArray();
126 events.reserve(json_arr.Size());
127 for(const auto& element : json_arr)
128 {
129 events.emplace_back(new EventModel{JSONObject::Deserializer{element}, nullptr});
130 }
131 }
132 {
133 const auto& json_arr = obj["States"].GetArray();
134 states.reserve(json_arr.Size());
135 for(const auto& element : json_arr)
136 {
137 states.emplace_back(new StateModel{
138 JSONObject::Deserializer{element}, scenario.context(), (QObject*)&scenario});
139 }
140 }
141 {
142 const auto& json_arr = obj["Cables"].GetArray();
143 cables = cableDataFromCablesJson(json_arr);
144 }
145
146 // We generate identifiers for the forthcoming elements
147 interval_ids = getStrongIdRange2<IntervalModel>(
148 intervals.size(), scenario.intervals, intervals);
149 timesync_ids = getStrongIdRange2<TimeSyncModel>(
150 timesyncs.size(), scenario.timeSyncs, timesyncs);
151 event_ids = getStrongIdRange2<EventModel>(events.size(), scenario.events, events);
152 state_ids = getStrongIdRange2<StateModel>(states.size(), scenario.states, states);
153 }
154
155 std::vector<TimeSyncModel*> timesyncs;
156 std::vector<IntervalModel*> intervals;
157 std::vector<EventModel*> events;
158 std::vector<StateModel*> states;
159 std::vector<Process::CableData> cables;
160
161 std::vector<Id<IntervalModel>> interval_ids;
162 std::vector<Id<TimeSyncModel>> timesync_ids;
163 std::vector<Id<EventModel>> event_ids;
164 std::vector<Id<StateModel>> state_ids;
165};
166
168{
170 const rapidjson::Value::Array& sourceProcesses,
171 const Scenario::IntervalModel& parent, const score::DocumentContext& ctx)
172 {
173 // TODO this is (again) really a bad idea... either they should be properly added,
174 // or the json should be modified without including anything in the
175 // scenario. Especially their parents aren't coherent (TimeSync must not
176 // have a parent because it tries to access the event in the scenario if it
177 // has one) We deserialize everything
178 {
179 static auto& pl = ctx.app.interfaces<Process::ProcessFactoryList>();
180 const auto& json_arr = sourceProcesses;
181 processes.reserve(json_arr.Size());
182 for(const auto& element : json_arr)
183 {
184 JSONObject::Deserializer deserializer{element};
185 auto proc = deserialize_interface(
186 pl, deserializer, ctx, const_cast<Scenario::IntervalModel*>(&parent));
187 if(proc)
188 processes.emplace_back(proc);
189 }
190 }
191
192 // We generate identifiers for the forthcoming elements
193 processes_ids = getStrongIdRange2<Process::ProcessModel>(
194 processes.size(), parent.processes, processes);
195 }
196
197 std::vector<Process::ProcessModel*> processes;
198 std::vector<Id<Process::ProcessModel>> processes_ids;
199};
200}
Definition JSONVisitor.hpp:423
The ObjectIdentifier class.
Definition ObjectIdentifier.hpp:21
The Path class is a typesafe wrapper around ObjectPath.
Definition Path.hpp:52
Definition Port.hpp:102
Definition ProcessList.hpp:10
Definition EventModel.hpp:36
Definition IntervalModel.hpp:50
score::EntityMap< Process::ProcessModel, true > processes
Definition IntervalModel.hpp:62
The core hierarchical and temporal process of score.
Definition ScenarioModel.hpp:37
Definition StateModel.hpp:63
Definition TimeSyncModel.hpp:34
The id_base_t class.
Definition Identifier.hpp:57
Main plug-in of score.
Definition score-plugin-dataflow/Dataflow/PortItem.hpp:13
Definition CableData.hpp:18
Definition ScenarioPaste.hpp:168
Definition ScenarioPaste.hpp:96
const T & interfaces() const
Access to a specific interface list.
Definition ApplicationContext.hpp:67
Definition DocumentContext.hpp:18