#include "Publicinc.hpp"
// Receiver
class Receiver
{
public:
string GetContent() const { return m_content; }
void SetContent(const string& content) { m_content = content; }
void Append(const string& strAppend) { m_content.append(strAppend); }
// void Show() const { printf("content is {%s}\n", m_content.c_str()); }
private:
string m_content;
};
ostream& operator<< (ostream& os, const Receiver& rhs)
{
os << "the current is: " << rhs.GetContent() << endl;
return os;
}
// void TestRecevier()
// {
// Receiver r;
// r.SetContent("abc");
// r.Show();
// cout << r;
// }
class Command
{
public:
Command(Receiver* pReceiver, string strAppend)
: m_pReceiver(pReceiver)
, m_append(strAppend)
{
}
virtual ~Command() {}
virtual void Execute() = 0;
protected:
Receiver* m_pReceiver;
string m_append;
};
class UndoCommand : public Command
{
public:
UndoCommand(Receiver* pReceiver, string strAppend)
: Command(pReceiver, strAppend)
{
}
virtual void Undo() = 0;
virtual void Redo() = 0;
};
class ConcreteCommand : public UndoCommand
{
public:
ConcreteCommand(Receiver* pReceiver, string strAppend)
: UndoCommand(pReceiver, strAppend)
{
}
virtual void Execute()
{
m_prevContent = m_pReceiver->GetContent();
m_pReceiver->Append(m_append);
m_currContent = m_pReceiver->GetContent();
}
virtual void Undo()
{
m_pReceiver->SetContent(m_prevContent);
}
virtual void Redo()
{
m_pReceiver->SetContent(m_currContent);
}
private:
string m_prevContent;
string m_currContent;
};
class CommandManager
{
typedef std::stack<Command*> CommandStack;
public:
~CommandManager()
{
while (m_exeCommands.size() > 0) {
Command* command = m_exeCommands.top();
m_exeCommands.pop();
delete command;
}
while (m_undoCommands.size() > 0) {
Command* command = m_undoCommands.top();
m_undoCommands.pop();
delete command;
}
}
void ExecuteCmd(Command* pCommand)
{
pCommand->Execute();
}
void UndoCmd()
{
if (m_exeCommands.size() > 0) {
UndoCommand* pCommand = dynamic_cast<UndoCommand*>(m_exeCommands.top());
m_exeCommands.pop();
pCommand->Undo();
m_undoCommands.push(pCommand);
}
}
void RedoCmd()
{
if (m_undoCommands.size() > 0) {
UndoCommand* pCommand = dynamic_cast<UndoCommand*>(m_undoCommands.top());
m_undoCommands.pop();
pCommand->Redo();
m_exeCommands.push(pCommand);
}
}
private:
CommandStack m_exeCommands;
CommandStack m_undoCommands;
};
void TestCommandUndoRedo()
{
CommandManager manager;
Receiver receiver;
// cout << r;
manager.ExecuteCmd(new ConcreteCommand(&receiver, "Zhongguo"));
manager.ExecuteCmd(new ConcreteCommand(&receiver, " "));
manager.ExecuteCmd(new ConcreteCommand(&receiver, "American"));
manager.ExecuteCmd(new ConcreteCommand(&receiver, " "));
manager.ExecuteCmd(new ConcreteCommand(&receiver, "Australia"));
cout << receiver;
manager.UndoCmd();
cout << receiver;
manager.UndoCmd();
cout << receiver;
}
// Receiver
class Receiver
{
public:
string GetContent() const { return m_content; }
void SetContent(const string& content) { m_content = content; }
void Append(const string& strAppend) { m_content.append(strAppend); }
// void Show() const { printf("content is {%s}\n", m_content.c_str()); }
private:
string m_content;
};
ostream& operator<< (ostream& os, const Receiver& rhs)
{
os << "the current is: " << rhs.GetContent() << endl;
return os;
}
// void TestRecevier()
// {
// Receiver r;
// r.SetContent("abc");
// r.Show();
// cout << r;
// }
class Command
{
public:
Command(Receiver* pReceiver, string strAppend)
: m_pReceiver(pReceiver)
, m_append(strAppend)
{
}
virtual ~Command() {}
virtual void Execute() = 0;
protected:
Receiver* m_pReceiver;
string m_append;
};
class UndoCommand : public Command
{
public:
UndoCommand(Receiver* pReceiver, string strAppend)
: Command(pReceiver, strAppend)
{
}
virtual void Undo() = 0;
virtual void Redo() = 0;
};
class ConcreteCommand : public UndoCommand
{
public:
ConcreteCommand(Receiver* pReceiver, string strAppend)
: UndoCommand(pReceiver, strAppend)
{
}
virtual void Execute()
{
m_prevContent = m_pReceiver->GetContent();
m_pReceiver->Append(m_append);
m_currContent = m_pReceiver->GetContent();
}
virtual void Undo()
{
m_pReceiver->SetContent(m_prevContent);
}
virtual void Redo()
{
m_pReceiver->SetContent(m_currContent);
}
private:
string m_prevContent;
string m_currContent;
};
class CommandManager
{
typedef std::stack<Command*> CommandStack;
public:
~CommandManager()
{
while (m_exeCommands.size() > 0) {
Command* command = m_exeCommands.top();
m_exeCommands.pop();
delete command;
}
while (m_undoCommands.size() > 0) {
Command* command = m_undoCommands.top();
m_undoCommands.pop();
delete command;
}
}
void ExecuteCmd(Command* pCommand)
{
pCommand->Execute();
}
void UndoCmd()
{
if (m_exeCommands.size() > 0) {
UndoCommand* pCommand = dynamic_cast<UndoCommand*>(m_exeCommands.top());
m_exeCommands.pop();
pCommand->Undo();
m_undoCommands.push(pCommand);
}
}
void RedoCmd()
{
if (m_undoCommands.size() > 0) {
UndoCommand* pCommand = dynamic_cast<UndoCommand*>(m_undoCommands.top());
m_undoCommands.pop();
pCommand->Redo();
m_exeCommands.push(pCommand);
}
}
private:
CommandStack m_exeCommands;
CommandStack m_undoCommands;
};
void TestCommandUndoRedo()
{
CommandManager manager;
Receiver receiver;
// cout << r;
manager.ExecuteCmd(new ConcreteCommand(&receiver, "Zhongguo"));
manager.ExecuteCmd(new ConcreteCommand(&receiver, " "));
manager.ExecuteCmd(new ConcreteCommand(&receiver, "American"));
manager.ExecuteCmd(new ConcreteCommand(&receiver, " "));
manager.ExecuteCmd(new ConcreteCommand(&receiver, "Australia"));
cout << receiver;
manager.UndoCmd();
cout << receiver;
manager.UndoCmd();
cout << receiver;
}