Class: OroGen::Loaders::Base
- Inherits:
-
Object
- Object
- OroGen::Loaders::Base
- Defined in:
- lib/orogen/loaders/base.rb
Overview
Definition of the base loader API
Direct Known Subclasses
Instance Attribute Summary collapse
-
#interface_typelist ⇒ Object
readonly
The list of types that can be used on an oroGen interface.
-
#loaded_deployment_models ⇒ Object
readonly
Set of deployment models that are known to us.
-
#loaded_projects ⇒ Hash<String,Spec::Project>
readonly
Set of projects loaded so far.
-
#loaded_task_models ⇒ Object
readonly
Set of task models that are known to us.
-
#loaded_typekits ⇒ Hash<String,Spec::Typekit>
readonly
Set of typekits loaded so far.
-
#project_load_callbacks ⇒ Array<#call>
readonly
Set of callbacks that are called whenever a new typekit gets loaded.
-
#registry ⇒ Object
readonly
The registry that includes types from all loaded typekits.
-
#root_loader ⇒ Object
readonly
The loader that should be used to resolve dependencies.
-
#typekit_load_callbacks ⇒ Array<#call>
readonly
Set of callbacks that are called whenever a new typekit gets loaded.
-
#typekits_by_type_name ⇒ Object
readonly
A mapping from type names to the typekits that define them.
Instance Method Summary collapse
- #added_child(loader) ⇒ Object
- #clear ⇒ Object
-
#define_dummy_types=(value) ⇒ Boolean
Sets the behaviour of the type resolution on unknown types.
-
#define_dummy_types? ⇒ Boolean
Sets the behaviour of the type resolution on unknown types.
-
#deployed_task_model_from_name(name, deployment_name = nil) ⇒ OroGen::Spec::TaskDeployment
Returns the deployed task model for the given name.
-
#deployment_model_from_name(name) ⇒ OroGen::Spec::Deployment
Returns the deployment model for the given deployment name.
-
#each_available_project_name {|project_name| ... } ⇒ Object
Enumerates the names of all available projects.
-
#find_deployments_from_deployed_task_name(name) ⇒ Set<String>
Returns the set of deployments that contain a certain task.
-
#find_project_from_deployment_name(name) ⇒ String?
Returns the project that defines the given deployment.
-
#find_task_library_from_task_model_name(name) ⇒ String?
Returns the task library name in which a task model is defined.
- #has_loaded_project?(name) ⇒ Boolean
-
#has_loaded_typekit?(name) ⇒ Boolean
Tests if a typekit with that name has been loaded.
-
#has_project?(name) ⇒ Boolean
Tests if a project with that name exists.
-
#has_typekit?(name) ⇒ Boolean
Tests if a typekit with that name exists.
-
#imported_typekits_for(typename, definition_typekits: true) ⇒ Set<Spec::Typekit>
Returns the typekit object that defines this type.
-
#initialize(root_loader = self) ⇒ Base
constructor
A new instance of Base.
- #inspect ⇒ Object
-
#interface_type?(typename) ⇒ Boolean
Tests whether the given type can be used on an interface.
-
#intermediate_type?(type) ⇒ Boolean
Tests whether the given type can be used on an interface.
-
#intermediate_type_for(type) ⇒ Model<Typelib::Type>
Returns the intermediate type that is paired with the given type.
-
#m_type?(type) ⇒ Boolean
Returns whether this type is a m-type (intermediate type generated by oroGen).
-
#on_project_load(initial_events = true, &block) ⇒ Object
Registers a callback that should be called with newly registered projects.
-
#on_typekit_load(initial_events = true, &block) ⇒ Object
Registers a callback that should be called with newly registered typekits.
-
#opaque_type_for(type) ⇒ Model<Typelib::Type>
Returns the opaque type that is paired with the given type.
-
#project_model_from_name(name) ⇒ OroGen::Spec::Project
Returns the project model corresponding to the given name.
- #project_model_from_text(text, name: nil, path: nil) ⇒ Object
-
#project_model_text_from_name(name) ⇒ (String,String)
Returns the textual representation of a project model.
-
#register_deployment_model(model) ⇒ void
Registers a new deployment model.
-
#register_project_model(project) ⇒ Object
Registers this project's subobjects.
-
#register_task_context_model(model) ⇒ void
Registers a new task model.
- #register_type_model(type, interface = true) ⇒ Object
-
#register_typekit_model(typekit) ⇒ Object
Registers information from this typekit.
-
#remove_project_load_callback(callback) ⇒ Object
Removes the given callback from the listeners to #on_project_load.
-
#resolve_interface_type(typename) ⇒ Object
Returns the type object for
typename
, validating that we can use it in a task interface, i.e. -
#resolve_type(type, options = Hash.new) ⇒ Model<Typelib::Type>
Resolves a type object.
-
#task_library_model_from_name(name) ⇒ OroGen::Spec::Project
Returns the task library model corresponding to the given name.
-
#task_model_from_name(name) ⇒ Spec::TaskContext
Returns the task model object corresponding to a model name.
-
#typekit_model_from_name(name) ⇒ Spec::Typekit
Loads a typekit from its name.
-
#typekit_model_text_from_name(name) ⇒ (String,String)
Returns the textual representation of a typekit.
- #typelib_type_for(t) ⇒ Object
Constructor Details
#initialize(root_loader = self) ⇒ Base
Returns a new instance of Base
50 51 52 53 54 55 56 57 58 |
# File 'lib/orogen/loaders/base.rb', line 50 def initialize(root_loader = self) @root_loader = root_loader || self if root_loader != self root_loader.added_child(self) end @typekit_load_callbacks = Array.new @project_load_callbacks = Array.new clear end |
Instance Attribute Details
#interface_typelist ⇒ Object (readonly)
The list of types that can be used on an oroGen interface
20 21 22 |
# File 'lib/orogen/loaders/base.rb', line 20 def interface_typelist @interface_typelist end |
#loaded_deployment_models ⇒ Object (readonly)
Set of deployment models that are known to us
14 15 16 |
# File 'lib/orogen/loaders/base.rb', line 14 def loaded_deployment_models @loaded_deployment_models end |
#loaded_projects ⇒ Hash<String,Spec::Project> (readonly)
Set of projects loaded so far
8 9 10 |
# File 'lib/orogen/loaders/base.rb', line 8 def loaded_projects @loaded_projects end |
#loaded_task_models ⇒ Object (readonly)
Set of task models that are known to us
11 12 13 |
# File 'lib/orogen/loaders/base.rb', line 11 def loaded_task_models @loaded_task_models end |
#loaded_typekits ⇒ Hash<String,Spec::Typekit> (readonly)
Set of typekits loaded so far
28 29 30 |
# File 'lib/orogen/loaders/base.rb', line 28 def loaded_typekits @loaded_typekits end |
#project_load_callbacks ⇒ Array<#call> (readonly)
Set of callbacks that are called whenever a new typekit gets loaded
48 49 50 |
# File 'lib/orogen/loaders/base.rb', line 48 def project_load_callbacks @project_load_callbacks end |
#registry ⇒ Object (readonly)
The registry that includes types from all loaded typekits
17 18 19 |
# File 'lib/orogen/loaders/base.rb', line 17 def registry @registry end |
#root_loader ⇒ Object (readonly)
The loader that should be used to resolve dependencies
31 32 33 |
# File 'lib/orogen/loaders/base.rb', line 31 def root_loader @root_loader end |
#typekit_load_callbacks ⇒ Array<#call> (readonly)
Set of callbacks that are called whenever a new typekit gets loaded
42 43 44 |
# File 'lib/orogen/loaders/base.rb', line 42 def typekit_load_callbacks @typekit_load_callbacks end |
#typekits_by_type_name ⇒ Object (readonly)
A mapping from type names to the typekits that define them
23 24 25 |
# File 'lib/orogen/loaders/base.rb', line 23 def typekits_by_type_name @typekits_by_type_name end |
Instance Method Details
#added_child(loader) ⇒ Object
70 71 |
# File 'lib/orogen/loaders/base.rb', line 70 def added_child(loader) end |
#clear ⇒ Object
60 61 62 63 64 65 66 67 68 |
# File 'lib/orogen/loaders/base.rb', line 60 def clear @loaded_projects = Hash.new @loaded_typekits = Hash.new @loaded_task_models = Hash.new @loaded_deployment_models = Hash.new @typekits_by_type_name = Hash.new @registry = Typelib::Registry.new @interface_typelist = Set.new end |
#define_dummy_types=(value) ⇒ Boolean
Sets the behaviour of the type resolution on unknown types
36 |
# File 'lib/orogen/loaders/base.rb', line 36 attr_predicate :define_dummy_types?, true |
#define_dummy_types? ⇒ Boolean
Sets the behaviour of the type resolution on unknown types
36 |
# File 'lib/orogen/loaders/base.rb', line 36 attr_predicate :define_dummy_types?, true |
#deployed_task_model_from_name(name, deployment_name = nil) ⇒ OroGen::Spec::TaskDeployment
Returns the deployed task model for the given name
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/orogen/loaders/base.rb', line 207 def deployed_task_model_from_name(name, deployment_name = nil) if deployment_name deployment = deployment_model_from_name(deployment_name) else deployment_names = find_deployments_from_deployed_task_name(name) if deployment_names.empty? raise DeployedTaskModelNotFound, "cannot find a deployed task called #{name}" elsif deployment_names.size > 1 raise AmbiguousName, "more than one deployment defines a deployed task called #{name}: #{deployment_names.map(&:name).sort.join(", ")}" end deployment = deployment_model_from_name(deployment_names.first) end if !(task = deployment.find_task_by_name(name)) if deployment_name raise DeployedTaskModelNotFound, "deployment #{deployment_name} does not have a task called #{name}" else raise InternalError, "deployment #{deployment_name} was supposed to have a task called #{name} but does not" end end task end |
#deployment_model_from_name(name) ⇒ OroGen::Spec::Deployment
Returns the deployment model for the given deployment name
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/orogen/loaders/base.rb', line 176 def deployment_model_from_name(name) if model = loaded_deployment_models[name] return model end project_name = find_project_from_deployment_name(name) if !project_name raise DeploymentModelNotFound, "there is no deployment called #{name} on #{self}" end project = project_model_from_name(project_name) deployment = project.deployers[name] if !deployment raise InternalError, "cannot find the deployment called #{name} in #{project.name}. Candidates were #{project.deployers.map(&:name).sort.join(", ")}" end deployment end |
#each_available_project_name {|project_name| ... } ⇒ Object
Enumerates the names of all available projects
545 546 547 548 |
# File 'lib/orogen/loaders/base.rb', line 545 def each_available_project_name return enum_for(__method__) if !block_given? nil end |
#find_deployments_from_deployed_task_name(name) ⇒ Set<String>
Returns the set of deployments that contain a certain task
539 540 |
# File 'lib/orogen/loaders/base.rb', line 539 def find_deployments_from_deployed_task_name(name) end |
#find_project_from_deployment_name(name) ⇒ String?
Returns the project that defines the given deployment
532 533 |
# File 'lib/orogen/loaders/base.rb', line 532 def find_project_from_deployment_name(name) end |
#find_task_library_from_task_model_name(name) ⇒ String?
Returns the task library name in which a task model is defined
524 525 526 |
# File 'lib/orogen/loaders/base.rb', line 524 def find_task_library_from_task_model_name(name) raise NotImplementedError, "#{self.class} does not implement #find_task_library_from_task_model_name" end |
#has_loaded_project?(name) ⇒ Boolean
455 456 457 |
# File 'lib/orogen/loaders/base.rb', line 455 def has_loaded_project?(name) loaded_projects.has_key?(name) end |
#has_loaded_typekit?(name) ⇒ Boolean
Tests if a typekit with that name has been loaded
508 509 510 |
# File 'lib/orogen/loaders/base.rb', line 508 def has_loaded_typekit?(name) loaded_typekits.has_key?(name) end |
#has_project?(name) ⇒ Boolean
Tests if a project with that name exists
500 501 502 |
# File 'lib/orogen/loaders/base.rb', line 500 def has_project?(name) loaded_projects.has_key?(name) end |
#has_typekit?(name) ⇒ Boolean
Tests if a typekit with that name exists
516 517 518 |
# File 'lib/orogen/loaders/base.rb', line 516 def has_typekit?(name) loaded_typekits.has_key?(name) end |
#imported_typekits_for(typename, definition_typekits: true) ⇒ Set<Spec::Typekit>
Returns the typekit object that defines this type
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/orogen/loaders/base.rb', line 350 def imported_typekits_for(typename, definition_typekits: true) if typename.respond_to?(:name) typename = typename.name end if typekits = typekits_by_type_name[typename] if definition_typekits definition_typekits = typekits.find_all { |tk| tk.include?(typename) } if definition_typekits.empty? raise DefinitionTypekitNotFound, "typekits #{typekits.map(&:name).sort.join(", ")} have #{typename} in their registries, but it seems that they got it from another typekit and I cannot find it. definition_typekits is true, I raise" end return definition_typekits.to_set else return typekits end end raise DefinitionTypekitNotFound, "#{typename} is not defined by any typekits loaded so far" end |
#inspect ⇒ Object
571 572 573 |
# File 'lib/orogen/loaders/base.rb', line 571 def inspect to_s end |
#interface_type?(typename) ⇒ Boolean
Tests whether the given type can be used on an interface
386 387 388 389 |
# File 'lib/orogen/loaders/base.rb', line 386 def interface_type?(typename) typename = typename.name if typename.respond_to?(:name) interface_typelist.include?(typename) end |
#intermediate_type?(type) ⇒ Boolean
Tests whether the given type can be used on an interface
395 396 397 398 |
# File 'lib/orogen/loaders/base.rb', line 395 def intermediate_type?(type) type = resolve_type(type) !type..get('orogen:intermediate_type_of').empty? end |
#intermediate_type_for(type) ⇒ Model<Typelib::Type>
Returns the intermediate type that is paired with the given type
416 417 418 419 420 |
# File 'lib/orogen/loaders/base.rb', line 416 def intermediate_type_for(type) type = resolve_type(type) intermediates = type..get('orogen:intermediate_type') registry.get(intermediates.first || type.name) end |
#m_type?(type) ⇒ Boolean
Returns whether this type is a m-type (intermediate type generated by oroGen)
428 429 430 431 |
# File 'lib/orogen/loaders/base.rb', line 428 def m_type?(type) type = resolve_type(type) type..get('orogen:generated_type') == ['true'] end |
#on_project_load(initial_events = true, &block) ⇒ Object
Registers a callback that should be called with newly registered projects
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/orogen/loaders/base.rb', line 113 def on_project_load(initial_events = true, &block) project_load_callbacks << block if initial_events current_set = loaded_projects.values.dup current_set.each do |p| block.call(p) end end block end |
#on_typekit_load(initial_events = true, &block) ⇒ Object
Registers a callback that should be called with newly registered typekits
309 310 311 312 313 314 315 316 317 |
# File 'lib/orogen/loaders/base.rb', line 309 def on_typekit_load(initial_events = true, &block) typekit_load_callbacks << block if initial_events current_set = loaded_typekits.values.dup current_set.each do |tk| block.call(tk) end end end |
#opaque_type_for(type) ⇒ Model<Typelib::Type>
Returns the opaque type that is paired with the given type
405 406 407 408 409 |
# File 'lib/orogen/loaders/base.rb', line 405 def opaque_type_for(type) type = resolve_type(type) opaques = type..get('orogen:intermediate_type_of') registry.get(opaques.first || type.name) end |
#project_model_from_name(name) ⇒ OroGen::Spec::Project
Returns the project model corresponding to the given name
79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/orogen/loaders/base.rb', line 79 def project_model_from_name(name) if project = loaded_projects[name] return project end name = name.to_str text, path = project_model_text_from_name(name) OroGen.info "loading oroGen project #{name}" project_model_from_text(text, name: name, path: path) end |
#project_model_from_text(text, name: nil, path: nil) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/orogen/loaders/base.rb', line 91 def project_model_from_text(text, name: nil, path: nil) project = Spec::Project.new(root_loader) project.typekit = if has_typekit?(name) typekit_model_from_name(name) else Spec::Typekit.new(root_loader, name) end Loaders::Project.new(project).__eval__(path, text) if name && (project.name != name) raise ArgumentError, "got project #{project.name} while loading #{name}" end register_project_model(project) project end |
#project_model_text_from_name(name) ⇒ (String,String)
Returns the textual representation of a project model
482 483 484 |
# File 'lib/orogen/loaders/base.rb', line 482 def project_model_text_from_name(name) raise NotImplementedError end |
#register_deployment_model(model) ⇒ void
This method returns an undefined value.
Registers a new deployment model
471 472 473 |
# File 'lib/orogen/loaders/base.rb', line 471 def register_deployment_model(model) loaded_deployment_models[model.name] = model end |
#register_project_model(project) ⇒ Object
Registers this project's subobjects
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
# File 'lib/orogen/loaders/base.rb', line 434 def register_project_model(project) if loaded_projects.has_key?(project.name) raise AlreadyRegistered, "there is already a project called #{project.name} registered on #{self}" end loaded_projects[project.name] = project if root_loader != self return root_loader.register_project_model(project) end project.tasks.each do |_, task_model| register_task_context_model(task_model) end project.deployers.each do |_, deployer_model| register_deployment_model(deployer_model) end project_load_callbacks.each do |callback| callback.call(project) end end |
#register_task_context_model(model) ⇒ void
This method returns an undefined value.
Registers a new task model
463 464 465 |
# File 'lib/orogen/loaders/base.rb', line 463 def register_task_context_model(model) loaded_task_models[model.name] = model end |
#register_type_model(type, interface = true) ⇒ Object
297 298 299 300 301 302 |
# File 'lib/orogen/loaders/base.rb', line 297 def register_type_model(type, interface = true) registry.merge type.registry.minimal(type.name) if interface interface_typelist << type.name end end |
#register_typekit_model(typekit) ⇒ Object
Registers information from this typekit
Callbacks registered by #on_typekit_load gets called with the new typekit as argument
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/orogen/loaders/base.rb', line 254 def register_typekit_model(typekit) if loaded_typekits.has_key?(typekit.name) raise AlreadyRegistered, "there is already a typekit called #{typekit.name} registered on #{self}" end loaded_typekits[typekit.name] = typekit if root_loader != self return root_loader.register_typekit_model(typekit) end registry.merge typekit.registry typekit.registry.each(with_aliases: false) do |type| self_type = registry.get(type.name) self_type..add('orogen:typekits', typekit.name) if typekit.include?(type.name) self_type..add('orogen:definition_typekits', typekit.name) end if type.contains_opaques? intermediate_type_name = typekit.intermediate_type_name_for(type) intermediate_type = registry.get(intermediate_type_name) self_type..add('orogen:intermediate_type', intermediate_type_name) intermediate_type..add('orogen:intermediate_type_of', type.name) if !type.opaque? intermediate_type..set('orogen:generated_type', 'true') end end end @interface_typelist |= typekit.interface_typelist typekit.registry.each(with_aliases: true) do |typename, _| typekits_by_type_name[typename] ||= Set.new typekits_by_type_name[typename] << typekit end typekit_load_callbacks.each do |callback| callback.call(typekit) end end |
#remove_project_load_callback(callback) ⇒ Object
Removes the given callback from the listeners to #on_project_load
128 129 130 |
# File 'lib/orogen/loaders/base.rb', line 128 def remove_project_load_callback(callback) project_load_callbacks.delete(callback) end |
#resolve_interface_type(typename) ⇒ Object
Returns the type object for typename
, validating that we can
use it in a task interface, i.e. that it will be registered in the
RTT's typeinfo system
371 372 373 374 375 376 377 378 379 380 |
# File 'lib/orogen/loaders/base.rb', line 371 def resolve_interface_type(typename) type = resolve_type(typename) if type < Typelib::ArrayType raise InvalidInterfaceType.new(type), "static arrays are not valid interface types. Use an array in a structure or a std::vector" elsif !interface_type?(type) typekits = imported_typekits_for(type.name) raise NotExportedType.new(type, typekits), "#{type.name}, defined in the #{typekits.map(&:name).join(", ")} typekits, is never exported" end type end |
#resolve_type(type, options = Hash.new) ⇒ Model<Typelib::Type>
Resolves a type object
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/orogen/loaders/base.rb', line 325 def resolve_type(type, = Hash.new) typename = if type.respond_to?(:name) type.name else type end registry.get(typename) rescue Typelib::NotFound => e if define_dummy_types? || [:define_dummy_type] type = registry.create_null(typename) register_type_model(type, interface: true) return type else raise e, "#{e.} using #{self}", e.backtrace end end |
#task_library_model_from_name(name) ⇒ OroGen::Spec::Project
Returns the task library model corresponding to the given name
138 139 140 141 142 143 144 |
# File 'lib/orogen/loaders/base.rb', line 138 def task_library_model_from_name(name) project = project_model_from_name(name) if project.self_tasks.empty? raise ProjectNotFound, "there is an oroGen project called #{name}, but it defines no tasks" end project end |
#task_model_from_name(name) ⇒ Spec::TaskContext
Returns the task model object corresponding to a model name
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/orogen/loaders/base.rb', line 152 def task_model_from_name(name) if model = loaded_task_models[name] return model end tasklib_name = find_task_library_from_task_model_name(name) if !tasklib_name raise TaskModelNotFound, "no task model #{name} is registered" end tasklib = project_model_from_name(tasklib_name) result = tasklib.tasks[name] if !result raise InternalError, "while looking up model of #{name}: found project #{tasklib_name}, but this project does not actually have a task model called #{name}" end result end |
#typekit_model_from_name(name) ⇒ Spec::Typekit
Loads a typekit from its name
235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/orogen/loaders/base.rb', line 235 def typekit_model_from_name(name) if typekit = loaded_typekits[name] return typekit end registry_xml, typelist_txt = typekit_model_text_from_name(name) typekit = Spec::Typekit.from_raw_data(root_loader, name, registry_xml, typelist_txt) if typekit.name != name raise InternalError, "inconsistency: got typekit #{typekit.name} while loading #{name}" end register_typekit_model(typekit) typekit end |
#typekit_model_text_from_name(name) ⇒ (String,String)
Returns the textual representation of a typekit
492 493 494 |
# File 'lib/orogen/loaders/base.rb', line 492 def typekit_model_text_from_name(name) raise NotImplementedError end |
#typelib_type_for(t) ⇒ Object
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 |
# File 'lib/orogen/loaders/base.rb', line 550 def typelib_type_for(t) if t.respond_to?(:name) return t if !t.contains_opaques? t = t.name end if registry.include?(t) type = registry.get(t) if type.contains_opaques? intermediate_type_for(type) elsif type.null? # 't' is an opaque type and there are no typelib marshallers # to convert it to something we can manipulate, raise raise Typelib::NotFound, "#{t} is a null type and there are no typelib marshallers registered in RTT to convert it to a typelib-compatible type" else type end else raise Typelib::NotFound, "#{t} cannot be found in the currently loaded registries" end end |