Created
February 17, 2013 07:03
-
-
Save plonk/4970511 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- coding: utf-8 -*- | |
| # my second attempt | |
| require 'weakref' | |
| module Event | |
| # イベント名 Symbol をキーとして、 | |
| # 関心を示したオブジェクトへの WeakRef を持つ。 | |
| # オブジェクトは Event モジュールを include している。 | |
| @@event_objects_map = Hash.new | |
| def Event.broadcast(name, *args) | |
| interested = @@event_objects_map[name] | |
| return unless interested # there's no-one interested in this type of event | |
| # 関心を登録したオブジェクトのイベントハンドラーを | |
| # 呼び出し、オブジェクトがすでに GC されていた場合は、 | |
| # リストから削除する。 | |
| interested.select! do |obj| | |
| begin | |
| obj.event_handler(name, *args) | |
| true # 残す | |
| rescue WeakRef::RefError | |
| puts "recycled object in the registry. discarding" | |
| false # 破棄する | |
| end | |
| end | |
| end | |
| # コールバック Proc を登録する | |
| def register_callback(name, &block) | |
| (@@event_objects_map[name] ||= []) << WeakRef.new(self) | |
| @event_callback_map ||= {} | |
| @event_callback_map[name] = block | |
| end | |
| def event_handler(event, *args) | |
| map = @event_callback_map | |
| return unless map | |
| return unless map[event] | |
| map[event].call(*args) | |
| end | |
| end | |
| # ーーー 以下実例 | |
| class GameObject | |
| include Event | |
| end | |
| a = GameObject.new | |
| b = GameObject.new | |
| # :some_event イベントにコールバックを登録する | |
| a.register_callback(:some_event) do |i, j| | |
| puts "a: #{i}, #{j}" | |
| end | |
| b.register_callback(:some_event) do |i, j| | |
| puts "b: #{i}, #{j}" | |
| end | |
| # a を開放する | |
| a = nil | |
| GC.start | |
| # b のコールバックだけが呼ばれるはず | |
| Event.broadcast(:some_event, 123, 456) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment