simplay/bofrev

View on GitHub
src/traits/observable.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'utility'

# Each Observer is supposed to implement #handle_event
module Observable

  # Define a new list of Observers
  # Every Observable instance maintains a list of @observers.
  module Initializer
    def initialize(*params)
      @observers = []
      super(*params)
    end
  end

  # hook including class' initializer in an pre-pending order.
  def self.included(klass)
    klass.send(:prepend, Initializer)
  end

  # Inform all observers that they should handle an occurred event.
  def notify_all
    @observers.each &:handle_event
  end

  # notify all observer with a certain message they are supposed to handle.
  # @param message [Event] any type of instance.
  #        The receiver is supposed to be able to handle this message
  def notify_all_with_message(message)
    @observers.each do |observer|
      observer.handle_event_with(message)
    end
  end

  # Inform all selected observers that they should handle an occurred event.
  #
  # @param type_name [Symbol] class name as down-cased symbol.
  def notify_all_targets_of_type(type_name)
    observers_of_type(type_name).each &:handle_event
  end

  # Inform all selected observers that they should handle an occurred
  # event with a certain message.
  #
  # @param type_name [Symbol] class name as down-cased symbol.
  # @param message [Event] any type of instance.
  #        The receiver is supposed to be able to handle this message
  def notify_all_targets_of_type_with_message(type_name, message)
    observers_of_type(type_name).each do |observer|
      observer.handle_event_with(message)
    end
  end

  # Append a new observer to the observers list.
  #
  # @param observer [Observer] listener of events thrown by this Observable.
  def subscribe(observer)
    @observers << observer
  end

  # Remove all observers of type :type_name from the observer list.
  #
  # @param type_name [Symbol] class name as down-cased symbol.
  # @hint: These observers will not get notified anymore.
  def unsubscribe(type_name)
    observers_of_type(type_name).each do |observer|
      unsubscribe_one(observer)
    end
  end

  # Removes a given observer from from the observer list.
  #
  # @param observer [Observer] listener of events thrown by this Observable.
  def unsubscribe_one(observer)
    @observers.delete(observer)
  end

  # Select all observers of a specified type.
  #
  # @hint: type_name is down-cased symbol representation of observer's class.
  # @param type_name [Symbol] class name as down-cased symbol.
  def observers_of_type(type_name)
    @observers.select do |observer|
      Utility.underscore(observer.class.to_s).downcase == type_name.to_s
    end
  end

end