MoveAndMergeState.hpp
1 #pragma once
2 
3 #include <Scenario/Commands/Scenario/Displacement/MoveEventMeta.hpp>
4 #include <Scenario/Commands/Scenario/Merge/MergeEvents.hpp>
5 #include <Scenario/Commands/Scenario/Merge/MergeTimeSyncs.hpp>
6 #include <Scenario/Document/Event/EventPresenter.hpp>
7 #include <Scenario/Document/Event/EventView.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/NothingTransitions.hpp>
18 #include <Scenario/Palette/Transitions/StateTransitions.hpp>
19 #include <Scenario/Palette/Transitions/TimeSyncTransitions.hpp>
20 #include <Scenario/Process/Algorithms/Accessors.hpp>
21 
22 #include <Magnetism/MagnetismAdjuster.hpp>
23 
24 #include <score/command/Dispatchers/MultiOngoingCommandDispatcher.hpp>
25 #include <score/locking/ObjectLocker.hpp>
26 //#include <Scenario/Application/ScenarioValidity.hpp>
27 #include <QFinalState>
28 
29 namespace Scenario
30 {
31 class ToolPalette;
32 /*
33 template <typename TheCommand>
34 class BugfixDispatcher final : public ICommandDispatcher
35 {
36 public:
37  const Scenario::ProcessModel& scenario;
38  BugfixDispatcher(const score::CommandStackFacade& stack
39  , const Scenario::ProcessModel& p)
40  : ICommandDispatcher{stack}
41  , scenario{p}
42  {
43  }
44 
45  template <typename... Args>
46  void submit(Args&&... args)
47  {
48  if (!m_cmd)
49  {
50  stack().disableActions();
51  m_cmd = std::make_unique<TheCommand>(std::forward<Args>(args)...);
52  ScenarioValidityChecker::checkValidity(scenario);
53  m_cmd->redo(stack().context());
54  ScenarioValidityChecker::checkValidity(scenario);
55  }
56  else
57  {
58  m_cmd->update(std::forward<Args>(args)...);
59  ScenarioValidityChecker::checkValidity(scenario);
60  m_cmd->redo(stack().context());
61  ScenarioValidityChecker::checkValidity(scenario);
62  }
63  }
64 
65  void commit()
66  {
67  if (m_cmd)
68  {
69  SendStrategy::Quiet::send(stack(), m_cmd.release());
70  stack().enableActions();
71  ScenarioValidityChecker::checkValidity(scenario);
72  }
73  }
74 
75  void rollback()
76  {
77  ScenarioValidityChecker::checkValidity(scenario);
78  if (m_cmd)
79  {
80  m_cmd->undo(stack().context());
81  ScenarioValidityChecker::checkValidity(scenario);
82  stack().enableActions();
83  }
84  m_cmd.reset();
85  }
86 
87 private:
88  std::unique_ptr<TheCommand> m_cmd;
89 };
90 */
91 template <
92  typename MoveEventCommand_T, // MoveEventMeta
93  typename Scenario_T, typename ToolPalette_T>
94 class MoveEventState final : public StateBase<Scenario_T>
95 {
96 public:
98  const ToolPalette_T& stateMachine, const Scenario_T& scenarioPath,
99  const score::CommandStackFacade& stack, score::ObjectLocker& locker,
100  QState* parent)
101  : StateBase<Scenario_T>{scenarioPath, parent}
102  , m_sm{stateMachine}
103  , m_movingDispatcher{stack}
104  {
105  this->setObjectName("MoveEventState");
106  using namespace Scenario::Command;
107  auto finalState = new QFinalState{this};
108 
109  auto mainState = new QState{this};
110  {
111  auto pressed = new QState{mainState};
112  auto released = new QState{mainState};
113 
114  auto onlyMoving = new QState{mainState};
115 
116  // General setup
117  mainState->setInitialState(pressed);
118  released->addTransition(finalState);
119 
120  // ***************************************
121  // transitions
122 
123  // press
124  score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
125  pressed, onlyMoving, *this);
126  score::make_transition<ReleaseOnAnything_Transition>(pressed, finalState);
127 
128  // update commands
129  score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
130  onlyMoving, onlyMoving, *this);
131 
132  // commit merging
133  score::make_transition<ReleaseOnAnything_Transition>(onlyMoving, released);
134 
135  // ********************************************
136  // What happens in each state.
137 
138  QObject::connect(pressed, &QState::entered, [&]() {
139  auto& scenar = stateMachine.model();
140  auto evId{this->clickedEvent};
141  if(!bool(evId) && bool(this->clickedState))
142  {
143  const Scenario::StateModel& st = scenar.state(*this->clickedState);
144  evId = st.eventId();
145  m_origPos.y = st.heightPercentage();
146  }
147 
148  if(!evId)
149  return;
150 
151  const Scenario::EventModel& ev = scenar.event(*evId);
152  m_origPos.date = ev.date();
153 
154  auto prev_csts = previousNonGraphIntervals(ev, 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 
166  // These 10 milliseconds are here to prevent "squashing"
167  // processes to zero, which leads to problem (they can't scale back!)
168  this->m_pressedPrevious = t + TimeVal::fromMsecs(10);
169  }
170  else
171  {
172  this->m_pressedPrevious = std::nullopt;
173  }
174 
175  this->m_pressPos = this->currentPoint;
176  });
177 
178  QObject::connect(onlyMoving, &QState::entered, [&]() {
179  auto& scenar = stateMachine.model();
180  // If we came here through a state.
181  auto evId = this->clickedEvent;
182  if(!bool(evId) && bool(this->clickedState))
183  {
184  evId = scenar.state(*this->clickedState).eventId();
185  }
186 
187  if(!evId)
188  return;
189 
190  TimeVal adjDate
191  = this->m_origPos.date + (this->currentPoint.date - this->m_pressPos.date);
192  m_lastDate = this->m_pressedPrevious
193  ? std::max(adjDate, *this->m_pressedPrevious)
194  : adjDate;
195 
196  auto [magPos, snap] = stateMachine.magnetic().getPosition(
197  &Scenario::parentTimeSync(*evId, stateMachine.model()), m_lastDate);
198  m_lastDate = magPos;
199  stateMachine.presenter().setSnapLine(magPos, snap);
200 
201  m_lastDate = std::max(m_lastDate, TimeVal{});
202 
203  if(this->clickedState)
204  {
205  auto new_y = m_origPos.y + (this->currentPoint.y - this->m_pressPos.y);
206  this->m_movingDispatcher.template submit<MoveEventCommand_T>(
207  this->m_scenario, *evId, m_lastDate, new_y,
208  stateMachine.editionSettings().expandMode(),
209  stateMachine.editionSettings().lockMode(), *this->clickedState);
210  }
211  else
212  {
213  this->m_movingDispatcher.template submit<MoveEventCommand_T>(
214  this->m_scenario, *evId, m_lastDate, this->currentPoint.y,
215  stateMachine.editionSettings().expandMode(),
216  stateMachine.editionSettings().lockMode());
217  }
218  });
219 
220  QObject::connect(released, &QState::entered, [&] {
221  if constexpr(std::is_same_v<Scenario::ToolPalette, ToolPalette_T>)
222  {
223  if(this->clickedState)
224  {
225  auto& st = this->m_scenario.state(*this->clickedState);
226  merge(st, this->m_lastDate);
227  }
228  }
229 
230  m_movingDispatcher.template commit<Command::MoveStateMacro>();
231  this->m_pressPos = {};
232  this->m_pressedPrevious = {};
233  stateMachine.presenter().setSnapLine({}, false);
234  });
235  }
236 
237  auto rollbackState = new QState{this};
238  score::make_transition<score::Cancel_Transition>(mainState, rollbackState);
239  rollbackState->addTransition(finalState);
240  QObject::connect(rollbackState, &QState::entered, [&] {
241  this->rollback();
242  this->m_pressPos = {};
243  this->m_pressedPrevious = {};
244  stateMachine.presenter().setSnapLine({}, false);
245  });
246 
247  this->setInitialState(mainState);
248  }
249 
250  void rollback() { m_movingDispatcher.template rollback<DefaultRollbackStrategy>(); }
251 
252  void merge(const StateModel& st, TimeVal date)
253  {
254  auto& ev = Scenario::parentEvent(st, this->m_scenario);
255  auto& ts = Scenario::parentTimeSync(ev, this->m_scenario);
256 
257  TimeSyncPresenter& sts_pres = m_sm.presenter().timeSync(ts.id());
258 
259  std::vector<QGraphicsItem*> toIgnore;
260  toIgnore.push_back(sts_pres.view());
261  toIgnore.push_back(&sts_pres.trigger());
262  for(auto& ev_id : sts_pres.model().events())
263  {
264  auto& ev = m_sm.presenter().event(ev_id);
265  toIgnore.push_back(ev.view());
266  for(auto& st_id : ev.model().states())
267  {
268  auto& st = m_sm.presenter().state(st_id);
269  toIgnore.push_back(st.view());
270  }
271  }
272 
273  for(auto& itv : Scenario::previousIntervals(sts_pres.model(), this->m_scenario))
274  {
275  auto& sst_pres
276  = m_sm.presenter().state(this->m_scenario.interval(itv).startState());
277  auto& sev_pres = m_sm.presenter().event(sst_pres.model().eventId());
278  TimeSyncPresenter& sts_pres
279  = m_sm.presenter().timeSync(sev_pres.model().timeSync());
280 
281  toIgnore.push_back(sts_pres.view());
282  for(auto& ev : sts_pres.events())
283  {
284  toIgnore.push_back(ev->view());
285  for(auto& st : ev->states())
286  {
287  toIgnore.push_back(st->view());
288  }
289  }
290 
291  toIgnore.push_back(&sts_pres.trigger());
292  }
293 
294  for(auto& itv : Scenario::nextIntervals(sts_pres.model(), this->m_scenario))
295  {
296  auto& sst_pres = m_sm.presenter().state(this->m_scenario.interval(itv).endState());
297  auto& sev_pres = m_sm.presenter().event(sst_pres.model().eventId());
298  auto& sts_pres = m_sm.presenter().timeSync(sev_pres.model().timeSync());
299 
300  toIgnore.push_back(sts_pres.view());
301  for(auto& ev : sts_pres.events())
302  {
303  toIgnore.push_back(ev->view());
304  for(auto& st : ev->states())
305  {
306  toIgnore.push_back(st->view());
307  }
308  }
309 
310  toIgnore.push_back(&sts_pres.trigger());
311  }
312 
313  QGraphicsItem* item = m_sm.itemAt({date, st.heightPercentage()}, toIgnore);
314 
315  if(auto stateToMerge = qgraphicsitem_cast<Scenario::StateView*>(item))
316  {
317  // this->rollback();
318  this->m_movingDispatcher.template submit<Command::MergeEvents>(
319  this->m_scenario, ev.id(),
320  Scenario::parentEvent(stateToMerge->presenter().model().id(), this->m_scenario)
321  .id());
322  }
323  else if(auto eventToMerge = qgraphicsitem_cast<Scenario::EventView*>(item))
324  {
325  // this->rollback();
326  this->m_movingDispatcher.template submit<Command::MergeEvents>(
327  this->m_scenario, ev.id(), eventToMerge->presenter().model().id());
328  }
329  else if(auto syncToMerge = qgraphicsitem_cast<Scenario::TimeSyncView*>(item))
330  {
331  // this->rollback();
332  this->m_movingDispatcher.template submit<Command::MergeTimeSyncs>(
333  this->m_scenario, ts.id(), syncToMerge->presenter().model().id());
334  }
335  }
336 
337  const ToolPalette_T& m_sm;
338  MultiOngoingCommandDispatcher m_movingDispatcher;
339  Scenario::Point m_pressPos{}; // where the click landed in the scenario
340  Scenario::Point m_origPos{}; // original position of the object being moved
341  std::optional<TimeVal> m_pressedPrevious;
342  TimeVal m_lastDate;
343  bool m_startEventCanBeMerged{};
344  bool m_endEventCanBeMerged{};
345 };
346 
348 // * Specialization for the ScenarioModel allows merging
349 // */
350 
351 // template <
352 // typename MoveEventCommand_T, // MoveEventMeta
353 // typename ToolPalette_T>
354 // class MoveEventState<MoveEventCommand_T, Scenario::ProcessModel,
355 // ToolPalette_T>
356 // final : public StateBase<Scenario::ProcessModel>
357 //{
358 // public:
359 // MoveEventState(
360 // const ToolPalette_T& stateMachine,
361 // const Scenario::ProcessModel& scenarioPath,
362 // const score::CommandStackFacade& stack,
363 // score::ObjectLocker& locker,
364 // QState* parent)
365 // : StateBase<Scenario::ProcessModel>{scenarioPath, parent}
366 // , m_movingDispatcher{stack}
367 // , m_mergingTnDispatcher{stack}
368 // , m_mergingEventDispatcher{stack}
369 // {
370 // this->setObjectName("MoveEventState");
371 // using namespace Scenario::Command;
372 // auto finalState = new QFinalState{this};
373 
374 // auto mainState = new QState{this};
375 // {
376 // auto pressed = new QState{mainState};
377 // auto released = new QState{mainState};
378 
379 // auto onlyMoving = new QState{mainState};
380 // auto mergingOnTimeSync = new QState{mainState};
381 // auto mergingOnEvent = new QState{mainState};
382 
383 // auto rollbackTnMerging = new QState{mainState};
384 // auto rollbackEventMerging = new QState{mainState};
385 
386 // // General setup
387 // mainState->setInitialState(pressed);
388 // released->addTransition(finalState);
389 
390 // rollbackTnMerging->addTransition(onlyMoving);
391 // rollbackEventMerging->addTransition(onlyMoving);
392 
393 // // ***************************************
394 // // transitions
395 
396 // // press
397 // score::
398 // make_transition<MoveOnAnything_Transition<Scenario::ProcessModel>>(
399 // pressed, onlyMoving, *this);
400 // score::make_transition<ReleaseOnAnything_Transition>(
401 // pressed, finalState);
402 
403 // // update commands
404 // // score::make_transition<MoveOnAnything_Transition<Scenario_T>>(
405 // // onlyMoving, onlyMoving, *this);
406 // //*
407 // score::
408 // make_transition<MoveOnAnythingButPonctual_Transition<Scenario::
409 // ProcessModel>>(
410 // onlyMoving, onlyMoving, *this);
411 
412 // score::
413 // make_transition<MoveOnTimeSync_Transition<Scenario::ProcessModel>>(
414 // onlyMoving, mergingOnTimeSync, *this);
415 
416 // score::make_transition<MoveOnEvent_Transition<Scenario::ProcessModel>>(
417 // onlyMoving, mergingOnEvent, *this);
418 // score::make_transition<MoveOnEvent_Transition<Scenario::ProcessModel>>(
419 // mergingOnEvent, mergingOnEvent, *this);
420 
421 // score::make_transition<MoveOnState_Transition<Scenario::ProcessModel>>(
422 // onlyMoving, mergingOnEvent, *this);
423 // score::make_transition<MoveOnState_Transition<Scenario::ProcessModel>>(
424 // mergingOnEvent, mergingOnEvent, *this);
425 // //*/
426 // // rollback merging
427 // score::
428 // make_transition<MoveOnAnythingButTimeSync_Transition<Scenario::
429 // ProcessModel>>(
430 // mergingOnTimeSync, rollbackTnMerging, *this);
431 // score::
432 // make_transition<MoveOnAnythingButEvent_Transition<Scenario::
433 // ProcessModel>>(
434 // mergingOnEvent, rollbackEventMerging, *this);
435 
436 // // commit merging
437 // score::make_transition<ReleaseOnAnything_Transition>(
438 // mergingOnTimeSync, released);
439 // score::make_transition<ReleaseOnAnything_Transition>(
440 // mergingOnEvent, released);
441 // score::make_transition<ReleaseOnAnything_Transition>(
442 // onlyMoving, released);
443 
444 // // ********************************************
445 // // What happens in each state.
446 
447 // QObject::connect(mergingOnTimeSync, &QState::entered, [&]() {
448 // qDebug("mergingOnTimenode");
449 
450 // auto& scenar = stateMachine.model();
451 // // If we came here through a state.
452 // auto evId = this->clickedEvent;
453 // if (!bool(evId) && bool(this->clickedState))
454 // {
455 // evId = scenar.state(*this->clickedState).eventId();
456 // }
457 // if (!evId)
458 // return;
459 
460 // auto tnId = scenar.event(*evId).timeSync();
461 
462 // if (this->currentPoint.date <= this->m_clickedPoint.date)
463 // {
464 // auto& tn = scenar.timeSync(tnId);
465 // const auto& prev = Scenario::previousIntervals(tn, scenar);
466 // if(!prev.empty())
467 // return;
468 // }
469 
470 // if (this->hoveredTimeSync && tnId != this->hoveredTimeSync)
471 // {
472 // this->m_movingDispatcher.rollback();
473 // this->m_mergingEventDispatcher.rollback();
474 
475 // this->m_mergingTnDispatcher.submit(
476 // this->m_scenario,
477 // tnId,
478 // *this->hoveredTimeSync);
479 // }
480 // else
481 // {
482 // qDebug("stuck 1");
483 // }
484 
485 // });
486 // QObject::connect(rollbackTnMerging, &QState::entered, [&]() {
487 // qDebug("rollbackTnMerging");
488 // m_mergingTnDispatcher.rollback();
489 // });
490 
491 // QObject::connect(mergingOnEvent, &QState::entered, [&]() {
492 // qDebug("mergingOnEvent");
493 
494 // auto& scenar = stateMachine.model();
495 // // If we came here through a state.
496 // auto clickedEvId = this->clickedEvent;
497 // if (!bool(clickedEvId) && bool(this->clickedState))
498 // {
499 // clickedEvId = scenar.state(*this->clickedState).eventId();
500 // qDebug("event 1");
501 // }
502 // else
503 // {
504 // qDebug("event 2")
505 // }
506 // if (!clickedEvId) { qDebug("bye 1");
507 // return;
508 // }
509 
510 // auto destinationEvId = this->hoveredEvent;
511 // if (!bool(destinationEvId) && bool(this->hoveredState))
512 // {
513 // destinationEvId = scenar.state(*this->hoveredState).eventId();
514 // }
515 
516 // if (!destinationEvId) { qDebug("bye 2");
517 // return;
518 // }
519 // auto tnId = scenar.event(*destinationEvId).timeSync();
520 
521 // if (this->currentPoint.date <= this->m_clickedPoint.date)
522 // {
523 // auto& tn = scenar.timeSync(tnId);
524 // const auto& prev = Scenario::previousIntervals(tn, scenar);
525 // if(!prev.empty()) { qDebug("bye 3");
526 // return;
527 // }
528 // }
529 
530 // qDebug() << *clickedEvId << *destinationEvId;
531 // if (*clickedEvId != *destinationEvId)
532 // {
533 // m_movingDispatcher.rollback();
534 // m_mergingTnDispatcher.rollback();
535 
536 // m_mergingEventDispatcher.submit(
537 // m_scenario,
538 // *clickedEvId,
539 // *destinationEvId);
540 // }
541 // else
542 // {
543 // m_mergingEventDispatcher.rollback();
544 // m_mergingTnDispatcher.rollback();
545 
546 // TimeVal date
547 // = this->m_pressedPrevious
548 // ? max(this->currentPoint.date, *this->m_pressedPrevious)
549 // : this->currentPoint.date;
550 
551 // if(this->clickedState)
552 // {
553 // this->m_movingDispatcher.submit(
554 // m_scenario,
555 // *clickedEvId,
556 // date,
557 // this->currentPoint.y,
558 // stateMachine.editionSettings().expandMode(),
559 // *this->clickedState);
560 // }
561 // else
562 // {
563 // this->m_movingDispatcher.submit(
564 // m_scenario,
565 // *clickedEvId,
566 // date,
567 // this->currentPoint.y,
568 // stateMachine.editionSettings().expandMode());
569 // }
570 // }
571 // });
572 // QObject::connect(rollbackEventMerging, &QState::entered, [&]() {
573 // qDebug("rollbackEventMerging");
574 // m_mergingEventDispatcher.rollback();
575 // });
576 
577 // QObject::connect(onlyMoving, &QState::entered, [&]() {
578 // qDebug("onlyMoving");
579 // auto& scenar = stateMachine.model();
580 // // If we came here through a state.
581 // auto evId = this->clickedEvent;
582 // if (!bool(evId) && bool(this->clickedState))
583 // {
584 // evId = scenar.state(*this->clickedState).eventId();
585 // }
586 // if (!evId)
587 // return;
588 
589 // TimeVal date
590 // = this->m_pressedPrevious
591 // ? std::max(this->currentPoint.date,
592 // *this->m_pressedPrevious) : this->currentPoint.date;
593 
594 // date = std::max(date, TimeVal{});
595 // if(this->clickedState)
596 // {
597 // this->m_movingDispatcher.submit(
598 // m_scenario,
599 // *evId,
600 // date,
601 // this->currentPoint.y,
602 // stateMachine.editionSettings().expandMode(),
603 // *this->clickedState);
604 // }
605 // else
606 // {
607 // this->m_movingDispatcher.submit(
608 // m_scenario,
609 // *evId,
610 // date,
611 // this->currentPoint.y,
612 // stateMachine.editionSettings().expandMode());
613 // }
614 // });
615 
616 // QObject::connect(pressed, &QState::entered, [&]() {
617 // this->m_clickedPoint = this->currentPoint;
618 
619 // const Scenario::ProcessModel& scenar = stateMachine.model();
620 
621 // // TODO refactor this part, it's used everywhere
622 // auto evId = this->clickedEvent;
623 // if (!bool(evId) && bool(this->clickedState))
624 // {
625 // evId = scenar.state(*this->clickedState).eventId();
626 // }
627 // if (!evId)
628 // return;
629 
630 // auto prev_csts = Scenario::previousIntervals(scenar.event(*evId),
631 // scenar); if (!prev_csts.empty())
632 // {
633 // // We find the one that starts the latest.
634 // TimeVal t = TimeVal::zero();
635 // for (const auto& cst_id : prev_csts)
636 // {
637 // const auto& other_date = scenar.interval(cst_id).date();
638 // if (other_date > t)
639 // t = other_date;
640 // }
641 
642 // // These 10 milliseconds are here to prevent "squashing"
643 // // processes to zero, which leads to problem (they can't scale
644 // back!) this->m_pressedPrevious = t + TimeVal::fromMsecs(10);
645 // }
646 // else
647 // {
648 // this->m_pressedPrevious = std::nullopt;
649 // }
650 
651 // });
652 
653 // QObject::connect(released, &QState::entered, [&]() {
654 // m_movingDispatcher.commit();
655 // m_mergingEventDispatcher.commit();
656 // m_mergingTnDispatcher.commit();
657 // m_pressedPrevious = std::nullopt;
658 // });
659 // }
660 
661 // auto rollbackState = new QState{this};
662 // score::make_transition<score::Cancel_Transition>(
663 // mainState, rollbackState);
664 // rollbackState->addTransition(finalState);
665 // QObject::connect(rollbackState, &QState::entered, [&]() {
666 // m_movingDispatcher.rollback();
667 // m_mergingTnDispatcher.rollback();
668 // m_mergingEventDispatcher.rollback();
669 // });
670 
671 // this->setInitialState(mainState);
672 // }
673 
674 // SingleOngoingCommandDispatcher<MoveEventCommand_T> m_movingDispatcher;
675 // SingleOngoingCommandDispatcher<Command::MergeTimeSyncs>
676 // m_mergingTnDispatcher; SingleOngoingCommandDispatcher<Command::MergeEvents>
677 // m_mergingEventDispatcher;
678 
679 // std::optional<TimeVal> m_pressedPrevious;
680 // Scenario::Point m_clickedPoint;
681 //};
682 }
The MultiOngoingCommandDispatcher class.
Definition: MultiOngoingCommandDispatcher.hpp:33
Definition: EventModel.hpp:36
Definition: MoveAndMergeState.hpp:95
Definition: ScenarioPaletteBaseStates.hpp:20
Definition: StateModel.hpp:63
Definition: TimeSyncPresenter.hpp:29
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:14
Definition: ScenarioPoint.hpp:13
Definition: TimeValue.hpp:21