ScenarioCreation_FromTimeSync.hpp
1 #pragma once
2 #include "ScenarioCreationState.hpp"
3 
4 #include <Scenario/Commands/Scenario/Creations/CreateInterval.hpp>
5 #include <Scenario/Commands/Scenario/Displacement/MoveEventMeta.hpp>
6 #include <Scenario/Commands/Scenario/Displacement/MoveNewEvent.hpp>
7 #include <Scenario/Document/TimeSync/TimeSyncModel.hpp>
8 #include <Scenario/Palette/Tools/ScenarioRollbackStrategy.hpp>
9 #include <Scenario/Palette/Transitions/AnythingTransitions.hpp>
10 #include <Scenario/Palette/Transitions/EventTransitions.hpp>
11 #include <Scenario/Palette/Transitions/IntervalTransitions.hpp>
12 #include <Scenario/Palette/Transitions/NothingTransitions.hpp>
13 #include <Scenario/Palette/Transitions/StateTransitions.hpp>
14 #include <Scenario/Palette/Transitions/TimeSyncTransitions.hpp>
15 
16 #include <QFinalState>
17 
18 namespace Scenario
19 {
20 template <typename Scenario_T, typename ToolPalette_T>
21 class Creation_FromTimeSync final : public CreationState<Scenario_T, ToolPalette_T>
22 {
23 public:
25  const ToolPalette_T& stateMachine, const Scenario_T& scenarioPath,
26  const score::CommandStackFacade& stack, QState* parent)
27  : CreationState<Scenario_T, ToolPalette_T>{
28  stateMachine, stack, std::move(scenarioPath), parent}
29  {
30  using namespace Scenario::Command;
31  auto finalState = new QFinalState{this};
32  QObject::connect(finalState, &QState::entered, [&]() { this->clearCreatedIds(); });
33 
34  auto mainState = new QState{this};
35  {
36  auto pressed = new QState{mainState};
37  auto released = new QState{mainState};
38  auto move_nothing = new StrongQState<MoveOnNothing>{mainState};
39  auto move_state = new StrongQState<MoveOnState>{mainState};
40  auto move_event = new StrongQState<MoveOnEvent>{mainState};
41  auto move_timesync = new StrongQState<MoveOnTimeSync>{mainState};
42 
43  // General setup
44  mainState->setInitialState(pressed);
45  released->addTransition(finalState);
46 
47  // Release
48  score::make_transition<ReleaseOnAnything_Transition>(mainState, released);
49 
50  // Pressed -> ...
51  auto t_pressed_moving_nothing
52  = score::make_transition<MoveOnNothing_Transition<Scenario_T>>(
53  pressed, move_nothing, *this);
54 
55  QObject::connect(t_pressed_moving_nothing, &QAbstractTransition::triggered, [&]() {
56  this->rollback();
57  createToNothing();
58  });
59 
61  // MoveOnNothing -> MoveOnNothing.
62  score::make_transition<MoveOnNothing_Transition<Scenario_T>>(
63  move_nothing, move_nothing, *this);
64 
65  // MoveOnNothing -> MoveOnState.
66  this->add_transition(move_nothing, move_state, [&]() {
67  this->rollback();
68  SCORE_TODO;
69  });
70 
71  // MoveOnNothing -> MoveOnEvent.
72  this->add_transition(move_nothing, move_event, [&]() {
73  if(this->hoveredEvent && this->createdEvents.contains(*this->hoveredEvent))
74  {
75  return;
76  }
77  this->rollback();
78 
79  createToEvent();
80  });
81 
82  // MoveOnNothing -> MoveOnTimeSync
83  this->add_transition(move_nothing, move_timesync, [&]() {
84  if(this->hoveredTimeSync
85  && this->createdTimeSyncs.contains(*this->hoveredTimeSync))
86  {
87  return;
88  }
89  this->rollback();
90  createToTimeSync();
91  });
92 
94  // MoveOnState -> MoveOnNothing
95  this->add_transition(move_state, move_nothing, [&]() {
96  this->rollback();
97  SCORE_TODO;
98  });
99 
100  // MoveOnState -> MoveOnState
101  // We don't do anything, the interval should not move.
102 
103  // MoveOnState -> MoveOnEvent
104  this->add_transition(move_state, move_event, [&]() {
105  this->rollback();
106  SCORE_TODO;
107  });
108 
109  // MoveOnState -> MoveOnTimeSync
110  this->add_transition(move_state, move_timesync, [&]() {
111  this->rollback();
112  SCORE_TODO;
113  });
114 
116  // MoveOnEvent -> MoveOnNothing
117  this->add_transition(move_event, move_nothing, [&]() {
118  this->rollback();
119  createToNothing();
120  });
121 
122  // MoveOnEvent -> MoveOnState
123  this->add_transition(move_event, move_state, [&]() {
124  this->rollback();
125  SCORE_TODO;
126  });
127 
128  // MoveOnEvent -> MoveOnEvent
129  score::make_transition<MoveOnEvent_Transition<Scenario_T>>(
130  move_event, move_event, *this);
131 
132  // MoveOnEvent -> MoveOnTimeSync
133  this->add_transition(move_event, move_timesync, [&]() {
134  if(this->hoveredTimeSync
135  && this->createdTimeSyncs.contains(*this->hoveredTimeSync))
136  {
137  return;
138  }
139  this->rollback();
140  createToTimeSync();
141  });
142 
144  // MoveOnTimeSync -> MoveOnNothing
145  this->add_transition(move_timesync, move_nothing, [&]() {
146  this->rollback();
147  createToNothing();
148  });
149 
150  // MoveOnTimeSync -> MoveOnState
151  this->add_transition(move_timesync, move_state, [&]() {
152  this->rollback();
153  SCORE_TODO;
154  });
155 
156  // MoveOnTimeSync -> MoveOnEvent
157  this->add_transition(move_timesync, move_event, [&]() {
158  if(this->hoveredEvent && this->createdEvents.contains(*this->hoveredEvent))
159  {
160  this->rollback();
161  return;
162  }
163  this->rollback();
164  createToEvent();
165  });
166 
167  // MoveOnTimeSync -> MoveOnTimeSync
168  score::make_transition<MoveOnTimeSync_Transition<Scenario_T>>(
169  move_timesync, move_timesync, *this);
170 
171  // What happens in each state.
172  QObject::connect(pressed, &QState::entered, [&]() {
173  this->m_clickedPoint = this->currentPoint;
174  createInitialEventAndState();
175  });
176 
177  QObject::connect(move_nothing, &QState::entered, [&]() {
178  if(this->createdEvents.empty() || this->createdIntervals.empty())
179  {
180  this->rollback();
181  return;
182  }
183 
184  this->currentPoint.date = stateMachine.magnetic().getPosition(
185  &stateMachine.model(), this->currentPoint.date);
186 
187  if(this->currentPoint.date <= this->m_clickedPoint.date)
188  {
189  this->currentPoint.date = this->m_clickedPoint.date + TimeVal::fromMsecs(10);
190  ;
191  }
192 
193  // Move the timesync
194  this->m_dispatcher.template submit<MoveNewEvent>(
195  this->m_scenario, this->createdIntervals.last(), this->createdEvents.last(),
196  this->currentPoint.date, this->currentPoint.y,
197  stateMachine.editionSettings().tool() == Tool::CreateSequence);
198  });
199 
200  QObject::connect(move_timesync, &QState::entered, [&]() {
201  if(this->createdEvents.empty())
202  {
203  this->rollback();
204  return;
205  }
206 
207  if(this->currentPoint.date <= this->m_clickedPoint.date)
208  {
209  return;
210  }
211 
212  this->m_dispatcher.template submit<MoveEventMeta>(
213  this->m_scenario, this->createdEvents.last(), TimeVal::zero(), 0.,
214  stateMachine.editionSettings().expandMode(), LockMode::Free);
215  });
216 
217  QObject::connect(released, &QState::entered, this, &Creation_FromTimeSync::commit);
218  }
219 
220  auto rollbackState = new QState{this};
221  score::make_transition<score::Cancel_Transition>(mainState, rollbackState);
222  rollbackState->addTransition(finalState);
223  QObject::connect(
224  rollbackState, &QState::entered, this, &Creation_FromTimeSync::rollback);
225 
226  this->setInitialState(mainState);
227  }
228 
229 private:
230  void createInitialEventAndState()
231  {
232  if(this->clickedTimeSync)
233  {
234  auto cmd = new Command::CreateEvent_State{
235  this->m_scenario, *this->clickedTimeSync, this->currentPoint.y};
236  this->m_dispatcher.submit(cmd);
237 
238  this->createdStates.append(cmd->createdState());
239  this->createdEvents.append(cmd->createdEvent());
240  }
241  }
242 
243  void createToNothing()
244  {
245  createInitialEventAndState();
246  this->createToNothing_base(this->createdStates.first());
247  }
248  void createToState()
249  {
250  createInitialEventAndState();
251  this->createToState_base(this->createdStates.first());
252  }
253  void createToEvent()
254  {
255  createInitialEventAndState();
256  this->createToEvent_base(this->createdStates.first());
257  }
258  void createToTimeSync()
259  {
260  // TODO "if hoveredTimeSync != clickedTimeSync"
261  createInitialEventAndState();
262  this->createToTimeSync_base(this->createdStates.first());
263  }
264 };
265 }
Definition: ScenarioCreation_FromTimeSync.hpp:22
Creation_FromTimeSync(const ToolPalette_T &stateMachine, const Scenario_T &scenarioPath, const score::CommandStackFacade &stack, QState *parent)
Definition: ScenarioCreation_FromTimeSync.hpp:24
Definition: ScenarioCreationState.hpp:66
A small abstraction layer over the score::CommandStack.
Definition: CommandStackFacade.hpp:20
Main plug-in of score.
Definition: score-plugin-dataflow/Dataflow/PortItem.hpp:14