vigilem-core 0.0.9

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.
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