add on method for registering blocks

examples updated
This commit is contained in:
onyx-and-iris 2023-08-18 00:27:43 +01:00
parent 3ea6db1703
commit fe1de43250
6 changed files with 45 additions and 56 deletions

View File

@ -656,22 +656,20 @@ Voicemeeter::Remote.new(:banana, ratelimit: 0.05, ldirty: true).run do
... ...
``` ```
#### `vm.register`|`vm.deregister` #### `vm.on`
Use the register/deregister methods to register/deregister callbacks and event observers. Use the `on` method to register blocks on the vm object to be called back later.
example: example:
```ruby ```ruby
# register a callback to receive updates # register a block with the on method
class App(): class App():
def initialize(vm) def initialize(vm)
@vm = vm @vm = vm
@vm.register(method(:on_pdirty)) @vm.on :pdirty do
...
def on_pdirty
... ...
end
``` ```
#### `vm.event` #### `vm.event`

View File

@ -3,36 +3,33 @@ require_relative "../../lib/voicemeeter"
class Main class Main
def initialize(vm) def initialize(vm)
@vm = vm @vm = vm
@vm.register([method(:on_pdirty), method(:on_mdirty), method(:on_midi), method(:on_ldirty)]) @vm.on :pdirty do
puts "pdirty"
end
@vm.on :mdirty do
puts "mdirty"
end
@vm.on :midi do
current = @vm.midi.current
puts "Value of midi input #{current}: #{@vm.midi.get(current)}"
end
@vm.on :ldirty do
@vm.bus.each do |bus|
puts "#{bus} #{bus.levels.all.join(" ")}" if bus.levels.isdirty?
end
end
end end
def run def run
puts "press <Enter> to quit" puts "press <Enter> to quit"
loop { break if gets.chomp.empty? } loop { break if gets.chomp.empty? }
end end
def on_pdirty
puts "pdirty"
end
def on_mdirty
puts "mdirty"
end
def on_midi
current = @vm.midi.current
puts "Value of midi input #{current}: #{@vm.midi.get(current)}"
end
def on_ldirty
@vm.bus.each do |bus|
puts "#{bus} #{bus.levels.all.join(" ")}" if bus.levels.isdirty?
end
end
end end
if $PROGRAM_NAME == __FILE__ if $PROGRAM_NAME == __FILE__
Voicemeeter::Remote.new(:potato, pdirty: true, mdirty: true, midi: true, ldirty: true).run do |vm| Voicemeeter::Remote
.new(:potato, pdirty: true, mdirty: true, midi: true, ldirty: true)
.run do |vm|
Main.new(vm).run Main.new(vm).run
end end
end end

View File

@ -5,7 +5,10 @@ class Main
def initialize(vm) def initialize(vm)
@vm = vm @vm = vm
@vm.register(self) @vm.on :midi do
current = @vm.midi.current
handler(current, @vm.midi.get(current))
end
end end
def run def run
@ -13,14 +16,7 @@ class Main
loop { break if gets.chomp.empty? } loop { break if gets.chomp.empty? }
end end
def on_update(event) def handler(i, val)
if event == :midi
current = @vm.midi.current
midi_handler(current, @vm.midi.get(current))
end
end
def midi_handler(i, val)
if i.between?(0, 7) if i.between?(0, 7)
@vm.strip[i].gainlayer[GAINLAYER].gain = (val * 72 / 127) - 60 @vm.strip[i].gainlayer[GAINLAYER].gain = (val * 72 / 127) - 60
end end

View File

@ -3,7 +3,7 @@ module Voicemeeter
# Base class for Remote types # Base class for Remote types
include Logging include Logging
include Worker include Worker
include Events::Callback include Events::Director
prepend Util::Cache prepend Util::Cache
attr_reader :kind, :midi, :event, :delay, :cache attr_reader :kind, :midi, :event, :delay, :cache

View File

@ -1,28 +1,26 @@
module Voicemeeter module Voicemeeter
module Events module Events
module Callback module Director
def callbacks def observers
@callbacks ||= [] @observers ||= {}
end
def on(event, method = nil, &block)
(observers[event] ||= []) << (block || method)
end end
def register(cbs) def register(cbs)
cbs = [cbs] unless cbs.respond_to? :each cbs = [cbs] unless cbs.respond_to? :each
cbs.each { |cb| callbacks << cb unless callbacks.include? cb } cbs.each { |cb| on(cb.name[3..].to_sym, cb) }
end end
def deregister(cbs) def deregister(cbs)
cbs = [cbs] unless cbs.respond_to? :each cbs = [cbs] unless cbs.respond_to? :each
callbacks.reject! { |cb| cbs.include? cb } cbs.each { |cb| observers[cb.name[3..].to_sym]&.reject! { |o| cbs.include? o } }
end end
private def trigger(event) def fire(event)
callbacks.each do |callback| observers[event]&.each { |block| block.call }
if callback.is_a? Method
callback.call if callback.name == "on_#{event}".to_sym
elsif callback.respond_to? :on_update
callback.on_update event
end
end
end end
end end

View File

@ -30,15 +30,15 @@ module Voicemeeter
Thread.new do Thread.new do
Thread.current.name = "worker" Thread.current.name = "worker"
while (event = que.pop) while (event = que.pop)
trigger :pdirty if event == :pdirty && pdirty? fire :pdirty if event == :pdirty && pdirty?
trigger :mdirty if event == :mdirty && mdirty? fire :mdirty if event == :mdirty && mdirty?
trigger :midi if event == :midi && get_midi_message fire :midi if event == :midi && get_midi_message
if event == :ldirty && ldirty? if event == :ldirty && ldirty?
cache[:strip_comp] = cache[:strip_level].zip(cache[:strip_buf]).map { |a, b| a != b } cache[:strip_comp] = cache[:strip_level].zip(cache[:strip_buf]).map { |a, b| a != b }
cache[:bus_comp] = cache[:bus_level].zip(cache[:bus_buf]).map { |a, b| a != b } cache[:bus_comp] = cache[:bus_level].zip(cache[:bus_buf]).map { |a, b| a != b }
cache[:strip_level] = cache[:strip_buf] cache[:strip_level] = cache[:strip_buf]
cache[:bus_level] = cache[:bus_buf] cache[:bus_level] = cache[:bus_buf]
trigger :ldirty fire :ldirty
end end
end end
logger.debug "closing #{Thread.current.name} thread" logger.debug "closing #{Thread.current.name} thread"