diff --git a/README.md b/README.md index ae5ad12..a2cee12 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ For a full list of requests refer to [Requests](https://github.com/obsproject/ob ### Events -Register `on_` callback methods. Method names should match the api event but snake cased. +Register blocks with the Event client using the `on` method. The event data will be passed to the block. example: @@ -75,23 +75,14 @@ example: class Observer def initialize @e_client = OBSWS::Events::Client.new(host: "localhost", port: 4455, password: "strongpassword") - # register callback methods with the Event client - @e_client.register( - [ - method(:on_current_program_scene_changed), - method(:on_input_mute_state_changed) - ] - ) + # register blocks on event types. + @e_client.on(:current_program_scene_changed) do |data| + ... + end + @e_client.on(:input_mute_state_changed) do |data| + ... + end end - - # define "on_" event methods. - def on_current_program_scene_changed(data) - ... - end - def on_input_mute_state_changed(data) - ... - end - ... end ``` diff --git a/examples/events/main.rb b/examples/events/main.rb index 6b0fd88..94d6b35 100644 --- a/examples/events/main.rb +++ b/examples/events/main.rb @@ -1,19 +1,28 @@ require_relative "../../lib/obsws" require "yaml" - class Main def initialize(**kwargs) @r_client = OBSWS::Requests::Client.new(**kwargs) @e_client = OBSWS::Events::Client.new(**kwargs) - @e_client.add_observer(self) + + @e_client.on(:current_program_scene_changed) do |data| + puts "Switched to scene #{data.scene_name}" + end + @e_client.on(:scene_created) do |data| + puts "scene #{data.scene_name} has been created" + end + @e_client.on(:input_mute_state_changed) do |data| + puts "#{data.input_name} mute toggled" + end + @e_client.on(:exit_started) do + puts "OBS closing!" + @r_client.close + @e_client.close + @running = false + end puts infostring - @running = true - end - - def run - sleep(0.1) while @running end def infostring @@ -24,23 +33,9 @@ class Main ].join(" ") end - def on_current_program_scene_changed(data) - puts "Switched to scene #{data.scene_name}" - end - - def on_scene_created(data) - puts "scene #{data.scene_name} has been created" - end - - def on_input_mute_state_changed(data) - puts "#{data.input_name} mute toggled" - end - - def on_exit_started - puts "OBS closing!" - @r_client.close - @e_client.close - @running = false + def run + @running = true + sleep(0.1) while @running end end diff --git a/examples/levels/main.rb b/examples/levels/main.rb index 9a896b8..16256f0 100644 --- a/examples/levels/main.rb +++ b/examples/levels/main.rb @@ -13,36 +13,29 @@ class Main def initialize(**kwargs) subs = OBSWS::Events::SUBS::LOW_VOLUME | OBSWS::Events::SUBS::INPUTVOLUMEMETERS @e_client = OBSWS::Events::Client.new(subs:, **kwargs) - @e_client.register( - [ - method(:on_input_mute_state_changed), - method(:on_input_volume_meters) - ] - ) + + @e_client.on(:input_mute_state_changed) do |data| + if data.input_name == DEVICE + puts "#{DEVICE} mute toggled" + end + end + @e_client.on(:input_volume_meters) do |data| + fget = ->(x) { (x > 0) ? (20 * Math.log(x, 10)).round(1) : -200.0 } + + data.inputs.each do |d| + name = d[:inputName] + if name == DEVICE && !d[:inputLevelsMul].empty? + left, right = d[:inputLevelsMul] + puts "#{name} [L: #{fget.call(left[LevelTypes::POSTFADER])}, R: #{fget.call(right[LevelTypes::POSTFADER])}]" + end + end + end end def run puts "press to quit" loop { break if gets.chomp.empty? } end - - def on_input_mute_state_changed(data) - if data.input_name == DEVICE - puts "#{DEVICE} mute toggled" - end - end - - def on_input_volume_meters(data) - fget = ->(x) { (x > 0) ? (20 * Math.log(x, 10)).round(1) : -200.0 } - - data.inputs.each do |d| - name = d[:inputName] - if name == DEVICE && !d[:inputLevelsMul].empty? - left, right = d[:inputLevelsMul] - puts "#{name} [L: #{fget.call(left[LevelTypes::POSTFADER])}, R: #{fget.call(right[LevelTypes::POSTFADER])}]" - end - end - end end def conn_from_yaml diff --git a/lib/obsws/event.rb b/lib/obsws/event.rb index ed99a0e..b8fb51e 100644 --- a/lib/obsws/event.rb +++ b/lib/obsws/event.rb @@ -28,43 +28,35 @@ module OBSWS ALL = LOW_VOLUME | HIGH_VOLUME end - module Callbacks + module EventDirector include Util::String def observers - @observers ||= [] + @observers ||= {} end - def add_observer(observer) - observer = [observer] unless observer.respond_to? :each - observer.each { |o| observers << o unless observers.include? o } + def on(event, method = nil, &block) + (observers[event] ||= []) << (block || method) end - def remove_observer(observer) - observer = [observer] unless observer.respond_to? :each - observers.reject! { |o| observer.include? o } + def register(cbs) + cbs = [cbs] unless cbs.respond_to? :each + cbs.each { |cb| on(cb.name[3..].to_sym, cb) } end - private def notify_observers(event, data) - observers.each do |o| - if o.is_a? Method - if o.name.to_s == "on_#{snakecase(event)}" - data.empty? ? o.call : o.call(data) - end - elsif o.respond_to? "on_#{snakecase(event)}" - data.empty? ? o.send("on_#{snakecase(event)}") : o.send("on_#{snakecase(event)}", data) - end - end + def deregister(cbs) + cbs = [cbs] unless cbs.respond_to? :each + cbs.each { |cb| observers[cb.name[3..].to_sym]&.reject! { |o| cbs.include? o } } end - alias_method :callbacks, :observers - alias_method :register, :add_observer - alias_method :deregister, :remove_observer + def fire(event, data) + observers[snakecase(event).to_sym]&.each { |block| data.empty? ? block.call : block.call(data) } + end end class Client include Logging - include Callbacks + include EventDirector include Mixin::TearDown include Mixin::OPCodes @@ -87,7 +79,7 @@ module OBSWS logger.debug("received: #{data}") event = data[:eventType] data = data.fetch(:eventData, {}) - notify_observers(event, Mixin::Data.new(data, data.keys)) + fire(event, Mixin::Data.new(data, data.keys)) end } end diff --git a/lib/obsws/version.rb b/lib/obsws/version.rb index 7b3d621..f59aa5e 100644 --- a/lib/obsws/version.rb +++ b/lib/obsws/version.rb @@ -7,11 +7,11 @@ module OBSWS end def minor - 5 + 6 end def patch - 8 + 0 end def to_a