Last active
July 3, 2016 22:37
-
-
Save mattmccray/3ce55fb4f0a68dce57f626786f8daf6d to your computer and use it in GitHub Desktop.
“You get undo for free!” and Other Lies… Snippets
This file contains hidden or 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
| /** | |
| * A simple command example that updates a todo's name. | |
| * | |
| * @param todoId {number} | |
| * @param newName {string} | |
| * @param context {MadeUpBackendAPI} | |
| */ | |
| function UpdateTodoName(todoId, newName, context) { | |
| // Get current name so we can revert back to it, if needed: | |
| const prevName = context.getObjectOfTye('todo', todoId).name | |
| return { | |
| execute() { | |
| context.updateObjectOfType('todo', todoId, { name:newName }) | |
| }, | |
| revert() { | |
| context.updateObjectOfType('todo', todoId, { name:prevName }) | |
| } | |
| } | |
| } |
This file contains hidden or 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
| /** | |
| * A little more complex command example that creates a todo, but also | |
| * tries to reuse the same todoId on any 'redo' calls. | |
| * | |
| * @param todoData {*} | |
| * @param context {MadeUpBackendAPI} | |
| */ | |
| function CreateTodo(todoData, context) { | |
| let todoId; | |
| return { | |
| execute() { | |
| if (!todoId) { | |
| // When first executed, save the ID. | |
| todoId = context.createObjectOfType('todo', todoData) | |
| } | |
| else { | |
| // When run as a 'redo', re-use the same ID so any future commands | |
| // on the redo stack will still work. | |
| context.createObjectOfTypeWithId('todo', todoId, todoData) | |
| } | |
| }, | |
| revert() { | |
| context.removeObjectOfType('todo', todoId) | |
| } | |
| } | |
| } | |
| /** | |
| * Potential example usage: | |
| * app.runCommand(CreateTodo, { name:'test', isComplete:false }) | |
| */ |
This file contains hidden or 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
| class CommandManager { | |
| undoStack = [] | |
| redoState = [] | |
| run(command) { | |
| command.execute() | |
| this.undoStack.push(command) | |
| this.redoStack.length = 0 | |
| } | |
| undo() { | |
| if (this.undoStack.length) { | |
| const command = this.undoStack.pop() | |
| command.revert() | |
| this.redoStack.push(command) | |
| } | |
| } | |
| redo() { | |
| if (this.redoStack.length) { | |
| const command = this.redoStack.pop() | |
| command.execute() | |
| this.undoStack.push(command) | |
| } | |
| } | |
| } |
This file contains hidden or 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
| class Application { | |
| commands = new CommandManager() | |
| backend = new MadeUpBackendAPI() | |
| runCommand(command, ...params) { | |
| params.push(this.backend) | |
| this.commands.run(command.apply(null, params)) | |
| } | |
| get canUndo() { | |
| return this.commands.undoStack.length > 0 | |
| } | |
| get canRedo() { | |
| return this.commands.redoStack.length > 0 | |
| } | |
| undo() { | |
| this.commands.undo() | |
| } | |
| redo() { | |
| this.commands.redo() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment