Class: Pluggaloid::Plugin

Inherits:
Object
  • Object
show all
Includes:
InstanceStorage
Defined in:
lib/pluggaloid/plugin.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Plugin

Args

plugin_name

プラグイン名



108
109
110
111
112
113
# File 'lib/pluggaloid/plugin.rb', line 108

def initialize(*args)
  super
  @defined_time = Time.new.freeze
  @events = Set.new
  @filters = Set.new
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, **kwrest, &proc) ⇒ Object

マジックメソッドを追加する。

on_?name

add_event(name)

filter_?name

add_event_filter(name)



311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/pluggaloid/plugin.rb', line 311

def method_missing(method, *args, **kwrest, &proc)
  method_name = method.to_s
  case
  when method_name.start_with?('on')
    event_name = method_name[(method_name[2] == '_' ? 3 : 2)..method_name.size]
    add_event(event_name.to_sym, *args, **kwrest, &proc)
  when method_name.start_with?('filter')
    event_name = method_name[(method_name[6] == '_' ? 7 : 6)..method_name.size]
    add_event_filter(event_name.to_sym, **kwrest, &proc)
  else
    super
  end
end

Class Attribute Details

.vmObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/pluggaloid/plugin.rb', line 17

def vm
        @vm ||= begin
raise Pluggaloid::NoDefaultDelayerError, "Default Delayer was not set." unless Delayer.default
vm = Pluggaloid::VM.new(
  Delayer: Delayer.default,
  Plugin: self,
  Event: Pluggaloid::Event,
  Listener: Pluggaloid::Listener,
  Filter: Pluggaloid::Filter,
  HandlerTag: Pluggaloid::HandlerTag,
  Subscriber: Pluggaloid::Subscriber,
  StreamGenerator: Pluggaloid::StreamGenerator
)
vm.Event.vm = vm end end

Instance Attribute Details

#defined_timeObject (readonly)

最初にプラグインがロードされた時刻(uninstallされるとリセットする)



104
105
106
# File 'lib/pluggaloid/plugin.rb', line 104

def defined_time
  @defined_time
end

#nameObject (readonly)

プラグインの名前



98
99
100
# File 'lib/pluggaloid/plugin.rb', line 98

def name
  @name
end

#specObject

spec



101
102
103
# File 'lib/pluggaloid/plugin.rb', line 101

def spec
  @spec
end

Class Method Details

.__clear_aF4e__Object



89
# File 'lib/pluggaloid/plugin.rb', line 89

alias __clear_aF4e__ clear!

.call(event_name, *args) ⇒ Object

イベント event_name を発生させる

Args

event_name

イベント名

*args

イベントの引数

Return

Delayer



57
58
# File 'lib/pluggaloid/plugin.rb', line 57

def call(event_name, *args)
vm.Event[event_name].call(*args) end

.clear!Object



90
91
92
93
94
# File 'lib/pluggaloid/plugin.rb', line 90

def clear!
if defined?(@vm) and @vm
  @vm.Event.clear!
  @vm = nil end
__clear_aF4e__() end

.collect(event_name, *specs) ⇒ Object

フィルタ event_name を実行し、defeventでPluggaloid::COLLECTと宣言されている引数の結果を列挙するEnumeratorを返す

Args

event_name

イベント名(String | Symbol)

*specs

Pluggaloid::COLLECT以外の引数

Return

Enumerator


75
76
77
# File 'lib/pluggaloid/plugin.rb', line 75

def collect(event_name, *specs)
  vm.Event[event_name].collect(*specs)
end

.create(plugin_name, &body) ⇒ Object

プラグインのインスタンスを返す。ブロックが渡された場合、そのブロックをプラグインのインスタンスのスコープで実行する

Args

plugin_name

プラグイン名

Return

Plugin



38
39
40
# File 'lib/pluggaloid/plugin.rb', line 38

def create(plugin_name, &body)
self[plugin_name].instance_eval(&body) if body
self[plugin_name] end

.defevent(event_name, options = {}) ⇒ Object

イベントを宣言する。

Args

event_name

イベント名

options

以下のキーを持つHash

:prototype

引数の数と型。Arrayで、type_strictが解釈できる条件を設定する

:priority

Delayerの優先順位



