aboutsummaryrefslogtreecommitdiff
path: root/kscurses/history_stack.jai
diff options
context:
space:
mode:
Diffstat (limited to 'kscurses/history_stack.jai')
-rw-r--r--kscurses/history_stack.jai69
1 files changed, 69 insertions, 0 deletions
diff --git a/kscurses/history_stack.jai b/kscurses/history_stack.jai
new file mode 100644
index 0000000..3f73df4
--- /dev/null
+++ b/kscurses/history_stack.jai
@@ -0,0 +1,69 @@
+History_Stack :: struct(
+ Action_Type : Type,
+ destructor : (obj : Action_Type) = default_destructor
+){
+ BUF_SIZE :: 100;
+ buffer : [BUF_SIZE]Action_Type;
+ offset, current, saved : int;
+}
+
+deinit :: (using history_stack : *History_Stack) {
+ guard(history);
+
+ for i : 0..saved-1 {
+ j := (i + offset) % BUF_SIZE;
+ destructor(buffer[offset]);
+ }
+ offset, current, saved = 0;
+}
+
+write :: (using history : *History_Stack, action : Edit_Action) {
+ guard(history);
+
+ for i : current..saved-1 {
+ j := (i + offset) % BUF_SIZE;
+ destructor(buffer[j]);
+ }
+
+ i0 := (offset + current) % BUF_SIZE;
+ if current == BUF_SIZE {
+ destructor(buffer[offset]);
+ saved = current;
+ offset = (offset + 1) % BUF_SIZE;
+ } else {
+ current += 1;
+ saved = current;
+ }
+ i1 := (offset + current) % BUF_SIZE;
+ assert(i0 == i1);
+ buffer[i0] = action;
+}
+
+
+undo :: (using history : *History) -> bool, Action_Type {
+ guard(history);
+ action : Action_Type = ---;
+ if current == 0 return false, action;
+ current -= 1;
+ action = buffer[(current + offset) % BUF_SIZE];
+ return true, action;
+}
+redo :: (using history : *History) -> bool, Action_Type {
+ guard(history);
+ action : Action_Type = ---;
+ if current == saved return false, action;
+ action = buffer[(current + offset) % BUF_SIZE];
+ current += 1;
+ return true, action;
+}
+
+#scope_file
+default_destructor :: (obj : $T) { }
+
+guard :: (using history : *History) #expand {
+ check :: (using history : *History) {
+ assert(0 <= current && current <= saved && saved <= BUF_SIZE);
+ assert(0 <= offset && offset <= BUF_SIZE);
+ }
+ check(history); defer check(history);
+} \ No newline at end of file