Module: Syskit::Models::Component
- Includes:
- MetaRuby::DSLs::FindThroughMethodMissing, MetaRuby::ModelAsClass, DataService, Base
- Included in:
- Component, Composition, TaskContext
- Defined in:
- lib/syskit/models/component.rb
Overview
Definition of model-level methods for the Component models. See the documentation of Model for an explanation of this.
Constant Summary collapse
- PROVIDES_ARGUMENTS =
{ as: nil, slave_of: nil }
Instance Attribute Summary collapse
-
#concrete_model ⇒ Object
If this model is specialized, returns the most derived model that is non-specialized.
Instance Method Summary collapse
-
#all_data_service ⇒ Array<String,BoundDataService>
The union, along the class hierarchy, of all the values stored in data_service.
-
#all_dynamic_service ⇒ Array<String,DynamicDataService>
The union, along the class hierarchy, of all the values stored in dynamic_service.
-
#all_stub_module ⇒ Array<Module>
The union, along the class hierarchy, of all the values stored in stub_module.
- #apply_missing_dynamic_services_from(from, specialize_if_needed = true) ⇒ Object
-
#as(service_model) ⇒ Object
Returns a view of this component as a producer of the given model.
-
#as_plan ⇒ Object
Returns a placeholder task that can be used to require that a task from this component model is deployed and started at a certain point in the plan.
-
#bind(object) ⇒ Roby::Task
Return a representation of an instance that is compatible with self.
- #can_merge?(target_model) ⇒ Boolean
- #clear_model ⇒ Object
-
#component_model? ⇒ Boolean
Wether this model truly represents a component model.
-
#compute_port_mappings(service_model, explicit_mappings = Hash.new) ⇒ Object
Compute the port mapping from the interface of 'service' onto the ports of 'self'.
-
#concrete_model? ⇒ Boolean
Returns true if this model is a “true” concrete model or a specialized one.
-
#connected?(out_port, in_port) ⇒ Boolean
Delegated call from Port#connected?.
-
#create_dynamic_instantiation_context(name, dynamic_service, **options) ⇒ Object
private
Creation of a DynamicDataService instantiation context.
-
#create_private_specialization ⇒ Object
Called by #specialize to create the composition model that will be used for a private specialization.
-
#create_proxy_task ⇒ Object
Create a Roby task that can be used as a placeholder for self in the plan.
-
#create_proxy_task_model(service_models, as: nil, extension: Placeholder) ⇒ Object
deprecated
Deprecated.
use Models::Placeholder.create_for instead
-
#data_service ⇒ Hash<String,BoundDataService>
The data services defined on this task, as a mapping from the data service full name to the BoundDataService object.
-
#data_services ⇒ Hash<String,BoundDataService>
The data services defined on this task, as a mapping from the data service full name to the BoundDataService object.
-
#deregister_placeholder_model(placeholder_m) ⇒ Object
private
Deregister a placeholder model.
-
#deregister_submodels(set) ⇒ Object
Clears all registered submodels.
-
#driver_for(model, arguments = Hash.new, &block) ⇒ Object
Declares that this task context model can be used as a driver for the device
model
. -
#dynamic_service(model, as: nil, addition_requires_reconfiguration: true, remove_when_unused: true, **backward) { ... } ⇒ Object
Declares that this component model can dynamically extend its interface by adding services of the given type.
-
#dynamic_services ⇒ Hash<String,DynamicDataService>
The set of dynamic services instantiated with #dynamic_service.
-
#each_com_bus_driver_service {|Model<ComBus>| ... } ⇒ void
Enumerate all the combus that are defined on this component model.
-
#each_data_service {|element| ... } ⇒ Object
Enumerates all objects registered in data_service.
-
#each_dynamic_service {|element| ... } ⇒ Object
Enumerates all objects registered in dynamic_service.
- #each_input_port ⇒ Object
-
#each_master_driver_service {|device_model| ... } ⇒ void
Enumerate all the devices that are defined on this component model.
- #each_output_port ⇒ Object
- #each_port ⇒ Object
-
#each_required_dynamic_service {|srv| ... } ⇒ Object
Enumerates the services that have been created from a dynamic service using #require_dynamic_service.
- #each_required_model {|concrete_model| ... } ⇒ Object
-
#each_root_data_service {|Models::BoundDataService| ... } ⇒ Object
Enumerates all services that are root (i.e. not slave of other services).
-
#each_slave_data_service(master_service) {|Models::BoundDataService| ... } ⇒ Object
Enumerates all services that are slave (i.e. not slave of other services).
-
#each_stub_module {|element| ... } ⇒ Object
Enumerates all objects registered in stub_module.
-
#ensure_model_is_specialized ⇒ Model<Component>
Makes sure this is a private specialized model.
-
#find_all_data_services_from_type(type) ⇒ Array<Models::BoundDataService>
Finds a single service that provides
type
. -
#find_data_service_from_type(type) ⇒ Models::BoundDataService?
Finds a single service that provides
type
. -
#find_directional_port_mapping(direction, port, expected_name) ⇒ String?
Finds the port of self that should be used for a service port 'port'.
- #find_input_port(name) ⇒ Object
-
#find_matching_service(target_model, pattern = nil) ⇒ Object
Generic data service selection method, based on a service type and an optional service name.
- #find_output_port(name) ⇒ Object
-
#find_placeholder_model(service_models, placeholder_type = Placeholder) ⇒ Object
private
Find an existing placeholder model based on self for the given service models.
- #find_port(name) ⇒ Object
- #find_through_method_missing(m, args) ⇒ Object
- #fullfills?(object) ⇒ Boolean
- #has_through_method_missing?(m) ⇒ Boolean
-
#if_already_present ⇒ InstanceRequirements
Optional dependency injection.
- #implicit_fullfilled_model ⇒ Object
-
#instanciate(plan, context = DependencyInjectionContext.new, task_arguments: Hash.new, **arguments) ⇒ Object
Generic instanciation of a component.
-
#instanciate_dynamic_input_port(name, type, port) ⇒ Port
Adds a new port to this model based on a known dynamic port.
-
#instanciate_dynamic_output_port(name, type, port) ⇒ Port
Adds a new port to this model based on a known dynamic port.
-
#merge(other_model) ⇒ Object
Returns the component model that is the merge model of self and the given other model.
- #merge_service_model(service_model, port_mappings) ⇒ Object
- #method_missing(m, *args, &block) ⇒ Object
-
#needs_stub?(component) ⇒ Boolean
Checks if a given component implementation needs to be stubbed.
-
#placeholder? ⇒ Boolean
Wether this model represents a placeholder for data services.
-
#port_mappings_for(model) ⇒ Object
Defined to be compatible, in port mapping code, with the data services.
-
#port_mappings_for_task ⇒ Object
Defined to be compatible, in port mapping code, with the data services.
- #prefer_deployed_tasks(*selections) ⇒ Object
-
#prepare_stub(component) ⇒ Object
Apply what's necessary for this component (from the underlying component implementation) to be a proper component stub.
-
#private_specialization=(value) ⇒ Model<TaskContext>
If true, this model is used internally as specialization of another component model (as e.g. to represent dynamic service instantiation).
-
#private_specialization? ⇒ Model<TaskContext>
If true, this model is used internally as specialization of another component model (as e.g. to represent dynamic service instantiation).
-
#promote_data_service(full_name, service) ⇒ Object
Method that maps data services from this component's parent models to this composition's own.
-
#promote_dynamic_service(name, dyn) ⇒ Object
Called by the dynamic_service accessors to promote dynamic services from our parent model to the corresponding dynamic services on the child models.
-
#provides(model, port_mappings = Hash.new, as: nil, slave_of: nil, bound_service_class: BoundDataService) ⇒ Object
Declares that this component provides the given data service.
-
#provides_dynamic(service_model, port_mappings = Hash.new, as: nil, slave_of: nil, bound_service_class: BoundDataService) ⇒ BoundDynamicDataService
Declares that this component model will dynamically provide the ports necessary to provide a service model.
-
#proxy_task_model(service_models, as: nil, extension: Placeholder) ⇒ Object
deprecated
Deprecated.
use Models::Placeholder.for instead
-
#register_placeholder_model(placeholder_m, service_models, placeholder_type = Placeholder) ⇒ Object
private
Register a new placeholder model for the given service models and placeholder type.
-
#require_dynamic_service(dynamic_service_name, as: nil, **dyn_options) ⇒ BoundDynamicDataService
Instanciate a dynamic service on this model.
-
#resolve(task) ⇒ Object
deprecated
Deprecated.
use #bind instead
- #selected_for(requirements) ⇒ Object
-
#self_port?(port) ⇒ Boolean
Test if the given port is a port of self.
-
#self_port_to_component_port(port) ⇒ Models::Port
Resolves the given port model into a component model where #component_model is a proper component (e.g. not a BoundDataService).
-
#specialization_counter ⇒ Object
An ID that represents which specialized model this is.
-
#specialize(name = nil) ⇒ Object
Creates a private specialization of the current model.
-
#stub(&block) ⇒ Object
Define a module that should be applied on the underlying Orocos::RubyTasks::StubTaskContext when running tests in non-live mode.
-
#stub_module ⇒ Array<Module>
List of modules that should be applied on the underlying Orocos::RubyTasks::StubTaskContext when running tests in non-stub mode.
-
#supermodel ⇒ Object
The model next in the ancestry chain, or nil if
self
is root. - #to_component_model ⇒ Object
-
#try_bind(object) ⇒ nil, Syskit::Component
Task if it fullfills self, nil otherwise.
-
#try_resolve(task) ⇒ Object
deprecated
Deprecated.
use #try_bind instead
- #use_conf(*spec, &block) ⇒ Object deprecated Deprecated.
-
#use_deployments(*selection) ⇒ Object
deprecated
Deprecated.
replaced by #prefer_deployed_tasks
-
#with_arguments(*spec, &block) ⇒ Object
This returns an InstanciatedComponent object that can be used in other #use statements in the deployment spec.
-
#with_conf(*spec, &block) ⇒ Object
This returns an InstanciatedComponent object that can be used in other #use statements in the deployment spec.
-
#with_dynamic_service(dynamic_service_name, options = Hash.new) ⇒ Object
Returns a model specialized from 'self' that has the required dynamic service.
Methods included from DataService
Methods included from Base
#dependency_injection_names, #pretty_print, #short_name, #to_instance_requirements, #to_s
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args, &block) ⇒ Object
720 721 722 723 724 725 |
# File 'lib/syskit/models/component.rb', line 720 def method_missing(m, *args, &block) if m == :orogen_model raise NoMethodError, "tried to use a method to access an oroGen model, but none exists on #{self}" end super end |
Instance Attribute Details
#concrete_model ⇒ Object
If this model is specialized, returns the most derived model that is non-specialized. Otherwise, returns self.
800 801 802 803 804 805 |
# File 'lib/syskit/models/component.rb', line 800 def concrete_model if @concrete_model return @concrete_model else return self end end |
Instance Method Details
#all_data_service ⇒ Array<String,BoundDataService>
The union, along the class hierarchy, of all the values stored in data_service
25 |
# File 'lib/syskit/models/component.rb', line 25 inherited_attribute(:data_service, :data_services, map: true) { Hash.new } |
#all_dynamic_service ⇒ Array<String,DynamicDataService>
The union, along the class hierarchy, of all the values stored in dynamic_service
457 |
# File 'lib/syskit/models/component.rb', line 457 inherited_attribute('dynamic_service', 'dynamic_services', map: true) { Hash.new } |
#all_stub_module ⇒ Array<Module>
The union, along the class hierarchy, of all the values stored in stub_module
34 |
# File 'lib/syskit/models/component.rb', line 34 inherited_attribute(:stub_module, :stub_modules) { [Module.new] } |
#apply_missing_dynamic_services_from(from, specialize_if_needed = true) ⇒ Object
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 |
# File 'lib/syskit/models/component.rb', line 1060 def apply_missing_dynamic_services_from(from, specialize_if_needed = true) missing_services = from.each_data_service.find_all do |_, srv| !find_data_service(srv.full_name) end if !missing_services.empty? # We really really need to specialize self. The reason is # that self.model, even though it has private # specializations, might be a reusable model from the system # designer's point of view. With the singleton class, we # know that it is not base_model = if specialize_if_needed then specialize else self end missing_services.each do |_, srv| = Hash[as: srv.name]. merge(srv.) base_model.require_dynamic_service srv.dynamic_service.name, end base_model else self end end |
#as(service_model) ⇒ Object
Returns a view of this component as a producer of the given model
This will fail if multiple services offer service_model
. In
this case, one would have to first explicitely select the service and only
then call #as on the returned BoundDataService object
237 238 239 240 241 242 243 |
# File 'lib/syskit/models/component.rb', line 237 def as(service_model) srv = find_data_service_from_type(service_model) if !srv raise ArgumentError, "no service of #{self} provides #{service_model}" end return srv.as(service_model) end |
#as_plan ⇒ Object
Returns a placeholder task that can be used to require that a task from this component model is deployed and started at a certain point in the plan.
It is usually used implicitely with the plan and relation methods directly:
cmp = task.depends_on(Cmp::MyComposition)
calls this method behind the scenes.
822 823 824 |
# File 'lib/syskit/models/component.rb', line 822 def as_plan Syskit::InstanceRequirementsTask.subplan(self) end |
#bind(object) ⇒ Roby::Task
Return a representation of an instance that is compatible with self
841 842 843 844 845 846 847 |
# File 'lib/syskit/models/component.rb', line 841 def bind(object) if component = try_bind(object) component else raise ArgumentError, "cannot bind #{self} to #{object}" end end |
#can_merge?(target_model) ⇒ Boolean
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 |
# File 'lib/syskit/models/component.rb', line 1020 def can_merge?(target_model) self_real_model = concrete_model target_real_model = target_model.concrete_model if self_real_model != self || target_real_model != target_model if !self_real_model.can_merge?(target_real_model) return false end elsif !super return false end # Verify that we don't have collisions in the instantiated # dynamic services each_data_service do |_, self_srv| task_srv = target_model.find_data_service(self_srv.name) next if !task_srv if task_srv.model != self_srv.model NetworkGeneration::MergeSolver.debug do "rejecting #{self}.merge(#{target_model}): dynamic service #{self_srv.name} is of model #{self_srv.model.short_name} on #{self} and of model #{task_srv.model.short_name} on #{target_model}" end return false elsif task_srv.dynamic? && self_srv.dynamic? if task_srv. != self_srv. NetworkGeneration::MergeSolver.debug do "rejecting #{self}.merge(#{target_model}): dynamic service #{self_srv.name} has options #{task_srv.} on self and #{self_srv.} on the candidate task" end return false end elsif task_srv.dynamic? || self_srv.dynamic? NetworkGeneration::MergeSolver.debug do "rejecting #{self}.merge(#{target_model}): #{self_srv.name} is a dynamic service on the receiver, but a static one on the target" end return false end end return true end |
#clear_model ⇒ Object
36 37 38 39 40 41 42 43 44 45 |
# File 'lib/syskit/models/component.rb', line 36 def clear_model super data_services.clear dynamic_services.clear # Note: the placeholder_models cache is cleared separately. The # reason is that we need to clear it on permanent and # non-permanent models alike, including component models that # are defined in syskit. The normal procedure is to call # #clear_model only on the models defined in the app(s) end |
#component_model? ⇒ Boolean
Wether this model truly represents a component model
955 956 957 |
# File 'lib/syskit/models/component.rb', line 955 def component_model? true end |
#compute_port_mappings(service_model, explicit_mappings = Hash.new) ⇒ Object
Compute the port mapping from the interface of 'service' onto the ports of 'self'
The returned hash is
service_interface_port_name => task_model_port_name
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
# File 'lib/syskit/models/component.rb', line 322 def compute_port_mappings(service_model, explicit_mappings = Hash.new) normalized_mappings = Hash.new explicit_mappings.each do |from, to| from = from.to_s if from.kind_of?(Symbol) to = to.to_s if to.kind_of?(Symbol) if !from.respond_to?(:to_str) raise ArgumentError, "unexpected value given in port mapping: #{from}, expected a string" elsif !to.respond_to?(:to_str) raise ArgumentError, "unexpected value given in port mapping: #{to}, expected a string" else normalized_mappings[from] = to end end # This is used later to verify that we don't automatically map # two different ports to the same port. It can be done # explicitly, though mapped_to_original = Hash.new { |h, k| h[k] = Array.new } result = Hash.new service_model.each_output_port do |port| if mapped_name = find_directional_port_mapping('output', port, normalized_mappings[port.name]) result[port.name] = mapped_name mapped_to_original[mapped_name] << port.name else raise InvalidPortMapping, "cannot find an equivalent output port for #{port.name}[#{port.type_name}] on #{short_name}" end end service_model.each_input_port do |port| if mapped_name = find_directional_port_mapping('input', port, normalized_mappings[port.name]) result[port.name] = mapped_name mapped_to_original[mapped_name] << port.name else raise InvalidPortMapping, "cannot find an equivalent input port for #{port.name}[#{port.type_name}] on #{short_name}" end end # Verify that we don't automatically map two different ports to # the same port mapped_to_original.each do |mapped, original| if original.size > 1 not_explicit = original.find_all { |pname| !normalized_mappings.has_key?(pname) } if !not_explicit.empty? raise InvalidPortMapping, "automatic port mapping would map ports #{original.sort.join(", ")} to the same port #{mapped}. I refuse to do this. If you actually mean to do it, provide the mapping #{original.map { |o| "\"#{o}\" => \"#{mapped}\"" }.join(", ")} explicitly" end end end result end |
#concrete_model? ⇒ Boolean
Returns true if this model is a “true” concrete model or a specialized one
809 810 811 |
# File 'lib/syskit/models/component.rb', line 809 def concrete_model? concrete_model == self end |
#connected?(out_port, in_port) ⇒ Boolean
Delegated call from Port#connected?
Always returns false as “plain” component ports cannot be connected
867 868 869 |
# File 'lib/syskit/models/component.rb', line 867 def connected?(out_port, in_port) false end |
#create_dynamic_instantiation_context(name, dynamic_service, **options) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Creation of a DynamicDataService instantiation context
DynamicDataService#instantiate delegates to this method to create the context in which the dynamic service setup block should be evaluated. It allows subclasses to provide specific additional APIs
564 565 566 |
# File 'lib/syskit/models/component.rb', line 564 def create_dynamic_instantiation_context(name, dynamic_service, **) DynamicDataService::InstantiationContext.new(self, name, dynamic_service, **) end |
#create_private_specialization ⇒ Object
Called by #specialize to create the composition model that will be used for a private specialization
750 751 752 |
# File 'lib/syskit/models/component.rb', line 750 def create_private_specialization new_submodel end |
#create_proxy_task ⇒ Object
Create a Roby task that can be used as a placeholder for self in the plan
The returned task is always marked as abstract
939 940 941 942 943 |
# File 'lib/syskit/models/component.rb', line 939 def create_proxy_task task = new task.abstract = true task end |
#create_proxy_task_model(service_models, as: nil, extension: Placeholder) ⇒ Object
use Models::Placeholder.create_for instead
924 925 926 927 |
# File 'lib/syskit/models/component.rb', line 924 def create_proxy_task_model(service_models, as: nil, extension: Placeholder) Roby.warn_deprecated "Component.create_proxy_task_model is deprecated, use Syskit::Models::Placeholder.create_for instead" extension.create_for(service_models, component_model: self, as: as) end |
#data_service ⇒ Hash<String,BoundDataService>
The data services defined on this task, as a mapping from the data service full name to the BoundDataService object.
25 |
# File 'lib/syskit/models/component.rb', line 25 inherited_attribute(:data_service, :data_services, map: true) { Hash.new } |
#data_services ⇒ Hash<String,BoundDataService>
The data services defined on this task, as a mapping from the data service full name to the BoundDataService object.
25 |
# File 'lib/syskit/models/component.rb', line 25 inherited_attribute(:data_service, :data_services, map: true) { Hash.new } |
#deregister_placeholder_model(placeholder_m) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Deregister a placeholder model
898 899 900 901 902 903 904 905 906 907 |
# File 'lib/syskit/models/component.rb', line 898 def deregister_placeholder_model(placeholder_m) key = placeholder_m.proxied_data_service_models.to_set if by_type = placeholder_models.delete(key) by_type.delete_if { |_, m| m == placeholder_m } if !by_type.empty? placeholder_models[key] = by_type end true end end |
#deregister_submodels(set) ⇒ Object
Clears all registered submodels
910 911 912 913 914 915 916 917 918 919 920 921 |
# File 'lib/syskit/models/component.rb', line 910 def deregister_submodels(set) super if @placeholder_models set.each do |m| if m.placeholder? deregister_placeholder_model(m) end end end true end |
#driver_for(model, arguments = Hash.new, &block) ⇒ Object
Declares that this task context model can be used as a driver for the
device model
.
It will create the corresponding device model if it does not already exist,
and return it. See the documentation of Component.data_service for the
description of arguments
702 703 704 705 706 |
# File 'lib/syskit/models/component.rb', line 702 def driver_for(model, arguments = Hash.new, &block) dserv = provides(model, arguments) argument "#{dserv.name}_dev" dserv end |
#dynamic_service(model, as: nil, addition_requires_reconfiguration: true, remove_when_unused: true, **backward) { ... } ⇒ Object
Declares that this component model can dynamically extend its interface by adding services of the given type
This only models the functionality of dynamically creating new services the actual related component setup needs to be done by overloading the component's #configure method.
457 |
# File 'lib/syskit/models/component.rb', line 457 inherited_attribute('dynamic_service', 'dynamic_services', map: true) { Hash.new } |
#dynamic_services ⇒ Hash<String,DynamicDataService>
The set of dynamic services instantiated with #dynamic_service
457 |
# File 'lib/syskit/models/component.rb', line 457 inherited_attribute('dynamic_service', 'dynamic_services', map: true) { Hash.new } |
#each_com_bus_driver_service {|Model<ComBus>| ... } ⇒ void
This method returns an undefined value.
Enumerate all the combus that are defined on this component model
66 67 68 69 70 71 72 73 |
# File 'lib/syskit/models/component.rb', line 66 def each_com_bus_driver_service(&block) return enum_for(:each_com_bus_driver_service) if !block_given? each_root_data_service do |srv| if srv.model < Syskit::ComBus yield(srv) end end end |
#each_data_service {|element| ... } ⇒ Object
Enumerates all objects registered in data_service
25 |
# File 'lib/syskit/models/component.rb', line 25 inherited_attribute(:data_service, :data_services, map: true) { Hash.new } |
#each_dynamic_service {|element| ... } ⇒ Object
Enumerates all objects registered in dynamic_service
457 |
# File 'lib/syskit/models/component.rb', line 457 inherited_attribute('dynamic_service', 'dynamic_services', map: true) { Hash.new } |
#each_input_port ⇒ Object
569 |
# File 'lib/syskit/models/component.rb', line 569 def each_input_port; end |
#each_master_driver_service {|device_model| ... } ⇒ void
This method returns an undefined value.
Enumerate all the devices that are defined on this component model
52 53 54 55 56 57 58 59 |
# File 'lib/syskit/models/component.rb', line 52 def each_master_driver_service(&block) return enum_for(:each_master_driver_service) if !block_given? each_root_data_service do |srv| if srv.model < Syskit::Device yield(srv) end end end |
#each_output_port ⇒ Object
570 |
# File 'lib/syskit/models/component.rb', line 570 def each_output_port; end |
#each_port ⇒ Object
568 |
# File 'lib/syskit/models/component.rb', line 568 def each_port; end |
#each_required_dynamic_service {|srv| ... } ⇒ Object
Enumerates the services that have been created from a dynamic service using #require_dynamic_service
509 510 511 512 513 514 515 516 |
# File 'lib/syskit/models/component.rb', line 509 def each_required_dynamic_service return enum_for(:each_required_dynamic_service) if !block_given? each_data_service do |_, srv| if srv.dynamic? yield(srv) end end end |
#each_required_model {|concrete_model| ... } ⇒ Object
1112 1113 1114 1115 |
# File 'lib/syskit/models/component.rb', line 1112 def each_required_model return enum_for(:each_required_model) if !block_given? yield(concrete_model) end |
#each_root_data_service {|Models::BoundDataService| ... } ⇒ Object
Enumerates all services that are root (i.e. not slave of other services)
154 155 156 157 158 159 160 161 |
# File 'lib/syskit/models/component.rb', line 154 def each_root_data_service(&block) return enum_for(:each_root_data_service) if !block_given? each_data_service(nil) do |name, service| if service.master? yield(service) end end end |
#each_slave_data_service(master_service) {|Models::BoundDataService| ... } ⇒ Object
Enumerates all services that are slave (i.e. not slave of other services)
141 142 143 144 145 146 147 148 |
# File 'lib/syskit/models/component.rb', line 141 def each_slave_data_service(master_service) return enum_for(:each_slave_data_service, master_service) if !block_given? each_data_service(nil) do |name, service| if service.master && (service.master.full_name == master_service.full_name) yield(service) end end end |
#each_stub_module {|element| ... } ⇒ Object
Enumerates all objects registered in stub_module
34 |
# File 'lib/syskit/models/component.rb', line 34 inherited_attribute(:stub_module, :stub_modules) { [Module.new] } |
#ensure_model_is_specialized ⇒ Model<Component>
Makes sure this is a private specialized model
788 789 790 791 792 793 |
# File 'lib/syskit/models/component.rb', line 788 def ensure_model_is_specialized if private_specialization? return self else return specialize end end |
#find_all_data_services_from_type(type) ⇒ Array<Models::BoundDataService>
Finds a single service that provides type
293 294 295 296 297 298 299 |
# File 'lib/syskit/models/component.rb', line 293 def find_all_data_services_from_type(type) result = [] each_data_service do |_, m| result << m.as(type) if m.fullfills?(type) end result end |
#find_data_service_from_type(type) ⇒ Models::BoundDataService?
Finds a single service that provides type
276 277 278 279 280 281 282 283 284 |
# File 'lib/syskit/models/component.rb', line 276 def find_data_service_from_type(type) candidates = find_all_data_services_from_type(type) if candidates.size > 1 raise AmbiguousServiceSelection.new(self, type, candidates), "multiple services match #{type.short_name} on #{short_name}" elsif candidates.size == 1 return candidates.first end end |
#find_directional_port_mapping(direction, port, expected_name) ⇒ String?
Finds the port of self that should be used for a service port 'port'
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/syskit/models/component.rb', line 392 def find_directional_port_mapping(direction, port, expected_name) port_name = expected_name || port.name component_port = send("find_#{direction}_port", port_name) if component_port && component_port.type == port.type return port_name elsif expected_name if !component_port known_ports = send("each_#{direction}_port"). map { |p| "#{p.name}[#{p.type.name}]" } raise InvalidPortMapping, "the provided port mapping from #{port.name} to #{port_name} is invalid: #{port_name} is not a #{direction} port in #{short_name}. Known output ports are #{known_ports.sort.join(", ")}" else raise InvalidPortMapping, "the provided port mapping from #{port.name} to #{port_name} is invalid: #{port_name} is of type #{component_port.type_name} in #{short_name} and I was expecting #{port.type}" end end candidates = send("each_#{direction}_port"). find_all { |p| p.type == port.type } if candidates.empty? return elsif candidates.size == 1 return candidates.first.name else raise InvalidPortMapping, "there are multiple candidates to map #{port.name}[#{port.type_name}]: #{candidates.map(&:name).sort.join(", ")}" end end |
#find_input_port(name) ⇒ Object
571 |
# File 'lib/syskit/models/component.rb', line 571 def find_input_port(name); end |
#find_matching_service(target_model, pattern = nil) ⇒ Object
Generic data service selection method, based on a service type and an optional service name. It implements the following algorithm:
* only services that match +target_model+ are considered
* if there is only one service of that type and no pattern is
given, that service is returned
* if there is a pattern given, it must be either the service
full name or its subname (for slaves)
* if an ambiguity is found between root and slave data
services, and there is only one root data service matching,
that data service is returned.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/syskit/models/component.rb', line 87 def find_matching_service(target_model, pattern = nil) # Find services in +child_model+ that match the type # specification matching_services = find_all_services_from_type(target_model) if pattern # match by name too # Find the selected service. There can be shortcuts, so # for instance bla.left would be able to select both the # 'left' main service or the 'bla.blo.left' slave # service. rx = /(^|\.)#{pattern}$/ matching_services.delete_if { |service| service.full_name !~ rx } end if matching_services.size > 1 main_matching_services = matching_services. find_all { |service| service.master? } if main_matching_services.size != 1 raise AmbiguousServiceSelection.new(self, target_model, main_matching_services), "there is more than one service of type #{target_model.name} in #{self.name}#{" matching name hint #{pattern}" if pattern}" end selected = main_matching_services.first else selected = matching_services.first end selected end |
#find_output_port(name) ⇒ Object
572 |
# File 'lib/syskit/models/component.rb', line 572 def find_output_port(name); end |
#find_placeholder_model(service_models, placeholder_type = Placeholder) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Find an existing placeholder model based on self for the given service models
880 881 882 883 884 |
# File 'lib/syskit/models/component.rb', line 880 def find_placeholder_model(service_models, placeholder_type = Placeholder) if by_type = placeholder_models[service_models] by_type[placeholder_type] end end |
#find_port(name) ⇒ Object
573 |
# File 'lib/syskit/models/component.rb', line 573 def find_port(name); end |
#find_through_method_missing(m, args) ⇒ Object
713 714 715 716 |
# File 'lib/syskit/models/component.rb', line 713 def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( self, m, args, '_srv'.freeze => :find_data_service) || super end |
#fullfills?(object) ⇒ Boolean
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 |
# File 'lib/syskit/models/component.rb', line 985 def fullfills?(object) if !object.respond_to?(:each_required_dynamic_service) return super end self_real_model = concrete_model object_real_model = if object.respond_to?(:concrete_model) object.concrete_model else object end if self_real_model == self return super elsif !self_real_model.fullfills?(object_real_model) return false elsif !object.respond_to?(:each_required_dynamic_service) return true end # We've checked the public interface, Verify that we also have all # dynamic services instanciated in 'object' object.each_required_dynamic_service do |object_srv| self_srv = find_data_service(object_srv.name) if !self_srv return false elsif !self_srv.dynamic? return false elsif !self_srv.same_service?(object_srv) return false end end return true end |
#has_through_method_missing?(m) ⇒ Boolean
708 709 710 711 |
# File 'lib/syskit/models/component.rb', line 708 def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( self, m, '_srv'.freeze => :find_data_service) || super end |
#if_already_present ⇒ InstanceRequirements
Optional dependency injection
Returns an InstanceRequirements that you can use to inject optional dependencies that will be fullfilled only if there is already a matching task deployed in the plan
This can only be meaningfully used when injected for a composition's optional child
201 202 203 |
# File 'lib/syskit/models/component.rb', line 201 def if_already_present to_instance_requirements.if_already_present end |
#implicit_fullfilled_model ⇒ Object
768 769 770 771 772 773 774 775 776 777 778 779 780 781 |
# File 'lib/syskit/models/component.rb', line 768 def implicit_fullfilled_model if !@implicit_fullfilled_model has_abstract = false @implicit_fullfilled_model = super.find_all do |m| has_abstract ||= (m == AbstractComponent) !m.respond_to?(:private_specialization?) || !m.private_specialization? end @implicit_fullfilled_model << AbstractComponent \ unless has_abstract end @implicit_fullfilled_model end |
#instanciate(plan, context = DependencyInjectionContext.new, task_arguments: Hash.new, **arguments) ⇒ Object
Generic instanciation of a component.
It creates a new task from the component model using Component.new, adds it to the plan and returns it.
167 168 169 170 |
# File 'lib/syskit/models/component.rb', line 167 def instanciate(plan, context = DependencyInjectionContext.new, task_arguments: Hash.new, **arguments) plan.add(task = new(task_arguments)) task end |
#instanciate_dynamic_input_port(name, type, port) ⇒ Port
Adds a new port to this model based on a known dynamic port
965 966 967 968 969 970 |
# File 'lib/syskit/models/component.rb', line 965 def instanciate_dynamic_input_port(name, type, port) orogen_model = Models.create_orogen_task_context_model orogen_model.input_ports[name] = port.instanciate(name, type) Syskit::Models.merge_orogen_task_context_models(self.orogen_model, [orogen_model]) find_input_port(name) end |
#instanciate_dynamic_output_port(name, type, port) ⇒ Port
Adds a new port to this model based on a known dynamic port
978 979 980 981 982 983 |
# File 'lib/syskit/models/component.rb', line 978 def instanciate_dynamic_output_port(name, type, port) orogen_model = Models.create_orogen_task_context_model orogen_model.output_ports[name] = port.instanciate(name, type) Syskit::Models.merge_orogen_task_context_models(self.orogen_model, [orogen_model]) find_output_port(name) end |
#merge(other_model) ⇒ Object
Returns the component model that is the merge model of self and the given other model
It will return self or other_model if they are “plain” models. In case other_model is a placeholder task model, the corresponding data service mappings will be computed and either self or another placeholder task model will be returned
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 |
# File 'lib/syskit/models/component.rb', line 1091 def merge(other_model) if other_model.kind_of?(Syskit::Models::BoundDataService) return other_model.merge(self) elsif other_model.placeholder? return other_model.merge(self) end if self <= other_model return self elsif other_model <= self return other_model elsif other_model.private_specialization? || private_specialization? base_model = result = concrete_model.merge(other_model.concrete_model) result = base_model.apply_missing_dynamic_services_from(self, true) return result.apply_missing_dynamic_services_from(other_model, base_model == result) else raise IncompatibleComponentModels.new(self, other_model), "models #{short_name} and #{other_model.short_name} are not compatible" end end |
#merge_service_model(service_model, port_mappings) ⇒ Object
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 |
# File 'lib/syskit/models/component.rb', line 1121 def merge_service_model(service_model, port_mappings) service_model.each_input_port do |p| self_name = port_mappings[p.name] || p.name self_p = find_input_port(self_name) if !self_p raise InvalidPortMapping, "#{self} cannot dynamically create ports" elsif p.type != self_p.type raise InvalidPortMapping, "#{self} already has a port named #{self_name} of type #{self_p.type}, cannot dynamically map #{p} onto it" end end service_model.each_output_port do |p| self_name = port_mappings[p.name] || p.name self_p = find_output_port(self_name) if !self_p raise InvalidPortMapping, "#{self} cannot dynamically create ports" elsif p.type != self_p.type raise InvalidPortMapping, "#{self} already has a port named #{self_name} of type #{self_p.type}, cannot dynamically map #{p} onto it" end end end |
#needs_stub?(component) ⇒ Boolean
Checks if a given component implementation needs to be stubbed
133 134 135 |
# File 'lib/syskit/models/component.rb', line 133 def needs_stub?(component) false end |
#placeholder? ⇒ Boolean
Wether this model represents a placeholder for data services
948 949 950 |
# File 'lib/syskit/models/component.rb', line 948 def placeholder? false end |
#port_mappings_for(model) ⇒ Object
Defined to be compatible, in port mapping code, with the data services
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/syskit/models/component.rb', line 251 def port_mappings_for(model) if model.kind_of?(Class) if fullfills?(model) mappings = Hash.new model.each_port do |port| mappings[port.name] = port.name end mappings else raise ArgumentError, "#{model.short_name} is not fullfilled by #{self}" end else find_data_service_from_type(model).port_mappings_for_task end end |
#port_mappings_for_task ⇒ Object
Defined to be compatible, in port mapping code, with the data services
246 247 248 |
# File 'lib/syskit/models/component.rb', line 246 def port_mappings_for_task Hash.new { |h,k| k } end |
#prefer_deployed_tasks(*selections) ⇒ Object
211 212 213 |
# File 'lib/syskit/models/component.rb', line 211 def prefer_deployed_tasks(*selections) to_instance_requirements.prefer_deployed_tasks(*selections) end |
#prepare_stub(component) ⇒ Object
Apply what's necessary for this component (from the underlying component implementation) to be a proper component stub
125 126 127 128 129 130 |
# File 'lib/syskit/models/component.rb', line 125 def prepare_stub(component) stub_modules = each_stub_module.to_a stub_modules.each do |m| component.orocos_task.extend m end end |
#private_specialization=(value) ⇒ Model<TaskContext>
If true, this model is used internally as specialization of another component model (as e.g. to represent dynamic service instantiation). Otherwise, it is an actual component model.
740 |
# File 'lib/syskit/models/component.rb', line 740 attr_predicate :private_specialization?, true |
#private_specialization? ⇒ Model<TaskContext>
If true, this model is used internally as specialization of another component model (as e.g. to represent dynamic service instantiation). Otherwise, it is an actual component model.
740 |
# File 'lib/syskit/models/component.rb', line 740 attr_predicate :private_specialization?, true |
#promote_data_service(full_name, service) ⇒ Object
Method that maps data services from this component's parent models to this composition's own
It is called as needed when calling #each_data_service
16 17 18 |
# File 'lib/syskit/models/component.rb', line 16 def promote_data_service(full_name, service) service.attach(self, verify: false) end |
#promote_dynamic_service(name, dyn) ⇒ Object
Called by the dynamic_service accessors to promote dynamic services from our parent model to the corresponding dynamic services on the child models
449 450 451 |
# File 'lib/syskit/models/component.rb', line 449 def promote_dynamic_service(name, dyn) dyn.attach(self) end |
#provides(model, port_mappings = Hash.new, as: nil, slave_of: nil, bound_service_class: BoundDataService) ⇒ Object
Declares that this component provides the given data service.
model
can either be the data service constant name (from
Syskit::DataServices), or its plain name.
If the data service defines an interface, the component must provide the required input and output ports. If an ambiguity exists, explicit port mappings must be provided.
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 |
# File 'lib/syskit/models/component.rb', line 610 def provides(model, port_mappings = Hash.new, as: nil, slave_of: nil, bound_service_class: BoundDataService) unless model.kind_of?(DataServiceModel) if model.kind_of?(Roby::Models::TaskServiceModel) return super(model) else raise ArgumentError, "expected a data service model as argument and got #{model}" end end unless as raise ArgumentError, "no service name given, please use the as: option" end name = as.to_str full_name = name if master = slave_of if master.respond_to?(:to_str) master_srv = find_data_service(master) if !master_srv raise ArgumentError, "master data service #{master_source} is not registered on #{self}" end master = master_srv end full_name = "#{master.full_name}.#{name}" end # Get the source name and the source model if data_services[full_name] raise ArgumentError, "there is already a data service named '#{full_name}' defined on '#{short_name}'" end # If a source with the same name exists, verify that the user is # trying to specialize it if has_data_service?(full_name) parent_type = find_data_service(full_name).model if !(model <= parent_type) raise ArgumentError, "#{self} has a data service named #{full_name} of type #{parent_type}, which is not a parent type of #{model}" end end if master && (master.component_model != self) data_services[master.full_name] = master.attach(self) end begin new_port_mappings = compute_port_mappings(model, port_mappings) rescue InvalidPortMapping => e raise InvalidProvides.new(self, model, e), "#{short_name} does not provide the '#{model.name}' service's interface. #{e.}", e.backtrace end service = bound_service_class.new(name, self, master, model, Hash.new) service.port_mappings[model] = new_port_mappings # Now, adapt the port mappings from +model+ itself and map # them into +service.port_mappings+ Models.update_port_mappings(service.port_mappings, new_port_mappings, model.port_mappings) # Remove from +arguments+ the items that were port mappings new_port_mappings.each do |from, to| if port_mappings[from].to_s == to # this was a port mapping ! port_mappings.delete(from) elsif port_mappings[from.to_sym].to_s == to port_mappings.delete(from.to_sym) end end if !port_mappings.empty? raise InvalidProvides.new(self, model), "invalid port mappings: #{port_mappings} do not match any ports in either #{self} or #{service}" end include model data_services[full_name] = service Models.debug do Models.debug "#{short_name} provides #{model.short_name}" Models.debug "port mappings" service.port_mappings.each do |m, mappings| Models.debug " #{m.short_name}: #{mappings}" end break end return service end |
#provides_dynamic(service_model, port_mappings = Hash.new, as: nil, slave_of: nil, bound_service_class: BoundDataService) ⇒ BoundDynamicDataService
Declares that this component model will dynamically provide the ports necessary to provide a service model
The main difference when compared to #provides is that service ports that are not mapped to the task are automatically created (provided a corresponding dynamic_input_port or dynamic_output_port declaration exists on the oroGen model).
435 436 437 438 439 440 441 442 443 444 |
# File 'lib/syskit/models/component.rb', line 435 def provides_dynamic(service_model, port_mappings = Hash.new, as: nil, slave_of: nil, bound_service_class: BoundDataService) # Do not use #filter_options here, it will transform the # port names into symbols port_mappings = DynamicDataService.update_component_model_interface( self, service_model, port_mappings) provides(service_model, port_mappings, as: as, slave_of: slave_of, bound_service_class: bound_service_class) end |
#proxy_task_model(service_models, as: nil, extension: Placeholder) ⇒ Object
use Models::Placeholder.for instead
930 931 932 933 |
# File 'lib/syskit/models/component.rb', line 930 def proxy_task_model(service_models, as: nil, extension: Placeholder) Roby.warn_deprecated "Component.proxy_task_model is deprecated, use Syskit::Models::Placeholder.for instead" extension.for(service_models, component_model: self, as: as) end |
#register_placeholder_model(placeholder_m, service_models, placeholder_type = Placeholder) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Register a new placeholder model for the given service models and placeholder type
890 891 892 893 |
# File 'lib/syskit/models/component.rb', line 890 def register_placeholder_model(placeholder_m, service_models, placeholder_type = Placeholder) by_type = (placeholder_models[service_models] ||= Hash.new) by_type[placeholder_type] = placeholder_m end |
#require_dynamic_service(dynamic_service_name, as: nil, **dyn_options) ⇒ BoundDynamicDataService
Instanciate a dynamic service on this model
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
# File 'lib/syskit/models/component.rb', line 536 def require_dynamic_service(dynamic_service_name, as: nil, **) if !as raise ArgumentError, "no name given, please provide the as: option" end service_name = as.to_s dyn = find_dynamic_service(dynamic_service_name) if !dyn raise ArgumentError, "#{short_name} has no dynamic service called #{dynamic_service_name}, available dynamic services are: #{each_dynamic_service.map { |name, _| name }.sort.join(", ")}" end if srv = find_data_service(service_name) if srv.fullfills?(dyn.service_model) return srv else raise ArgumentError, "there is already a service #{service_name}, but it is of type #{srv.model.short_name} while the dynamic service #{dynamic_service_name} expects #{dyn.service_model.short_name}" end end dyn.instanciate(service_name, **) end |
#resolve(task) ⇒ Object
use #bind instead
850 851 852 853 854 |
# File 'lib/syskit/models/component.rb', line 850 def resolve(task) Roby.warn_deprecated "#{__method__} is deprecated, use "\ "Models::Component#bind instead" bind(task) end |
#selected_for(requirements) ⇒ Object
1117 1118 1119 |
# File 'lib/syskit/models/component.rb', line 1117 def selected_for(requirements) InstanceSelection.new(nil, self.to_instance_requirements, requirements.to_instance_requirements) end |
#self_port?(port) ⇒ Boolean
Test if the given port is a port of self
731 732 733 |
# File 'lib/syskit/models/component.rb', line 731 def self_port?(port) port.component_model == self end |
#self_port_to_component_port(port) ⇒ Models::Port
Resolves the given port model into a component model where #component_model is a proper component (e.g. not a BoundDataService)
It is not meant to be used directly. Use Port#to_component_port instead
311 312 313 |
# File 'lib/syskit/models/component.rb', line 311 def self_port_to_component_port(port) return port end |
#specialization_counter ⇒ Object
An ID that represents which specialized model this is
743 744 745 746 |
# File 'lib/syskit/models/component.rb', line 743 def specialization_counter @specialization_counter ||= 0 @specialization_counter += 1 end |
#specialize(name = nil) ⇒ Object
Creates a private specialization of the current model
755 756 757 758 759 760 761 762 763 764 765 766 |
# File 'lib/syskit/models/component.rb', line 755 def specialize(name = nil) klass = create_private_specialization if name klass.name = name else klass.name = "#{self.name}{#{self.specialization_counter}}" end klass.private_specialization = true klass.private_model klass.concrete_model = concrete_model klass end |
#stub(&block) ⇒ Object
Define a module that should be applied on the underlying Orocos::RubyTasks::StubTaskContext when running tests in non-live mode
119 120 121 |
# File 'lib/syskit/models/component.rb', line 119 def stub(&block) stub_modules.first.class_eval(&block) end |
#stub_module ⇒ Array<Module>
List of modules that should be applied on the underlying Orocos::RubyTasks::StubTaskContext when running tests in non-stub mode
34 |
# File 'lib/syskit/models/component.rb', line 34 inherited_attribute(:stub_module, :stub_modules) { [Module.new] } |
#supermodel ⇒ Object
The model next in the ancestry chain, or nil if self
is root
173 174 175 176 177 |
# File 'lib/syskit/models/component.rb', line 173 def supermodel if superclass.respond_to?(:register_submodel) return superclass end end |
#to_component_model ⇒ Object
10 |
# File 'lib/syskit/models/component.rb', line 10 def to_component_model; self end |
#try_bind(object) ⇒ nil, Syskit::Component
Returns task if it fullfills self, nil otherwise
831 832 833 |
# File 'lib/syskit/models/component.rb', line 831 def try_bind(object) object if object.fullfills?(self) end |
#try_resolve(task) ⇒ Object
use #try_bind instead
857 858 859 860 861 |
# File 'lib/syskit/models/component.rb', line 857 def try_resolve(task) Roby.warn_deprecated "#{__method__} is deprecated, use "\ "Models::Component#try_bind instead" try_bind(task) end |
#use_conf(*spec, &block) ⇒ Object
216 217 218 |
# File 'lib/syskit/models/component.rb', line 216 def use_conf(*spec, &block) with_conf(*spec, &block) end |
#use_deployments(*selection) ⇒ Object
replaced by #prefer_deployed_tasks
206 207 208 |
# File 'lib/syskit/models/component.rb', line 206 def use_deployments(*selection) prefer_deployed_tasks(*selection) end |
#with_arguments(*spec, &block) ⇒ Object
This returns an InstanciatedComponent object that can be used in other #use statements in the deployment spec
For instance,
add(Cmp::CorridorServoing).
use(Cmp::Odometry.with_arguments('special_behaviour' => true))
187 188 189 |
# File 'lib/syskit/models/component.rb', line 187 def with_arguments(*spec, &block) InstanceRequirements.new([self]).with_arguments(*spec, &block) end |
#with_conf(*spec, &block) ⇒ Object
This returns an InstanciatedComponent object that can be used in other #use statements in the deployment spec
For instance,
add(Cmp::CorridorServoing).
use(Cmp::Odometry.use_conf('special_conf'))
228 229 230 |
# File 'lib/syskit/models/component.rb', line 228 def with_conf(*spec, &block) InstanceRequirements.new([self]).with_conf(*spec, &block) end |
#with_dynamic_service(dynamic_service_name, options = Hash.new) ⇒ Object
Returns a model specialized from 'self' that has the required dynamic service
522 523 524 525 526 |
# File 'lib/syskit/models/component.rb', line 522 def with_dynamic_service(dynamic_service_name, = Hash.new) model = ensure_model_is_specialized model.require_dynamic_service(dynamic_service_name, ) model end |