48
49
# File 'lib/pluggaloid/plugin.rb', line 48

def defevent(event_name, options = {})
vm.Event[event_name].options = options end

.filter_cancel!Object

互換性のため



84
85
# File 'lib/pluggaloid/plugin.rb', line 84

def filter_cancel!
vm.Filter.cancel! end

.filtering(event_name, *args) ⇒ Object

引数 args をフィルタリングした結果を返す

Args

*args

引数

Return

フィルタされた引数の配列



65
66
# File 'lib/pluggaloid/plugin.rb', line 65

def filtering(event_name, *args)
vm.Event[event_name].filtering(*args) end

.uninstall(plugin_name) ⇒ Object

互換性のため



80
81
# File 'lib/pluggaloid/plugin.rb', line 80

def uninstall(plugin_name)
self[plugin_name].uninstall end

Instance Method Details

#add_event(event_name, **kwrest, &callback) ⇒ Object

イベントリスナを新しく登録する

Args

event

監視するEventのインスタンス

name:

名前(String | nil)

slug:

イベントリスナスラッグ(Symbol | nil)

tags:

Pluggaloid::HandlerTag|Array リスナのタグ

&callback

コールバック

Return

Pluggaloid::Listener



124
125
126
127
# File 'lib/pluggaloid/plugin.rb', line 124

def add_event(event_name, **kwrest, &callback)
result = vm.Listener.new(vm.Event[event_name], **kwrest, &callback)
@events << result
result end

#add_event_filter(event_name, **kwrest, &callback) ⇒ Object

イベントフィルタを新しく登録する

Args

event_name

イベント名(String | Symbol)

name:

名前(String | nil)

slug:

フィルタスラッグ(Symbol | nil)

tags:

Pluggaloid::HandlerTag|Array フィルタのタグ

&callback

コールバック

Return

Pluggaloid::Filter



138
139
140
141
# File 'lib/pluggaloid/plugin.rb', line 138

def add_event_filter(event_name, **kwrest, &callback)
result = vm.Filter.new(vm.Event[event_name], **kwrest, &callback)
@filters << result
result end

#collect(event_name, *specs) ⇒ Object



167
168
169
# File 'lib/pluggaloid/plugin.rb', line 167

def collect(event_name, *specs)
  self.class.collect(event_name, *specs)
end

#collection(event_name, *specs, &block) ⇒ Object

追加・削除がフィルタに反映されるコレクションオブジェクトを作成する。同時に event_name にフィルタが定義され、フィルタが呼ばれるとその時点のコレクションオブジェクトの内容を全て列挙する。フィルタと対になるコレクションオブジェクトは、 _&block_ の引数として渡される。

Args

event_name

イベント名(String | Symbol)

*specs

Pluggaloid::COLLECT以外の引数

&block

コレクションオブジェクトを受け取って一度だけ実行されるblock

Return

_&block_ の戻り値



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/pluggaloid/plugin.rb', line 181

def collection(event_name, *specs, &block)
  event = vm.Event[event_name]
  mutation = Pluggaloid::Collection.new(event, *specs)
  add_event_filter(event_name, name: 'collection(%s line %i)' % block.source_location) do |*args|
    if mutation.argument_hash_same?(args)
      mutation.values.each(&args[event.collect_index].method(:<<))
    end
    args
  end
  block.call(mutation)
end

#defdsl(dsl_name, &callback) ⇒ Object

DSLメソッドを新しく追加する。追加されたメソッドは呼ぶと &callback が呼ばれ、その戻り値が返される。引数も順番通り全て &callbackに渡される

Args

dsl_name

新しく追加するメソッド名

&callback

実行されるメソッド

Return

self



293
294
295
296
# File 'lib/pluggaloid/plugin.rb', line 293

def defdsl(dsl_name, &callback)
self.class.instance_eval {
  define_method(dsl_name, &callback) }
self end

#defevent(event_name, options = {}) ⇒ Object

イベント event_name を宣言する

Args

event_name

イベント名

options

イベントの定義



282
283
284
# File 'lib/pluggaloid/plugin.rb', line 282

def defevent(event_name, options={})
  vm.Event[event_name].defevent({ plugin: self, **options })
end

#detach(*args) ⇒ Object

