Created
May 9, 2011 21:10
-
-
Save ajpalkovic/963423 to your computer and use it in GitHub Desktop.
Ruco/History
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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