-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMementoCommandController.h
133 lines (105 loc) · 3.43 KB
/
MementoCommandController.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#pragma once
#include"RxCommand/IncludeExtLibs.h"
#include"RxCommand/CommandControllerAction.h"
#include"RxCommand/MementoCommand.h"
namespace Reactor
{
/**
* Command objects can offer an undo mechanism by retaining the state necessary to
* roll back the behavior they execute. If the state is heavyweight or hard to restore,
* however, a MEMENTO (414) that snapshots the receiver’s state before executing the
* command may provide a simpler, more lightweight option.
*
* TODO: Caretakers is not thread safe
*/
template <typename Return>
class MementoCommandController
: public CommandControllerAction<Return>
, public Templates::UndoRedoBase
{
public:
MementoCommandController(CommandControllerPolicy policy, RxThreadPool::Ptr threadPool)
: CommandControllerAction<Return>(policy, threadPool)
{}
virtual ~MementoCommandController()
{}
CLASS_TRAITS(MementoCommandController)
// ------------------------------------------
// Interface UndoRedoBase
// ------------------------------------------
virtual bool Undo()
{
return caretakers_.Undo();
}
virtual bool Redo()
{
return caretakers_.Redo();
}
virtual void ClearUndo()
{
caretakers_.ClearUndo();
}
virtual void ClearRedo()
{
caretakers_.ClearRedo();
}
virtual bool CreateMemento() const
{
return caretakers_.CreateMemento();
}
// -----------------------------------------------------------
// Interface CommandObserver <T>
// -----------------------------------------------------------
virtual bool OnComplete(Command<Return>* command)
{
IINFO() << "Completed command " << command->GetName();
this->processOnComplete(command);
return true;
}
virtual bool OnNext(Command<Return>* command, Return value)
{
IINFO() << "Command " << command->GetName() << " value: " << value;
caretakers_.CreateMemento();
this->processOnNext(command, value);
return true;
}
virtual bool OnError(Command<Return>* command, BaseLib::GeneralException exception)
{
IINFO() << "Command " << command->GetName() << " exception: " << exception.what();
this->processOnError(command, exception);
return true;
}
// ------------------------------------------
// Add functions
// ------------------------------------------
bool Add(typename MementoCommandActions<Return>::Ptr command)
{
CommandBase::Ptr commandBase = std::dynamic_pointer_cast<CommandBase>(command);
ASSERT(commandBase != nullptr);
bool isAdded = this->AddCommand(commandBase);
if(isAdded)
{
//Locker locker(this);
caretakers_.push_back(command);
}
return isAdded;
}
private:
Templates::Caretakers caretakers_;
};
// ---------------------------------------------------------------
// MementoCommandControllerKeyValue
// ---------------------------------------------------------------
template <typename K, typename V>
class MementoCommandControllerKeyValue
: public MementoCommandController<IMap<K,V>>
{
public:
MementoCommandControllerKeyValue(CommandControllerPolicy policy, RxThreadPool::Ptr threadPool)
: MementoCommandController<IMap<K,V>>(policy, threadPool)
{ }
virtual ~MementoCommandControllerKeyValue()
{ }
CLASS_TRAITS(MementoCommandControllerKeyValue)
};
}