pluggaloid 1.4.1 → 1.5.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/lib/pluggaloid.rb +4 -2
- data/lib/pluggaloid/error.rb +2 -0
- data/lib/pluggaloid/event.rb +33 -5
- data/lib/pluggaloid/plugin.rb +6 -1
- data/lib/pluggaloid/stream_generator.rb +88 -0
- data/lib/pluggaloid/subscriber.rb +1 -1
- data/lib/pluggaloid/version.rb +1 -1
- data/test/generate_test.rb +117 -0
- data/test/handle_in_generate_test.rb +59 -0
- data/test/reactive_test.rb +10 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb97cc313e04d222f6f4513ce075cffb211337e5d4bda1f95b6be810d6faeee5
|
4
|
+
data.tar.gz: af791c5310e60264c2e0ea17591bd9e5baf65e57a5c2c97e8d0ba282c751cf11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36d56d8c824ec9e6f5486316aaf928bb9cd5a5a9966ec621150dac344cc8c3b9180e7ba51299aeb65b8332ce587e7ba9a82a963aa05024878247ef0000a40335
|
7
|
+
data.tar.gz: 937450b9967accb7197a16b4a1815aa11ed7bd7e86d933302392d04b32c6e7e055978a5878d4974bd45e610929def0e66bfaf27c0c3c9255a96233a4f7f9eef4
|
data/lib/pluggaloid.rb
CHANGED
@@ -8,13 +8,14 @@ require "pluggaloid/handler"
|
|
8
8
|
require 'pluggaloid/listener'
|
9
9
|
require 'pluggaloid/subscriber'
|
10
10
|
require 'pluggaloid/filter'
|
11
|
+
require 'pluggaloid/stream_generator'
|
11
12
|
require "pluggaloid/handler_tag"
|
12
13
|
require 'pluggaloid/error'
|
13
14
|
|
14
15
|
require 'delayer'
|
15
16
|
|
16
17
|
module Pluggaloid
|
17
|
-
VM = Struct.new(*%i<Delayer Plugin Event Listener Filter HandlerTag Subscriber>, keyword_init: true)
|
18
|
+
VM = Struct.new(*%i<Delayer Plugin Event Listener Filter HandlerTag Subscriber StreamGenerator>, keyword_init: true)
|
18
19
|
|
19
20
|
class PrototypeStream; end
|
20
21
|
class PrototypeCollect; end
|
@@ -28,7 +29,8 @@ module Pluggaloid
|
|
28
29
|
Listener: Class.new(Listener),
|
29
30
|
Filter: Class.new(Filter),
|
30
31
|
HandlerTag: Class.new(HandlerTag),
|
31
|
-
Subscriber: Class.new(Subscriber)
|
32
|
+
Subscriber: Class.new(Subscriber),
|
33
|
+
StreamGenerator: Class.new(StreamGenerator))
|
32
34
|
vm.Plugin.vm = vm.Event.vm = vm
|
33
35
|
end
|
34
36
|
end
|
data/lib/pluggaloid/error.rb
CHANGED
data/lib/pluggaloid/event.rb
CHANGED
@@ -18,7 +18,8 @@ class Pluggaloid::Event
|
|
18
18
|
@options = {}
|
19
19
|
@listeners = [].freeze
|
20
20
|
@filters = [].freeze
|
21
|
-
@subscribers = {}
|
21
|
+
@subscribers = Hash.new { |h, k| h[k] = [] }
|
22
|
+
@stream_generators = Hash.new { |h, k| h[k] = Set.new }
|
22
23
|
end
|
23
24
|
|
24
25
|
def prototype
|
@@ -89,19 +90,29 @@ class Pluggaloid::Event
|
|
89
90
|
end
|
90
91
|
@listeners = [*@listeners, listener].freeze
|
91
92
|
end
|
93
|
+
@stream_generators.values.each do |generators|
|
94
|
+
generators.each(&:on_subscribed)
|
95
|
+
end
|
92
96
|
when Pluggaloid::Subscriber
|
97
|
+
accepted_hash = listener.accepted_hash
|
93
98
|
Lock.synchronize do
|
94
|
-
@subscribers[
|
95
|
-
@subscribers[listener.accepted_hash] << listener
|
99
|
+
@subscribers[accepted_hash] << listener
|
96
100
|
end
|
101
|
+
@stream_generators.fetch(accepted_hash, nil)&.each(&:on_subscribed)
|
97
102
|
else
|
98
103
|
raise Pluggaloid::ArgumentError, "First argument must be Pluggaloid::Listener or Pluggaloid::Subscriber, but given #{listener.class}."
|
99
104
|
end
|
100
105
|
self
|
101
106
|
end
|
102
107
|
|
103
|
-
|
104
|
-
|
108
|
+
# subscribe(_*specs_) で、ストリームの受信をしようとしているリスナが定義されていればtrueを返す。
|
109
|
+
# on_* で通常のイベントリスナが登録されて居る場合は、 _*specs_ の内容に関わらず常にtrueを返す。
|
110
|
+
def subscribe?(*specs)
|
111
|
+
!@listeners.empty? || @subscribers.key?(argument_hash(specs, nil))
|
112
|
+
end
|
113
|
+
|
114
|
+
def subscribe_hash?(hash) # :nodoc:
|
115
|
+
!@listeners.empty? || @subscribers.key?(hash)
|
105
116
|
end
|
106
117
|
|
107
118
|
def delete_listener(listener)
|
@@ -121,6 +132,18 @@ class Pluggaloid::Event
|
|
121
132
|
@subscribers.delete(listener.accepted_hash)
|
122
133
|
end
|
123
134
|
end
|
135
|
+
@stream_generators.fetch(listener.accepted_hash, nil)&.each(&:on_unsubscribed)
|
136
|
+
self
|
137
|
+
end
|
138
|
+
|
139
|
+
def delete_stream_generator(listener)
|
140
|
+
Lock.synchronize do
|
141
|
+
ss = @stream_generators[listener.accepted_hash]
|
142
|
+
ss.delete(listener)
|
143
|
+
if ss.empty?
|
144
|
+
@stream_generators.delete(listener.accepted_hash)
|
145
|
+
end
|
146
|
+
end
|
124
147
|
self
|
125
148
|
end
|
126
149
|
|
@@ -193,6 +216,11 @@ class Pluggaloid::Event
|
|
193
216
|
end
|
194
217
|
end
|
195
218
|
|
219
|
+
def register_stream_generator(stream_generator)
|
220
|
+
@stream_generators[stream_generator.accepted_hash] << stream_generator
|
221
|
+
self
|
222
|
+
end
|
223
|
+
|
196
224
|
def collection_add_event
|
197
225
|
self.class['%{name}__add' % {name: name}]
|
198
226
|
end
|
data/lib/pluggaloid/plugin.rb
CHANGED
@@ -24,7 +24,8 @@ module Pluggaloid
|
|
24
24
|
Listener: Pluggaloid::Listener,
|
25
25
|
Filter: Pluggaloid::Filter,
|
26
26
|
HandlerTag: Pluggaloid::HandlerTag,
|
27
|
-
Subscriber: Pluggaloid::Subscriber
|
27
|
+
Subscriber: Pluggaloid::Subscriber,
|
28
|
+
StreamGenerator: Pluggaloid::StreamGenerator
|
28
29
|
)
|
29
30
|
vm.Event.vm = vm end end
|
30
31
|
|
@@ -139,6 +140,10 @@ module Pluggaloid
|
|
139
140
|
@filters << result
|
140
141
|
result end
|
141
142
|
|
143
|
+
def generate(event_name, *specs, **kwrest, &block)
|
144
|
+
vm.StreamGenerator.new(vm.Event[event_name], *specs, plugin: self, **kwrest, &block)
|
145
|
+
end
|
146
|
+
|
142
147
|
def subscribe(event_name, *specs, **kwrest, &block)
|
143
148
|
if block
|
144
149
|
result = vm.Subscriber.new(vm.Event[event_name], *specs, **kwrest, &block)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'securerandom'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
class Pluggaloid::StreamGenerator < Pluggaloid::Handler
|
6
|
+
attr_reader :accepted_hash
|
7
|
+
|
8
|
+
def initialize(event, *specs, plugin:, **kwrest, &callback)
|
9
|
+
raise Pluggaloid::UndefinedStreamIndexError, 'To call generate(%{event}), it must define prototype arguments include `Pluggaloid::STREAM\'.' % {event: event.name} unless event.stream_index
|
10
|
+
super(event, **kwrest)
|
11
|
+
@callback = callback
|
12
|
+
@specs = specs.freeze
|
13
|
+
@accepted_hash = @event.argument_hash(specs, nil)
|
14
|
+
@last_subscribe_state = @event.subscribe?(*@specs)
|
15
|
+
@plugin = plugin
|
16
|
+
subscribe_start if @last_subscribe_state
|
17
|
+
@event.register_stream_generator(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_subscribed
|
21
|
+
if !@last_subscribe_state
|
22
|
+
@last_subscribe_state = true
|
23
|
+
subscribe_start
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_unsubscribed
|
28
|
+
subscribe_state = @event.subscribe_hash?(@accepted_hash)
|
29
|
+
if @last_subscribe_state && !subscribe_state
|
30
|
+
@last_subscribe_state = false
|
31
|
+
subscribe_stop
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# このリスナを削除する
|
36
|
+
# ==== Return
|
37
|
+
# self
|
38
|
+
def detach
|
39
|
+
@event.delete_stream_generator(self)
|
40
|
+
@yielder&.die
|
41
|
+
@yielder = nil
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def subscribe_start
|
48
|
+
@tag = @plugin.handler_tag do
|
49
|
+
@yielder = Yielder.new(@event, args: @specs)
|
50
|
+
@callback.call(@yielder)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def subscribe_stop
|
55
|
+
@plugin.detach(@tag)
|
56
|
+
@yielder.die
|
57
|
+
@yielder = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
class Yielder
|
61
|
+
def initialize(event, args:)
|
62
|
+
@event = event
|
63
|
+
@args = args.freeze
|
64
|
+
@alive = true
|
65
|
+
end
|
66
|
+
|
67
|
+
def bulk_add(lst)
|
68
|
+
raise Pluggaloid::NoReceiverError, "All event listener of #{self.class} already detached." if die?
|
69
|
+
args = @args.dup
|
70
|
+
args.insert(@event.stream_index, lst)
|
71
|
+
@event.call(*args)
|
72
|
+
end
|
73
|
+
|
74
|
+
def add(value)
|
75
|
+
bulk_add([value])
|
76
|
+
end
|
77
|
+
alias_method :<<, :add
|
78
|
+
|
79
|
+
def die?
|
80
|
+
!@alive
|
81
|
+
end
|
82
|
+
|
83
|
+
def die
|
84
|
+
@alive = false
|
85
|
+
freeze
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -12,7 +12,7 @@ class Pluggaloid::Subscriber < Pluggaloid::Handler
|
|
12
12
|
# [tags:] Pluggaloid::HandlerTag|Array リスナのタグ
|
13
13
|
# [&callback] コールバック
|
14
14
|
def initialize(event, *specs, **kwrest, &callback)
|
15
|
-
raise Pluggaloid::UndefinedStreamIndexError, 'To call subscribe(), it must define prototype arguments include `Pluggaloid::STREAM\'.' unless event.stream_index
|
15
|
+
raise Pluggaloid::UndefinedStreamIndexError, 'To call subscribe(%{event}), it must define prototype arguments include `Pluggaloid::STREAM\'.' % {event: event.name} unless event.stream_index
|
16
16
|
super(event, **kwrest)
|
17
17
|
@callback = callback
|
18
18
|
@accepted_hash = @event.argument_hash(specs, nil)
|
data/lib/pluggaloid/version.rb
CHANGED
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
describe 'event' do
|
18
|
+
before do
|
19
|
+
log = @log = []
|
20
|
+
Pluggaloid::Plugin.create(:event) do
|
21
|
+
defevent :list, prototype: [Integer, Pluggaloid::STREAM]
|
22
|
+
|
23
|
+
generate(:list, 1) do |yielder|
|
24
|
+
log << [:g1, :start]
|
25
|
+
on_tick do |digit|
|
26
|
+
log << [:g1, digit]
|
27
|
+
yielder << digit
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'does not call generate block in not subscribed' do
|
34
|
+
assert_equal([], @log)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does not call generate block in subscribed other caller arguments' do
|
38
|
+
Pluggaloid::Plugin.create(:event) do
|
39
|
+
subscribe(:list, 2) {}
|
40
|
+
end
|
41
|
+
assert_equal([], @log)
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'after subscribe' do
|
45
|
+
before do
|
46
|
+
listener = nil
|
47
|
+
Pluggaloid::Plugin.create(:event) do
|
48
|
+
listener = subscribe(:list, 1) {}
|
49
|
+
end
|
50
|
+
@listener = listener
|
51
|
+
eval_all_events
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'call generate block' do
|
55
|
+
assert_equal([[:g1, :start]], @log)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'call once generate block if subscribe twice' do
|
59
|
+
Pluggaloid::Plugin.create(:event) do
|
60
|
+
subscribe(:list, 1) {}
|
61
|
+
end
|
62
|
+
eval_all_events
|
63
|
+
assert_equal([[:g1, :start]], @log)
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'detach all listeners' do
|
67
|
+
before do
|
68
|
+
Pluggaloid::Plugin.create(:event).detach(@listener)
|
69
|
+
Pluggaloid::Plugin.call(:event, 1, [69])
|
70
|
+
eval_all_events
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should detach handlers in generate block after unsubscribed' do
|
74
|
+
assert_equal([[:g1, :start]], @log)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'after add_event_listener' do
|
81
|
+
before do
|
82
|
+
listener = nil
|
83
|
+
Pluggaloid::Plugin.create(:event) do
|
84
|
+
listener = on_list { |_num, _lst| ; }
|
85
|
+
end
|
86
|
+
@listener = listener
|
87
|
+
eval_all_events
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'call generate block' do
|
91
|
+
assert_equal([[:g1, :start]], @log)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'call once generate block if subscribe twice' do
|
95
|
+
Pluggaloid::Plugin.create(:event) do
|
96
|
+
on_list { |_num, _lst| ; }
|
97
|
+
end
|
98
|
+
eval_all_events
|
99
|
+
assert_equal([[:g1, :start]], @log)
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'detach all listeners' do
|
103
|
+
before do
|
104
|
+
Pluggaloid::Plugin.create(:event).detach(@listener)
|
105
|
+
Pluggaloid::Plugin.call(:event, 1, [105])
|
106
|
+
eval_all_events
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'detach handlers in generate block after unsubscribed' do
|
110
|
+
assert_equal([[:g1, :start]], @log)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
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 'hoge' do
|
18
|
+
refute Pluggaloid::Event[:tick].subscribe?
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'event' do
|
22
|
+
before do
|
23
|
+
log = @log = []
|
24
|
+
listener = nil
|
25
|
+
Pluggaloid::Plugin.create(:event) do
|
26
|
+
defevent :list, prototype: [Integer, Pluggaloid::STREAM]
|
27
|
+
|
28
|
+
generate(:list, 1) do |yielder|
|
29
|
+
log << [:g1, :start]
|
30
|
+
on_tick do |digit|
|
31
|
+
log << [:g1, digit]
|
32
|
+
yielder << digit
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
listener = subscribe(:list, 1) do |stream|
|
37
|
+
;
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@listener = listener
|
41
|
+
eval_all_events
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'subscribed event which define in generate block' do
|
45
|
+
assert Pluggaloid::Event[:tick].subscribe?
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'unsubscribe generate stream' do
|
49
|
+
before do
|
50
|
+
Pluggaloid::Plugin.create(:event).detach(@listener)
|
51
|
+
eval_all_events
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'unsubscribed event which define in generate block' do
|
55
|
+
refute Pluggaloid::Event[:tick].subscribe?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/test/reactive_test.rb
CHANGED
@@ -58,7 +58,7 @@ describe(Pluggaloid::Plugin) do
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
it "subscribe?" do
|
61
|
+
it "subscribe? first value" do
|
62
62
|
Pluggaloid::Plugin.create(:event) do
|
63
63
|
defevent :increase, prototype: [Integer, Pluggaloid::STREAM]
|
64
64
|
subscribe(:increase, 1) do |v|
|
@@ -66,7 +66,16 @@ describe(Pluggaloid::Plugin) do
|
|
66
66
|
end
|
67
67
|
assert(Pluggaloid::Plugin[:event].subscribe?(:increase, 1))
|
68
68
|
refute(Pluggaloid::Plugin[:event].subscribe?(:increase, 2))
|
69
|
+
end
|
69
70
|
|
71
|
+
it "subscribe? last value" do
|
72
|
+
Pluggaloid::Plugin.create(:event) do
|
73
|
+
defevent :increase, prototype: [Pluggaloid::STREAM, Integer]
|
74
|
+
subscribe(:increase, 1) do |v|
|
75
|
+
end
|
76
|
+
end
|
77
|
+
assert(Pluggaloid::Plugin[:event].subscribe?(:increase, 1))
|
78
|
+
refute(Pluggaloid::Plugin[:event].subscribe?(:increase, 2))
|
70
79
|
end
|
71
80
|
|
72
81
|
it "subscribe? returns always true if plugin listener exist" do
|
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.5.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: 2020-
|
11
|
+
date: 2020-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: delayer
|
@@ -116,10 +116,13 @@ files:
|
|
116
116
|
- lib/pluggaloid/listener.rb
|
117
117
|
- lib/pluggaloid/plugin.rb
|
118
118
|
- lib/pluggaloid/stream.rb
|
119
|
+
- lib/pluggaloid/stream_generator.rb
|
119
120
|
- lib/pluggaloid/subscriber.rb
|
120
121
|
- lib/pluggaloid/version.rb
|
121
122
|
- pluggaloid.gemspec
|
122
123
|
- test/collect_test.rb
|
124
|
+
- test/generate_test.rb
|
125
|
+
- test/handle_in_generate_test.rb
|
123
126
|
- test/handler_tag_test.rb
|
124
127
|
- test/helper.rb
|
125
128
|
- test/multi_vm_test.rb
|
@@ -150,6 +153,8 @@ specification_version: 4
|
|
150
153
|
summary: Extensible plugin system
|
151
154
|
test_files:
|
152
155
|
- test/collect_test.rb
|
156
|
+
- test/generate_test.rb
|
157
|
+
- test/handle_in_generate_test.rb
|
153
158
|
- test/handler_tag_test.rb
|
154
159
|
- test/helper.rb
|
155
160
|
- test/multi_vm_test.rb
|