pluggaloid 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -0
- data/lib/pluggaloid/event.rb +50 -7
- data/lib/pluggaloid/plugin.rb +31 -7
- data/lib/pluggaloid/stream.rb +92 -0
- data/lib/pluggaloid/subscriber.rb +35 -0
- data/lib/pluggaloid/version.rb +1 -1
- data/lib/pluggaloid.rb +13 -7
- data/pluggaloid.gemspec +2 -2
- data/test/plugin_test.rb +8 -0
- data/test/reactive_test.rb +248 -0
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e068709da8ec715bcb2454af10c5b8cdf60f8da92b96357fef5996753af4930c
|
4
|
+
data.tar.gz: 4bd0da1c90d5bfa19a21f436e7f59b272f93804619386b6b30b6c3ecc42c23db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91f7e39fed67236f339ca54b72deff6d68b4bc5482ddcfb5fd589edadea3628532e6a71f239228989dc9928ceaf25a7af947ff5444bd733ff20d23714b392511
|
7
|
+
data.tar.gz: a625889e2d9b505d7713688b0bd744b2cc5b54ec4f396a007680a54d8f4c99aa3c99c48ce45ea6d9022b3c85028196adeb3765a0c30f99ba16fdeb51559273e9
|
data/README.md
CHANGED
@@ -54,6 +54,25 @@ Pluggaloid::newは、プラグイン機構を制御するためのDelayer, Plugi
|
|
54
54
|
|
55
55
|
コンストラクタの唯一の引数には `Delayer.generate_class(priority: %i<high normal low>, default: :normal)`のように、優先順位付きでデフォルト優先度が設定されたDelayerを渡します。
|
56
56
|
|
57
|
+
## Reactive Filter
|
58
|
+
|
59
|
+
### each_slice(times)
|
60
|
+
|
61
|
+
_times_ 要素ずつブロックに渡して繰り返します。
|
62
|
+
要素数が _times_ で割り切れないときは、要素が _times_ 個になるまで待ちます。
|
63
|
+
|
64
|
+
### throttle(sec)
|
65
|
+
|
66
|
+
最後に要素を受信してから、 _sec_ 秒の間に受信した要素を捨てます。
|
67
|
+
|
68
|
+
### debounce(sec)
|
69
|
+
|
70
|
+
_sec_ 秒要素を受信しなかった場合、最後の要素を送信する。
|
71
|
+
|
72
|
+
### buffer(sec)
|
73
|
+
|
74
|
+
_sec_ 秒の間に受信した要素を、 _sec_ 秒ごとに配列にまとめて送信する。
|
75
|
+
|
57
76
|
## Contributing
|
58
77
|
|
59
78
|
1. Fork it ( https://github.com/toshia/pluggaloid/fork )
|
data/lib/pluggaloid/event.rb
CHANGED
@@ -18,6 +18,7 @@ class Pluggaloid::Event
|
|
18
18
|
@options = {}
|
19
19
|
@listeners = [].freeze
|
20
20
|
@filters = [].freeze
|
21
|
+
@subscribers = {}
|
21
22
|
end
|
22
23
|
|
23
24
|
def vm
|
@@ -62,18 +63,29 @@ class Pluggaloid::Event
|
|
62
63
|
event_filter.filtering(*acm) } } end
|
63
64
|
|
64
65
|
def add_listener(listener)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
case listener
|
67
|
+
when Pluggaloid::Listener
|
68
|
+
Lock.synchronize do
|
69
|
+
if @listeners.map(&:slug).include?(listener.slug)
|
70
|
+
raise Pluggaloid::DuplicateListenerSlugError, "Listener slug #{listener.slug} already exists."
|
71
|
+
end
|
72
|
+
@listeners = [*@listeners, listener].freeze
|
73
|
+
end
|
74
|
+
when Pluggaloid::Subscriber
|
75
|
+
Lock.synchronize do
|
76
|
+
@subscribers[listener.accepted_hash] ||= []
|
77
|
+
@subscribers[listener.accepted_hash] << listener
|
71
78
|
end
|
72
|
-
|
79
|
+
else
|
80
|
+
raise Pluggaloid::ArgumentError, "First argument must be Pluggaloid::Listener or Pluggaloid::Subscriber, but given #{listener.class}."
|
73
81
|
end
|
74
82
|
self
|
75
83
|
end
|
76
84
|
|
85
|
+
def subscribe?(*args)
|
86
|
+
!@listeners.empty? || @subscribers.key?(argument_hash(args))
|
87
|
+
end
|
88
|
+
|
77
89
|
def delete_listener(listener)
|
78
90
|
Lock.synchronize do
|
79
91
|
@listeners = @listeners.dup
|
@@ -83,6 +95,17 @@ class Pluggaloid::Event
|
|
83
95
|
self
|
84
96
|
end
|
85
97
|
|
98
|
+
def delete_subscriber(listener)
|
99
|
+
Lock.synchronize do
|
100
|
+
ss = @subscribers[listener.accepted_hash]
|
101
|
+
ss.delete(listener)
|
102
|
+
if ss.empty?
|
103
|
+
@subscribers.delete(listener.accepted_hash)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
86
109
|
# イベントフィルタを追加する
|
87
110
|
# ==== Args
|
88
111
|
# [event_filter] イベントフィルタ(Filter)
|
@@ -109,8 +132,28 @@ class Pluggaloid::Event
|
|
109
132
|
self
|
110
133
|
end
|
111
134
|
|
135
|
+
def argument_hash(args)
|
136
|
+
args.each_with_index.map do |item, i|
|
137
|
+
if i != yield_index
|
138
|
+
item.hash
|
139
|
+
end
|
140
|
+
end.compact.freeze
|
141
|
+
end
|
142
|
+
|
143
|
+
def yield_index
|
144
|
+
unless defined?(@yield_index)
|
145
|
+
@yield_index = self.options[:prototype].index(Pluggaloid::STREAM)
|
146
|
+
end
|
147
|
+
@yield_index
|
148
|
+
end
|
149
|
+
|
112
150
|
private
|
113
151
|
def call_all_listeners(args)
|
152
|
+
if yield_index
|
153
|
+
@subscribers[argument_hash(args)]&.each do |subscriber|
|
154
|
+
subscriber.call(*args)
|
155
|
+
end
|
156
|
+
end
|
114
157
|
catch(:plugin_exit) do
|
115
158
|
@listeners.each do |listener|
|
116
159
|
listener.call(*args)
|
data/lib/pluggaloid/plugin.rb
CHANGED
@@ -18,12 +18,14 @@ module Pluggaloid
|
|
18
18
|
@vm ||= begin
|
19
19
|
raise Pluggaloid::NoDefaultDelayerError, "Default Delayer was not set." unless Delayer.default
|
20
20
|
vm = Pluggaloid::VM.new(
|
21
|
-
Delayer.default,
|
22
|
-
self,
|
23
|
-
Pluggaloid::Event,
|
24
|
-
Pluggaloid::Listener,
|
25
|
-
Pluggaloid::Filter,
|
26
|
-
Pluggaloid::HandlerTag
|
21
|
+
Delayer: Delayer.default,
|
22
|
+
Plugin: self,
|
23
|
+
Event: Pluggaloid::Event,
|
24
|
+
Listener: Pluggaloid::Listener,
|
25
|
+
Filter: Pluggaloid::Filter,
|
26
|
+
HandlerTag: Pluggaloid::HandlerTag,
|
27
|
+
Subscriber: Pluggaloid::Subscriber
|
28
|
+
)
|
27
29
|
vm.Event.vm = vm end end
|
28
30
|
|
29
31
|
# プラグインのインスタンスを返す。
|
@@ -126,6 +128,26 @@ module Pluggaloid
|
|
126
128
|
@filters << result
|
127
129
|
result end
|
128
130
|
|
131
|
+
def subscribe(event_name, *specs, **kwrest, &block)
|
132
|
+
if block
|
133
|
+
result = vm.Subscriber.new(vm.Event[event_name], *specs, **kwrest, &block)
|
134
|
+
@events << result
|
135
|
+
result
|
136
|
+
else
|
137
|
+
Stream.new(
|
138
|
+
Enumerator.new do |yielder|
|
139
|
+
@events << vm.Subscriber.new(vm.Event[event_name], *specs, **kwrest) do |stream|
|
140
|
+
stream.each(&yielder.method(:<<))
|
141
|
+
end
|
142
|
+
end.lazy
|
143
|
+
)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def subscribe?(event_name, *specs)
|
148
|
+
vm.Event[event_name].subscribe?(*specs)
|
149
|
+
end
|
150
|
+
|
129
151
|
# このプラグインのHandlerTagを作る。
|
130
152
|
# ブロックが渡された場合は、ブロックの中を実行し、ブロックの中で定義された
|
131
153
|
# Handler全てにTagを付与する。
|
@@ -187,7 +209,7 @@ module Pluggaloid
|
|
187
209
|
def detach(*args)
|
188
210
|
listener = args.last
|
189
211
|
case listener
|
190
|
-
when vm.Listener
|
212
|
+
when vm.Listener, vm.Subscriber
|
191
213
|
@events.delete(listener)
|
192
214
|
listener.detach
|
193
215
|
when vm.Filter
|
@@ -253,6 +275,8 @@ module Pluggaloid
|
|
253
275
|
when method_name.start_with?('filter')
|
254
276
|
event_name = method_name[(method_name[6] == '_' ? 7 : 6)..method_name.size]
|
255
277
|
add_event_filter(event_name.to_sym, **kwrest, &proc)
|
278
|
+
else
|
279
|
+
super
|
256
280
|
end
|
257
281
|
end
|
258
282
|
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pluggaloid
|
4
|
+
class Stream
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
def initialize(enumerator)
|
8
|
+
@enumerator = enumerator
|
9
|
+
end
|
10
|
+
|
11
|
+
def throttle(sec)
|
12
|
+
throttling = 0
|
13
|
+
@enumerator.select do |item|
|
14
|
+
r0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
15
|
+
if throttling <= r0
|
16
|
+
throttling = r0 + sec
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def debounce(sec)
|
22
|
+
throttling_promise = nil
|
23
|
+
Stream.new(
|
24
|
+
Enumerator.new do |yielder|
|
25
|
+
@enumerator.each do |item|
|
26
|
+
throttling_promise&.cancel
|
27
|
+
throttling_promise = Delayer.new(delay: sec) do
|
28
|
+
yielder << item
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end.lazy
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def buffer(sec)
|
36
|
+
throttling_promise = nil
|
37
|
+
buffer = []
|
38
|
+
Stream.new(
|
39
|
+
Enumerator.new do |yielder|
|
40
|
+
@enumerator.each do |item|
|
41
|
+
buffer << item
|
42
|
+
throttling_promise ||= Delayer.new(delay: sec) do
|
43
|
+
yielder << buffer.freeze
|
44
|
+
buffer = []
|
45
|
+
throttling_promise = nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end.lazy
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def merge(*streams)
|
53
|
+
Stream.new(Merge.new(self, *streams).lazy)
|
54
|
+
end
|
55
|
+
|
56
|
+
(Enumerator.instance_methods - Enumerator.superclass.instance_methods).each do |method_name|
|
57
|
+
define_method(method_name) do |*rest, **kwrest, &block|
|
58
|
+
if kwrest.empty?
|
59
|
+
r = @enumerator.__send__(method_name, *rest, &block)
|
60
|
+
else
|
61
|
+
r = @enumerator.__send__(method_name, *rest, **kwrest, &block)
|
62
|
+
end
|
63
|
+
if r.is_a?(Enumerator::Lazy)
|
64
|
+
Pluggaloid::Stream.new(r)
|
65
|
+
else
|
66
|
+
r
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Merge
|
72
|
+
include Enumerable
|
73
|
+
|
74
|
+
def initialize(*sources)
|
75
|
+
@sources = sources
|
76
|
+
end
|
77
|
+
|
78
|
+
def each(&block)
|
79
|
+
fiber = Fiber.new do
|
80
|
+
loop do
|
81
|
+
block.call(Fiber.yield)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
fiber.resume
|
85
|
+
@sources.each do |source|
|
86
|
+
source.each(&fiber.method(:resume))
|
87
|
+
end
|
88
|
+
self
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'securerandom'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
class Pluggaloid::Subscriber < Pluggaloid::Handler
|
6
|
+
attr_reader :accepted_hash
|
7
|
+
|
8
|
+
# ==== Args
|
9
|
+
# [event] 監視するEventのインスタンス
|
10
|
+
# [name:] 名前(String | nil)
|
11
|
+
# [slug:] イベントリスナスラッグ(Symbol | nil)
|
12
|
+
# [tags:] Pluggaloid::HandlerTag|Array リスナのタグ
|
13
|
+
# [&callback] コールバック
|
14
|
+
def initialize(event, *specs, **kwrest, &callback)
|
15
|
+
super(event, **kwrest)
|
16
|
+
@callback = callback
|
17
|
+
@accepted_hash = @event.argument_hash(specs)
|
18
|
+
event.add_listener(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
# イベントを実行する
|
22
|
+
# ==== Args
|
23
|
+
# [stream] イベントの引数
|
24
|
+
def call(*args)
|
25
|
+
@callback.call(args[@event.yield_index])
|
26
|
+
end
|
27
|
+
|
28
|
+
# このリスナを削除する
|
29
|
+
# ==== Return
|
30
|
+
# self
|
31
|
+
def detach
|
32
|
+
@event.delete_subscriber(self)
|
33
|
+
self
|
34
|
+
end
|
35
|
+
end
|
data/lib/pluggaloid/version.rb
CHANGED
data/lib/pluggaloid.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require "pluggaloid/version"
|
2
2
|
require "pluggaloid/plugin"
|
3
|
+
require 'pluggaloid/stream'
|
3
4
|
require 'pluggaloid/event'
|
4
5
|
require "pluggaloid/identity"
|
5
6
|
require "pluggaloid/handler"
|
6
7
|
require 'pluggaloid/listener'
|
8
|
+
require 'pluggaloid/subscriber'
|
7
9
|
require 'pluggaloid/filter'
|
8
10
|
require "pluggaloid/handler_tag"
|
9
11
|
require 'pluggaloid/error'
|
@@ -11,15 +13,19 @@ require 'pluggaloid/error'
|
|
11
13
|
require 'delayer'
|
12
14
|
|
13
15
|
module Pluggaloid
|
14
|
-
VM = Struct.new(*%i<Delayer Plugin Event Listener Filter HandlerTag
|
16
|
+
VM = Struct.new(*%i<Delayer Plugin Event Listener Filter HandlerTag Subscriber>, keyword_init: true)
|
17
|
+
|
18
|
+
class PrototypeStream; end
|
19
|
+
STREAM = PrototypeStream.new.freeze
|
15
20
|
|
16
21
|
def self.new(delayer)
|
17
|
-
vm = VM.new(delayer,
|
18
|
-
Class.new(Plugin),
|
19
|
-
Class.new(Event),
|
20
|
-
Class.new(Listener),
|
21
|
-
Class.new(Filter),
|
22
|
-
Class.new(HandlerTag)
|
22
|
+
vm = VM.new(Delayer: delayer,
|
23
|
+
Plugin: Class.new(Plugin),
|
24
|
+
Event: Class.new(Event),
|
25
|
+
Listener: Class.new(Listener),
|
26
|
+
Filter: Class.new(Filter),
|
27
|
+
HandlerTag: Class.new(HandlerTag),
|
28
|
+
Subscriber: Class.new(Subscriber))
|
23
29
|
vm.Plugin.vm = vm.Event.vm = vm
|
24
30
|
end
|
25
31
|
end
|
data/pluggaloid.gemspec
CHANGED
@@ -18,9 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.required_ruby_version = '>= 2.
|
21
|
+
spec.required_ruby_version = '>= 2.5.0'
|
22
22
|
|
23
|
-
spec.add_dependency 'delayer', '>= 1.
|
23
|
+
spec.add_dependency 'delayer', '>= 1.1.0', '< 2.0'
|
24
24
|
spec.add_dependency 'instance_storage', ">= 1.0.0", "< 2.0.0"
|
25
25
|
|
26
26
|
spec.add_development_dependency "bundler"
|
data/test/plugin_test.rb
CHANGED
@@ -0,0 +1,248 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
require 'pluggaloid'
|
7
|
+
require_relative 'helper'
|
8
|
+
|
9
|
+
describe(Pluggaloid::Plugin) do
|
10
|
+
include PluggaloidTestHelper
|
11
|
+
|
12
|
+
before do
|
13
|
+
Delayer.default = Delayer.generate_class(priority: %i<high normal low>, default: :normal)
|
14
|
+
Pluggaloid::Plugin.clear!
|
15
|
+
end
|
16
|
+
|
17
|
+
it "subscribe" do
|
18
|
+
sum = []
|
19
|
+
|
20
|
+
Pluggaloid::Plugin.create(:event) do
|
21
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
22
|
+
subscribe(:increase, 1) do |v|
|
23
|
+
sum = v
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
eval_all_events do
|
28
|
+
Pluggaloid::Event[:increase].call(1, [:one])
|
29
|
+
Pluggaloid::Event[:increase].call(2, [:two])
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_equal(%i[one], sum)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "subscribe?" do
|
36
|
+
sum = []
|
37
|
+
|
38
|
+
Pluggaloid::Plugin.create(:event) do
|
39
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
40
|
+
subscribe(:increase, 1) do |v|
|
41
|
+
end
|
42
|
+
end
|
43
|
+
assert(Pluggaloid::Plugin[:event].subscribe?(:increase, 1))
|
44
|
+
refute(Pluggaloid::Plugin[:event].subscribe?(:increase, 2))
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
it "subscribe? returns always true if plugin listener exist" do
|
49
|
+
sum = []
|
50
|
+
|
51
|
+
Pluggaloid::Plugin.create(:event) do
|
52
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
53
|
+
on_increase do |i, y|
|
54
|
+
end
|
55
|
+
end
|
56
|
+
assert(Pluggaloid::Plugin[:event].subscribe?(:increase, 1))
|
57
|
+
assert(Pluggaloid::Plugin[:event].subscribe?(:increase, 2))
|
58
|
+
end
|
59
|
+
|
60
|
+
it "subscribe enumerable" do
|
61
|
+
sum = []
|
62
|
+
|
63
|
+
Pluggaloid::Plugin.create(:event) do
|
64
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
65
|
+
subscribe(:increase, 1).each do |v|
|
66
|
+
sum = v
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
eval_all_events do
|
71
|
+
Pluggaloid::Event[:increase].call(1, [:one])
|
72
|
+
Pluggaloid::Event[:increase].call(2, [:two])
|
73
|
+
end
|
74
|
+
|
75
|
+
assert_equal(:one, sum)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "detach" do
|
79
|
+
sum = 0
|
80
|
+
subscriber = nil
|
81
|
+
Pluggaloid::Plugin.create(:event) do
|
82
|
+
defevent :increase, prototype: [Pluggaloid::STREAM]
|
83
|
+
subscriber = subscribe(:increase) do |v|
|
84
|
+
sum += v
|
85
|
+
end
|
86
|
+
end
|
87
|
+
eval_all_events do
|
88
|
+
Pluggaloid::Event[:increase].call(1)
|
89
|
+
end
|
90
|
+
assert_equal(1, sum, "It should execute subscriber when event called")
|
91
|
+
|
92
|
+
eval_all_events do
|
93
|
+
Pluggaloid::Plugin[:event].detach subscriber
|
94
|
+
Pluggaloid::Event[:increase].call(1)
|
95
|
+
end
|
96
|
+
assert_equal(1, sum, "It should not execute detached subscriber when event called")
|
97
|
+
end
|
98
|
+
|
99
|
+
it "subscribe enumerable chain" do
|
100
|
+
sum = []
|
101
|
+
|
102
|
+
Pluggaloid::Plugin.create(:event) do
|
103
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
104
|
+
subscribe(:increase, 1).map{|v| v.to_s }.each do |v|
|
105
|
+
sum << v
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
eval_all_events do
|
110
|
+
Pluggaloid::Event[:increase].call(1, [:one])
|
111
|
+
Pluggaloid::Event[:increase].call(2, [:two])
|
112
|
+
Pluggaloid::Event[:increase].call(1, [:three])
|
113
|
+
end
|
114
|
+
|
115
|
+
assert_equal(%w[one three], sum)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "subscribe each_slice" do
|
119
|
+
sum = []
|
120
|
+
|
121
|
+
Pluggaloid::Plugin.create(:event) do
|
122
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
123
|
+
subscribe(:increase, 1).each_slice(3).each do |v|
|
124
|
+
sum << v
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
eval_all_events do
|
129
|
+
Pluggaloid::Event[:increase].call(1, 100.times)
|
130
|
+
end
|
131
|
+
|
132
|
+
assert_equal([0, 1, 2], sum.first)
|
133
|
+
assert_equal([96, 97, 98], sum.last)
|
134
|
+
assert_equal(33, sum.size)
|
135
|
+
|
136
|
+
eval_all_events do
|
137
|
+
Pluggaloid::Event[:increase].call(1, [100, 101])
|
138
|
+
end
|
139
|
+
|
140
|
+
assert_equal([99, 100, 101], sum.last)
|
141
|
+
assert_equal(34, sum.size)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "throttle" do
|
145
|
+
sum = []
|
146
|
+
|
147
|
+
Pluggaloid::Plugin.create(:event) do
|
148
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
149
|
+
subscribe(:increase, 1).throttle(0.001).each do |v|
|
150
|
+
sum << v
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
eval_all_events do
|
155
|
+
Pluggaloid::Event[:increase].call(1, (1..10).to_a)
|
156
|
+
Pluggaloid::Event[:increase].call(1, (11..20).to_a)
|
157
|
+
end
|
158
|
+
|
159
|
+
assert_equal(1, sum.last)
|
160
|
+
assert_equal(1, sum.size)
|
161
|
+
|
162
|
+
sleep 0.01
|
163
|
+
|
164
|
+
eval_all_events do
|
165
|
+
Pluggaloid::Event[:increase].call(1, (21..30).to_a)
|
166
|
+
end
|
167
|
+
|
168
|
+
assert_equal(21, sum.last)
|
169
|
+
assert_equal(2, sum.size)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "debounce" do
|
173
|
+
sum = []
|
174
|
+
|
175
|
+
Pluggaloid::Plugin.create(:event) do
|
176
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
177
|
+
subscribe(:increase, 1).debounce(0.01).each do |v|
|
178
|
+
sum << v
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
eval_all_events do
|
183
|
+
Pluggaloid::Event[:increase].call(1, (1..10).to_a)
|
184
|
+
Pluggaloid::Event[:increase].call(1, (11..20).to_a)
|
185
|
+
end
|
186
|
+
|
187
|
+
assert_equal(0, sum.size)
|
188
|
+
|
189
|
+
sleep 0.02
|
190
|
+
Delayer.run
|
191
|
+
|
192
|
+
assert_equal(1, sum.size)
|
193
|
+
assert_equal(20, sum.last)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "buffer" do
|
197
|
+
sum = []
|
198
|
+
|
199
|
+
Pluggaloid::Plugin.create(:event) do
|
200
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
201
|
+
subscribe(:increase, 1).buffer(0.01).each do |v|
|
202
|
+
sum << v
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
eval_all_events do
|
207
|
+
Pluggaloid::Event[:increase].call(1, (1..10).to_a)
|
208
|
+
Pluggaloid::Event[:increase].call(1, (11..20).to_a)
|
209
|
+
end
|
210
|
+
|
211
|
+
assert_equal(0, sum.size)
|
212
|
+
|
213
|
+
sleep 0.1
|
214
|
+
Delayer.run
|
215
|
+
Pluggaloid::Event[:increase].call(1, [21])
|
216
|
+
Delayer.run
|
217
|
+
|
218
|
+
assert_equal(1, sum.size)
|
219
|
+
assert_equal((1..20).to_a, sum.last)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "merge" do
|
223
|
+
sum = sum1 = sum2 = 0
|
224
|
+
Pluggaloid::Plugin.create(:event) do
|
225
|
+
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
226
|
+
subscribe(:increase, 1).each do |v|
|
227
|
+
sum1 += v
|
228
|
+
end
|
229
|
+
|
230
|
+
subscribe(:increase, 2).each do |v|
|
231
|
+
sum2 += v
|
232
|
+
end
|
233
|
+
|
234
|
+
subscribe(:increase, 1).merge(subscribe(:increase, 2)).each do |v|
|
235
|
+
sum += v
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
eval_all_events do
|
240
|
+
Pluggaloid::Event[:increase].call(1, (1..10).to_a)
|
241
|
+
Pluggaloid::Event[:increase].call(2, (11..20).to_a)
|
242
|
+
end
|
243
|
+
|
244
|
+
assert_equal((1..10).to_a.sum, sum1)
|
245
|
+
assert_equal((11..20).to_a.sum, sum2)
|
246
|
+
assert_equal((1..20).to_a.sum, sum)
|
247
|
+
end
|
248
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pluggaloid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toshiaki Asai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: delayer
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.1.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '2.0'
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.
|
29
|
+
version: 1.1.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2.0'
|
@@ -113,12 +113,15 @@ files:
|
|
113
113
|
- lib/pluggaloid/identity.rb
|
114
114
|
- lib/pluggaloid/listener.rb
|
115
115
|
- lib/pluggaloid/plugin.rb
|
116
|
+
- lib/pluggaloid/stream.rb
|
117
|
+
- lib/pluggaloid/subscriber.rb
|
116
118
|
- lib/pluggaloid/version.rb
|
117
119
|
- pluggaloid.gemspec
|
118
120
|
- test/handler_tag_test.rb
|
119
121
|
- test/helper.rb
|
120
122
|
- test/multi_vm_test.rb
|
121
123
|
- test/plugin_test.rb
|
124
|
+
- test/reactive_test.rb
|
122
125
|
homepage: https://rubygems.org/gems/pluggaloid
|
123
126
|
licenses:
|
124
127
|
- MIT
|
@@ -131,14 +134,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
134
|
requirements:
|
132
135
|
- - ">="
|
133
136
|
- !ruby/object:Gem::Version
|
134
|
-
version: 2.
|
137
|
+
version: 2.5.0
|
135
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
139
|
requirements:
|
137
140
|
- - ">="
|
138
141
|
- !ruby/object:Gem::Version
|
139
142
|
version: '0'
|
140
143
|
requirements: []
|
141
|
-
rubygems_version: 3.
|
144
|
+
rubygems_version: 3.1.2
|
142
145
|
signing_key:
|
143
146
|
specification_version: 4
|
144
147
|
summary: Extensible plugin system
|
@@ -147,3 +150,4 @@ test_files:
|
|
147
150
|
- test/helper.rb
|
148
151
|
- test/multi_vm_test.rb
|
149
152
|
- test/plugin_test.rb
|
153
|
+
- test/reactive_test.rb
|