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