Skip to content

Instantly share code, notes, and snippets.

@ajpalkovic
Created May 9, 2011 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajpalkovic/963423 to your computer and use it in GitHub Desktop.
Save ajpalkovic/963423 to your computer and use it in GitHub Desktop.
Ruco/History
module Ruco
class History
attr_accessor :timeout
def initialize(options)
@options = options
@stack = [@options.delete(:state)]
@timeout = options.delete(:timeout) || 0
clear_timeout
@position = 0
end
def state
@stack[@position]
end
def add(state)
return unless tracked_field_changes?(state)
remove_undone_states
if merge_timeout?
@position += 1
timeout!
end
@stack[@position] = state
limit_stack
end
def undo
clear_timeout
@position = [@position - 1, 0].max
end
def redo
clear_timeout
@position = [@position + 1, @stack.size - 1].min
end
private
def clear_timeout
@last_merge = 0
end
def remove_undone_states
@stack.slice!(@position + 1, 9999999)
end
def tracked_field_changes?(data)
@options[:track].any? do |field|
state[field] != data[field]
end
end
def limit_stack
to_remove = @stack.size - @options[:entries]
return if to_remove < 1
@stack.slice!(0, to_remove)
@position -= to_remove
end
def timeout!
@last_merge = Time.now.to_f
end
def merge_timeout?
(Time.now.to_f - @last_merge) >= @timeout # if timeout is 0, then it should always create a new state
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment