Module: Roby::Models::Task

Includes:
MetaRuby::ModelAsClass, Arguments
Included in:
Task
Defined in:
lib/roby/models/task.rb

Defined Under Namespace

Classes: AsPlanProxy, Template, TemplateEventGenerator

Constant Summary collapse

@@exception_handler_id =
0

Constants included from Arguments

Arguments::NO_DEFAULT_ARGUMENT

Event Relations collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Arguments

#argument, #arguments, #default_argument, #meaningful_arguments

Class Method Details

.define_method_unless_present(m, name, &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.

Helper method for #define_event_methods



643
644
645
646
647
# File 'lib/roby/models/task.rb', line 643

def self.define_method_unless_present(m, name, &block)
    return if m.method_defined?(name)

    m.send(:define_method, name, &block)
end

.model_attribute_list(name) ⇒ Object

Declares an attribute set which follows the task models inheritance hierarchy. Define the corresponding enumeration methods as well.

For instance,

model_attribute_list 'signal'

defines the model-level signals, which can be accessed through

.each_signal(model)
.signals(model)
#each_signal(model)


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
296
297
298
299
300
301
# File 'lib/roby/models/task.rb', line 271

def self.model_attribute_list(name) # :nodoc:
    class_eval <<~MODEL_ATTRIBUTE_ACCESSORS, __FILE__, __LINE__ + 1
        inherited_attribute("#{name}_set", "#{name}_sets", map: true) { Hash.new { |h, k| h[k] = Set.new } }
        def each_#{name}(model)
            for obj in #{name}s(model)
                yield(obj)
            end
            self
        end
        def #{name}s(model)
            result = Set.new
            each_#{name}_set(model, false) do |set|
                result.merge set
            end
            result
        end

        def all_#{name}s
            if @all_#{name}s
                @all_#{name}s
            else
                result = Hash.new
                each_#{name}_set do |from, targets|
                    result[from] ||= Set.new
                    result[from].merge(targets)
                end
                @all_#{name}s = result
            end
        end
    MODEL_ATTRIBUTE_ACCESSORS
end

.model_relation(name) ⇒ Object



303
304
305
# File 'lib/roby/models/task.rb', line 303

def self.model_relation(name)
    model_attribute_list(name)
end

Instance Method Details

#abstractObject

Declare that this task model defines abstract tasks. Abstract tasks can be used to represent an action, without specifically representing how this action should be done.

Instances of abstract task models are not executable, i.e. they cannot be started.

See Also:

  • executable?


497
498
499
# File 'lib/roby/models/task.rb', line 497

def abstract
    @abstract = true
end

#all_modelsObject

Deprecated.

Use #each_submodel instead



239
240
241
# File 'lib/roby/models/task.rb', line 239

def all_models
    submodels
end

#as_plan(**arguments) ⇒ Object

Default implementation of the #as_plan method

The #as_plan method is used to use task models as representation of abstract actions. For instance, if an #as_plan method is available on a particular MoveTo task model, one can do

root.depends_on(MoveTo)

This default implementation looks for planning methods declared in the main Roby application planners that return the required task type or one of its subclasses. If one is found, it is using it to generate the action. Otherwise, it falls back to returning a new instance of this task model, unless the model is abstract in which case it raises ArgumentError.

It can be used with

class TaskModel < Roby::Task
end

root = Roby::Task.new
child = root.depends_on(TaskModel)

If arguments need to be given, the #with_arguments method should be used:

root = Roby::Task.new
child = root.depends_on(TaskModel.with_arguments(id: 200))


224
225
226
227
228
229
230
231
232
233
234
# File 'lib/roby/models/task.rb', line 224

def as_plan(**arguments)
    Roby.app.prepare_action(self, **arguments).first
rescue Application::ActionResolutionError
    if abstract?
        raise Application::ActionResolutionError,
              "#{self} is abstract and no planning method exists "\
              "that returns it"
    end

    new(**arguments)
end

#can_merge?(target_model) ⇒ Boolean

Returns:

  • (Boolean)


898
899
900
# File 'lib/roby/models/task.rb', line 898

def can_merge?(target_model)
    fullfills?(target_model)
end

Establish model-level causal links between events of that task. These signals will be established on all the instances of this task model (and its subclasses).

Causal links are used during event propagation to order the propagation properly. Establish a causal link when e.g. an event handler might call or emit on another of this task’s event

signal start: [:one, :two]

Examples:

when establishing multiple relations from the same source

use name-to-arrays

Parameters:

  • mappings (Hash<Symbol,Array<Symbol>>, Hash<Symbol,Symbol>)

    the source-to-target mappings



381
382
383
384
385
386
387
388
389
# File 'lib/roby/models/task.rb', line 381

def causal_link(mappings)
    mappings.each do |from, to|
        from = event_model(from).symbol
        causal_link_sets[from].merge(
            Array[*to].map { |ev| event_model(ev).symbol }
        )
    end
    update_terminal_flag
end

#clear_modelObject

Clears all definitions saved in this model. This is to be used by the reloading code



245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/roby/models/task.rb', line 245

def clear_model
    class_eval do
        # Remove event models
        events.each_key do |ev_symbol|
            remove_const ev_symbol.to_s.camelcase(:upper)
        end

        [@events, @signal_sets, @forwarding_sets, @causal_link_sets,
         @arguments, @handler_sets, @precondition_sets].each do |set|
            set&.clear
        end
    end
    super
end

#compute_terminal_events(events) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/roby/models/task.rb', line 154

def compute_terminal_events(events)
    success_events = [events[:success]].to_set
    failure_events = [events[:failed]].to_set
    terminal_events = [
        events[:stop], events[:success], events[:failed]
    ].to_set

    event_set = events.values.to_set
    discover_terminal_events(
        event_set, terminal_events, success_events, events[:success]
    )
    discover_terminal_events(
        event_set, terminal_events, failure_events, events[:failed]
    )
    discover_terminal_events(
        event_set, terminal_events, nil, events[:stop]
    )

    events.each_value do |ev|
        next unless ev.event_model.terminal?

        if !success_events.include?(ev) && !failure_events.include?(ev)
            terminal_events << ev
        end
    end

    [terminal_events, success_events, failure_events]
end

#define_command_method(event_name, 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.

Define the method that will be used as command for the given event

Parameters:

  • event_name (Symbol)

    the event name



610
611
612
613
614
615
616
617
# File 'lib/roby/models/task.rb', line 610

def define_command_method(event_name, block)
    check_arity(block, 1, strict: true)
    define_method("event_command_#{event_name}", &block)
    method = instance_method("event_command_#{event_name}")
    lambda do |dst_task, *event_context|
        method.bind(dst_task).call(*event_context)
    end
end

#define_event_methods(event_name) ⇒ 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.

Define support methods for a task event

Parameters:

  • event_name (Symbol)

    the event name



624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
# File 'lib/roby/models/task.rb', line 624

def define_event_methods(event_name)
    event_name = event_name.to_sym
    Task.define_method_unless_present(self, "#{event_name}_event") do
        @bound_events[event_name] || event(event_name)
    end
    Task.define_method_unless_present(self, "#{event_name}?") do
        (@bound_events[event_name] || event(event_name)).emitted?
    end
    Task.define_method_unless_present(self, "#{event_name}!") do |*context|
        (@bound_events[event_name] || event(event_name)).call(*context)
    end
    Task.define_method_unless_present(singleton_class, "#{event_name}_event") do
        find_event_model(event_name)
    end
end

#discover_terminal_events(events, terminal_set, set, root) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/roby/models/task.rb', line 135

def discover_terminal_events(events, terminal_set, set, root)
    stack = [root]
    until stack.empty?
        vertex = stack.shift
        [EventStructure::Signal, EventStructure::Forwarding]
            .each do |relation|
                vertex.parent_objects(relation).each do |parent|
                    next unless events.include?(parent)
                    next if parent[vertex, relation]
                    next if terminal_set.include?(parent)

                    terminal_set << parent
                    set   << parent if set
                    stack << parent
                end
            end
    end
end

#enum_eventsObject



701
702
703
704
705
706
# File 'lib/roby/models/task.rb', line 701

def enum_events
    Roby.warn_deprecated(
        "#enum_events is deprecated, use #each_event without a block instead"
    )
    each_event
end

#event(event_name, options = {}, &block) ⇒ Hash<Symbol,TaskEvent>

The events defined by the task model

Returns:



567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
# File 'lib/roby/models/task.rb', line 567

def event(event_name, options = {}, &block)
    event_name = event_name.to_sym

    options = validate_options(
        options,
        controlable: nil, command: nil, terminal: nil,
        model: find_event_model(event_name) || Roby::TaskEvent
    )

    if options.key?(:controlable)
        options[:command] = options[:controlable]
    elsif !options.key?(:command) && block
        options[:command] = define_command_method(event_name, block)
    end
    validate_event_definition_request(event_name, options)

    # Define the event class
    new_event = options[:model].new_submodel(
        task_model: self,
        terminal: options[:terminal],
        symbol: event_name, command: options[:command]
    )
    new_event.permanent_model = permanent_model?

    old_model = find_event_model(event_name)
    setup_terminal_handler =
        options[:terminal] &&
        new_event.symbol != :stop &&
        (!old_model || !old_model.terminal?)

    events[new_event.symbol] = new_event
    forward(new_event => :stop) if setup_terminal_handler
    const_set(event_name.to_s.camelcase(:upper), new_event)

    define_event_methods(event_name)
    new_event
end

#event_model(model_def) ⇒ Model<TaskEvent>

Accesses an event model

This method gives access to this task’s event models. If given a name, it returns the corresponding event model. If given an event model, it verifies that the model is part of the events of self and returns it.

Returns:

  • (Model<TaskEvent>)

    a subclass of Roby::TaskEvent

Raises:

  • (ArgumentError)

    if the provided event name or model does not exist on self



730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
# File 'lib/roby/models/task.rb', line 730

def event_model(model_def)
    if model_def.respond_to?(:to_sym)
        ev_model = find_event_model(model_def.to_sym)
        unless ev_model
            all_events = each_event.map { |name, _| name }
            unless ev_model
                raise ArgumentError,
                      "#{model_def} is not an event of #{name}: "\
                      "#{all_events}"
            end
        end
    elsif model_def.respond_to?(:has_ancestor?) &&
          model_def.has_ancestor?(Roby::TaskEvent)
        # Check that model_def is an event class for us
        ev_model = event_model(model_def.symbol)
        if ev_model != model_def
            raise ArgumentError,
                  "the event model #{model_def} is not a model for "\
                  "#{name} (found #{ev_model} with the same name)"
        end
    else
        raise ArgumentError,
              "wanted either a symbol or an event class, got #{model_def}"
    end

    ev_model
end

#find_event_model(name) ⇒ Object Also known as: has_event?

Find the event class for event, or nil if event is not an event name for this model



716
717
718
# File 'lib/roby/models/task.rb', line 716

def find_event_model(name)
    find_event(name.to_sym)
end

#forward(mappings) ⇒ Object

Establish model-level forwarding between events of that task. These relations will be established on all the instances of this task model (and its subclasses).

Forwarding is used to cause the target event to be emitted when the source event is.

Examples:

# A task that is stopped as soon as it is started
class MyTask < Roby::Task
  forward start: :stop
end

Parameters:

  • mappings (Hash<Symbol,Array<Symbol>>, Hash<Symbol,Symbol>)

    the source-to-target mappings

See Also:

  • #forward
  • EventGenerator#forward.
  • the forwarding relation.


409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# File 'lib/roby/models/task.rb', line 409

def forward(mappings)
    mappings.each do |from, to|
        from    = event_model(from).symbol
        targets = Array[*to].map { |ev| event_model(ev).symbol }

        if event_model(from).terminal?
            non_terminal = targets.find_all do |name|
                !event_model(name).terminal?
            end
            unless non_terminal.empty?
                raise ArgumentError,
                      "trying to establish a forwarding relation from "\
                      "the terminal event #{from} to the non-terminal "\
                      "event(s) #{targets}"
            end
        end

        forwarding_sets[from].merge targets
    end
    update_terminal_flag
end

#from(object) ⇒ Object

Helper method to define delayed arguments from related objects

Examples:

propagate an argument from a parent task

argument :target, default: from(:parent).target


437
438
439
440
441
442
443
# File 'lib/roby/models/task.rb', line 437

def from(object)
    if object.kind_of?(Symbol)
        Roby.from(nil).send(object)
    else
        Roby.from(object)
    end
end

#from_state(state_object = State) ⇒ Object

Helper method to define delayed arguments from the State object

Examples:

get an argument from the State object

argument :initial_pose, default: from_state.pose


449
450
451
# File 'lib/roby/models/task.rb', line 449

def from_state(state_object = State)
    Roby.from_state(state_object)
end

#fullfills?(models) ⇒ Boolean

Returns:

  • (Boolean)


882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
# File 'lib/roby/models/task.rb', line 882

def fullfills?(models)
    models =
        if models.respond_to?(:each)
            models.to_a
        else
            [models]
        end

    models.each do |m|
        m.each_fullfilled_model do |test_m|
            return false unless has_ancestor?(test_m)
        end
    end
    true
end

#instantiate_event_relations(template) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/roby/models/task.rb', line 63

def instantiate_event_relations(template)
    events = template.events_by_name

    all_signals.each do |generator, signalled_events|
        next if signalled_events.empty?

        generator = events[generator]
        signalled_events.each do |signalled|
            signalled = events[signalled]
            generator.signals signalled
        end
    end

    all_forwardings.each do |generator, signalled_events|
        next if signalled_events.empty?

        generator = events[generator]

        signalled_events.each do |signalled|
            signalled = events[signalled]
            generator.forward_to signalled
        end
    end

    all_causal_links.each do |generator, signalled_events|
        next if signalled_events.empty?

        generator = events[generator]

        signalled_events.each do |signalled|
            signalled = events[signalled]
            generator.add_causal_link signalled
        end
    end

    # Add a link from internal_event to stop if stop is controllable
    if events[:stop].controlable?
        events[:internal_error].signals events[:stop]
    end

    terminal_events, success_events, failure_events =
        compute_terminal_events(events)

    template.terminal_events = terminal_events
    template.success_events = success_events
    template.failure_events = failure_events
    start_event = events[:start]

    # WARN: the start event CAN be terminal: it can be a signal from
    # :start to a terminal event
    #
    # Create the precedence relations between 'normal' events and
    # the terminal events
    root_terminal_events = terminal_events.find_all do |ev|
        (ev != start_event) && ev.root?(Roby::EventStructure::Precedence)
    end

    events.each_value do |ev|
        next if ev == start_event
        next if terminal_events.include?(ev)

        if ev.root?(Roby::EventStructure::Precedence)
            start_event.add_precedence(ev)
        end
        if ev.leaf?(Roby::EventStructure::Precedence)
            root_terminal_events.each do |terminal|
                ev.add_precedence(terminal)
            end
        end
    end
end

#interruptibleObject

Declare that tasks of this model can be interrupted by calling the command of Task#failed_event

Raises:

  • (ArgumentError)

    if Task#failed_event is not controlable.



470
471
472
473
474
475
476
477
478
479
480
481
482
# File 'lib/roby/models/task.rb', line 470

def interruptible
    if !has_event?(:failed) || !event_model(:failed).controlable?
        raise ArgumentError, "failed is not controlable"
    end

    event(:stop) do |context|
        if starting?
            start_event.signals stop_event
            return
        end
        failed!(context)
    end
end

#invalidate_templateObject



42
43
44
# File 'lib/roby/models/task.rb', line 42

def invalidate_template
    @template = nil
end

#match(*args) ⇒ Object

Returns a TaskMatcher object that matches this task model



866
867
868
869
870
871
872
873
874
# File 'lib/roby/models/task.rb', line 866

def match(*args)
    matcher = Queries::TaskMatcher.new
    if args.empty? && self != Task
        matcher.which_fullfills(self)
    else
        matcher.which_fullfills(*args)
    end
    matcher
end

#on(*event_names) {|context| ... } ⇒ Object

Adds an event handler for the given event model. The block is going to be called whenever some events are emitted.

Unlike a block given to EventGenerator#on, the block is evaluated in the context of the task instance.

Parameters:

  • event_names (Array<Symbol>)

    the name of the events on which to install the handler

Yield Parameters:

  • context (Object)

    the arguments passed to Task#emit when the event was emitted

Raises:

  • (ArgumentError)


773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
# File 'lib/roby/models/task.rb', line 773

def on(*event_names, &user_handler)
    raise ArgumentError, "#on called without a block" unless user_handler

    check_arity(user_handler, 1, strict: true)
    event_names.each do |from|
        from = event_model(from).symbol
        if user_handler
            method_name =
                "event_handler_#{from}_"\
                "#{Object.address_from_id(user_handler.object_id).to_s(16)}"
            define_method(method_name, &user_handler)

            handler = ->(event) { event.task.send(method_name, event) }
            handler_sets[from] <<
                EventGenerator::EventHandler.new(handler, false, false)
        end
    end
end

#on_exception(matcher) {|exception| ... } ⇒ Object

Defines an exception handler.

When propagating exceptions, ExecutionException goes up in the task hierarchy and calls matching handlers on the tasks it finds, and on their planning task. The first matching handler is called, and the exception propagation assumes that it handled the exception (i.e. won’t look for new handlers) unless it calls Task#pass_exception

Examples:

install a handler for a TaskModelViolation exception

on_exception(TaskModelViolation, ...) do |task, exception_object|
    if cannot_handle
        task.pass_exception # send to the next handler
    end
    do_handle
end

Parameters:

Yield Parameters:



843
844
845
846
847
848
849
850
851
# File 'lib/roby/models/task.rb', line 843

def on_exception(matcher, &handler)
    check_arity(handler, 1, strict: true)
    matcher = matcher.to_execution_exception_matcher
    id = (@@exception_handler_id += 1)
    define_method("exception_handler_#{id}", &handler)
    exception_handlers.unshift(
        [matcher, instance_method("exception_handler_#{id}")]
    )
end

#poll(&block) ⇒ Object

Declares that the given block should be called at each execution cycle, when the task is running. Use it that way:

class MyTask < Roby::Task
  poll do
    ... do something ...
  end
end

If the given polling block raises an exception, the task will be terminated by emitting its failed event.

Raises:

  • (ArgumentError)


813
814
815
816
817
# File 'lib/roby/models/task.rb', line 813

def poll(&block)
    raise ArgumentError, "no block given" unless block_given?

    define_method(:poll_handler, &block)
end

#precondition(event, reason, &block) ⇒ Object



792
793
794
795
# File 'lib/roby/models/task.rb', line 792

def precondition(event, reason, &block)
    event = event_model(event)
    precondition_sets[event.symbol] << [reason, block]
end

#provided_servicesObject

Returns the lists of tags this model fullfills.



798
799
800
# File 'lib/roby/models/task.rb', line 798

def provided_services
    ancestors.find_all { |m| m.kind_of?(Models::TaskServiceModel) }
end

#query(*args) ⇒ Object



855
856
857
858
859
860
861
862
863
# File 'lib/roby/models/task.rb', line 855

def query(*args)
    q = Queries::Query.new
    if args.empty? && self != Task
        q.which_fullfills(self)
    else
        q.which_fullfills(*args)
    end
    q
end

#signal(mappings) ⇒ Object

Establish model-level signals between events of that task. These signals will be established on all the instances of this task model (and its subclasses).

Signals cause the target event(s) command to be called when the source event is emitted.

signal start: [:one, :two]

Examples:

when establishing multiple relations from the same

source use name-to-arrays

Parameters:

  • mappings (Hash<Symbol,Array<Symbol>>, Hash<Symbol,Symbol>)

    the source-to-target mappings

Raises:

  • (ArgumentError)

    if the target event is not controlable, i.e. not have a command



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
# File 'lib/roby/models/task.rb', line 339

def signal(mappings)
    mappings.each do |from, to|
        from    = event_model(from)
        targets = Array[*to].map { |ev| event_model(ev) }

        if from.terminal?
            non_terminal = targets.find_all { |ev| !ev.terminal? }
            unless non_terminal.empty?
                raise ArgumentError,
                      "trying to establish a signal from the terminal "\
                      "event #{from} to the non-terminal "\
                      "events #{non_terminal}"
            end
        end
        non_controlable = targets.find_all { |ev| !ev.controlable? }
        unless non_controlable.empty?
            raise ArgumentError,
                  "trying to signal #{non_controlable.join(' ')} which "\
                  "is/are not controlable"
        end

        signal_sets[from.symbol].merge(
            targets.map(&:symbol)
        )
    end
    update_terminal_flag
end

#templateObject

The plan that is used to instantiate this task model



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/roby/models/task.rb', line 47

def template
    return @template if @template

    template = Template.new
    each_event do |event_name, event_model|
        event = TemplateEventGenerator.new(
            event_model.controlable?, event_model, plan: template
        )
        template.add(event)
        template.events_by_name[event_name] = event
    end

    instantiate_event_relations(template)
    @template = template
end

#terminal_eventsObject

Get the list of terminal events for this task model



709
710
711
712
# File 'lib/roby/models/task.rb', line 709

def terminal_events
    each_event.find_all { |_, e| e.terminal? }
              .map { |_, e| e }
end

#terminatesObject

Declare that tasks of this model can finish by simply emitting stop, i.e. with no specific action.

Examples:

class MyTask < Roby::Task
  terminates
end


461
462
463
464
# File 'lib/roby/models/task.rb', line 461

def terminates
    event :failed, command: true, terminal: true
    interruptible
end

#to_coordination_task(_task_model) ⇒ Object



902
903
904
# File 'lib/roby/models/task.rb', line 902

def to_coordination_task(_task_model)
    Roby::Coordination::Models::TaskFromAsPlan.new(self, self)
end

#to_execution_exception_matcherQueries::ExecutionExceptionMatcher

Returns an exception match object that matches exceptions originating from this task.

Returns:



878
879
880
# File 'lib/roby/models/task.rb', line 878

def to_execution_exception_matcher
    Queries::ExecutionExceptionMatcher.new.with_origin(self)
end

#update_terminal_flagObject

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.

Update the terminal flag for the event models that are defined in this task model. The event is terminal if model-level signals (#signal) or forwards (#forward) lead to the emission of #stop_event



507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
# File 'lib/roby/models/task.rb', line 507

def update_terminal_flag # :nodoc:
    events = each_event.map { |name, _| name }
    terminal_events = [:stop]
    events.delete(:stop)

    loop do
        old_size = terminal_events.size
        events.delete_if do |ev|
            signals_terminal = signals(ev).any? do |sig_ev|
                terminal_events.include?(sig_ev)
            end
            signals_terminal ||= forwardings(ev).any? do |sig_ev|
                terminal_events.include?(sig_ev)
            end

            if signals_terminal

                terminal_events << ev
                true
            end
        end
        break if old_size == terminal_events.size
    end

    terminal_events.each do |sym|
        if (ev = self.events[sym])
            ev.terminal = true
        else
            ev = superclass.event_model(sym)
            unless ev.terminal?
                event sym, model: ev, terminal: true,
                           command: (ev.method(:call) rescue nil)
            end
        end
    end
end

#with_arguments(arguments = {}) ⇒ Object

If this class model has an ‘as_plan’, this specifies what arguments should be passed to as_plan



185
186
187
188
189
190
191
192
193
# File 'lib/roby/models/task.rb', line 185

def with_arguments(arguments = {})
    if respond_to?(:as_plan)
        AsPlanProxy.new(self, arguments)
    else
        raise NoMethodError,
              "#with_arguments is invalid on #self, as #self does not "\
              "have an #as_plan method"
    end
end