Skip to content

Instantly share code, notes, and snippets.

@Anaminus
Created September 15, 2015 11:23
Show Gist options
  • Select an option

  • Save Anaminus/ca57dd4fecea31dc9247 to your computer and use it in GitHub Desktop.

Select an option

Save Anaminus/ca57dd4fecea31dc9247 to your computer and use it in GitHub Desktop.
HistoryStack
package hist
type Value interface{}
// Implements both an undo and redo stack using a circular buffer.
type HistoryStack struct {
buffer []Value
head, tail, cur int
ud, rd bool
}
func CreateHistoryStack(size int) *HistoryStack {
return &HistoryStack{
buffer: make([]Value, size),
}
}
func (s *HistoryStack) inc(v *int) {
*v++
if *v >= len(s.buffer) {
*v = 0
}
}
func (s *HistoryStack) dec(v *int) {
*v--
if *v < 0 {
*v = len(s.buffer) - 1
}
}
func (s *HistoryStack) Do(v Value) {
if s.head == s.tail && s.ud {
s.inc(&s.head)
}
if s.rd {
if s.tail <= s.cur {
for i := s.cur; i < len(s.buffer); i++ {
s.buffer[i] = nil
}
for i := 0; i < s.tail; i++ {
s.buffer[i] = nil
}
} else {
for i := s.cur; i <= s.tail; i++ {
s.buffer[i] = nil
}
}
s.tail = s.cur
s.rd = false
}
s.buffer[s.cur] = v
s.ud = true
s.inc(&s.cur)
s.inc(&s.tail)
}
func (s *HistoryStack) Undo() (v Value) {
if s.ud {
s.dec(&s.cur)
v = s.buffer[s.cur]
if s.cur == s.head {
s.ud = false
}
s.rd = true
}
return
}
func (s *HistoryStack) Redo() (v Value) {
if s.rd {
v = s.buffer[s.cur]
s.inc(&s.cur)
if s.cur == s.tail {
s.rd = false
}
s.ud = true
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment