Mercurial > hg > ugly-duckling
comparison src/app/Session.ts @ 462:2624bb55dbf6
Fix ordering of adding to history (after an action). Add functions for stepping through the history.
author | Lucas Thompson <dev@lucas.im> |
---|---|
date | Fri, 30 Jun 2017 13:59:21 +0100 |
parents | ccce2c09502e |
children | caef9a302bec |
comparison
equal
deleted
inserted
replaced
461:34db9d45663f | 462:2624bb55dbf6 |
---|---|
62 }; | 62 }; |
63 | 63 |
64 export class PersistentStack<T> { | 64 export class PersistentStack<T> { |
65 private stack: T[]; | 65 private stack: T[]; |
66 private history: T[][]; | 66 private history: T[][]; |
67 private historyOffset: number; | |
67 | 68 |
68 constructor() { | 69 constructor() { |
69 this.stack = []; | 70 this.stack = []; |
70 this.history = []; | 71 this.history = [[]]; |
72 this.historyOffset = 0; | |
71 } | 73 } |
72 | 74 |
73 shift(): T { | 75 shift(): T { |
74 this.history.push([...this.stack]); | |
75 const item = this.stack[0]; | 76 const item = this.stack[0]; |
76 this.stack = this.stack.slice(1); | 77 this.stack = this.stack.slice(1); |
78 this.history.push([...this.stack]); | |
77 return item; | 79 return item; |
78 } | 80 } |
79 | 81 |
80 unshift(item: T): number { | 82 unshift(item: T): number { |
83 this.stack = [item, ...this.stack]; | |
81 this.history.push([...this.stack]); | 84 this.history.push([...this.stack]); |
82 this.stack = [item, ...this.stack]; | |
83 return this.stack.length; | 85 return this.stack.length; |
84 } | 86 } |
85 | 87 |
86 findIndex(predicate: (value: T, | 88 findIndex(predicate: (value: T, |
87 index: number, | 89 index: number, |
96 get(index: number): T { | 98 get(index: number): T { |
97 return this.stack[index]; | 99 return this.stack[index]; |
98 } | 100 } |
99 | 101 |
100 set(index: number, value: T) { | 102 set(index: number, value: T) { |
101 this.history.push([...this.stack]); | |
102 this.stack = [ | 103 this.stack = [ |
103 ...this.stack.slice(0, index), | 104 ...this.stack.slice(0, index), |
104 value, | 105 value, |
105 ...this.stack.slice(index + 1) | 106 ...this.stack.slice(index + 1) |
106 ]; | 107 ]; |
108 this.history.push([...this.stack]); | |
107 } | 109 } |
108 | 110 |
109 map<U>(transform: (value: T, index: number, array: T[]) => U): U[] { | 111 map<U>(transform: (value: T, index: number, array: T[]) => U): U[] { |
110 return this.stack.map(transform); | 112 return this.stack.map(transform); |
111 } | 113 } |
117 initialValue: U): U { | 119 initialValue: U): U { |
118 return this.stack.reduce(reducer, initialValue); | 120 return this.stack.reduce(reducer, initialValue); |
119 } | 121 } |
120 | 122 |
121 remove(...indices: number[]) { | 123 remove(...indices: number[]) { |
122 this.history.push([...this.stack]); | |
123 this.stack = this.stack.reduce((acc, item, i) => { | 124 this.stack = this.stack.reduce((acc, item, i) => { |
124 if (!indices.includes(i)) { | 125 if (!indices.includes(i)) { |
125 acc.push(item); | 126 acc.push(item); |
126 } | 127 } |
127 return acc; | 128 return acc; |
128 }, [] as T[]); | 129 }, [] as T[]); |
130 this.history.push([...this.stack]); | |
131 } | |
132 | |
133 stepBack(): void { | |
134 const latest = this.history.length - 1; | |
135 if (++this.historyOffset <= latest) { | |
136 this.stack = this.history[latest - this.historyOffset]; | |
137 } else { | |
138 this.historyOffset = latest; | |
139 } | |
140 } | |
141 | |
142 stepForward(): void { | |
143 const latest = this.history.length - 1; | |
144 if (--this.historyOffset >= 0) { | |
145 this.stack = this.history[latest - this.historyOffset]; | |
146 } else { | |
147 this.historyOffset = 0; | |
148 } | |
129 } | 149 } |
130 | 150 |
131 toIterable(): Iterable<T> { | 151 toIterable(): Iterable<T> { |
132 return this.stack; | 152 return this.stack; |
133 } | 153 } |