vigilem-core 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/vigilem/core.rb +9 -0
- data/lib/vigilem/core/abstract_device.rb +97 -0
- data/lib/vigilem/core/adapters.rb +2 -0
- data/lib/vigilem/core/adapters/adapter.rb +57 -0
- data/lib/vigilem/core/adapters/basic_adapter.rb +43 -0
- data/lib/vigilem/core/adapters/buffered_adapter.rb +28 -0
- data/lib/vigilem/core/buffer.rb +151 -0
- data/lib/vigilem/core/buffer_handler.rb +95 -0
- data/lib/vigilem/core/default_buffer.rb +45 -0
- data/lib/vigilem/core/demultiplexer.rb +225 -0
- data/lib/vigilem/core/device.rb +43 -0
- data/lib/vigilem/core/event_handler.rb +156 -0
- data/lib/vigilem/core/eventable.rb +80 -0
- data/lib/vigilem/core/hooks.rb +36 -0
- data/lib/vigilem/core/hooks/callback.rb +66 -0
- data/lib/vigilem/core/hooks/callback_proc.rb +25 -0
- data/lib/vigilem/core/hooks/conditional_hook.rb +62 -0
- data/lib/vigilem/core/hooks/hook.rb +193 -0
- data/lib/vigilem/core/hooks/inheritable.rb +24 -0
- data/lib/vigilem/core/hooks/meta_callback.rb +53 -0
- data/lib/vigilem/core/hooks/utils.rb +23 -0
- data/lib/vigilem/core/hub.rb +50 -0
- data/lib/vigilem/core/input_system_handler.rb +55 -0
- data/lib/vigilem/core/lockable_pipeline_component.rb +30 -0
- data/lib/vigilem/core/multiplexer.rb +168 -0
- data/lib/vigilem/core/pipeline.rb +68 -0
- data/lib/vigilem/core/stat.rb +121 -0
- data/lib/vigilem/core/system.rb +9 -0
- data/lib/vigilem/core/system/check.rb +33 -0
- data/lib/vigilem/core/transfer_agent.rb +67 -0
- data/lib/vigilem/core/version.rb +5 -0
- data/spec/bug_notes.txt +12 -0
- data/spec/given_helper.rb +12 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/vigilem/core/abstract_device_spec.rb +103 -0
- data/spec/vigilem/core/adapters/adapter_spec.rb +28 -0
- data/spec/vigilem/core/adapters/basic_adapter_spec.rb +53 -0
- data/spec/vigilem/core/adapters/buffered_adapter_spec.rb +16 -0
- data/spec/vigilem/core/buffer_handler_spec.rb +51 -0
- data/spec/vigilem/core/buffer_spec.rb +236 -0
- data/spec/vigilem/core/default_buffer_spec.rb +17 -0
- data/spec/vigilem/core/demultiplexer_spec.rb +166 -0
- data/spec/vigilem/core/device_spec.rb +62 -0
- data/spec/vigilem/core/event_handler_spec.rb +134 -0
- data/spec/vigilem/core/hooks/callback_proc_spec.rb +66 -0
- data/spec/vigilem/core/hooks/hook_spec.rb +230 -0
- data/spec/vigilem/core/hooks/inheritable_spec.rb +19 -0
- data/spec/vigilem/core/hooks/meta_callback_spec.rb +69 -0
- data/spec/vigilem/core/hooks/utils_spec.rb +25 -0
- data/spec/vigilem/core/hooks_spec.rb +50 -0
- data/spec/vigilem/core/hub_spec.rb +51 -0
- data/spec/vigilem/core/input_system_handler_spec.rb +33 -0
- data/spec/vigilem/core/lockable_pipeline_component_spec.rb +19 -0
- data/spec/vigilem/core/multiplexer_spec.rb +113 -0
- data/spec/vigilem/core/pipeline_spec.rb +5 -0
- data/spec/vigilem/core/stat_spec.rb +63 -0
- data/spec/vigilem/core/system/check_spec.rb +24 -0
- data/spec/vigilem/core/system_spec.rb +29 -0
- data/spec/vigilem/core/transfer_agent_spec.rb +80 -0
- metadata +273 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
module Vigilem
|
2
|
+
module Core
|
3
|
+
# @abstract
|
4
|
+
# contract the ensures some common event methods are available
|
5
|
+
module Eventable
|
6
|
+
# @abstract need to override read_many_nonblock, optional synchronize
|
7
|
+
module ReadMethods
|
8
|
+
|
9
|
+
# @abstract
|
10
|
+
# @param [Integer] max_number_of_events=1
|
11
|
+
# @return [Array]
|
12
|
+
def read_many_nonblock(max_number_of_events=1)
|
13
|
+
raise NotImplemented, 'read_many_nonblock not overridden'
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# passes to super if exists, otherwise yield makes
|
18
|
+
# overwriting it optional
|
19
|
+
def synchronize
|
20
|
+
if defined?(super)
|
21
|
+
super
|
22
|
+
else
|
23
|
+
yield
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# reads until a specified number of events have been read
|
28
|
+
# @param [Integer] number_of_events=1
|
29
|
+
# @return [Array]
|
30
|
+
def read_many(number_of_events=1)
|
31
|
+
synchronize {
|
32
|
+
until (events ||= []).size == number_of_events
|
33
|
+
events += read_many_nonblock(number_of_events)
|
34
|
+
end
|
35
|
+
events
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
# reads one Object without blocking if source is empty
|
40
|
+
# @return [Object]
|
41
|
+
def read_one_nonblock
|
42
|
+
synchronize {
|
43
|
+
read_many_nonblock.slice!(0)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
# reads one Object and blocking if source is empty
|
48
|
+
# @return [Object]
|
49
|
+
def read_one
|
50
|
+
synchronize {
|
51
|
+
read_many.slice!(0)
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
include ReadMethods
|
57
|
+
|
58
|
+
# @abstract
|
59
|
+
module WriteMethods
|
60
|
+
# @abstract
|
61
|
+
# @param [Integer] number_of_events=1
|
62
|
+
def write_many_nonblock(*events)
|
63
|
+
raise NotImplemented, 'write_many_nonblock not overridden'
|
64
|
+
end
|
65
|
+
|
66
|
+
# @abstract
|
67
|
+
# @param [Integer] number_of_events=1
|
68
|
+
def write_many(*events)
|
69
|
+
raise NotImplemented, 'write_many not overridden'
|
70
|
+
end
|
71
|
+
|
72
|
+
alias_method :write_one_nonblock, :write_many_nonblock
|
73
|
+
alias_method :write_one, :write_many
|
74
|
+
end
|
75
|
+
|
76
|
+
include WriteMethods
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'vigilem/core/hooks/inheritable'
|
2
|
+
|
3
|
+
module Vigilem::Core
|
4
|
+
#
|
5
|
+
# extend this
|
6
|
+
module Hooks
|
7
|
+
|
8
|
+
include Inheritable
|
9
|
+
|
10
|
+
#
|
11
|
+
# @param base
|
12
|
+
def self.extended(base)
|
13
|
+
# instance_level
|
14
|
+
base.send(:define_method, :run_hook) do |hook_name, *args, &block|
|
15
|
+
self.class.hooks.find {|hook| hook.name == hook_name }.run(self, *args, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# class level
|
21
|
+
# finds a hook by that name and runs it
|
22
|
+
# @param hook_name the hook to find
|
23
|
+
# @param [Array] args arguments to be passed to the hook
|
24
|
+
# @param [Proc] block Proc to be passed to the hook
|
25
|
+
# @return [Hook]
|
26
|
+
def run_hook(hook_name, *args, &block)
|
27
|
+
hooks.find {|hook| hook.name == hook_name }.run(self, *args, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Vigilem::Core::HooksBase = Vigilem::Core::Hooks
|
34
|
+
|
35
|
+
require 'vigilem/core/hooks/hook'
|
36
|
+
require 'vigilem/core/hooks/conditional_hook'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Vigilem::Core::Hooks
|
2
|
+
# core interface for a callback
|
3
|
+
# @abstract
|
4
|
+
module Callback
|
5
|
+
|
6
|
+
#
|
7
|
+
attr_accessor :options, :result
|
8
|
+
|
9
|
+
# @see CallbackProc
|
10
|
+
# @param [Hash] opts
|
11
|
+
# @param [Proc] block
|
12
|
+
# @return [CallbackProc]
|
13
|
+
def self.new(opts={}, &block)
|
14
|
+
CallbackProc.new(opts, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
# evaluates the Callback in the specified context
|
18
|
+
# @param context
|
19
|
+
# @param [Array] args
|
20
|
+
# @param [Proc] block
|
21
|
+
# @return [Array]
|
22
|
+
def evaluate(context, *args, &block)
|
23
|
+
self.result = if block
|
24
|
+
context.define_singleton_method(:__callback__, &self)
|
25
|
+
ret = context.send :__callback__, *args, &block
|
26
|
+
context.class_eval { send :remove_method, :__callback__ }
|
27
|
+
ret
|
28
|
+
else
|
29
|
+
context.instance_exec(*args, &self)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
alias_method :[], :evaluate
|
34
|
+
|
35
|
+
# calls super if defined? otherwise calls to_proc.call(*args, &block)
|
36
|
+
# @see Proc#call
|
37
|
+
# @param [Array] args
|
38
|
+
# @param [Proc] block
|
39
|
+
# @return result
|
40
|
+
def call(*args, &block)
|
41
|
+
self.result = defined?(super) ? super(*args, &block) : to_proc.call(*args, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
# calls super, otherwise it's just a helper
|
45
|
+
# @raise [RuntimeError]
|
46
|
+
# @return [Proc]; this object as a Proc
|
47
|
+
def to_proc
|
48
|
+
defined?(super) ? super : raise('must overload to_proc')
|
49
|
+
end
|
50
|
+
|
51
|
+
# calls super, otherwise it's just a helpful reminder
|
52
|
+
# @raise [RuntimeError]
|
53
|
+
# @return [Proc]; this object as a Proc
|
54
|
+
def binding
|
55
|
+
defined?(super) ? super : raise('must overload binding')
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# @param res
|
61
|
+
# @return res
|
62
|
+
def result=(res)
|
63
|
+
@result = res
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'vigilem/core/hooks/callback'
|
2
|
+
|
3
|
+
module Vigilem::Core::Hooks
|
4
|
+
# like a proc but with the added benifit of being called on
|
5
|
+
# in a different context essentially `instance_eval'
|
6
|
+
class CallbackProc < Proc
|
7
|
+
|
8
|
+
include Callback
|
9
|
+
|
10
|
+
#
|
11
|
+
# @param [Hash] opts for meta use
|
12
|
+
# @param [Proc] block proc to be converted to a CallbackProc
|
13
|
+
def initialize(opts={}, &block)
|
14
|
+
@options = opts
|
15
|
+
super(&block)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Hash]
|
19
|
+
def options
|
20
|
+
@options ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'vigilem/core/hooks'
|
2
|
+
|
3
|
+
module Vigilem::Core::Hooks
|
4
|
+
#
|
5
|
+
#
|
6
|
+
class ConditionalHook < Hook
|
7
|
+
|
8
|
+
# enumerate over the callbacks
|
9
|
+
# @param [Array] args
|
10
|
+
# @param [Proc] block
|
11
|
+
# @return
|
12
|
+
def enumerate(args={}, &block)
|
13
|
+
passed, failed = [], []
|
14
|
+
hook = self
|
15
|
+
super do |callback|
|
16
|
+
if hook.condition.call(*callback.options[:condition_args])
|
17
|
+
hook.passed << callback
|
18
|
+
callback.evaluate(args[:context], *args[:args], &args[:block])
|
19
|
+
else
|
20
|
+
hook.failed << callback
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# @param [Proc] condition
|
27
|
+
# @return
|
28
|
+
def condition(&condition)
|
29
|
+
condition ? @condition = condition : @condition ||= lambda { true }
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# @return [Array]
|
34
|
+
def passed
|
35
|
+
@passed ||= []
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# @return [Array]
|
40
|
+
def failed
|
41
|
+
@failed ||= []
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# @return [Array<Array,Array>]
|
46
|
+
def status_hash
|
47
|
+
[[passed, failed]].hash
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# @return
|
52
|
+
def default_body
|
53
|
+
@default_body ||= begin
|
54
|
+
hook = self
|
55
|
+
lambda do |*args, &block|
|
56
|
+
hook.callbacks << CallbackProc.new({:condition_args => args }, &block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'vigilem/core/hooks/utils'
|
2
|
+
|
3
|
+
require 'vigilem/core/hooks/callback_proc'
|
4
|
+
|
5
|
+
require 'vigilem/core/hooks/meta_callback'
|
6
|
+
|
7
|
+
module Vigilem
|
8
|
+
module Core::Hooks
|
9
|
+
#
|
10
|
+
# bindable group of callbacks
|
11
|
+
class Hook
|
12
|
+
|
13
|
+
attr_reader :name, :options, :owner
|
14
|
+
|
15
|
+
# @param hook_name
|
16
|
+
# @param [Hash] options
|
17
|
+
# @param [Proc] config
|
18
|
+
def initialize(hook_name, options={}, &config)
|
19
|
+
@name = hook_name
|
20
|
+
options[:inheritable] = true if options[:inheritable].nil?
|
21
|
+
(@options = options).freeze
|
22
|
+
@callbacks = []
|
23
|
+
instance_eval(&config) if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# @return [TrueClass || FalseClass]
|
28
|
+
def inheritable?
|
29
|
+
!!@options[:inheritable]
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# @param callback
|
34
|
+
# @return
|
35
|
+
def <<(callback)
|
36
|
+
@callbacks << (callback.is_a?(Callback) ? callback : CallbackProc.new(&callback))
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# @see #<<
|
41
|
+
# @param [Proc] callback
|
42
|
+
# @return
|
43
|
+
def add(&callback)
|
44
|
+
self << callback
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# @param context
|
49
|
+
# @return
|
50
|
+
def callbacks(context=nil)
|
51
|
+
if context then @callbacks.reject {|cb| Utils.callback_is_in_subclass?(context, cb) } else @callbacks end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# @param [Array] args
|
56
|
+
# @param [Proc] block
|
57
|
+
# @return [Array]
|
58
|
+
def call(*args, &block)
|
59
|
+
enumerate({:args => args, :block => block }, &on_run)
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# @param context
|
64
|
+
# @param [Array] args
|
65
|
+
# @param [Proc] block
|
66
|
+
# @return [Array]
|
67
|
+
def run(context, *args, &block)
|
68
|
+
enumerate({:args => args, :block => block, :context => context }, &on_run)
|
69
|
+
end
|
70
|
+
|
71
|
+
alias_method :evaluate, :run
|
72
|
+
|
73
|
+
#
|
74
|
+
#
|
75
|
+
# @return [Proc]
|
76
|
+
def default_body
|
77
|
+
@default_body ||= begin
|
78
|
+
hook = self
|
79
|
+
lambda do |opts={}, &block|
|
80
|
+
raise 'block not given' unless block
|
81
|
+
hook.callbacks << CallbackProc.new(opts, &block)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [String]
|
87
|
+
def to_s
|
88
|
+
"#{super().chomp('>')} #{name}>"
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [Array]; [name, self]
|
92
|
+
def to_ary
|
93
|
+
[self.name, self]
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return {name => self}
|
97
|
+
def to_h
|
98
|
+
{self.name => self }
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# @return [Proc]
|
103
|
+
def to_proc
|
104
|
+
body()
|
105
|
+
end
|
106
|
+
|
107
|
+
# @todo Error for name collision
|
108
|
+
# @param context the object to bind this hook to
|
109
|
+
# @return the result of the evaluation
|
110
|
+
def bind(context)
|
111
|
+
hook, hook_body = self, body()
|
112
|
+
self.owner = Support::Utils.get_class(context)
|
113
|
+
ret = context.instance_eval do
|
114
|
+
define_singleton_method(hook.name, &hook_body)
|
115
|
+
end
|
116
|
+
owner.hooks << hook
|
117
|
+
ret
|
118
|
+
end
|
119
|
+
|
120
|
+
# uses define_method instead
|
121
|
+
# of define_singleton_method like bind!
|
122
|
+
#
|
123
|
+
# hmm I could have one hook that spans multiple instances, bad or good?
|
124
|
+
# doesn't work with @owner
|
125
|
+
# @param [Class] klass
|
126
|
+
# @return
|
127
|
+
def generate(klass)
|
128
|
+
hook, hook_body = self, body()
|
129
|
+
self.owner = klass
|
130
|
+
ret = klass.instance_eval do
|
131
|
+
define_method(hook.name, &hook_body)
|
132
|
+
end
|
133
|
+
klass.hooks << hook
|
134
|
+
ret
|
135
|
+
end
|
136
|
+
|
137
|
+
class << self
|
138
|
+
|
139
|
+
#
|
140
|
+
# @param [Array<Callback>] call_backs
|
141
|
+
# @param [Array] args
|
142
|
+
# @param [Proc] block
|
143
|
+
# @return [Array]
|
144
|
+
def enumerate(call_backs, args={}, &block)
|
145
|
+
call_backs.inject([]) do |results, callback|
|
146
|
+
mcb = MetaCallback.new(callback)
|
147
|
+
if block
|
148
|
+
yield(mcb)
|
149
|
+
elsif args.has_key?(:context)
|
150
|
+
mcb.evaluate(args[:context], *args[:args], &args[:block])
|
151
|
+
else
|
152
|
+
mcb.call(*args[:args], &args[:block])
|
153
|
+
end
|
154
|
+
results << mcb.result if mcb.ran?
|
155
|
+
results
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
private_class_method :enumerate
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
attr_writer :owner
|
164
|
+
|
165
|
+
#
|
166
|
+
# @param [Hash] args
|
167
|
+
# @param [Proc] block
|
168
|
+
# @return [Array]
|
169
|
+
def enumerate(args={}, &block)
|
170
|
+
self.class.send :enumerate, callbacks(args[:context]), args, &block
|
171
|
+
end
|
172
|
+
|
173
|
+
#
|
174
|
+
# @param [Proc] block
|
175
|
+
# @return [Proc]
|
176
|
+
def on_run(&block)
|
177
|
+
@on_run = block
|
178
|
+
end
|
179
|
+
|
180
|
+
#
|
181
|
+
# @param [Proc] block
|
182
|
+
# @return [Proc]
|
183
|
+
def body(&block)
|
184
|
+
if block
|
185
|
+
@body = block
|
186
|
+
else
|
187
|
+
@body ||= default_body
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|