Module: Debouncer::Debounceable

Defined in:
lib/debouncer/debounceable.rb

Instance Method Summary collapse

Instance Method Details

#debounce(name, delay, rescue_with: nil, group_by: :object_id, reduce_with: nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/debouncer/debounceable.rb', line 5

def debounce(name, delay, rescue_with: nil, group_by: :object_id, reduce_with: nil)
  name =~ /^(\w+)([?!=]?)$/ or
      raise ArgumentError, 'Invalid method name'

  base_name = $1
  suffix    = $2
  immediate = "#{base_name}_immediately#{suffix}"

  debouncer_for_method name, delay do |d|
    d.rescuer do |ex|
      case rescue_with
        when Symbol
          __send__ rescue_with, ex
        when Proc
          rescue_with[ex]
        else
          # Silent failure
      end
    end if rescue_with

    d.reducer do |old, args, id|
      case reduce_with
        when Symbol
          debouncing_instance(name, id).__send__ reduce_with, old, args
        when Proc
          reduce_with[old, args, id]
        else
          raise ArgumentError
      end
    end if reduce_with
  end

  class_eval <<-RUBY, __FILE__, __LINE__ + 1
    alias_method :#{immediate}, :#{name}

    def #{name}(*args)
      id = #{group_by}
      #{self.name}.debouncing_instance :#{name}, id, self
      #{self.name}.debouncer_for_method(:#{name}).debounce(id, *args) { |*args| #{immediate} *args }
    end

    def flush_#{name}
      #{self.name}.debouncer_for_method(:#{name}).flush #{group_by}
    end

    def self.join_#{name}
      debouncer_for_method(:#{name}).join
    end

    def self.cancel_#{name}
      debouncer_for_method(:#{name}).kill
    end
  RUBY
end

#debouncer_for_method(name, delay = 0, &block) ⇒ Object



60
61
62
63
# File 'lib/debouncer/debounceable.rb', line 60

def debouncer_for_method(name, delay = 0, &block)
  @method_debouncers       ||= {}
  @method_debouncers[name] ||= Debouncer.new(delay, &block)
end

#debouncing_instance(method, id, instance = nil) ⇒ Object



65
66
67
68
69
70
71
72
# File 'lib/debouncer/debounceable.rb', line 65

def debouncing_instance(method, id, instance = nil)
  hash = (@debouncing_instances ||= {})[method] ||= {}
  if instance
    hash[id] = instance
  else
    hash[id]
  end
end