Module: Syskit::Models::Placeholder::Creation Private

Included in:
Syskit::Models::Placeholder
Defined in:
lib/syskit/models/placeholder.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Encapsulation of the methods that allow to create placeholder models

This is separated to ease the creation of specialized placeholder types such as Actions::Profile::Tag

Instance Method Summary collapse

Instance Method Details

#create_for(models, component_model: nil, as: nil) ⇒ Component

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.

Create a task model that is an aggregate of all the provided models (components and services)

You usually should use proxy_component_model_for instead of this

Parameters:

  • as (String)

    the name of the newly created model

  • the (Set<Component,DataService,BoundDataService>)

    set of component and data service models. There can be only one component model (as per Ruby's single-inheritance system). If a bound data service is provided, its underlying component model is used as base model and the service is returned instead of the plain task

  • component_model (Component, nil)

    historically, methods were called with a mix of component models and data service models. If the component model (Component or BoundDataService) is known, it should be given to create_proxy_component_model_for and proxy_component_model_for through this parameter to avoid re-resolving it.

Returns:



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/syskit/models/placeholder.rb', line 207

def create_for(models, component_model: nil, as: nil)
    task_model, service_models, _ =
        resolve_models_argument(models, component_model: component_model)

    name_models = service_models.map(&:to_s).sort.join(",")
    if task_model != Syskit::Component
        name_models = "#{task_model},#{name_models}"
    end
    model = task_model.specialize(as || ("#{self}<%s>" % [name_models]))
    model.abstract
    model.concrete_model = nil
    model.include self.task_extension
    model.extend  self
    model.proxied_component_model = task_model
    model.proxied_data_service_models = service_models.dup
    model.update_proxy_mappings

    service_models.each_with_index do |m, i|
        model.provides m, as: "m#{i}"
    end
    model
end

#for(models, component_model: nil, as: nil) ⇒ 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.

Returns a component model that can be used to represent an instance of an arbitrary set of models in a plan

Unlike #create_for, it will create a new model only if needed, that is if both data services are actually requested, and if #for has not yet been called with the same parameter (in which case the model created then will be returned)

This is the main entry point. It will cache created models so that proxying the same set of services on the same component model returns the same result.

Parameters:

  • as (String)

    the name of the newly created model

  • the (Set<Component,DataService,BoundDataService>)

    set of component and data service models. There can be only one component model (as per Ruby's single-inheritance system). If a bound data service is provided, its underlying component model is used as base model and the service is returned instead of the plain task

  • component_model (Component, nil)

    historically, methods were called with a mix of component models and data service models. If the component model (Component or BoundDataService) is known, it should be given to create_proxy_component_model_for and proxy_component_model_for through this parameter to avoid re-resolving it.



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/syskit/models/placeholder.rb', line 243

def for(models, component_model: nil, as: nil)
    task_model, service_models, service =
        resolve_models_argument(models, component_model: component_model)

    service_models = service_models.to_set
    if service_models.empty?
        proxy_component_model = task_model
    elsif cached_model = task_model.find_placeholder_model(service_models, self)
        proxy_component_model = cached_model
    else
        service_models = service_models.to_set
        proxy_component_model =
            create_for(service_models, component_model: task_model, as: as)
        task_model.register_placeholder_model(proxy_component_model, service_models, self)
    end

    if service
        service.attach(proxy_component_model)
    else proxy_component_model
    end
end

#new_specialized_placeholder(task_extension: Syskit::Placeholder, &block) ⇒ 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.

Create a new specialized placeholder type that provides the same API than Placeholder



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/syskit/models/placeholder.rb', line 168

def new_specialized_placeholder(task_extension: Syskit::Placeholder, &block)
    self_ = self
    creation = Module.new do
        include self_::Creation
    end
    model = Module.new do
        include self_
        const_set(:Creation, creation)
        extend creation
    end

    if task_extension != Syskit::Placeholder
        creation.class_eval do
            define_method(:task_extension) { task_extension }
        end
    end

    if block
        model.class_eval(&block)
    end
    model
end

#resolve_models_argument(models, component_model: nil) ⇒ Component, ...

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.

Resolves the base task model and set of service models that should be used to create a proxy task model for the given component and/or service models

This is a helper method for create_proxy_component_model_for and proxy_component_model_for

Parameters:

  • the (Set<Component,DataService,BoundDataService>)

    set of component and data service models. There can be only one component model (as per Ruby's single-inheritance system). If a bound data service is provided, its underlying component model is used as base model and the service is returned instead of the plain task

  • component_model (Component, nil)

    historically, methods were called with a mix of component models and data service models. If the component model (Component or BoundDataService) is known, it should be given to create_proxy_component_model_for and proxy_component_model_for through this parameter to avoid re-resolving it.

Returns:



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/syskit/models/placeholder.rb', line 286

def resolve_models_argument(models, component_model: nil)
    if component_model
        if component_model.respond_to?(:component_model)
            bound_service = component_model
            component_model = component_model.component_model
        end
        models = models.find_all { |srv| !component_model.fullfills?(srv) }
        return component_model, models, bound_service
    end

    service = nil
    models = models.map do |m|
        if m.respond_to?(:component_model)
            if service
                raise ArgumentError, "more than one bound data service given: #{service} and #{m}"
            end
            service = m
            m.component_model
        else m
        end
    end
    task_models, service_models = models.partition { |t| t <= Syskit::Component }
    if task_models.empty?
        return Syskit::Component, service_models, service
    elsif task_models.size == 1
        task_model = task_models.first
        service_models.delete_if { |srv| task_model.fullfills?(srv) }
        return task_model, service_models, service
    else
        raise ArgumentError, "cannot create a proxy for multiple component models at the same time"
    end
end

#task_extensionObject

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.

Return the module that should be included in the newly created models

It defaults to Placeholder



195
196
197
# File 'lib/syskit/models/placeholder.rb', line 195

def task_extension
    Syskit::Placeholder
end