Class: Debouncer
- Inherits:
-
Object
show all
- Includes:
- Inspection
- Defined in:
- lib/debouncer.rb,
lib/debouncer/group.rb,
lib/debouncer/version.rb,
lib/debouncer/debounceable.rb
Defined Under Namespace
Modules: Debounceable
Classes: Group
Constant Summary
collapse
- DEFAULT_GROUP =
Object.new
- EMPTY =
Object.new
- VERSION =
'0.2.2'
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Inspection
#inspect
Constructor Details
#initialize(delay, &block) ⇒ Debouncer
Returns a new instance of Debouncer.
14
15
16
17
18
19
20
21
22
|
# File 'lib/debouncer.rb', line 14
def initialize(delay, &block)
self.delay = delay
raise ArgumentError, 'Expected a block' unless block
@timeouts = {}
@threads = []
@rescuers = {}
@block = block
@lock = Mutex.new
end
|
Instance Attribute Details
#delay ⇒ Object
Returns the value of attribute delay.
12
13
14
|
# File 'lib/debouncer.rb', line 12
def delay
@delay
end
|
Instance Method Details
#arity ⇒ Object
29
30
31
|
# File 'lib/debouncer.rb', line 29
def arity
@block.arity
end
|
#call(*args, &block) ⇒ Object
Also known as:
[]
47
48
49
|
# File 'lib/debouncer.rb', line 47
def call(*args, &block)
call_with_id DEFAULT_GROUP, *args, &block
end
|
#call_with_id(id, *args, &block) ⇒ Object
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
# File 'lib/debouncer.rb', line 52
def call_with_id(id, *args, &block)
args << block if block
run_thread = nil
exclusively do
thread = @timeouts[id] ||= new_thread { begin_delay id, args }
@flush = [id]
old_args = thread[:args]
thread[:args] =
if @reducer
initial, reducer = @reducer
old_args ||= initial || []
if reducer.is_a? Symbol
old_args.__send__ reducer, args
elsif reducer.respond_to? :call
reducer.call old_args, args, id
end
else
args.empty? ? old_args : args
end
if @flush.is_a? Array
thread[:run_at] = Time.now + @delay
else
thread.kill
@timeouts.delete id
@threads.delete thread
run_thread = new_thread { run_block thread }
run_thread = nil unless @flush
@flush = false
end
end
run_thread.join if run_thread
self
end
|
#flush(id = EMPTY, and_join: false) ⇒ Object
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/debouncer.rb', line 86
def flush(id = EMPTY, and_join: false)
if @lock.owned?
raise ArgumentError, 'You cannot flush other groups from inside a reducer' unless id == EMPTY || [id] == @flush
@flush = and_join
elsif id == EMPTY
flush @timeouts.keys.first while @timeouts.any?
else
thread = exclusively do
if (old_thread = @timeouts.delete(id))
old_thread.kill
@threads.delete old_thread
new_thread { run_block old_thread }
end
end
thread.join if thread
end
self
end
|
#flush!(*args) ⇒ Object
105
106
107
|
# File 'lib/debouncer.rb', line 105
def flush!(*args)
flush *args, and_join: true
end
|
#group(id) ⇒ Object
43
44
45
|
# File 'lib/debouncer.rb', line 43
def group(id)
Group.new self, id
end
|
#inspect_params ⇒ Object
128
129
130
|
# File 'lib/debouncer.rb', line 128
def inspect_params
{delay: @delay, timeouts: @timeouts.count, threads: @threads.count}
end
|
#join(id = EMPTY, kill_first: false) ⇒ Object
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/debouncer.rb', line 109
def join(id = EMPTY, kill_first: false)
if id == EMPTY
while (thread = exclusively { @threads.find &:alive? })
thread.kill if kill_first
thread.join
end
exclusively { [@threads, @timeouts].each &:clear } if kill_first
elsif (thread = exclusively { @timeouts.delete id })
@threads.delete thread
thread.kill if kill_first
thread.join
end
self
end
|
#kill(id = EMPTY) ⇒ Object
124
125
126
|
# File 'lib/debouncer.rb', line 124
def kill(id = EMPTY)
join id, kill_first: true
end
|
#reducer(*initial, &block) ⇒ Object
33
34
35
36
|
# File 'lib/debouncer.rb', line 33
def reducer(*initial, &block)
@reducer = [initial, block || initial.pop]
self
end
|
#rescuer(kind = StandardError, &block) ⇒ Object
38
39
40
41
|
# File 'lib/debouncer.rb', line 38
def rescuer(kind = StandardError, &block)
@rescuers[kind] = block
self
end
|
#runs_at(id = DEFAULT_GROUP) ⇒ Object
140
141
142
143
|
# File 'lib/debouncer.rb', line 140
def runs_at(id = DEFAULT_GROUP)
thread = @timeouts[id]
thread && thread[:run_at]
end
|
#sleeping? ⇒ Boolean
136
137
138
|
# File 'lib/debouncer.rb', line 136
def sleeping?
@timeouts.length.nonzero?
end
|
#to_proc ⇒ Object
132
133
134
|
# File 'lib/debouncer.rb', line 132
def to_proc
method(:call).to_proc
end
|