Loading...
Searching...
No Matches
MultiOngoingCommandDispatcher.hpp
1#pragma once
2#include <score/command/Dispatchers/ICommandDispatcher.hpp>
3#include <score/command/Dispatchers/SendStrategy.hpp>
4
5// Creates commands on a list and keep updating the latest command
6// up to the next new command.
7namespace RollbackStrategy
8{
9struct Simple
10{
11 static void
12 rollback(const score::DocumentContext& ctx, const std::vector<score::Command*>& cmds)
13 {
14 for(int i = cmds.size() - 1; i >= 0; --i)
15 {
16 cmds[i]->undo(ctx);
17 }
18 }
19};
20}
21
33{
34public:
36 : ICommandDispatcher{stack}
37 {
38 }
39
40 ~MultiOngoingCommandDispatcher() { cleanup(); }
41
42 void submit(score::Command* cmd)
43 {
44 stack().disableActions();
45 cmd->redo(stack().context());
46 m_cmds.push_back(cmd);
47 }
48
49 void submitQuiet(score::Command* cmd)
50 {
51 stack().disableActions();
52 m_cmds.push_back(cmd);
53 }
54
55 template <typename TheCommand, typename... Args>
56 void submit(Args&&... args)
57 {
58 if(m_cmds.empty())
59 {
60 stack().disableActions();
61 auto cmd = new TheCommand(std::forward<Args>(args)...);
62 cmd->redo(stack().context());
63 m_cmds.push_back(cmd);
64 }
65 else
66 {
67 score::Command* last = m_cmds.back();
68 if(last->key() == TheCommand::static_key())
69 {
70 safe_cast<TheCommand*>(last)->update(std::forward<Args>(args)...);
71 safe_cast<TheCommand*>(last)->redo(stack().context());
72 }
73 else
74 {
75 auto cmd = new TheCommand(std::forward<Args>(args)...);
76 cmd->redo(stack().context());
77 m_cmds.push_back(cmd);
78 }
79 }
80 }
81
82 // Give it something that behaves like AggregateCommand
83 template <typename CommitCommand>
84 void commit()
85 {
86 if(!m_cmds.empty())
87 {
88 auto theCmd = new CommitCommand;
89 for(auto& cmd : m_cmds)
90 {
91 theCmd->addCommand(cmd);
92 }
93
94 SendStrategy::Quiet::send(stack(), theCmd);
95 m_cmds.clear();
96
97 stack().enableActions();
98 }
99 }
100
101 template <typename RollbackStrategy>
102 void rollback()
103 {
104 RollbackStrategy::rollback(stack().context(), m_cmds);
105
106 cleanup();
107 m_cmds.clear();
108
109 stack().enableActions();
110 }
111
112private:
113 void cleanup()
114 {
115 std::for_each(m_cmds.rbegin(), m_cmds.rend(), [](auto cmd) { delete cmd; });
116 }
117
118 std::vector<score::Command*> m_cmds;
119};
The ICommandDispatcher class.
Definition ICommandDispatcher.hpp:21
The MultiOngoingCommandDispatcher class.
Definition MultiOngoingCommandDispatcher.hpp:33
The Command class.
Definition Command.hpp:34
A small abstraction layer over the score::CommandStack.
Definition CommandStackFacade.hpp:20
Definition MultiOngoingCommandDispatcher.hpp:10
Definition DocumentContext.hpp:18