NSNotificationCenterを真似してみたくなったので書いてみた。使い道はあとで考える。TupleSpaceを借りてきたのであんまりあたまを使わなかった。
require 'rinda/tuplespace' require 'singleton' class NotificationCenter include Singleton class Handle def initialize; @removed = false; end def remove; @removed = true; end def removed?; @removed; end end def initialize @place = Rinda::TupleSpace.new @any = Object.new end def add(observer, message, event, object) object ||= @any @place.write([event, object, observer, message, Handle.new]) end def remove(observer, message, event, object) object ||= @any tuple = @place.take([event, object, observer, message, nil], 0) tuple[4].removed rescue end def post(event, from, info=nil) dispatch(event, from, info) end def dispatch_one(from, info, tuple) event, ignore, observer, message, handle = tuple return if handle.removed? observer.send(message, event, from, info) end def dispatch(event, from, info) @place.read_all([event, from, nil, nil, nil]).each do |tuple| dispatch_one(from, info, tuple) end @place.read_all([event, @any, nil, nil, nil]).each do |tuple| dispatch_one(from, info, tuple) end end end if __FILE__ == $0 class Foo def initialize @ns = NotificationCenter.instance @ns.add(self, :notify, :foo, self) end def notify(event, from, info) p event @ns.remove(self, :notify, :foo, self) end def change @ns.post(:foo, self) end end foo = Foo.new foo.change foo.change end
通知を非同期に(あとで)送る版。
NSNotificationCenterって、通知は即座に送られるの?
require 'thread' class AsyncNotificationCenter < NotificationCenter def initialize @queue = Queue.new super() end def post(event, from, info=nil) @queue.push([event, from, info]) end def flush while ! @queue.empty? event, from, info = @queue.pop dispatch(event, from, info) end end end
あとで読む。
- 作者: 木下誠
- 出版社/メーカー: ビー・エヌ・エヌ新社
- 発売日: 2008/08/30
- メディア: 単行本(ソフトカバー)
- 購入: 19人 クリック: 165回
- この商品を含むブログ (113件) を見る