ScenarioModel.hpp
1 #pragma once
2 #include <Process/Process.hpp>
3 #include <Process/TimeValue.hpp>
4 
5 #include <Scenario/Document/CommentBlock/CommentBlockModel.hpp>
6 #include <Scenario/Document/Event/EventModel.hpp>
7 #include <Scenario/Document/Interval/IntervalModel.hpp>
8 #include <Scenario/Document/State/StateModel.hpp>
9 #include <Scenario/Document/TimeSync/TimeSyncModel.hpp>
10 #include <Scenario/Instantiations.hpp>
11 #include <Scenario/Process/ScenarioInterface.hpp>
12 #include <Scenario/Process/ScenarioProcessMetadata.hpp>
13 
14 #include <score/model/EntityMap.hpp>
15 #include <score/model/IdentifiedObjectMap.hpp>
16 #include <score/model/Identifier.hpp>
17 #include <score/selection/Selection.hpp>
19 #include <score/serialization/VisitorInterface.hpp>
20 #include <score/tools/std/Optional.hpp>
21 
22 #include <QList>
23 #include <QObject>
24 #include <QVector>
25 
26 #include <verdigris>
27 namespace Scenario
28 {
29 struct TimenodeGraph;
30 
34 class SCORE_PLUGIN_SCENARIO_EXPORT ProcessModel final
35  : public Process::ProcessModel
36  , public ScenarioInterface
37 {
38  W_OBJECT(ProcessModel)
39 
40  SCORE_SERIALIZE_FRIENDS
41  PROCESS_METADATA_IMPL(Scenario::ProcessModel)
42  friend class ScenarioTemporalLayerFactory;
43 
44 public:
45  std::unique_ptr<Process::AudioInlet> inlet;
46  std::unique_ptr<Process::AudioOutlet> outlet;
47 
49  const TimeVal& duration, const Id<Process::ProcessModel>& id,
50  const score::DocumentContext& ctx, QObject* parent);
51  template <typename Impl>
52  ProcessModel(Impl& vis, const score::DocumentContext& ctx, QObject* parent)
53  : Process::ProcessModel{vis, parent}
54  , m_context{ctx}
55  {
56  vis.writeTo(*this);
57  init();
58  }
59 
60  const score::DocumentContext& context() const noexcept { return m_context; }
61  void init();
62  bool hasCycles() const noexcept;
63 
64  ~ProcessModel() override;
65 
67 
68  // Accessors
69  score::IndirectContainer<IntervalModel> getIntervals() const final override
70  {
71  return intervals.map().as_indirect_vec();
72  }
73 
74  score::IndirectContainer<StateModel> getStates() const final override
75  {
76  return states.map().as_indirect_vec();
77  }
78 
79  score::IndirectContainer<EventModel> getEvents() const final override
80  {
81  return events.map().as_indirect_vec();
82  }
83 
84  score::IndirectContainer<TimeSyncModel> getTimeSyncs() const final override
85  {
86  return timeSyncs.map().as_indirect_vec();
87  }
88 
89  IntervalModel* findInterval(const Id<IntervalModel>& id) const final override
90  {
91  if(auto it = intervals.map().m_map.find(id); it != intervals.map().m_map.end())
92  {
93  return it->second;
94  }
95  return nullptr;
96  }
97  EventModel* findEvent(const Id<EventModel>& id) const final override
98  {
99  if(auto it = events.map().m_map.find(id); it != events.map().m_map.end())
100  {
101  return it->second;
102  }
103  return nullptr;
104  }
105  TimeSyncModel* findTimeSync(const Id<TimeSyncModel>& id) const final override
106  {
107  if(auto it = timeSyncs.map().m_map.find(id); it != timeSyncs.map().m_map.end())
108  {
109  return it->second;
110  }
111  return nullptr;
112  }
113  StateModel* findState(const Id<StateModel>& id) const final override
114  {
115  if(auto it = states.map().m_map.find(id); it != states.map().m_map.end())
116  {
117  return it->second;
118  }
119  return nullptr;
120  }
121 
122  IntervalModel& interval(const Id<IntervalModel>& intervalId) const final override
123  {
124  return intervals.at(intervalId);
125  }
126  EventModel& event(const Id<EventModel>& eventId) const final override
127  {
128  return events.at(eventId);
129  }
130  TimeSyncModel& timeSync(const Id<TimeSyncModel>& timeSyncId) const final override
131  {
132  return timeSyncs.at(timeSyncId);
133  }
134  StateModel& state(const Id<StateModel>& stId) const final override
135  {
136  return states.at(stId);
137  }
138  CommentBlockModel& comment(const Id<CommentBlockModel>& cmtId) const
139  {
140  return comments.at(cmtId);
141  }
142 
143  TimeSyncModel& startTimeSync() const { return timeSyncs.at(m_startTimeSyncId); }
144 
145  EventModel& startEvent() const { return events.at(m_startEventId); }
146 
152 
153  void intervalMoved(const Scenario::IntervalModel* arg_1) const
154  E_SIGNAL(SCORE_PLUGIN_SCENARIO_EXPORT, intervalMoved, arg_1)
155 
156  void locked() E_SIGNAL(SCORE_PLUGIN_SCENARIO_EXPORT, locked)
157  void unlocked() E_SIGNAL(SCORE_PLUGIN_SCENARIO_EXPORT, unlocked)
158 
159  void lock() { locked(); };
160  W_SLOT(lock)
161  void unlock() { unlocked(); };
162  W_SLOT(unlock)
163 
164 
165  void setDurationAndScale(const TimeVal& newDuration) noexcept override;
166  void setDurationAndGrow(const TimeVal& newDuration) noexcept override;
167  void setDurationAndShrink(const TimeVal& newDuration) noexcept override;
168 
169  void ancestorStartDateChanged() override;
170  void ancestorTempoChanged() override;
171 
172  Selection selectableChildren() const noexcept override;
173  Selection selectedChildren() const noexcept override;
174 
175  INLINE_PROPERTY_VALUE(
176  bool, exclusive, = false, exclusive, setExclusive, exclusiveChanged)
177 
178 private:
179  void loadPreset(const Process::Preset& preset) override;
180  Process::Preset savePreset() const noexcept override;
181 
182  void setSelection(const Selection& s) const noexcept override;
183  bool event(QEvent* e) override { return QObject::event(e); }
184 
185  TimeVal contentDuration() const noexcept override;
186 
187  template <typename Fun>
188  void apply(Fun fun) const
189  {
190  fun(&ProcessModel::intervals);
191  fun(&ProcessModel::states);
192  fun(&ProcessModel::events);
193  fun(&ProcessModel::timeSyncs);
194  fun(&ProcessModel::comments);
195  }
196  const score::DocumentContext& m_context;
197 
198  Id<TimeSyncModel> m_startTimeSyncId{};
199  Id<EventModel> m_startEventId{};
200  Id<StateModel> m_startStateId{};
201  // By default, creation in the void will make a interval
202  // that goes to the startEvent and add a new state
203 
204  std::unique_ptr<TimenodeGraph> m_graph;
205 };
206 
207 Scenario::ProcessModel* closestParentScenario(const QObject* parentObj) noexcept;
208 }
209 // TODO this ought to go in Selection.hpp ?
210 template <typename Vector>
211 std::vector<const typename Vector::value_type*> selectedElements(const Vector& in)
212 {
213  std::vector<const typename Vector::value_type*> out;
214  for(const auto& elt : in)
215  {
216  if(elt.selection.get())
217  out.push_back(&elt);
218  }
219 
220  return out;
221 }
222 
223 template <typename T, typename Container>
224 std::vector<const T*> filterSelectionByType(const Container& sel)
225 {
226  std::vector<const T*> selected_elements;
227  for(auto obj : sel)
228  {
229  // TODO replace with a virtual Element::type() which will be faster.
230  if(auto casted_obj = qobject_cast<const T*>(obj.data()))
231  {
232  if(casted_obj->selection.get())
233  {
234  selected_elements.push_back(casted_obj);
235  }
236  }
237  }
238 
239  return selected_elements;
240 }
241 
242 namespace Scenario
243 {
244 SCORE_PLUGIN_SCENARIO_EXPORT const QVector<Id<IntervalModel>> intervalsBeforeTimeSync(
245  const Scenario::ProcessModel&, const Id<TimeSyncModel>& timeSyncId);
246 
247 inline auto& intervals(const Scenario::ProcessModel& scenar)
248 {
249  return scenar.intervals;
250 }
251 inline auto& events(const Scenario::ProcessModel& scenar)
252 {
253  return scenar.events;
254 }
255 inline auto& timeSyncs(const Scenario::ProcessModel& scenar)
256 {
257  return scenar.timeSyncs;
258 }
259 inline auto& states(const Scenario::ProcessModel& scenar)
260 {
261  return scenar.states;
262 }
263 
264 template <>
266 {
267  static const constexpr auto accessor = static_cast<
269  &intervals);
270 };
271 template <>
273 {
274  static const constexpr auto accessor = static_cast<
275  const score::EntityMap<EventModel>& (*)(const Scenario::ProcessModel&)>(&events);
276 };
277 template <>
279 {
280  static const constexpr auto accessor = static_cast<
282  &timeSyncs);
283 };
284 template <>
286 {
287  static const constexpr auto accessor = static_cast<
288  const score::EntityMap<StateModel>& (*)(const Scenario::ProcessModel&)>(&states);
289 };
290 }
291 DESCRIPTION_METADATA(SCORE_PLUGIN_SCENARIO_EXPORT, Scenario::ProcessModel, "Scenario")
292 
293 Q_DECLARE_METATYPE(const Scenario::ProcessModel*)
294 Q_DECLARE_METATYPE(Scenario::ProcessModel*)
295 W_REGISTER_ARGTYPE(const Scenario::ProcessModel*)
296 W_REGISTER_ARGTYPE(Scenario::ProcessModel*)
297 W_REGISTER_ARGTYPE(const Scenario::ProcessModel&)
298 W_REGISTER_ARGTYPE(Scenario::ProcessModel&)
299 W_REGISTER_ARGTYPE(Scenario::ProcessModel)
The Process class.
Definition: score-lib-process/Process/Process.hpp:61
Definition: CommentBlockModel.hpp:25
Definition: EventModel.hpp:36
Definition: IntervalModel.hpp:50
The core hierarchical and temporal process of score.
Definition: ScenarioModel.hpp:37
Definition: ScenarioInterface.hpp:20
Definition: ScenarioFactory.hpp:25
Definition: StateModel.hpp:63
Definition: TimeSyncModel.hpp:35
Definition: Selection.hpp:12
The id_base_t class.
Definition: Identifier.hpp:57
The EntityMap class.
Definition: EntityMap.hpp:36
Definition: IndirectContainer.hpp:129
Main plug-in of score.
Definition: score-plugin-dataflow/Dataflow/PortItem.hpp:14
Definition: Preset.hpp:32
Definition: ScenarioInterface.hpp:55
Definition: TimeValue.hpp:21
Definition: DocumentContext.hpp:18