Created
November 14, 2012 00:20
-
-
Save grodtron/4069336 to your computer and use it in GitHub Desktop.
Simple calculator program to demonstrate the command pattern in cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.o | |
*.swp | |
*.swo | |
*.zip | |
test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef COMMAND_H_ | |
#define COMMAND_H_ | |
class Command { | |
public: | |
virtual void doit() = 0; | |
virtual void undo() = 0; | |
virtual ~Command(){} | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Commands.h" | |
AddCommand::AddCommand(int * target, int x) | |
: target(target), x(x) | |
{ | |
} | |
void AddCommand::doit(){ | |
*target += x; | |
} | |
void AddCommand::undo(){ | |
*target -= x; | |
} | |
MultCommand::MultCommand(int * target, int x) | |
: target(target), x(x) | |
{ | |
} | |
void MultCommand::doit(){ | |
*target *= x; | |
} | |
void MultCommand::undo(){ | |
*target /= x; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef COMMANDS_H_ | |
#define COMMANDS_H_ | |
#include "Command.h" | |
class AddCommand : public Command { | |
private: | |
int * target; | |
int x; | |
public: | |
AddCommand(int * target, int x); | |
void doit(); | |
void undo(); | |
}; | |
class MultCommand : public Command { | |
private: | |
int * target; | |
int x; | |
public: | |
MultCommand(int * target, int x); | |
void doit(); | |
void undo(); | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* CommandStack.cpp | |
* | |
* Created on: 05.11.2012 | |
* Author: dsinnig | |
*/ | |
#include "CommandStack.h" | |
#include <iostream> | |
CommandStack::CommandStack (int size) : size(size), currentNumberOfCommands(0) { | |
commands = new Command*[size]; | |
} | |
CommandStack::~CommandStack() { | |
clear(); // delete all of the commands | |
delete [] commands; // delete the array itself | |
} | |
Command* CommandStack::pop() { | |
return (currentNumberOfCommands > 0) ? commands[--currentNumberOfCommands] : NULL; | |
} | |
void CommandStack::push(Command* aCommand) { | |
if (currentNumberOfCommands < size) | |
commands[currentNumberOfCommands++] = aCommand; | |
} | |
bool CommandStack::empty() { | |
return currentNumberOfCommands == 0; | |
} | |
// Clear the entire stack, deleting all the commands that it held | |
void CommandStack::clear(){ | |
// Loop over all of the commands in the stack | |
while(currentNumberOfCommands > 0){ | |
--currentNumberOfCommands; | |
// delete the current command, and set the pointer | |
// to NULL (because it's a good habit to do so) | |
delete commands[currentNumberOfCommands]; | |
commands[currentNumberOfCommands] = NULL; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* CommandStack.h | |
* | |
* Created on: 05.11.2012 | |
* Author: dsinnig | |
*/ | |
#ifndef COMMANDSTACK_H_ | |
#define COMMANDSTACK_H_ | |
#include "Command.h" | |
class CommandStack { | |
public: | |
CommandStack (int size); | |
virtual ~CommandStack(); | |
Command* pop(); | |
void push(Command* aCommand); | |
bool empty(); | |
void clear(); | |
private: | |
int size; | |
int currentNumberOfCommands; | |
Command** commands; | |
}; | |
#endif /* COMMANDSTACK_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Invoker.h" | |
Invoker::Invoker() | |
: undoStack(16), | |
redoStack(16) | |
{ | |
} | |
void Invoker::execute(Command * command){ | |
command->doit(); | |
undoStack.push(command); | |
redoStack.clear(); | |
} | |
void Invoker::undo(){ | |
if(!undoStack.empty()){ | |
Command * command = undoStack.pop(); | |
command->undo(); | |
redoStack.push(command); | |
} | |
} | |
void Invoker::redo(){ | |
if(!redoStack.empty()){ | |
Command * command = redoStack.pop(); | |
command->doit(); | |
undoStack.push(command); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef INVOKER_H_ | |
#define INVOKER_H_ | |
#include "CommandStack.h" | |
#include "Command.h" | |
class Invoker { | |
private: | |
CommandStack undoStack; | |
CommandStack redoStack; | |
public: | |
Invoker(); | |
void execute(Command *); | |
void undo(); | |
void redo(); | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using std::cout; | |
using std::cin; | |
using std::endl; | |
#include "Commands.h" | |
#include "Invoker.h" | |
// This function will ask the user for input in a loop | |
// and execute commands, or redo/undo them based on that | |
// input | |
void commandLoop(){ | |
// The invoker of the commands | |
Invoker invoker; | |
// the receiver of the commands | |
int receiver; | |
// initialize the receiver | |
cout << "Set initial value to: "; | |
cin >> receiver; | |
while(1){ | |
char in; | |
int val; | |
cout << "Enter command [ '+' (add) | '*' (multiply) | 'u' (undo) | 'r' (redo) ]: "; | |
cin >> in; | |
switch (in){ | |
case '+': | |
cout << "Enter value: "; | |
cin >> val; | |
invoker.execute(new AddCommand(&receiver, val)); | |
break; | |
case '*': | |
cout << "Enter value: "; | |
cin >> val; | |
invoker.execute(new MultCommand(&receiver, val)); | |
break; | |
case 'u': | |
invoker.undo(); | |
break; | |
case 'r': | |
invoker.redo(); | |
break; | |
default: | |
// end the loop | |
return; | |
} | |
cout << "== Value is now: " << receiver << endl; | |
} | |
} | |
int main(){ | |
commandLoop(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.PHONY: clean all | |
all: test | |
%.o: %.cpp | |
g++ -ggdb -c $< -o $@ | |
test: $(shell ls -1 *.cpp | sed 's/\.cpp/\.o/') | |
g++ -ggdb $^ -o $@ | |
clean: | |
rm -f *.o | |
rm -f test |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment