vigilem-core 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/lib/vigilem/core.rb +9 -0
  3. data/lib/vigilem/core/abstract_device.rb +97 -0
  4. data/lib/vigilem/core/adapters.rb +2 -0
  5. data/lib/vigilem/core/adapters/adapter.rb +57 -0
  6. data/lib/vigilem/core/adapters/basic_adapter.rb +43 -0
  7. data/lib/vigilem/core/adapters/buffered_adapter.rb +28 -0
  8. data/lib/vigilem/core/buffer.rb +151 -0
  9. data/lib/vigilem/core/buffer_handler.rb +95 -0
  10. data/lib/vigilem/core/default_buffer.rb +45 -0
  11. data/lib/vigilem/core/demultiplexer.rb +225 -0
  12. data/lib/vigilem/core/device.rb +43 -0
  13. data/lib/vigilem/core/event_handler.rb +156 -0
  14. data/lib/vigilem/core/eventable.rb +80 -0
  15. data/lib/vigilem/core/hooks.rb +36 -0
  16. data/lib/vigilem/core/hooks/callback.rb +66 -0
  17. data/lib/vigilem/core/hooks/callback_proc.rb +25 -0
  18. data/lib/vigilem/core/hooks/conditional_hook.rb +62 -0
  19. data/lib/vigilem/core/hooks/hook.rb +193 -0
  20. data/lib/vigilem/core/hooks/inheritable.rb +24 -0
  21. data/lib/vigilem/core/hooks/meta_callback.rb +53 -0
  22. data/lib/vigilem/core/hooks/utils.rb +23 -0
  23. data/lib/vigilem/core/hub.rb +50 -0
  24. data/lib/vigilem/core/input_system_handler.rb +55 -0
  25. data/lib/vigilem/core/lockable_pipeline_component.rb +30 -0
  26. data/lib/vigilem/core/multiplexer.rb +168 -0
  27. data/lib/vigilem/core/pipeline.rb +68 -0
  28. data/lib/vigilem/core/stat.rb +121 -0
  29. data/lib/vigilem/core/system.rb +9 -0
  30. data/lib/vigilem/core/system/check.rb +33 -0
  31. data/lib/vigilem/core/transfer_agent.rb +67 -0
  32. data/lib/vigilem/core/version.rb +5 -0
  33. data/spec/bug_notes.txt +12 -0
  34. data/spec/given_helper.rb +12 -0
  35. data/spec/spec_helper.rb +7 -0
  36. data/spec/vigilem/core/abstract_device_spec.rb +103 -0
  37. data/spec/vigilem/core/adapters/adapter_spec.rb +28 -0
  38. data/spec/vigilem/core/adapters/basic_adapter_spec.rb +53 -0
  39. data/spec/vigilem/core/adapters/buffered_adapter_spec.rb +16 -0
  40. data/spec/vigilem/core/buffer_handler_spec.rb +51 -0
  41. data/spec/vigilem/core/buffer_spec.rb +236 -0
  42. data/spec/vigilem/core/default_buffer_spec.rb +17 -0
  43. data/spec/vigilem/core/demultiplexer_spec.rb +166 -0
  44. data/spec/vigilem/core/device_spec.rb +62 -0
  45. data/spec/vigilem/core/event_handler_spec.rb +134 -0
  46. data/spec/vigilem/core/hooks/callback_proc_spec.rb +66 -0
  47. data/spec/vigilem/core/hooks/hook_spec.rb +230 -0
  48. data/spec/vigilem/core/hooks/inheritable_spec.rb +19 -0
  49. data/spec/vigilem/core/hooks/meta_callback_spec.rb +69 -0
  50. data/spec/vigilem/core/hooks/utils_spec.rb +25 -0
  51. data/spec/vigilem/core/hooks_spec.rb +50 -0
  52. data/spec/vigilem/core/hub_spec.rb +51 -0
  53. data/spec/vigilem/core/input_system_handler_spec.rb +33 -0
  54. data/spec/vigilem/core/lockable_pipeline_component_spec.rb +19 -0
  55. data/spec/vigilem/core/multiplexer_spec.rb +113 -0
  56. data/spec/vigilem/core/pipeline_spec.rb +5 -0
  57. data/spec/vigilem/core/stat_spec.rb +63 -0
  58. data/spec/vigilem/core/system/check_spec.rb +24 -0
  59. data/spec/vigilem/core/system_spec.rb +29 -0
  60. data/spec/vigilem/core/transfer_agent_spec.rb +80 -0
  61. 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