/
UndoSystem.h
97 lines (70 loc) · 2.52 KB
/
UndoSystem.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#pragma once
#include <map>
#include <set>
#include <functional>
#include "iundo.h"
#include "icommandsystem.h"
#include "Stack.h"
#include "StackFiller.h"
#include "registry/CachedKey.h"
namespace undo
{
constexpr const char* const RKEY_UNDO_QUEUE_SIZE = "user/ui/undo/queueSize";
/**
* greebo: The UndoSystem (interface: iundo.h) is maintaining two internal
* stacks of Operations (one for Undo, one for Redo), each containing a list
* of Undoables plus their snapshot data.
*
* The Undoables are responsible of submitting their data to the UndoSystem
* before their data is changed, not knowing which or whether an operation is
* currently active. If there actually is an Undo Operation in the works,
* this system is handling all of the paperwork.
*
* On undo or redo, the Undoables are called to re-import the states
* as stored in their UndoMementos. When undoing operations, the Undoables
* themselves are again responsible for submitting their data to the UndoSystem
* such that it can record the changes and store them in the RedoStack.
*
* The RedoStack is discarded as soon as a new Undoable Operation is recorded
* and pushed to the UndoStack.
*/
class UndoSystem final :
public IUndoSystem
{
private:
// The undo and redo stacks
UndoStack _undoStack;
UndoStack _redoStack;
UndoStack* _activeUndoStack;
std::map<IUndoable*, UndoStackFiller> _undoables;
registry::CachedKey<std::size_t> _undoLevels;
sigc::signal<void> _signalPostUndo;
sigc::signal<void> _signalPostRedo;
sigc::signal<void(EventType, const std::string&)> _eventSignal;
public:
UndoSystem();
~UndoSystem();
IUndoStateSaver* getStateSaver(IUndoable& undoable) override;
void releaseStateSaver(IUndoable& undoable) override;
void start() override;
bool operationStarted() const override;
// greebo: This finishes the current operation and
// removes it instantly from the stack
void cancel() override;
void finish(const std::string& command) override;
void undo() override;
void redo() override;
void clear() override;
sigc::signal<void>& signal_postUndo() override;
// Emitted after a redo operation is fully completed, allows objects to refresh their state
sigc::signal<void>& signal_postRedo() override;
sigc::signal<void(EventType, const std::string&)>& signal_undoEvent() override;
private:
void startUndo();
bool finishUndo(const std::string& command);
void startRedo();
bool finishRedo(const std::string& command);
// Assigns the given stack to all of the Undoables listed in the map
void setActiveUndoStack(UndoStack* stack);
};
}