Class: OpenHAB::DSL::Debouncer
- Inherits:
-
Object
- Object
- OpenHAB::DSL::Debouncer
- Defined in:
- lib/openhab/dsl/debouncer.rb
Overview
Provides the feature for debouncing calls to a given block.
The debouncer can filter events and only allow the events on the leading or trailing edge of the given interval. Its behavior can be customized through settings passed to its constructor.
The following timing diagram illustrates the incoming triggers and the actual executions using various options.
“‘ruby
1 1 2 2 3 3 4 4
0 5 0 5 0 5 0 5 0 5
Triggers : ‘X.X…X…X..XX.X.X.…..XXXXXXXXXXX.…X.….’ leading: false for:5 : ‘|.…X|.…X |.…X |.…X|.…X |.…X’ leading: true for:5 : ‘X.….X.…..X.…X.…..X.…X.…X.…X.….’
more options, leading: false Triggers : ‘X.X…X…X..XX.X.X.…..XXXXXXXXXXX.…X.….’ for:5 idle:3 : ‘|.…X|.…..X|.…..X…|.….….…X.|.…X’ for:5 idle:5 : ‘|.….….….….…..X.|.….….…..X.….’ for:5..5 idle:X : ‘|.…X|.…X.|.…X.…..|.…X|.…X…|.…X’ for:5..6 idle:5 : ‘|.….X…|.….X.|.…X.|.….X|.….X.|.…X’ for:5..7 idle:5 : ‘|.…..X..|.…..X|.…X.|.…..X|.…..X.….’ for:5..8 idle:5 : ‘|.……X.|.……X.…..|.……X|.….X.….’ for:5..8 idle:3 : ‘|.…X|.…..X|.…..X…|.……X|.…X|.…X’ for:5..8 idle:2 : ‘|.…X|.….X|.…..X.…|.……X|.…X|.…X’ “‘
Notes:
-
‘|` indicates the start of the debounce period
-
With ‘for: 5..5` (a range with begin=end), the `idle_time` argument is irrelevant and be unset/set to any value as it will not alter the debouncer’s behavior.
-
Without an ‘idle_time`, the range end in `for: X..Y` is irrelevant. It is equivalent to `for: X` without the end of the range.
Instance Attribute Summary collapse
-
#idle_time ⇒ Duration?
readonly
The minimum idle time to stop debouncing.
-
#interval ⇒ Range?
readonly
The range of accepted debounce period, or nil if debouncing is disabled.
Instance Method Summary collapse
-
#call { ... } ⇒ void
Debounces calls to the given block.
-
#call! ⇒ Object
Executes the latest block passed to the #debounce call regardless of any debounce settings.
-
#flush ⇒ Boolean
Immediately executes any outstanding event of a trailing edge debounce.
-
#initialize(for:, leading: false, idle_time: nil) ⇒ void
constructor
Constructor to create a debouncer object.
-
#leading? ⇒ true, false
Returns true to indicate that this is a leading edge debouncer.
-
#reset ⇒ Boolean
Resets the debounce period and cancels any outstanding block executions of a trailing edge debouncer.
Constructor Details
#initialize(for:, leading: false, idle_time: nil) ⇒ void
Constructor to create a debouncer object.
The constructor sets the options and behaviour of the debouncer when the #call method is called.
Terminology:
-
‘calls` are invocations of the #call method, i.e. the events that need to be throttled / debounced.
-
‘executions` are the actual code executions of the given block. Executions usually occur less frequently than the call to the debounce method.
84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/openhab/dsl/debouncer.rb', line 84 def initialize(for:, leading: false, idle_time: nil) @interval = binding.local_variable_get(:for) return unless @interval @interval = (@interval..) unless @interval.is_a?(Range) @leading = leading @idle_time = idle_time @mutex = Mutex.new @block = nil @timer = nil reset end |
Instance Attribute Details
#idle_time ⇒ Duration? (readonly)
Returns The minimum idle time to stop debouncing.
48 49 50 |
# File 'lib/openhab/dsl/debouncer.rb', line 48 def idle_time @idle_time end |
#interval ⇒ Range? (readonly)
Returns The range of accepted debounce period, or nil if debouncing is disabled.
45 46 47 |
# File 'lib/openhab/dsl/debouncer.rb', line 45 def interval @interval end |
Instance Method Details
#call { ... } ⇒ void
This method returns an undefined value.
Debounces calls to the given block.
This method is meant to be called repeatedly with the same given block. However, if no block is given, it will call and debounce the previously given block
124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/openhab/dsl/debouncer.rb', line 124 def call(&block) @block = block if block raise ArgumentError, "No block has been provided" unless @block return call! unless @interval # passthrough mode, no debouncing when @interval is nil now = ZonedDateTime.now if leading? leading_edge_debounce(now) else trailing_edge_debounce(now) end @mutex.synchronize { @last_timestamp = now } end |
#call! ⇒ Object
Executes the latest block passed to the OpenHAB::DSL#debounce call regardless of any debounce settings.
144 145 146 |
# File 'lib/openhab/dsl/debouncer.rb', line 144 def call! @block.call end |
#flush ⇒ Boolean
Immediately executes any outstanding event of a trailing edge debounce. The next call will start a new period.
It has no effect on a leading edge debouncer - use #reset instead.
173 174 175 176 177 178 179 180 |
# File 'lib/openhab/dsl/debouncer.rb', line 173 def flush @mutex.synchronize do if @timer&.cancel call! true end end end |
#leading? ⇒ true, false
Returns true to indicate that this is a leading edge debouncer.
187 188 189 |
# File 'lib/openhab/dsl/debouncer.rb', line 187 def leading? @leading end |
#reset ⇒ Boolean
Resets the debounce period and cancels any outstanding block executions of a trailing edge debouncer.
-
A leading edge debouncer will execute its block on the next call and start a new debounce period.
-
A trailing edge debouncer will reset its debounce timer and the next call will become the start of a new debounce period.
157 158 159 160 161 162 |
# File 'lib/openhab/dsl/debouncer.rb', line 157 def reset @mutex.synchronize do @last_timestamp = @leading_timestamp = @interval.begin.ago - 1.second if leading? @timer&.cancel end end |