1 /* 2 Copyright © 2020, Luna Nielsen 3 Distributed under the 2-Clause BSD License, see LICENSE file. 4 5 Authors: Luna Nielsen 6 */ 7 module engine.core.astack; 8 import std.exception; 9 10 /** 11 A stack of actions performed in the game 12 13 Actions can be undone and redone. 14 Pushing a new action to the stack will overwrite actions past the current top cursor. 15 */ 16 class ActionStack(ActionT) { 17 private: 18 ActionT[] stack; 19 size_t top; 20 21 public: 22 23 /** 24 Push an action to the stack 25 26 Returns the resulting top of the stack 27 */ 28 ActionT push(ActionT item) { 29 30 // First remove any elements in the undo/redo chain after our top 31 stack.length = top+1; 32 33 // Move the top up one element 34 top++; 35 36 // Add new item 37 stack ~= item; 38 return stack[$-1]; 39 } 40 41 /** 42 Get the current top of the stack 43 */ 44 ActionT get() { 45 enforce(stack.length > 0, "ActionStack is empty."); 46 return stack[top]; 47 } 48 49 /** 50 Undo an action 51 52 Returns the resulting top of the stack 53 */ 54 ActionT undo() { 55 enforce(stack.length > 0, "ActionStack is empty."); 56 if (top > 0) top--; 57 return stack[top]; 58 } 59 60 /** 61 Redo an action 62 63 Returns the resulting top of the stack 64 */ 65 ActionT redo() { 66 enforce(stack.length > 0, "ActionStack is empty."); 67 if (top < stack.length) top++; 68 return stack[top]; 69 } 70 71 /** 72 Clear the action stack 73 */ 74 void clear() { 75 top = 0; 76 stack.length = 0; 77 } 78 79 /** 80 Gets whether the action stack is empty. 81 */ 82 bool empty() { 83 return stack.length == 0; 84 } 85 86 /** 87 Returns true if there's any actions left to undo 88 */ 89 bool canUndo() { 90 return top > 0; 91 } 92 93 /** 94 Returns true if there's any actions left to redo 95 */ 96 bool canRedo() { 97 return top < stack.length; 98 } 99 }