Update connect/disconnect action states.
[kaya.git] / lib / observer_utils.rb
blob7cf37fdd1dc43b4a7b4d7ddcacdadc2d7335bf39
1 # Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 require 'observer'
9 require 'utils'
11 module Observer
12   def update(data)
13     data.each_key do |key|
14       m = begin
15         method("on_#{key}")
16       rescue NameError
17       end
18       
19       if m
20         case m.arity
21         when 0
22           m[]
23         when 1
24           m[data[key]]
25         else
26           m[*data[key]]
27         end
28       end
29     end
30   end
31 end
33 module Observable
34   def on(event, &blk)
35     observe(event, &blk)
36   end
37   
38   def observe(event, &blk)
39     obs = SimpleObserver.new(event, &blk)
40     add_observer obs
41     # return observer so that we can remove it later
42     obs
43   end
44   
45   def observe_limited(event, &blk)
46     obs = LimitedObserver.new(self, event, &blk)
47     add_observer obs
48     obs
49   end
51   def fire(e)
52     changed
53     notify_observers any_to_event(e)
54   end
55   
56   def any_to_event(e)
57     if e.is_a? Symbol
58       { e => nil }
59     else
60       e
61     end
62   end
63 end
65 class Proc
66   def generic_call(args)
67     case arity
68     when 0
69       call
70     when 1
71       call(args)
72     else
73       call(*args)
74     end
75   end
76 end
78 class SimpleObserver
79   def initialize(event, &blk)
80     @event = event
81     @blk = blk
82   end
83   
84   def update(data)
85     if data.has_key?(@event)
86       @blk.generic_call(data[@event])
87     end
88   end
89 end
91 class LimitedObserver < SimpleObserver
92   def initialize(observed, event, &blk)
93     super(event, &blk)
94     @observed = observed
95   end
96   
97   def update(data)
98     remove = super(data)
99     @observed.delete_observer(self) if remove
100     remove
101   end