Class: Philiprehberger::Debounce::Debouncer
- Inherits:
-
Object
- Object
- Philiprehberger::Debounce::Debouncer
- Defined in:
- lib/philiprehberger/debounce/debouncer.rb
Overview
Delays execution until the wait period elapses without new calls.
When #call is invoked, any pending execution is cancelled and the timer restarts. The block only fires once the caller stops calling for the full wait duration.
Instance Method Summary collapse
-
#call(*args) ⇒ void
Invoke the debouncer with optional arguments.
-
#cancel ⇒ void
Cancel any pending execution.
-
#flush ⇒ void
Execute the pending block immediately and cancel the timer.
-
#initialize(wait:, leading: false, trailing: true, &block) ⇒ Debouncer
constructor
A new instance of Debouncer.
-
#pending? ⇒ Boolean
Whether there is a pending execution.
Constructor Details
#initialize(wait:, leading: false, trailing: true, &block) ⇒ Debouncer
Returns a new instance of Debouncer.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/philiprehberger/debounce/debouncer.rb', line 20 def initialize(wait:, leading: false, trailing: true, &block) raise ArgumentError, 'block is required' unless block raise ArgumentError, 'wait must be positive' unless wait.positive? raise ArgumentError, 'at least one of leading or trailing must be true' if !leading && !trailing @wait = wait @leading = leading @trailing = trailing @block = block @mutex = Mutex.new @pending = false @last_args = nil @called_leading = false @generation = 0 end |
Instance Method Details
#call(*args) ⇒ void
This method returns an undefined value.
Invoke the debouncer with optional arguments.
Resets the internal timer. The block will execute after wait seconds of inactivity (trailing edge) or immediately on the first call (leading edge).
43 44 45 46 47 48 49 50 51 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 |
# File 'lib/philiprehberger/debounce/debouncer.rb', line 43 def call(*args) @mutex.synchronize do @last_args = args @pending = true @generation += 1 current_gen = @generation # Leading edge: fire immediately on the first call of a new cycle if @leading && !@called_leading @called_leading = true execute(args) end # Start a new trailing timer if @trailing || @leading Thread.new do sleep @wait @mutex.synchronize do # Only fire if no new calls happened since this timer started if @generation == current_gen && @pending if @trailing args_to_use = @last_args @pending = false @last_args = nil @called_leading = false execute(args_to_use) else @pending = false @called_leading = false end end end end end end end |
#cancel ⇒ void
This method returns an undefined value.
Cancel any pending execution.
84 85 86 87 88 89 90 91 |
# File 'lib/philiprehberger/debounce/debouncer.rb', line 84 def cancel @mutex.synchronize do @generation += 1 @pending = false @last_args = nil @called_leading = false end end |
#flush ⇒ void
This method returns an undefined value.
Execute the pending block immediately and cancel the timer.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/philiprehberger/debounce/debouncer.rb', line 96 def flush args = nil should_execute = false @mutex.synchronize do if @pending args = @last_args should_execute = true @generation += 1 @pending = false @last_args = nil @called_leading = false end end execute(args) if should_execute end |
#pending? ⇒ Boolean
Whether there is a pending execution.
117 118 119 |
# File 'lib/philiprehberger/debounce/debouncer.rb', line 117 def pending? @mutex.synchronize { @pending } end |