minilab 1.0.0-mswin32
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.
- data/.document +2 -0
- data/CHANGES +2 -0
- data/LICENSE +19 -0
- data/README +107 -0
- data/Rakefile +145 -0
- data/config/environment.rb +15 -0
- data/config/objects.yml +22 -0
- data/lib/analog_io.rb +30 -0
- data/lib/digital_auxport_io.rb +49 -0
- data/lib/digital_configuration.rb +66 -0
- data/lib/digital_port_io.rb +68 -0
- data/lib/extension/extconf.rb +4 -0
- data/lib/extension/minilab_hardware.c +235 -0
- data/lib/extension/minilab_hardware.so +0 -0
- data/lib/library_translator.rb +48 -0
- data/lib/minilab.rb +149 -0
- data/lib/minilab_context.rb +39 -0
- data/lib/result_verifier.rb +14 -0
- data/test/integration/analog_input_output_test.rb +43 -0
- data/test/integration/connect_to_hardware_test.rb +13 -0
- data/test/integration/digital_input_output_test.rb +114 -0
- data/test/integration/integration_test.rb +53 -0
- data/test/integration/require_minilab_test.rb +9 -0
- data/test/system/analog_input.test +3 -0
- data/test/system/analog_output.test +37 -0
- data/test/system/digital_port_input.test +5 -0
- data/test/system/digital_port_output.test +39 -0
- data/test/system/digital_port_read_byte.test +26 -0
- data/test/system/digital_screw_terminals_input.test +2 -0
- data/test/system/digital_screw_terminals_output.test +11 -0
- data/test/system/minilab_driver.rb +85 -0
- data/test/test_helper.rb +11 -0
- data/test/unit/analog_io_test.rb +87 -0
- data/test/unit/digital_auxport_io_test.rb +114 -0
- data/test/unit/digital_configuration_test.rb +136 -0
- data/test/unit/digital_port_io_test.rb +117 -0
- data/test/unit/library_translator_test.rb +100 -0
- data/test/unit/minilab_context_test.rb +82 -0
- data/test/unit/minilab_hardware_test.rb +83 -0
- data/test/unit/minilab_test.rb +131 -0
- data/test/unit/result_verifier_test.rb +33 -0
- data/vendor/behaviors/lib/behaviors.rb +50 -0
- data/vendor/behaviors/tasks/behaviors_tasks.rake +140 -0
- data/vendor/behaviors/test/behaviors_tasks_test.rb +71 -0
- data/vendor/behaviors/test/behaviors_test.rb +50 -0
- data/vendor/behaviors/test/tasks_test/Rakefile +16 -0
- data/vendor/behaviors/test/tasks_test/doc/behaviors.html +55 -0
- data/vendor/behaviors/test/tasks_test/lib/user.rb +2 -0
- data/vendor/behaviors/test/tasks_test/test/user_test.rb +17 -0
- data/vendor/constructor/Rakefile +44 -0
- data/vendor/constructor/config/environment.rb +12 -0
- data/vendor/constructor/lib/constructor.rb +132 -0
- data/vendor/constructor/test/constructor_test.rb +366 -0
- data/vendor/constructor/test/helper.rb +3 -0
- data/vendor/diy/README +26 -0
- data/vendor/diy/Rakefile +18 -0
- data/vendor/diy/lib/constructor.rb +114 -0
- data/vendor/diy/lib/diy.rb +329 -0
- data/vendor/diy/proto/context.rb +117 -0
- data/vendor/diy/proto/context.yml +20 -0
- data/vendor/diy/test/diy_test.rb +370 -0
- data/vendor/diy/test/files/broken_construction.yml +7 -0
- data/vendor/diy/test/files/cat/cat.rb +4 -0
- data/vendor/diy/test/files/cat/extra_conflict.yml +5 -0
- data/vendor/diy/test/files/cat/heritage.rb +2 -0
- data/vendor/diy/test/files/cat/needs_input.yml +3 -0
- data/vendor/diy/test/files/cat/the_cat_lineage.rb +1 -0
- data/vendor/diy/test/files/dog/dog_model.rb +4 -0
- data/vendor/diy/test/files/dog/dog_presenter.rb +4 -0
- data/vendor/diy/test/files/dog/dog_view.rb +2 -0
- data/vendor/diy/test/files/dog/file_resolver.rb +2 -0
- data/vendor/diy/test/files/dog/other_thing.rb +2 -0
- data/vendor/diy/test/files/dog/simple.yml +11 -0
- data/vendor/diy/test/files/donkey/foo.rb +8 -0
- data/vendor/diy/test/files/donkey/foo/bar/qux.rb +7 -0
- data/vendor/diy/test/files/fud/objects.yml +13 -0
- data/vendor/diy/test/files/fud/toy.rb +15 -0
- data/vendor/diy/test/files/gnu/objects.yml +14 -0
- data/vendor/diy/test/files/gnu/thinger.rb +8 -0
- data/vendor/diy/test/files/goat/base.rb +8 -0
- data/vendor/diy/test/files/goat/can.rb +6 -0
- data/vendor/diy/test/files/goat/goat.rb +6 -0
- data/vendor/diy/test/files/goat/objects.yml +12 -0
- data/vendor/diy/test/files/goat/paper.rb +6 -0
- data/vendor/diy/test/files/goat/plane.rb +8 -0
- data/vendor/diy/test/files/goat/shirt.rb +6 -0
- data/vendor/diy/test/files/goat/wings.rb +8 -0
- data/vendor/diy/test/files/horse/holder_thing.rb +4 -0
- data/vendor/diy/test/files/horse/objects.yml +7 -0
- data/vendor/diy/test/files/yak/core_model.rb +4 -0
- data/vendor/diy/test/files/yak/core_presenter.rb +4 -0
- data/vendor/diy/test/files/yak/core_view.rb +1 -0
- data/vendor/diy/test/files/yak/data_source.rb +1 -0
- data/vendor/diy/test/files/yak/fringe_model.rb +4 -0
- data/vendor/diy/test/files/yak/fringe_presenter.rb +4 -0
- data/vendor/diy/test/files/yak/fringe_view.rb +1 -0
- data/vendor/diy/test/files/yak/my_objects.yml +21 -0
- data/vendor/diy/test/test_helper.rb +40 -0
- data/vendor/hardmock/CHANGES +8 -0
- data/vendor/hardmock/LICENSE +7 -0
- data/vendor/hardmock/README +48 -0
- data/vendor/hardmock/Rakefile +100 -0
- data/vendor/hardmock/TODO +7 -0
- data/vendor/hardmock/config/environment.rb +12 -0
- data/vendor/hardmock/homepage/demo.rb +21 -0
- data/vendor/hardmock/homepage/hardmock_sample.png +0 -0
- data/vendor/hardmock/homepage/index.html +65 -0
- data/vendor/hardmock/init.rb +3 -0
- data/vendor/hardmock/lib/hardmock.rb +634 -0
- data/vendor/hardmock/lib/method_cleanout.rb +14 -0
- data/vendor/hardmock/rcov.rake +18 -0
- data/vendor/hardmock/test/functional/assert_error_test.rb +52 -0
- data/vendor/hardmock/test/functional/auto_verify_test.rb +192 -0
- data/vendor/hardmock/test/functional/direct_mock_usage_test.rb +396 -0
- data/vendor/hardmock/test/functional/hardmock_test.rb +380 -0
- data/vendor/hardmock/test/test_helper.rb +23 -0
- data/vendor/hardmock/test/unit/expectation_builder_test.rb +18 -0
- data/vendor/hardmock/test/unit/expector_test.rb +56 -0
- data/vendor/hardmock/test/unit/method_cleanout_test.rb +35 -0
- data/vendor/hardmock/test/unit/mock_control_test.rb +172 -0
- data/vendor/hardmock/test/unit/mock_test.rb +273 -0
- data/vendor/hardmock/test/unit/simple_expectation_test.rb +345 -0
- data/vendor/hardmock/test/unit/trapper_test.rb +60 -0
- data/vendor/hardmock/test/unit/verify_error_test.rb +34 -0
- data/vendor/systir/systir.rb +403 -0
- data/vendor/systir/test/unit/ui/xml/testrunner.rb +192 -0
- data/vendor/systir/test/unit/ui/xml/xmltestrunner.xslt +109 -0
- metadata +235 -0
@@ -0,0 +1,329 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
#
|
4
|
+
# DIY (Dependency Injection in Yaml) is a simple dependency injection library
|
5
|
+
# which focuses on declarative composition of objects through setter injection.
|
6
|
+
#
|
7
|
+
# == Examples
|
8
|
+
#
|
9
|
+
# === A Simple Context
|
10
|
+
#
|
11
|
+
# The context is a hash specified in in a yaml file. Each top-level key identifies
|
12
|
+
# an object. When the context is created and queried for an object, by default,
|
13
|
+
# the context will require a file with the same name:
|
14
|
+
# require 'foo'
|
15
|
+
# next, by default, it will call new on a class from the camel-cased name of the key:
|
16
|
+
# Foo.new
|
17
|
+
#
|
18
|
+
# foo.rb:
|
19
|
+
# class Foo; end
|
20
|
+
#
|
21
|
+
# context.yml:
|
22
|
+
# ---
|
23
|
+
# foo:
|
24
|
+
# bar:
|
25
|
+
#
|
26
|
+
# c = DIY::Context.from_file('context.yml')
|
27
|
+
# c[:foo] #=> #<Foo:0x81eb0>
|
28
|
+
#
|
29
|
+
# === Specifying Class Name
|
30
|
+
#
|
31
|
+
# If the class name isn't the camel-cased key:
|
32
|
+
#
|
33
|
+
# foo.rb:
|
34
|
+
# class MyFoo; end
|
35
|
+
#
|
36
|
+
# context.yml:
|
37
|
+
# ---
|
38
|
+
# foo:
|
39
|
+
# class: MyFoo
|
40
|
+
# bar:
|
41
|
+
#
|
42
|
+
# === Specifying Ruby File to Require
|
43
|
+
#
|
44
|
+
# If the file the class resides in isn't named after they key:
|
45
|
+
#
|
46
|
+
# fun_stuff.rb:
|
47
|
+
# class Foo; end
|
48
|
+
#
|
49
|
+
# context.yml:
|
50
|
+
# ---
|
51
|
+
# foo:
|
52
|
+
# lib: fun_stuff
|
53
|
+
# bar:
|
54
|
+
#
|
55
|
+
# === Constructor Arguments
|
56
|
+
#
|
57
|
+
# DIY allows specification of constructor arguments as hash key-value pairs
|
58
|
+
# using the <tt>compose</tt> directive.
|
59
|
+
#
|
60
|
+
# foo.rb:
|
61
|
+
# class Foo
|
62
|
+
# def initialize(args)
|
63
|
+
# @bar = args[:bar]
|
64
|
+
# @other = args[:other]
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# context.yml:
|
69
|
+
# ---
|
70
|
+
# foo:
|
71
|
+
# compose: bar, other
|
72
|
+
# bar:
|
73
|
+
# other:
|
74
|
+
#
|
75
|
+
# To make constructor definition easier use constructor:
|
76
|
+
#
|
77
|
+
# foo.rb:
|
78
|
+
# class Foo
|
79
|
+
# constructor :bar, :other
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# If the constructor argument names don't match up with the object keys
|
83
|
+
# in the context, they can be mapped explicitly.
|
84
|
+
#
|
85
|
+
# foo.rb:
|
86
|
+
# class Foo
|
87
|
+
# constructor :bar, :other
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# context.yml:
|
91
|
+
# ---
|
92
|
+
# foo:
|
93
|
+
# bar: my_bar
|
94
|
+
# other: the_other_one
|
95
|
+
# my_bar:
|
96
|
+
# the_other_one:
|
97
|
+
#
|
98
|
+
module DIY
|
99
|
+
class Context
|
100
|
+
def initialize(context_hash, extra_inputs={})
|
101
|
+
raise "Nil context hash" unless context_hash
|
102
|
+
raise "Need a hash" unless context_hash.kind_of?(Hash)
|
103
|
+
[ "[]", "keys" ].each do |mname|
|
104
|
+
unless extra_inputs.respond_to?(mname)
|
105
|
+
raise "Extra inputs must respond to hash-like [] operator and methods #keys and #each"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# store extra inputs
|
110
|
+
if extra_inputs.kind_of?(Hash)
|
111
|
+
@extra_inputs = {}
|
112
|
+
extra_inputs.each { |k,v| @extra_inputs[k.to_s] = v } # smooth out the names
|
113
|
+
else
|
114
|
+
@extra_inputs = extra_inputs
|
115
|
+
end
|
116
|
+
|
117
|
+
# Collect object and subcontext definitions
|
118
|
+
@defs = {}
|
119
|
+
@sub_context_defs = {}
|
120
|
+
context_hash.each do |name,info|
|
121
|
+
name = name.to_s
|
122
|
+
case name
|
123
|
+
when /^\+/
|
124
|
+
# subcontext
|
125
|
+
@sub_context_defs[name.gsub(/^\+/,'')] = info
|
126
|
+
else
|
127
|
+
# normal object def
|
128
|
+
if extra_inputs_has(name)
|
129
|
+
raise ConstructionError.new(name, "Object definition conflicts with parent context")
|
130
|
+
end
|
131
|
+
@defs[name] = ObjectDef.new(name,info)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# init the cache
|
137
|
+
@cache = {}
|
138
|
+
@cache['this_context'] = self
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.from_yaml(io_or_string, extra_inputs={})
|
142
|
+
raise "nil input to YAML" unless io_or_string
|
143
|
+
Context.new(YAML.load(io_or_string), extra_inputs)
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.from_file(fname, extra_inputs={})
|
147
|
+
raise "nil file name" unless fname
|
148
|
+
self.from_yaml(File.read(fname), extra_inputs)
|
149
|
+
end
|
150
|
+
|
151
|
+
def get_object(obj_name)
|
152
|
+
key = obj_name.to_s
|
153
|
+
obj = @cache[key]
|
154
|
+
unless obj
|
155
|
+
if extra_inputs_has(key)
|
156
|
+
obj = @extra_inputs[key]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
unless obj
|
160
|
+
obj = construct_object(key)
|
161
|
+
@cache[key] = obj
|
162
|
+
end
|
163
|
+
obj
|
164
|
+
end
|
165
|
+
alias :[] :get_object
|
166
|
+
|
167
|
+
def set_object(obj_name,obj)
|
168
|
+
key = obj_name.to_s
|
169
|
+
raise "object '#{key}' already exists in context" if @cache.keys.include?(key)
|
170
|
+
@cache[key] = obj
|
171
|
+
end
|
172
|
+
alias :[]= :set_object
|
173
|
+
|
174
|
+
def keys
|
175
|
+
@defs.keys
|
176
|
+
end
|
177
|
+
|
178
|
+
# Instantiate and yield the named subcontext
|
179
|
+
def within(sub_context_name)
|
180
|
+
# Find the subcontext definitaion:
|
181
|
+
context_def = @sub_context_defs[sub_context_name.to_s]
|
182
|
+
raise "No sub-context named #{sub_context_name}" unless context_def
|
183
|
+
# Instantiate a new context using self as parent:
|
184
|
+
context = Context.new( context_def, self )
|
185
|
+
|
186
|
+
yield context
|
187
|
+
end
|
188
|
+
|
189
|
+
def contains_object(obj_name)
|
190
|
+
key = obj_name.to_s
|
191
|
+
@defs.keys.member?(key) or extra_inputs_has(key)
|
192
|
+
end
|
193
|
+
|
194
|
+
def build_everything
|
195
|
+
@defs.keys.each { |k| self[k] }
|
196
|
+
end
|
197
|
+
alias :build_all :build_everything
|
198
|
+
alias :preinstantiate_singletons :build_everything
|
199
|
+
|
200
|
+
private
|
201
|
+
def construct_object(key)
|
202
|
+
# Find the object definition
|
203
|
+
obj_def = @defs[key]
|
204
|
+
raise "No object definition for '#{key}'" unless obj_def
|
205
|
+
|
206
|
+
# If object def mentions a library, load it
|
207
|
+
require obj_def.library if obj_def.library
|
208
|
+
|
209
|
+
# Resolve all components for the object
|
210
|
+
arg_hash = {}
|
211
|
+
obj_def.components.each do |name,value|
|
212
|
+
case value
|
213
|
+
when Lookup
|
214
|
+
arg_hash[name.to_sym] = get_object(value.name)
|
215
|
+
when StringValue
|
216
|
+
arg_hash[name.to_sym] = value.literal_value
|
217
|
+
else
|
218
|
+
raise "Cannot cope with component definition '#{value.inspect}'"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
# Get a reference to the class for the object
|
222
|
+
big_c = get_class_for_name_with_module_delimeters(obj_def.class_name)
|
223
|
+
# Make and return the instance
|
224
|
+
if arg_hash.keys.size > 0
|
225
|
+
return big_c.new(arg_hash)
|
226
|
+
else
|
227
|
+
return big_c.new
|
228
|
+
end
|
229
|
+
rescue Exception => oops
|
230
|
+
cerr = ConstructionError.new(key,oops)
|
231
|
+
cerr.set_backtrace(oops.backtrace)
|
232
|
+
raise cerr
|
233
|
+
end
|
234
|
+
|
235
|
+
def get_class_for_name_with_module_delimeters(class_name)
|
236
|
+
class_name.split(/::/).inject(Object) do |mod,const_name| mod.const_get(const_name) end
|
237
|
+
end
|
238
|
+
|
239
|
+
def extra_inputs_has(key)
|
240
|
+
if key.nil? or key.strip == ''
|
241
|
+
raise ArgumentError.new("Cannot lookup objects with nil keys")
|
242
|
+
end
|
243
|
+
@extra_inputs.keys.member?(key) or @extra_inputs.keys.member?(key.to_sym)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
class Lookup #:nodoc:
|
248
|
+
attr_reader :name
|
249
|
+
def initialize(obj_name)
|
250
|
+
@name = obj_name
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
class ObjectDef #:nodoc:
|
255
|
+
attr_accessor :name, :class_name, :library, :components
|
256
|
+
def initialize(name,info=nil)
|
257
|
+
if info
|
258
|
+
info = info.clone
|
259
|
+
else
|
260
|
+
info = {}
|
261
|
+
end
|
262
|
+
|
263
|
+
@components = {}
|
264
|
+
|
265
|
+
# Object name
|
266
|
+
@name = name
|
267
|
+
|
268
|
+
# Class name
|
269
|
+
@class_name = info.delete 'class'
|
270
|
+
@class_name ||= info.delete 'type'
|
271
|
+
@class_name ||= camelize(@name)
|
272
|
+
|
273
|
+
# Library
|
274
|
+
@library = info.delete 'library'
|
275
|
+
@library ||= info.delete 'lib'
|
276
|
+
@library ||= underscore(@class_name)
|
277
|
+
|
278
|
+
# Auto-compose
|
279
|
+
compose = info.delete 'compose'
|
280
|
+
if compose
|
281
|
+
case compose
|
282
|
+
when Array
|
283
|
+
auto_names = compose.map { |x| x.to_s }
|
284
|
+
when String
|
285
|
+
auto_names = compose.split(',').map { |x| x.to_s.strip }
|
286
|
+
when Symbol
|
287
|
+
auto_names = [ compose.to_s ]
|
288
|
+
else
|
289
|
+
raise "Cannot auto compose object #{@name}, bad 'compose' format: #{compose.inspect}"
|
290
|
+
end
|
291
|
+
end
|
292
|
+
auto_names ||= []
|
293
|
+
auto_names.each do |cname|
|
294
|
+
@components[cname] = Lookup.new(cname)
|
295
|
+
end
|
296
|
+
|
297
|
+
# Remaining keys
|
298
|
+
info.each do |key,val|
|
299
|
+
@components[key.to_s] = Lookup.new(val.to_s)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
private
|
304
|
+
# Ganked this from Inflector:
|
305
|
+
def camelize(lower_case_and_underscored_word)
|
306
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
307
|
+
end
|
308
|
+
# Ganked this from Inflector:
|
309
|
+
def underscore(camel_cased_word)
|
310
|
+
camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
# Exception raised when an object can't be created which is defined in the context.
|
315
|
+
class ConstructionError < RuntimeError
|
316
|
+
def initialize(object_name, cause=nil) #:nodoc:
|
317
|
+
object_name = object_name
|
318
|
+
cause = cause
|
319
|
+
m = "Failed to construct '#{object_name}'"
|
320
|
+
if cause
|
321
|
+
m << "\n ...caused by:\n >>> #{cause}"
|
322
|
+
end
|
323
|
+
super m
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
|
329
|
+
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
class DiyContext
|
6
|
+
def initialize(context_hash)
|
7
|
+
@defs = {}
|
8
|
+
context_hash.each do |name,info|
|
9
|
+
@defs[name.to_s] = ObjectDef.new(name,info)
|
10
|
+
end
|
11
|
+
@cache = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.from_yaml(text)
|
15
|
+
DiyContext.new(YAML.load(text))
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.from_file(fname)
|
19
|
+
self.from_yaml(File.read(fname))
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_object(obj_name)
|
23
|
+
key = obj_name.to_s
|
24
|
+
obj = @cache[key]
|
25
|
+
unless obj
|
26
|
+
obj = construct_object(key)
|
27
|
+
@cache[key] = obj
|
28
|
+
end
|
29
|
+
obj
|
30
|
+
end
|
31
|
+
|
32
|
+
def contains_object(obj_name)
|
33
|
+
!@defs[obj_name].nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def construct_object(key)
|
38
|
+
# Find the object definition
|
39
|
+
obj_def = @defs[key]
|
40
|
+
raise "No object definition for '#{key}'"
|
41
|
+
|
42
|
+
# If object def mentions a library, load it
|
43
|
+
require obj_def.library if obj_def.library
|
44
|
+
|
45
|
+
# Resolve all components for the object
|
46
|
+
arg_hash = {}
|
47
|
+
obj_def.components.each do |name,value|
|
48
|
+
case value
|
49
|
+
when Lookup
|
50
|
+
arg_hash[name.to_sym] = get_object(value.name)
|
51
|
+
when StringValue
|
52
|
+
arg_hash[name.to_sym] = value.literal_value
|
53
|
+
else
|
54
|
+
raise "Cannot cope with component definition '#{value.inspect}'"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
# Get a reference to the class for the object
|
58
|
+
big_c = self.class.const_get(obj_def.class_name)
|
59
|
+
# Make and return the instance
|
60
|
+
big_c.new(arg_hash)
|
61
|
+
end
|
62
|
+
|
63
|
+
class Lookup
|
64
|
+
attr_reader :name
|
65
|
+
def initialize(obj_name)
|
66
|
+
@name = @obj_name
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class ObjectDef
|
71
|
+
attr_accessor :name, :class_name, :library, :components
|
72
|
+
def initialize(name,info={})
|
73
|
+
info ||= {}
|
74
|
+
|
75
|
+
@components = {}
|
76
|
+
|
77
|
+
# Object name
|
78
|
+
@name = name
|
79
|
+
|
80
|
+
# Class name
|
81
|
+
@class_name = info.delete 'class'
|
82
|
+
@class_name ||= info.delete 'type'
|
83
|
+
@class_name ||= Inflector.camelize(@name)
|
84
|
+
|
85
|
+
# Library
|
86
|
+
@library = info.delete 'library'
|
87
|
+
@library ||= info.delete 'lib'
|
88
|
+
@library ||= Inflector.underscore(@class_name)
|
89
|
+
|
90
|
+
# Auto-compose
|
91
|
+
compose = info.delete 'compose'
|
92
|
+
if compose
|
93
|
+
case compose
|
94
|
+
when Array
|
95
|
+
auto_names = compose.map { |x| x.to_s }
|
96
|
+
when String
|
97
|
+
auto_names = compose.split(',').map { |x| x.to_s }
|
98
|
+
when Symbol
|
99
|
+
auto_names = [ compose.to_s ]
|
100
|
+
else
|
101
|
+
raise "Cannot auto compose object #{@name}, bad 'compose' format: #{compose.inspect}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
auto_names ||= []
|
105
|
+
auto_names.each do |cname|
|
106
|
+
@components[cname] = Lookup.new(cname)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Remaining keys
|
110
|
+
info.each do |key,val|
|
111
|
+
@components[key.to_s] = Lookup.new(val.to_s)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
app_form:
|
2
|
+
class: MainAppForm
|
3
|
+
|
4
|
+
file_resolver:
|
5
|
+
class: FileResolver
|
6
|
+
lib: tools/happy_stuff
|
7
|
+
|
8
|
+
bep_host_config:
|
9
|
+
ini_file: (value) config.ini
|
10
|
+
compose: file_resolver
|
11
|
+
|
12
|
+
basic_dialog_shower:
|
13
|
+
compose:
|
14
|
+
- open_file_dialog
|
15
|
+
- error_dialog
|
16
|
+
|
17
|
+
hoss:
|
18
|
+
my_shower: basic_dialog_shower
|
19
|
+
|
20
|
+
boss:
|