Sha256: 0e25e47b900f885dc20cf9d1b0481c727173aec2c503bc01a93858828b976b0c

Contents?: true

Size: 1.49 KB

Versions: 1

Compression:

Stored size: 1.49 KB

Contents

require 'weakref'

module LIFX
  # @private
  module Observable
    class ObserverCallbackMismatch < ArgumentError; end
    class ObserverCallbackNotFound < ArgumentError; end

    def add_observer(obj, type, &callback)
      if !callback_type_exists?(type)
        raise ObserverCallbackNotFound.new
      end
      if !callback_has_required_keys?(type, callback)
        raise ObserverCallbackMismatch.new
      end
      observers[type][WeakRef.new(obj)] = callback
    end

    def remove_observer(obj, type)
      observers[type].delete(obj)
    end

    def remove_observers
      observers.clear
    end

    def notify_observers(type, **args)
      observers[type].each do |_, callback|
        callback.call(**args)
      end
    end

    def callback_type_exists?(type)
      !!observer_callback_definition[type]
    end

    def callback_has_required_keys?(type, callback)
      (required_keys_for_callback(type) - required_keys_in_proc(callback)).empty?
    end

    def observer_callback_definition
      {}
    end

    def required_keys_for_callback(type)
      @_required_keys_for_callback ||= {}
      @_required_keys_for_callback[type] ||= begin
        return [] if !observer_callback_definition[type]
        required_keys_in_proc(observer_callback_definition[type])
      end
    end

    def required_keys_in_proc(proc)
      proc.parameters.select do |type, _|
        type == :keyreq
      end.map(&:last)
    end

    def observers
      @_observers ||= Hash.new { |h, k| h[k] = {} }
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
lifx-0.4.8 lib/lifx/observable.rb