イベントを削除する。引数は、Pluggaloid::ListenerかPluggaloid::Filterのみ(on_*やfilter_*の戻り値)。互換性のため、二つ引数がある場合は第一引数は無視され、第二引数が使われる。

Args

*args

引数

Return

self



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/pluggaloid/plugin.rb', line 250

def detach(*args)
listener = args.last
case listener
when vm.Listener, vm.Subscriber
  @events.delete(listener)
  listener.detach
when vm.Filter
  @filters.delete(listener)
  listener.detach
when Enumerable
  listener.each(&method(:detach))
else
  raise ArgumentError, "Argument must be Pluggaloid::Listener, Pluggaloid::Filter, Pluggaloid::HandlerTag or Enumerable. But given #{listener.class}."
end
self end

#filters(&block) ⇒ Object

フィルタを列挙する

Return

Set of Pluggaloid::Filter



235
236
237
238
239
240
241
# File 'lib/pluggaloid/plugin.rb', line 235

def filters(&block)
  if block
    @filters.each(&block)
  else
    @filters.dup
  end
end

#generate(event_name, *specs, **kwrest, &block) ⇒ Object



143
144
145
# File 'lib/pluggaloid/plugin.rb', line 143

def generate(event_name, *specs, **kwrest, &block)
  vm.StreamGenerator.new(vm.Event[event_name], *specs, plugin: self, **kwrest, &block)
end

#handler_tag(slug = SecureRandom.uuid, name = slug, &block) ⇒ Object

このプラグインのHandlerTagを作る。ブロックが渡された場合は、ブロックの中を実行し、ブロックの中で定義されたHandler全てにTagを付与する。

Args

slug

スラッグ

name

タグ名

Return

Pluggaloid::HandlerTag



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/pluggaloid/plugin.rb', line 201

def handler_tag(slug=SecureRandom.uuid, name=slug, &block)
  tag = case slug
        when String, Symbol
          vm.HandlerTag.new(slug: slug.to_sym, name: name.to_s, plugin: self)
        when vm.HandlerTag
          slug
        else
          raise Pluggaloid::TypeError, "Argument `slug' must be instance of Symbol, String or Pluggaloid::HandlerTag, but given #{slug.class}."
        end
  if block
    handlers = @events + @filters
    block.(tag)
    (@events + @filters - handlers).each do |handler|
      handler.add_tag(tag)
    end
  else
    tag
  end
end

#listeners(&block) ⇒ Object

イベントリスナを列挙する

Return

Set of Pluggaloid::Listener



224
225
226
227
228
229
230
# File 'lib/pluggaloid/plugin.rb', line 224

def listeners(&block)
  if block
    @events.each(&block)
  else
    @events.dup
  end
end

#onunload(&callback) ⇒ Object Also known as: on_unload

プラグインが Plugin.uninstall される時に呼ばれるブロックを登録する。



299
300
301
302
303
304
305
# File 'lib/pluggaloid/plugin.rb', line 299

def onunload(&callback)
  add_event(:unload) do |plugin_slug|
    if plugin_slug == self.name
      callback.call
    end
  end
end

#subscribe(event_name, *specs, **kwrest, &block) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/pluggaloid/plugin.rb', line 147

def subscribe(event_name, *specs, **kwrest, &block)
  if block
    result = vm.Subscriber.new(vm.Event[event_name], *specs, **kwrest, &block)
    @events << result
    result
  else
    Stream.new(
      Enumerator.new do |yielder|
        @events << vm.Subscriber.new(vm.Event[event_name], *specs, **kwrest) do |stream|
          stream.each(&yielder.method(:<<))
        end
      end.lazy
    )
  end
end

#subscribe?(event_name, *specs) ⇒ Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/pluggaloid/plugin.rb', line 163

def subscribe?(event_name, *specs)
  vm.Event[event_name].subscribe?(*specs)
end

#uninstallObject

このプラグインを破棄する

Return

self



269
270
271
272
273
274
275
276
# File 'lib/pluggaloid/plugin.rb', line 269

def uninstall
vm.Event[:unload].call(self.name)
vm.Delayer.new do
  @events.map(&:detach)
  @filters.map(&:detach)
  self.class.destroy name
end
self end