Loading...
Searching...
No Matches
MoveStates.hpp
1#pragma once
2#include <Scenario/Commands/Scenario/Displacement/MoveEventMeta.hpp>
3#include <Scenario/Commands/Scenario/Merge/MergeEvents.hpp>
4#include <Scenario/Document/Event/EventPresenter.hpp>
5#include <Scenario/Document/Event/EventView.hpp>
6#include <Scenario/Document/Interval/Temporal/TemporalIntervalPresenter.hpp>
7#include <Scenario/Document/Interval/Temporal/TemporalIntervalView.hpp>
8#include <Scenario/Document/State/StatePresenter.hpp>
9#include <Scenario/Document/State/StateView.hpp>
10#include <Scenario/Document/TimeSync/TimeSyncPresenter.hpp>
11#include <Scenario/Document/TimeSync/TimeSyncView.hpp>
12#include <Scenario/Document/TimeSync/TriggerView.hpp>
13#include <Scenario/Palette/ScenarioPaletteBaseStates.hpp>
14#include <Scenario/Palette/Tools/ScenarioRollbackStrategy.hpp>
15#include <Scenario/Palette/Transitions/AnythingTransitions.hpp>
16#include <Scenario/Palette/Transitions/EventTransitions.hpp>
17#include <Scenario/Palette/Transitions/IntervalTransitions.hpp>
18#include <Scenario/Palette/Transitions/NothingTransitions.hpp>
19#include <Scenario/Palette/Transitions/TimeSyncTransitions.hpp>
20#include <Scenario/Process/Algorithms/Accessors.hpp>
21
22#include <score/command/Dispatchers/MultiOngoingCommandDispatcher.hpp>
23#include <score/command/Dispatchers/SingleOngoingCommandDispatcher.hpp>
24#include <score/locking/ObjectLocker.hpp>
25
26#include <QApplication>
27#include <QFinalState>
28
29namespace Scenario
30{
31template <
32 typename MoveBraceCommand_T, // SetMinDuration or setMaxDuration
33 typename Scenario_T, typename ToolPalette_T>
34class MoveIntervalBraceState final : public StateBase<Scenario_T>
35{
36public:
38 const ToolPalette_T& stateMachine, const Scenario_T& scenarioPath,
40 QState* parent)
41 : StateBase<Scenario_T>{scenarioPath, parent}
42 , m_dispatcher{stack}
43 {
44 this->setObjectName("MoveIntervalBraceState");
45 using namespace Scenario::Command;
46 auto finalState = new QFinalState{this};
47
48 auto mainState = new QState{this};
49 {
50 auto pressed = new QState{mainState};
51 auto released = new QState{mainState};
52 auto moving = new QState{mainState};
53
54 mainState->setInitialState(pressed);
55 released->addTransition(finalState);
56
57 score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
58 pressed, moving, *this);
59 score::make_transition<ReleaseOnAnything_Transition>(pressed, finalState);
60
61 score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
62 moving, moving, *this);
63 score::make_transition<ReleaseOnAnything_Transition>(moving, released);
64
65 QObject::connect(pressed, &QState::entered, [&]() {
66 this->m_initialDate = this->currentPoint.date;
67 if(this->clickedInterval)
68 {
69 auto& scenar = stateMachine.model();
70 auto& cstr = scenar.interval(*this->clickedInterval);
71 this->m_initialDuration
72 = ((cstr.duration)
73 .*MoveBraceCommand_T::corresponding_member)(); // = interval
74 // MinDuration
75 // or
76 // maxDuration
77 }
78 });
79
80 QObject::connect(moving, &QState::entered, [&]() {
81 if(this->clickedInterval)
82 {
83 auto& scenar = stateMachine.model();
84 auto& cstr = scenar.interval(*this->clickedInterval);
85 auto date = this->currentPoint.date - *m_initialDate + *m_initialDuration;
86
87 date = stateMachine.magnetic().getPosition(&stateMachine.model(), date);
88
89 this->m_dispatcher.submit(cstr, date, false);
90 }
91 });
92
93 QObject::connect(
94 released, &QState::entered, [&]() { this->m_dispatcher.commit(); });
95 }
96
97 auto rollbackState = new QState{this};
98 score::make_transition<score::Cancel_Transition>(mainState, rollbackState);
99 rollbackState->addTransition(finalState);
100 QObject::connect(
101 rollbackState, &QState::entered, [&]() { m_dispatcher.rollback(); });
102
103 this->setInitialState(mainState);
104 }
106
107private:
108 std::optional<TimeVal> m_initialDate;
109 std::optional<TimeVal> m_initialDuration;
110};
111
112template <
113 typename MoveTimeSyncCommand_T, // MoveEventMeta
114 typename Scenario_T, typename ToolPalette_T>
115class MoveTimeSyncState final : public StateBase<Scenario_T>
116{
117public:
119 const ToolPalette_T& stateMachine, const Scenario_T& scenarioPath,
121 QState* parent)
122 : StateBase<Scenario_T>{scenarioPath, parent}
123 , m_dispatcher{stack}
124 {
125 this->setObjectName("MoveTimeSyncState");
126 using namespace Scenario::Command;
127 auto finalState = new QFinalState{this};
128
129 auto mainState = new QState{this};
130 {
131 auto pressed = new QState{mainState};
132 auto released = new QState{mainState};
133 auto moving = new QState{mainState};
134
135 // General setup
136 mainState->setInitialState(pressed);
137 released->addTransition(finalState);
138
139 score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
140 pressed, moving, *this);
141 score::make_transition<ReleaseOnAnything_Transition>(pressed, finalState);
142 score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
143 moving, moving, *this);
144 score::make_transition<ReleaseOnAnything_Transition>(moving, released);
145
146 // What happens in each state.
147 QObject::connect(pressed, &QState::entered, [&]() {
148 if(!this->clickedTimeSync)
149 return;
150
151 auto& scenar = stateMachine.model();
152
153 auto prev_csts
154 = previousNonGraphIntervals(scenar.timeSync(*this->clickedTimeSync), scenar);
155 if(!prev_csts.empty())
156 {
157 // We find the one that starts the latest.
158 TimeVal t = TimeVal::zero();
159 for(const auto& cst_id : prev_csts)
160 {
161 const auto& other_date = scenar.interval(cst_id).date();
162 if(other_date > t)
163 t = other_date;
164 }
165 this->m_pressedPrevious = t;
166 }
167 else
168 {
169 this->m_pressedPrevious = std::nullopt;
170 }
171 });
172
173 QObject::connect(moving, &QState::entered, [&]() {
174 if(!this->clickedTimeSync)
175 return;
176
177 // Get the 1st event on the timesync.
178 auto& scenar = stateMachine.model();
179 auto& tn = scenar.timeSync(*this->clickedTimeSync);
180 SCORE_ASSERT(!tn.events().empty());
181 const auto& ev_id = tn.events().front();
182 auto date = this->currentPoint.date;
183
184 date = stateMachine.magnetic().getPosition(&stateMachine.model(), date);
185
186 if(this->m_pressedPrevious)
187 {
188 date = max(date, *this->m_pressedPrevious);
189 }
190
191 m_dispatcher.submit(
192 this->m_scenario, ev_id, date, this->currentPoint.y,
193 stateMachine.editionSettings().expandMode(),
194 stateMachine.editionSettings().lockMode());
195 });
196
197 QObject::connect(released, &QState::entered, [&]() {
198 m_dispatcher.commit();
199 m_pressedPrevious = {};
200 });
201 }
202
203 auto rollbackState = new QState{this};
204 score::make_transition<score::Cancel_Transition>(mainState, rollbackState);
205 rollbackState->addTransition(finalState);
206 QObject::connect(
207 rollbackState, &QState::entered, [&]() { m_dispatcher.rollback(); });
208
209 this->setInitialState(mainState);
210 }
211
213 std::optional<TimeVal> m_pressedPrevious;
214};
215}
Definition MoveStates.hpp:35
Definition MoveStates.hpp:116
Definition ScenarioPaletteBaseStates.hpp:20
The SingleOngoingCommandDispatcher class.
Definition SingleOngoingCommandDispatcher.hpp:17
A small abstraction layer over the score::CommandStack.
Definition CommandStackFacade.hpp:20
The ObjectLocker class.
Definition ObjectLocker.hpp:21
Main plug-in of score.
Definition score-plugin-dataflow/Dataflow/PortItem.hpp:13
Definition TimeValue.hpp:21