1 module pixelperfectengine.concrete.eventchainsystem; 2 3 import collections.linkedlist; 4 /** 5 * Defines an undoable event. 6 */ 7 public interface UndoableEvent{ 8 public void redo(); ///called both when a redo command is initialized or the event is added to the stack. 9 public void undo(); ///called when an undo command is initialized on the stack. 10 } 11 12 /** 13 * Implements an undoable event list with automatic handling of undo/redo commands 14 */ 15 public class UndoableStack{ 16 alias EventStack = LinkedList!(UndoableEvent); 17 protected EventStack events; 18 protected size_t currentPos, currentCap, maxLength; 19 20 public this(size_t maxElements) @safe pure nothrow{ 21 maxLength = maxElements; 22 //events.length = maxElements; 23 } 24 /** 25 * Adds an event to the top of the stack. If there are any undone events, they'll be lost. Bottom event is always lost. 26 */ 27 public void addToTop(UndoableEvent e){ 28 while(currentPos) { 29 events.remove(0); 30 currentPos--; 31 } 32 events.insertAt(e, 0); 33 e.redo; 34 while(events.length > maxLength) events.remove(maxLength); 35 } 36 /** 37 * Undos top event. 38 */ 39 public void undo(){ 40 if(currentPos < events.length){ 41 events[currentPos].undo; 42 currentPos++; 43 } 44 } 45 /** 46 * Redos top event. 47 */ 48 public void redo() { 49 if(currentPos >= 0){ 50 currentPos--; 51 events[currentPos].redo; 52 } 53 } 54 /** 55 * Returns the length of the current stack 56 */ 57 public size_t length() { 58 return events.length; 59 } 60 }