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,24 @@
1
+ require 'vigilem/support/core_ext'
2
+
3
+ module Vigilem
4
+ module Core
5
+ module Hooks
6
+ #
7
+ module Inheritable
8
+
9
+ #
10
+ # @param base
11
+ def inherited(base)
12
+ base.extend Inheritable
13
+ end
14
+
15
+ #
16
+ # @return [Array]
17
+ def hooks
18
+ @hooks ||= (self.superclass.respond(:hooks) || []).select(&:inheritable?)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ require 'delegate'
2
+
3
+ module Vigilem::Core::Hooks
4
+ # @todo better name?
5
+ # CallbackProc that remebers if it has been ran/evaluated/called
6
+ class MetaCallback < DelegateClass(CallbackProc)
7
+
8
+ #
9
+ # @param [CallbackProc] cbp a CallbackProc
10
+ # to be converted to a MetaCallback
11
+ # @param [Proc] block a Proc to be converted to a MetaCallback
12
+ def initialize(cbp=nil, &block)
13
+ self.ran = false
14
+ super(cbp || CallbackProc.new(&block))
15
+ end
16
+
17
+ #
18
+ # @param context the context which to evaluate under
19
+ # @param [Array] args arguments to be passed to the proc
20
+ # @param [Proc] block Proc to be passed to the proc
21
+ # @return the result of the
22
+ def evaluate(context, *args, &block)
23
+ self.ran = true
24
+ super(context, *args, &block)
25
+ end
26
+
27
+ alias_method :[], :evaluate
28
+
29
+ #
30
+ # @param [Array] args arguments to be passed to the proc
31
+ # @param [Proc] block Proc to be passed to the proc
32
+ # @return the result of the proc
33
+ def call(*args, &block)
34
+ self.ran = true
35
+ super(*args, &block)
36
+ end
37
+
38
+ # whether or not this proc ran
39
+ # @return [TrueClass || FalseClass]
40
+ def ran?
41
+ @ran
42
+ end
43
+
44
+ private
45
+
46
+ #
47
+ # @param [TrueClass || FalseClass] status
48
+ # @return @ran
49
+ def ran=(status)
50
+ @ran = status
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,23 @@
1
+ require 'vigilem/support/utils'
2
+
3
+ module Vigilem
4
+ module Core::Hooks
5
+ #
6
+ # utils for the Hooks
7
+ module Utils
8
+
9
+ include Support::KernelUtils
10
+
11
+ #
12
+ # if context of callback is a subclass of this context
13
+ # @param context
14
+ # @param callback
15
+ # @return [FalseClass || TrueClass]
16
+ def callback_is_in_subclass?(context, callback)
17
+ get_class(callback.binding.eval('self')) < get_class(context)
18
+ end
19
+
20
+ extend self
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,50 @@
1
+ require 'vigilem/support/obj_space'
2
+
3
+ module Vigilem
4
+ module Core
5
+ # copies events or messages from the system to all the
6
+ # attached buffers except the link, much like a network hub
7
+ class Hub
8
+
9
+ attr_reader :buffers, :group_id
10
+
11
+ # @param group
12
+ def initialize(group)
13
+ @group_id = group
14
+ @buffers = []
15
+ end
16
+
17
+ #
18
+ # @param [EventBuffer] buffer that will receive events from the hub
19
+ # @return self is expected like array
20
+ def add_buffer(buffer)
21
+ @buffers << buffer
22
+ self
23
+ end
24
+
25
+ alias_method :<<, :add_buffer
26
+
27
+ #
28
+ # @param [Array] msgs the messages to push out
29
+ # @return [Array] the buffers that got updated
30
+ def demux(buff, *msgs)
31
+ buffers.except(buff).select {|buffer| buffer.concat(msgs) unless msgs.empty? }
32
+ end
33
+
34
+ extend Support::ObjSpace
35
+
36
+ class << self
37
+
38
+ #
39
+ # finds a hub based on a group identifier, if no Hub is found
40
+ # a new one is returned
41
+ # @param link the link registered for a hub
42
+ # @return [Hub] the hub for passed in link
43
+ def aquire(grp_id)
44
+ all.find {|hub| hub.group_id == grp_id } || obj_register(new(grp_id))
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,55 @@
1
+ require 'forwardable'
2
+
3
+ require 'vigilem/support/core_ext'
4
+
5
+ require 'vigilem/core/lockable_pipeline_component'
6
+
7
+ require 'vigilem/core/adapters/basic_adapter'
8
+
9
+ require 'vigilem/core/buffer_handler'
10
+
11
+ require 'vigilem/core/transfer_agent'
12
+
13
+ module Vigilem
14
+ module Core
15
+ #
16
+ # methods to hand the lower level bindings
17
+ module InputSystemHandler
18
+
19
+ include BufferHandler
20
+
21
+ include Adapters::BasicAdapter
22
+
23
+ include LockablePipelineComponent
24
+
25
+ extend Support::ObjSpace
26
+
27
+ extend ActiveSupport::Concern
28
+
29
+ #
30
+ # @param buffer_type
31
+ # @return
32
+ def initialize_input_system_handler(buffer_type=[])
33
+ ret = initialize_buffer_handler(buffer_type)
34
+ InputSystemHandler.obj_register(self)
35
+ self.class.obj_register(self)
36
+ ret
37
+ end
38
+
39
+ #
40
+ #
41
+ module ClassMethods
42
+ include Support::ObjSpace
43
+
44
+ include Forwardable
45
+
46
+ #
47
+ #
48
+ def self.extended(base)
49
+ base.extend Support::ObjSpace
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,30 @@
1
+ require 'vigilem/support/core_ext'
2
+
3
+ module Vigilem
4
+ module Core
5
+ #
6
+ module LockablePipelineComponent
7
+
8
+ #
9
+ # name collision with demultiplexer and bufferhandler
10
+ def semaphore
11
+ @semaphore ||= (semaphore! || Monitor.new)
12
+ end
13
+
14
+ #
15
+ # checks #source component for #semaphore without memoization
16
+ def semaphore!
17
+ self.respond.source.respond.semaphore
18
+ end
19
+
20
+ #
21
+ #
22
+ def synchronize
23
+ semaphore.synchronize do
24
+ yield
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,168 @@
1
+ require 'active_support/concern'
2
+
3
+ require 'vigilem/support/obj_space'
4
+
5
+ require 'vigilem/support/utils'
6
+
7
+ module Vigilem
8
+ module Core
9
+ #
10
+ #
11
+ module Multiplexer
12
+
13
+ extend Support::ObjSpace
14
+
15
+ extend ActiveSupport::Concern
16
+
17
+ attr_writer :inputs
18
+
19
+ attr_accessor :out
20
+
21
+ alias_method :output, :out
22
+ alias_method :output=, :out=
23
+
24
+ #
25
+ # @param [Array<IO || Array>] in_ios_or_arrays
26
+ # @param [Array<#<< || #concat>] out
27
+ # @return
28
+ def initialize_multiplexer(in_ios_or_arrays, out=nil)
29
+ @inputs = in_ios_or_arrays
30
+
31
+ @out = out
32
+ self.class.obj_register(self)
33
+ multiplexers = ::Vigilem::Core::Multiplexer.all
34
+ if (ties = multiplexers.flat_map {|muxer| self.intersect muxer }).any?
35
+ raise NotImplemented, "Multiplexers cannot share the same inputs `#{ties.inspect}'"
36
+ end
37
+ multiplexers << self
38
+ end
39
+
40
+ # @todo change name to select?
41
+ # @return [Array<IO> || NilClass] objects ready to be read, or nil
42
+ # if nothing is to be read
43
+ def ready?
44
+ if not (ios = inputs.select {|io| io.respond_to? :to_io }).empty?
45
+ @ready, others = IO.select(ios, nil, nil, 0)
46
+ end
47
+ @ready ||= []
48
+ @ready += inputs.select {|ary| ary.respond_to?(:empty?) and ary.empty? }
49
+ end
50
+
51
+ #
52
+ # @raise [ArgumentError]
53
+ # @return [Array]
54
+ def __sweep__(len)
55
+ recursive_check(RuntimeError)
56
+ sweep(len)
57
+ end
58
+
59
+ #
60
+ # @param [Integer] num
61
+ # @return
62
+ def sweep(num)
63
+ raise NotImplemented, "#sweep method not defined on `#{self}' needs to be overriden"
64
+ end
65
+
66
+ #
67
+ # pushes the converted array from #sweep to #out
68
+ # @param [Integer] len
69
+ # @return [Array]
70
+ def mux(len)
71
+ ary = __sweep__(len)
72
+ if out.respond_to? :concat
73
+ out.concat(ary)
74
+ elsif out.respond_to? :<<
75
+ ary.each {|item| out << item }
76
+ else
77
+ raise TypeError, "`#{self}'#out is `#{self.out.inspect}' and does not respond to #concat or #<<"
78
+ end
79
+ out.flush if out.respond_to? :flush
80
+ ary
81
+ end
82
+
83
+ #
84
+ # @return [Array]
85
+ def inputs
86
+ @inputs ||= []
87
+ end
88
+
89
+ # adds a inputs and runs a uniq
90
+ # @param [Array<IO || Array>] added_inputs
91
+ # @return [Array<IO || Array>]
92
+ def add_inputs(*added_inputs)
93
+ if not added_inputs.empty?
94
+ (self.inputs += added_inputs).uniq! {|obj| obj.object_id }
95
+ recursive_check
96
+ end
97
+ self.inputs
98
+ end
99
+
100
+ #
101
+ #
102
+ module ClassMethods
103
+
104
+ include Support::ObjSpace
105
+
106
+ #
107
+ # @param [Module] base
108
+ def self.extended(base)
109
+ base.extend Support::ObjSpace
110
+ end
111
+
112
+ end
113
+
114
+ extend ClassMethods
115
+
116
+ #
117
+ # @see Object#inspect
118
+ # @return [String]
119
+ def inspect
120
+ if out.is_a? Array # @todo switch from regex
121
+ updated_out = super.gsub(/@out=.+?(\s+|>)/, "@out=#<#{out.class}:#{Support::Utils.inspect_id(out)} #{out}>\\1")
122
+
123
+ if inputs.any? {|inp| inp.is_a? Array }
124
+ str_ary_bdy = inputs.map do |inp|
125
+ if inp.is_a?(Array)
126
+ "#<#{inp.class}:#{Support::Utils.inspect_id(inp)} #{inp}>"
127
+ else
128
+ inp
129
+ end
130
+ end.join(', ')
131
+ updated_out.gsub(/@inputs=.+?(\s+|>)/, "@inputs=[#{str_ary_bdy}]\\1")
132
+ end || updated_out
133
+
134
+ else
135
+ super
136
+ end
137
+ end
138
+
139
+ # compares the inputs to the list or multiplexer given
140
+ # @param [Multiplexer || Array<IO> || Array<Array<>>] other_mux_or_ios_or_arrays
141
+ # @return [Array]
142
+ def intersect(*other_mux_or_ios_or_arrays)
143
+ ios, non_fileno = self.inputs.partition {|inpt| inpt.respond_to?(:fileno) }
144
+ ios_fn = ios.map(&:fileno)
145
+
146
+ non_fileno.map!(&:object_id)
147
+
148
+ ary = other_mux_or_ios_or_arrays.respond_to?(:inputs) ? other_mux_or_ios_or_arrays.inputs : other_mux_or_ios_or_arrays
149
+ ary.select do |inp|
150
+ if inp.respond_to? :fileno
151
+ ios_fn.include? inp.fileno
152
+ else
153
+ non_fileno.include? inp.object_id #default compares by #hash
154
+ end
155
+ end
156
+ end
157
+
158
+ private
159
+ # checks to make sure that an input doesn't match an output thus causing
160
+ # a recursive loop, raises an error if found
161
+ # @raise [ArgumentError]
162
+ # @return
163
+ def recursive_check(arg_type=ArgumentError)
164
+ raise arg_type, "Recursive multiplexer `#{self}' has `#{out}' as an input and output" unless intersect(out).empty?
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,68 @@
1
+ module Vigilem
2
+ module Core
3
+ #
4
+ # observer of components and thier connections
5
+ # the catch is that input_systems don;t have an entry point
6
+ # for determining thier source
7
+ class Pipeline
8
+ attr_reader :device
9
+
10
+ #
11
+ # @param [#link] device most likely a Core::Device
12
+ def initialize(device)
13
+ @device = device
14
+ rebuild
15
+ end
16
+
17
+ extend Support::ObjSpace
18
+
19
+ # get the next item that #source
20
+ # is pointing to
21
+ # @return
22
+ def succ
23
+ @iter ||= device
24
+ @iter.respond(:source)
25
+ end
26
+
27
+ # the start of the pipeline
28
+ # @return [#source]
29
+ def reset_iter
30
+ @iter = device
31
+ end
32
+
33
+ # rebuilds the cache
34
+ # @return [Array]
35
+ def rebuild
36
+ ary = [device]
37
+ while current = succ
38
+ ary << current
39
+ end
40
+ reset_iter
41
+ cache = ary
42
+ end
43
+
44
+ # updates the status
45
+ # called when a component changes it's sauce
46
+ # @return [TrueClass]
47
+ def update
48
+ @changed = true
49
+ end
50
+
51
+ # checks whether or not this item changed
52
+ # @return [TrueClass || FalseClass]
53
+ def changed?
54
+ @changed ||= false
55
+ end
56
+
57
+ # @return [Array] all the components in the pipeline
58
+ def to_a
59
+ changed? ? rebuild : cache
60
+ end
61
+
62
+ alias_method :to_ary, :to_a
63
+
64
+ private
65
+ attr_accessor :cache
66
+ end
67
+ end
68
+ end