Class: Pluggaloid::Event
- Inherits:
-
Object
- Object
- Pluggaloid::Event
- Includes:
- InstanceStorage
- Defined in:
- lib/pluggaloid/event.rb
Constant Summary collapse
- Lock =
Mutex.new
Class Attribute Summary collapse
-
.filter_another_thread ⇒ Object
Returns the value of attribute filter_another_thread.
-
.vm ⇒ Object
Returns the value of attribute vm.
Instance Attribute Summary collapse
-
#options ⇒ Object
- オプション。以下のキーを持つHash :prototype
- 引数の数と型。Arrayで、type_strictが解釈できる条件を設定する :priority
-
Delayerの優先順位.
Class Method Summary collapse
Instance Method Summary collapse
-
#add_filter(event_filter) ⇒ Object
イベントフィルタを追加する ==== Args [event_filter] イベントフィルタ(Filter) ==== Return self.
- #add_listener(listener) ⇒ Object
- #argument_hash(args, exclude_index) ⇒ Object
-
#call(*args) ⇒ Object
イベントを引数 args で発生させる ==== Args [*args] イベントの引数 ==== Return Delayerか、イベントを待ち受けているリスナがない場合はnil.
-
#collect(*args) ⇒ Object
defeventで定義されたprototype引数に Pluggaloid::COLLECT を含むイベントに対して使える。 フィルタの Pluggaloid::COLLECT 引数に空の配列を渡して実行したあと、その配列を返す。 ==== Args [*args] Pluggaloid::COLLECT 以外の引数のリスト ==== Return [Array] フィルタ実行結果.
- #collect_index ⇒ Object
- #collection_add_event ⇒ Object
- #collection_delete_event ⇒ Object
-
#defevent(new_options) ⇒ Object
イベント event_name を宣言する ==== Args [new_options] イベントの定義.
-
#delete_filter(event_filter) ⇒ Object
イベントフィルタを削除する ==== Args [event_filter] イベントフィルタ(EventFilter) ==== Return self.
- #delete_listener(listener) ⇒ Object
- #delete_stream_generator(listener) ⇒ Object
- #delete_subscriber(listener) ⇒ Object
-
#filtering(*args) ⇒ Object
引数 args をフィルタリングした結果を返す ==== Args [*args] 引数 ==== Return フィルタされた引数の配列.
-
#initialize(*args) ⇒ Event
constructor
A new instance of Event.
-
#priority ⇒ Object
イベントの優先順位を取得する ==== Return プラグインの優先順位.
- #prototype ⇒ Object
- #register_stream_generator(stream_generator) ⇒ Object
- #stream_index ⇒ Object
-
#subscribe?(*specs) ⇒ Boolean
subscribe(_*specs_) で、ストリームの受信をしようとしているリスナが定義されていればtrueを返す。 on_* で通常のイベントリスナが登録されて居る場合は、 _*specs_ の内容に関わらず常にtrueを返す。.
-
#subscribe_hash?(hash) ⇒ Boolean
:nodoc:.
- #vm ⇒ Object
Constructor Details
#initialize(*args) ⇒ Event
Returns a new instance of Event.
16 17 18 19 20 21 22 23 |
# File 'lib/pluggaloid/event.rb', line 16 def initialize(*args) super @options = {} @listeners = [].freeze @filters = [].freeze @subscribers = Hash.new { |h, k| h[k] = [] } @stream_generators = Hash.new { |h, k| h[k] = Set.new } end |
Class Attribute Details
.filter_another_thread ⇒ Object
Returns the value of attribute filter_another_thread.
247 248 249 |
# File 'lib/pluggaloid/event.rb', line 247 def filter_another_thread @filter_another_thread end |
.vm ⇒ Object
Returns the value of attribute vm.
247 248 249 |
# File 'lib/pluggaloid/event.rb', line 247 def vm @vm end |
Instance Attribute Details
#options ⇒ Object
オプション。以下のキーを持つHash
- :prototype
-
引数の数と型。Arrayで、type_strictが解釈できる条件を設定する
- :priority
-
Delayerの優先順位
11 12 13 |
# File 'lib/pluggaloid/event.rb', line 11 def @options end |
Class Method Details
.__clear_aF4e__ ⇒ Object
249 |
# File 'lib/pluggaloid/event.rb', line 249 alias __clear_aF4e__ clear! |
.clear! ⇒ Object
250 251 252 253 |
# File 'lib/pluggaloid/event.rb', line 250 def clear! @filter_another_thread = false __clear_aF4e__() end |
Instance Method Details
#add_filter(event_filter) ⇒ Object
イベントフィルタを追加する
Args
- event_filter
-
イベントフィルタ(Filter)
Return
self
155 156 157 158 159 160 |
# File 'lib/pluggaloid/event.rb', line 155 def add_filter(event_filter) unless event_filter.is_a? Pluggaloid::Filter raise Pluggaloid::ArgumentError, "First argument must be Pluggaloid::Filter, but given #{event_filter.class}." end @filters = [*@filters, event_filter].freeze self end |
#add_listener(listener) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/pluggaloid/event.rb', line 84 def add_listener(listener) case listener when Pluggaloid::Listener Lock.synchronize do if @listeners.map(&:slug).include?(listener.slug) raise Pluggaloid::DuplicateListenerSlugError, "Listener slug #{listener.slug} already exists." end @listeners = [*@listeners, listener].freeze end @stream_generators.values.each do |generators| generators.each(&:on_subscribed) end when Pluggaloid::Subscriber accepted_hash = listener.accepted_hash Lock.synchronize do @subscribers[accepted_hash] << listener end @stream_generators.fetch(accepted_hash, nil)&.each(&:on_subscribed) else raise Pluggaloid::ArgumentError, "First argument must be Pluggaloid::Listener or Pluggaloid::Subscriber, but given #{listener.class}." end self end |
#argument_hash(args, exclude_index) ⇒ Object
176 177 178 179 180 181 182 |
# File 'lib/pluggaloid/event.rb', line 176 def argument_hash(args, exclude_index) args.each_with_index.map do |item, i| if i != exclude_index item.hash end end.compact.freeze end |
#call(*args) ⇒ Object
イベントを引数 args で発生させる
Args
- *args
-
イベントの引数
Return
Delayerか、イベントを待ち受けているリスナがない場合はnil
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/pluggaloid/event.rb', line 58 def call(*args) if self.class.filter_another_thread if @filters.empty? vm.Delayer.new(*Array(priority)) do call_all_listeners(args) end else Thread.new do filtered_args = filtering(*args) if filtered_args.is_a? Array vm.Delayer.new(*Array(priority)) do call_all_listeners(filtered_args) end end end end else vm.Delayer.new(*Array(priority)) do args = filtering(*args) if not @filters.empty? call_all_listeners(args) if args.is_a? Array end end end |
#collect(*args) ⇒ Object
defeventで定義されたprototype引数に Pluggaloid::COLLECT を含むイベントに対して使える。フィルタの Pluggaloid::COLLECT 引数に空の配列を渡して実行したあと、その配列を返す。
Args
- *args
-
Pluggaloid::COLLECT 以外の引数のリスト
Return
- Array
-
フィルタ実行結果
204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/pluggaloid/event.rb', line 204 def collect(*args) specified_index = args.index(Pluggaloid::COLLECT) specified_index&.yield_self(&args.method(:delete_at)) insert_index = collect_index || specified_index if insert_index Enumerator.new do |yielder| cargs = args.dup cargs.insert(insert_index, yielder) filtering(*cargs) end else raise Pluggaloid::UndefinedCollectionIndexError, 'To call collect(), it must define prototype arguments include `Pluggaloid::COLLECT\'.' end end |
#collect_index ⇒ Object
191 192 193 194 195 196 |
# File 'lib/pluggaloid/event.rb', line 191 def collect_index unless defined?(@collect_index) @collect_index = self.prototype&.index(Pluggaloid::COLLECT) end @collect_index end |
#collection_add_event ⇒ Object
224 225 226 |
# File 'lib/pluggaloid/event.rb', line 224 def collection_add_event self.class['%{name}__add' % {name: name}] end |
#collection_delete_event ⇒ Object
228 229 230 |
# File 'lib/pluggaloid/event.rb', line 228 def collection_delete_event self.class['%{name}__delete' % {name: name}] end |
#defevent(new_options) ⇒ Object
イベント event_name を宣言する
Args
- new_options
-
イベントの定義
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/pluggaloid/event.rb', line 32 def defevent() @options.merge!() if collect_index new_proto = self.prototype.dup new_proto[self.collect_index] = Pluggaloid::STREAM collection_add_event.defevent(prototype: new_proto) collection_delete_event.defevent(prototype: new_proto) end self end |
#delete_filter(event_filter) ⇒ Object
イベントフィルタを削除する
Args
- event_filter
-
イベントフィルタ(EventFilter)
Return
self
167 168 169 170 171 172 173 174 |
# File 'lib/pluggaloid/event.rb', line 167 def delete_filter(event_filter) Lock.synchronize do @filters = @filters.dup @filters.delete(event_filter) @filters.freeze end self end |
#delete_listener(listener) ⇒ Object
118 119 120 121 122 123 124 125 |
# File 'lib/pluggaloid/event.rb', line 118 def delete_listener(listener) Lock.synchronize do @listeners = @listeners.dup @listeners.delete(listener) @listeners.freeze end self end |
#delete_stream_generator(listener) ⇒ Object
139 140 141 142 143 144 145 146 147 148 |
# File 'lib/pluggaloid/event.rb', line 139 def delete_stream_generator(listener) Lock.synchronize do ss = @stream_generators[listener.accepted_hash] ss.delete(listener) if ss.empty? @stream_generators.delete(listener.accepted_hash) end end self end |
#delete_subscriber(listener) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/pluggaloid/event.rb', line 127 def delete_subscriber(listener) Lock.synchronize do ss = @subscribers[listener.accepted_hash] ss.delete(listener) if ss.empty? @subscribers.delete(listener.accepted_hash) end end @stream_generators.fetch(listener.accepted_hash, nil)&.each(&:on_unsubscribed) self end |
#filtering(*args) ⇒ Object
引数 args をフィルタリングした結果を返す
Args
- *args
-
引数
Return
フィルタされた引数の配列
79 80 81 82 |
# File 'lib/pluggaloid/event.rb', line 79 def filtering(*args) catch(:filter_exit) { @filters.reduce(args){ |acm, event_filter| event_filter.filtering(*acm) } } end |
#priority ⇒ Object
イベントの優先順位を取得する
Return
プラグインの優先順位
49 50 51 |
# File 'lib/pluggaloid/event.rb', line 49 def priority if @options.has_key? :priority @options[:priority] end end |
#prototype ⇒ Object
25 26 27 |
# File 'lib/pluggaloid/event.rb', line 25 def prototype @options[:prototype] end |
#register_stream_generator(stream_generator) ⇒ Object
219 220 221 222 |
# File 'lib/pluggaloid/event.rb', line 219 def register_stream_generator(stream_generator) @stream_generators[stream_generator.accepted_hash] << stream_generator self end |
#stream_index ⇒ Object
184 185 186 187 188 189 |
# File 'lib/pluggaloid/event.rb', line 184 def stream_index unless defined?(@stream_index) @stream_index = self.prototype&.index(Pluggaloid::STREAM) end @stream_index end |
#subscribe?(*specs) ⇒ Boolean
subscribe(_*specs_) で、ストリームの受信をしようとしているリスナが定義されていればtrueを返す。on_* で通常のイベントリスナが登録されて居る場合は、 _*specs_ の内容に関わらず常にtrueを返す。
110 111 112 |
# File 'lib/pluggaloid/event.rb', line 110 def subscribe?(*specs) !@listeners.empty? || @subscribers.key?(argument_hash(specs, nil)) end |
#subscribe_hash?(hash) ⇒ Boolean
:nodoc:
114 115 116 |
# File 'lib/pluggaloid/event.rb', line 114 def subscribe_hash?(hash) # :nodoc: !@listeners.empty? || @subscribers.key?(hash) end |
#vm ⇒ Object
43 44 |
# File 'lib/pluggaloid/event.rb', line 43 def vm self.class.vm end |