StandardDisplacementPolicy.hpp
1 #pragma once
2 #include <Process/ProcessList.hpp>
3 #include <Process/TimeValue.hpp>
4 
5 #include <Scenario/Commands/Scenario/Deletions/ClearInterval.hpp>
6 #include <Scenario/Document/Event/EventModel.hpp>
7 #include <Scenario/Document/Interval/IntervalModel.hpp>
8 #include <Scenario/Document/Interval/Slot.hpp>
9 #include <Scenario/Document/TimeSync/TimeSyncModel.hpp>
10 #include <Scenario/Process/Algorithms/Accessors.hpp>
11 #include <Scenario/Process/Algorithms/ProcessPolicy.hpp>
12 #include <Scenario/Process/Algorithms/StandardCreationPolicy.hpp>
13 #include <Scenario/Process/ScenarioModel.hpp>
14 #include <Scenario/Tools/dataStructures.hpp>
15 
16 #include <score/document/DocumentInterface.hpp>
17 #include <score/model/Identifier.hpp>
18 #include <score/tools/MapCopy.hpp>
19 
20 namespace Scenario
21 {
22 class ProcessModel;
28 {
29 public:
30  template <typename ProcessScaleMethod>
31  static void updatePositions(
32  Scenario::ProcessModel& scenario, ProcessScaleMethod&& scaleMethod,
33  const ElementsProperties& propsToUpdate)
34  {
35  // update each affected timesyncs
36  for(auto it = propsToUpdate.timesyncs.cbegin(); it != propsToUpdate.timesyncs.cend();
37  ++it)
38  {
39  auto& curTimenodeToUpdate = scenario.timeSync(it->first);
40  auto& curTimenodePropertiesToUpdate = it->second;
41 
42  curTimenodeToUpdate.setDate(curTimenodePropertiesToUpdate.newDate);
43 
44  // update related events
45  for(const auto& event : curTimenodeToUpdate.events())
46  {
47  scenario.events.at(event).setDate(curTimenodePropertiesToUpdate.newDate);
48  }
49  }
50 
51  // update affected intervals
52  for(auto& e : propsToUpdate.intervals)
53  {
54  auto curIntervalPropertiesToUpdate_id = e.first;
55 
56  auto& curInterval = scenario.intervals.at(curIntervalPropertiesToUpdate_id);
57  auto& curIntervalPropertiesToUpdate = e.second;
58 
59  // compute default duration here
60  const auto& date = Scenario::startEvent(curInterval, scenario).date();
61  const auto& endDate = Scenario::endEvent(curInterval, scenario).date();
62 
63  TimeVal defaultDuration = endDate - date;
64 
65  // set start date and default duration
66  using namespace ossia;
67  if(curInterval.date() != date)
68  {
69  curInterval.setStartDate(date);
70  }
71  curInterval.duration.setDefaultDuration(defaultDuration);
72 
73  curInterval.duration.setMinDuration(curIntervalPropertiesToUpdate.newMin);
74  curInterval.duration.setMaxDuration(curIntervalPropertiesToUpdate.newMax);
75 
76  for(auto& process : curInterval.processes)
77  {
78  scaleMethod(process, defaultDuration);
79  }
80 
81  scenario.intervalMoved(&curInterval);
82  }
83  }
84 
85  template <typename ProcessScaleMethod>
86  static void revertPositions(
87  const score::DocumentContext& ctx, Scenario::ProcessModel& scenario,
88  ProcessScaleMethod&& scaleMethod, const ElementsProperties& propsToUpdate)
89  {
90  // update each affected timesyncs with old values
91  for(auto it = propsToUpdate.timesyncs.cbegin(); it != propsToUpdate.timesyncs.cend();
92  ++it)
93  {
94  auto& curTimenodeToUpdate = scenario.timeSync(it->first);
95  auto& curTimenodePropertiesToUpdate = it->second;
96 
97  curTimenodeToUpdate.setDate(curTimenodePropertiesToUpdate.oldDate);
98 
99  // update related events to mach the date
100  for(const auto& event : curTimenodeToUpdate.events())
101  {
102  scenario.events.at(event).setDate(curTimenodePropertiesToUpdate.oldDate);
103  }
104  }
105 
106  // update affected intervals with old values and restore processes
107  for(auto& e : propsToUpdate.intervals)
108  {
109  auto curIntervalPropertiesToUpdate_id = e.first;
110 
111  auto& curInterval = scenario.intervals.at(curIntervalPropertiesToUpdate_id);
112  const IntervalProperties& curIntervalPropertiesToUpdate = e.second;
113 
114  // compute default duration here
115  const auto& date = Scenario::startEvent(curInterval, scenario).date();
116  const auto& endDate = Scenario::endEvent(curInterval, scenario).date();
117 
118  TimeVal defaultDuration = endDate - date;
119 
120  SCORE_ASSERT(defaultDuration == curIntervalPropertiesToUpdate.oldDefault);
121 
122  // set start date and default duration
123  using namespace ossia;
124  if(curInterval.date() != curIntervalPropertiesToUpdate.oldDate)
125  {
126  curInterval.setStartDate(curIntervalPropertiesToUpdate.oldDate);
127  }
128  curInterval.duration.setDefaultDuration(curIntervalPropertiesToUpdate.oldDefault);
129 
130  // set durations
131  curInterval.duration.setMinDuration(curIntervalPropertiesToUpdate.oldMin);
132  curInterval.duration.setMaxDuration(curIntervalPropertiesToUpdate.oldMax);
133 
134  // Now we have to restore the state of each interval that might have
135  // been modified
136  // during this command.
137 
138  // 1. Clear the interval
139  {
140  curInterval.clearSmallView();
141 
142  // We make copies since the iterators might change.
143  // TODO check if this is still valid wrt boost::multi_index
144  auto processes = shallow_copy(curInterval.processes);
145  for(auto process : processes)
146  {
147  if(!(process->flags() & Process::ProcessFlags::TimeIndependent))
148  RemoveProcess(curInterval, process->id());
149  }
150  }
151 
152  // 2. Restore the rackes & processes.
153  // Restore the interval. The saving is done in
154  // GenericDisplacementPolicy.
155  curIntervalPropertiesToUpdate.reload(curInterval);
156 
157  scenario.intervalMoved(&curInterval);
158  }
159  }
160 };
161 }
The displacementPolicy class This class allows to implement multiple displacement behaviors.
Definition: StandardDisplacementPolicy.hpp:28
The core hierarchical and temporal process of score.
Definition: ScenarioModel.hpp:37
Main plug-in of score.
Definition: score-plugin-dataflow/Dataflow/PortItem.hpp:14
Definition: dataStructures.hpp:65
Definition: dataStructures.hpp:52
Definition: TimeValue.hpp:21
Definition: DocumentContext.hpp:18