diff --git a/README.md b/README.md index 143cff4..cb916cd 100644 --- a/README.md +++ b/README.md @@ -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: ```ruby -# register a callback to receive updates +# register a block with the on method class App(): def initialize(vm) @vm = vm - @vm.register(method(:on_pdirty)) - ... - - def on_pdirty - ... + @vm.on :pdirty do + ... + end ``` #### `vm.event` diff --git a/examples/events/main.rb b/examples/events/main.rb index fb7882a..0d8f931 100644 --- a/examples/events/main.rb +++ b/examples/events/main.rb @@ -3,36 +3,33 @@ require_relative "../../lib/voicemeeter" class Main def initialize(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 def run puts "press to quit" loop { break if gets.chomp.empty? } 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 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 end end diff --git a/examples/midi/main.rb b/examples/midi/main.rb index 70fa4ac..421481b 100644 --- a/examples/midi/main.rb +++ b/examples/midi/main.rb @@ -5,7 +5,10 @@ class Main def initialize(vm) @vm = vm - @vm.register(self) + @vm.on :midi do + current = @vm.midi.current + handler(current, @vm.midi.get(current)) + end end def run @@ -13,14 +16,7 @@ class Main loop { break if gets.chomp.empty? } end - def on_update(event) - if event == :midi - current = @vm.midi.current - midi_handler(current, @vm.midi.get(current)) - end - end - - def midi_handler(i, val) + def handler(i, val) if i.between?(0, 7) @vm.strip[i].gainlayer[GAINLAYER].gain = (val * 72 / 127) - 60 end diff --git a/lib/voicemeeter/base.rb b/lib/voicemeeter/base.rb index fb6c434..c6de5c3 100644 --- a/lib/voicemeeter/base.rb +++ b/lib/voicemeeter/base.rb @@ -3,7 +3,7 @@ module Voicemeeter # Base class for Remote types include Logging include Worker - include Events::Callback + include Events::Director prepend Util::Cache attr_reader :kind, :midi, :event, :delay, :cache diff --git a/lib/voicemeeter/event.rb b/lib/voicemeeter/event.rb index 87e0937..6c3250d 100644 --- a/lib/voicemeeter/event.rb +++ b/lib/voicemeeter/event.rb @@ -1,28 +1,26 @@ module Voicemeeter module Events - module Callback - def callbacks - @callbacks ||= [] + module Director + def observers + @observers ||= {} + end + + def on(event, method = nil, &block) + (observers[event] ||= []) << (block || method) end def register(cbs) 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 def deregister(cbs) 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 - private def trigger(event) - callbacks.each do |callback| - 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 + def fire(event) + observers[event]&.each { |block| block.call } end end diff --git a/lib/voicemeeter/worker.rb b/lib/voicemeeter/worker.rb index f11bdbb..ca41d17 100644 --- a/lib/voicemeeter/worker.rb +++ b/lib/voicemeeter/worker.rb @@ -30,15 +30,15 @@ module Voicemeeter Thread.new do Thread.current.name = "worker" while (event = que.pop) - trigger :pdirty if event == :pdirty && pdirty? - trigger :mdirty if event == :mdirty && mdirty? - trigger :midi if event == :midi && get_midi_message + fire :pdirty if event == :pdirty && pdirty? + fire :mdirty if event == :mdirty && mdirty? + fire :midi if event == :midi && get_midi_message if event == :ldirty && ldirty? 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[:strip_level] = cache[:strip_buf] cache[:bus_level] = cache[:bus_buf] - trigger :ldirty + fire :ldirty end end logger.debug "closing #{Thread.current.name} thread"