Sha256: a8245659fc3617de45c829ee0eef7cb1088e68fd7e3276c7d58cc36bcba8a6d5

Contents?: true

Size: 1.91 KB

Versions: 1

Compression:

Stored size: 1.91 KB

Contents

# frozen_string_literal: true

module Micro
  module Observers

    class Manager
      EMPTY_HASH = {}.freeze

      EqualTo = -> (observer) do
        -> item { item[0] == :observer && item[1] == observer }
      end

      def self.for(subject)
        new(subject)
      end

      def initialize(subject, list = nil)
        @subject = subject

        @list = Utils.compact_array(list.kind_of?(Array) ? list : [])
      end

      def included?(observer)
        @list.any?(&EqualTo[observer])
      end

      def attach(observer, options = EMPTY_HASH)
        if options[:allow_duplication] || !included?(observer)
          @list << [:observer, observer, options[:data]]
        end

        self
      end

      def on(options=EMPTY_HASH)
        event, callable, with = options[:event], options[:call], options[:with]

        return self unless event.is_a?(Symbol) && callable.respond_to?(:call)

        arg = with.is_a?(Proc) ? with.call(@subject) : (arg || subject)

        @list << [:callable, event, [callable, arg]]
      end

      def detach(observer)
        @list.delete_if(&EqualTo[observer])

        self
      end

      def notify(event)
        notify!(event)

        self
      end

      def call(*actions)
        EventsOrActions[actions].each { |act| notify!(act) }

        self
      end

      private

        def notify!(evt_or_act)
          @list.each do |strategy, observer, data|
            call!(observer, strategy, data, with: evt_or_act)
          end
        end

        def call!(observer, strategy, data, with:)
          return data[0].call(data[1]) if strategy == :callable && observer == with

          if strategy == :observer && observer.respond_to?(with)
            handler = observer.method(with)

            return handler.call(@subject) if handler.arity == 1

            handler.call(@subject, data)
          end
        end

      private_constant :EMPTY_HASH, :EqualTo
    end

  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
u-observers-0.4.0 lib/micro/observers/manager.rb