public
Description: A tool for assembling web and print comics.
Homepage: http://rubyforge.org/projects/minicomic
Clone URL: git://github.com/mental/minicomic.git
minicomic / lib / minicomic / util / observable.rb
100644 73 lines (59 sloc) 1.489 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
require 'thread'
require 'minicomic/util/broadcast'
 
module Minicomic
module Util
 
class Observable
  module Observer
  end
 
  class ObserverBroadcast < Util::Broadcast
  end
 
  class << self
    def observer_method(name, arity=-1)
      name = name.to_sym
      if arity < 0
        required = -arity - 1
        rest = true
      else
        required = arity
        rest = false
      end
      args = (0...required).map { |n| "arg#{n}" }
      args.push "*args" if rest
      self::ObserverBroadcast.class_eval { broadcast_method name }
      self::Observer.module_eval "def #{name}(#{args.join(', ')}) ; end"
    end
    private :observer_method
 
    def inherited(target)
      old_module = target.const_get :Observer
      target.const_set :Observer, Module.new { include old_module }
 
      old_class = target.const_get :ObserverBroadcast
      target.const_set :ObserverBroadcast, Class.new(old_class)
 
      super(target)
    end
  end
 
  def initialize(sequencer)
    @observable_sequencer = sequencer
    @observers = self.class::ObserverBroadcast.new
  end
 
  def later(&block)
    @observable_sequencer.later(&block)
    self
  end
  private :later
 
  def update_new_observer(observer)
  end
  private :update_new_observer
 
  def add_observer(observer)
    later do
      @observers.add_recipient(observer)
      update_new_observer(observer)
    end
  end
 
  def remove_observer(observer)
    later do
      @observers.remove_recipient(observer)
    end
  end
end
 
end
end