Hi there,
I'm interested in people's thoughts on this approach to implementing undoable / redoable commands within a PureMVC application:
1. create an IUndoableCommand interface in controller namespace with methods undo() and redo()
2. create a CommandHistoryProxy as below
public class CommandHistoryProxy extends Proxy implements IProxy {
private var _commands:Array;
private var _index:uint;
public static const NAME:String = 'CommandHistoryProxy';
public function CommandHistoryProxy() {
super(NAME);
init();
}
private function init():void {
_commands = new Array();
_index = 0;
}
public function putCommand(command : IUndoableCommand) : void {
_commands[_index++] = command;
_commands.splice(_index, _commands.length - _index);
}
public function previous():IUndoableCommand {
return _commands[--_index];
}
public function next():IUndoableCommand {
return _commands[_index++];
}
public function hasPreviousCommands():Boolean {
return _index > 0;
}
public function hasNextCommands():Boolean {
return _index < _commands.length;
}
}
}
3. create a concrete ItemSelectedCommand command which implements IUndoableCommand. Its execute method does something like this:
undo_item = INode(note.getBody());
var command_history_proxy : CommandHistoryProxy = facade.retrieveProxy(CommandHistoryProxy.NAME) as CommandHistoryProxy;
command_history_proxy.putCommand(this);
Its undo and redo methods change state and send appropriate notifications
4. A ComandHistoryMediator which listens for ApplicationFacade.ITEM_SELECTED notifications (to toggle visibility of undo / redo buttons), and contains a CommandHistory view component which:
- contains undo and redo buttons
- has public methods to set the visibility of each
- dispatches CommandHistory.UNDO and CommandHistory.REDO methods
The CommandHistoryMediator defines onUndo and onRedo methods which simply retrieve the appropriate command
var command:IUndoableCommand = command_history_proxy.previous()
and then calls command.undo / command.redo
I was also wondering what the best approach for implementing multiple arrays of command histories would be? Is the type parameter of the sendNotification method an appropriate place to specify the type of the command history to store? For instance, if CommandHistoryProxy was reworked to store arrays of command histories as a hash, using the sendNotification's state method I might do something like sendNotification(ApplicationFacade.ITEM_SELECTED, item, ApplicationFacade.APPROPRIATE_STATE), so the execute method of ItemSelectedCommand might do
command_history_proxy.putCommand(this, ApplicationFacade.APPROPRIATE_STATE
I'm also wondering whether it makes sense to subclass Notification to implement getUndoBody() and getRedoBody() depending on the command history requirements. Is that a sensible case for subclassing?
cheers,
justsee