Class: Roby::PlanService

Inherits:
Object show all
Extended by:
Transaction::Proxying::Cache
Defined in:
lib/roby/plan_service.rb

Overview

A plan service represents a “place” in the plan. I.e. it initially is attached to a given task instance, but its attachment will move when the task is replaced by another one, thus allowing to track a task that performs a given service for the system.

It forwards method calls to the underlying task

Instance Attribute Summary collapse

Attributes included from Transaction::Proxying::Cache

#transaction_forwarder_module, #transaction_proxy_module

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(task) ⇒ PlanService

Returns a new instance of PlanService.



33
34
35
36
37
38
39
40
# File 'lib/roby/plan_service.rb', line 33

def initialize(task)
    @event_handlers = Hash.new
    @finalization_handlers = Array.new
    @replacement_handlers = Array.new
    @plan_status_handlers = Array.new
    self.task = task
    task.plan.add_plan_service(self)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args, &block) ⇒ Object

Forwards all calls to #task



181
182
183
# File 'lib/roby/plan_service.rb', line 181

def method_missing(*args, &block) # :nodoc:
    task.public_send(*args, &block)
end

Instance Attribute Details

#event_handlersObject (readonly)

The set of event handlers that have been defined for this service

It is a mapping from a symbol (that represents the event name) to a set of procs that represent the handlers themselves

See Also:



25
26
27
# File 'lib/roby/plan_service.rb', line 25

def event_handlers
  @event_handlers
end

#finalization_handlersObject (readonly)

Set of blocks that will be called when the service itself is finalized

See Also:



18
19
20
# File 'lib/roby/plan_service.rb', line 18

def finalization_handlers
  @finalization_handlers
end

#plan_status_handlersObject (readonly)

The set of handlers for mission/permanent status change



31
32
33
# File 'lib/roby/plan_service.rb', line 31

def plan_status_handlers
  @plan_status_handlers
end

#replacement_handlersObject (readonly)

The set of handlers for replacments

See Also:



29
30
31
# File 'lib/roby/plan_service.rb', line 29

def replacement_handlers
  @replacement_handlers
end

#taskRoby::Task

The underlying task

Returns:



14
15
16
# File 'lib/roby/plan_service.rb', line 14

def task
  @task
end

Class Method Details

.get(task) ⇒ Object

Returns a plan service for task. If a service is already defined for task, it will return it.



168
169
170
171
172
173
174
# File 'lib/roby/plan_service.rb', line 168

def self.get(task)
    if service = task.plan.find_plan_service(task)
        service
    else
        new(task)
    end
end

Instance Method Details

#__handle_event__(event) ⇒ Object

Event handler that is actually added to the tasks, to implement the event handlers



112
113
114
115
116
117
118
119
120
121
# File 'lib/roby/plan_service.rb', line 112

def __handle_event__(event) # :nodoc:
    # Only proceeed if the event's origin is the task that currently
    # represents that service
    return if event.task != task

    # And call the handlers
    event_handlers[event.generator.symbol].each do |handler|
        handler.call(event)
    end
end

#__to_s__Object



57
# File 'lib/roby/plan_service.rb', line 57

alias __to_s__ to_s

#create_transaction_proxy(transaction) ⇒ Object



196
197
198
# File 'lib/roby/plan_service.rb', line 196

def create_transaction_proxy(transaction)
    transaction.create_and_register_proxy_plan_service(self)
end

#finalized!Object

Called by the plan when the service is finalized



124
125
126
127
128
129
130
# File 'lib/roby/plan_service.rb', line 124

def finalized!
    if task.plan.executable?
        finalization_handlers.each do |h|
            h.call
        end
    end
end

#initialize_copy(source) ⇒ Object



42
43
44
45
46
47
48
49
# File 'lib/roby/plan_service.rb', line 42

def initialize_copy(source)
    super

    @event_handlers = source.event_handlers.dup
    @finalization_handlers = source.finalization_handlers.dup
    @replacement_handlers = source.replacement_handlers.dup
    @plan_status_handlers = source.plan_status_handlers.dup
end

#kind_of?(*args) ⇒ Boolean

Returns:

  • (Boolean)


192
193
194
# File 'lib/roby/plan_service.rb', line 192

def kind_of?(*args)
    super || task.kind_of?(*args)
end

#notify_task_status_change(new_status) ⇒ Object

Called to notify about a plan status change for the underlying task



91
92
93
94
95
# File 'lib/roby/plan_service.rb', line 91

def notify_task_status_change(new_status)
    plan_status_handlers.each do |h|
        h.call(new_status)
    end
end

#on(event, &block) ⇒ Object

Defines an event handler for this service

This event handler will only be called if symbol is emitted by the task that currently provides this service.

For instance, if you do

service = PlanService.get(t)
service.on(:success) do
    STDERR.puts "message"
end
plan.replace(t, t2)

Then, before the replacement, ‘message’ is displayed if t emits :success. After the replacement, it will be displayed if t2 emits :success, and will not be displayed if t does.



155
156
157
158
159
160
161
162
163
164
# File 'lib/roby/plan_service.rb', line 155

def on(event, &block)
    check_arity(block, 1)
    event = event.to_sym
    if event_handlers.has_key?(event)
        event_handlers[event] << block
    else
        task.event(event).on(on_replace: :drop, &method(:__handle_event__))
        (event_handlers[event] = Array.new) << block
    end
end

#on_plan_status_change(initial: true) {|status| ... } ⇒ Object

Registers a callback that is called when the task’s mission/permanent status changes

Yield Parameters:

  • status (Symbol)

    one of :mission, :permanent or :normal



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/roby/plan_service.rb', line 74

def on_plan_status_change(initial: true, &block)
    plan_status_handlers << block
    if initial
        current_status =
            if task.plan.mission_task?(task)
                :mission
            elsif task.plan.permanent_task?(task)
                :permanent
            else :normal
            end
        block.call(current_status)
    end
end

#on_replacement { ... } ⇒ Object

Register a callback that should be called when the underlying task is replaced

Yields:

  • old, new



66
67
68
# File 'lib/roby/plan_service.rb', line 66

def on_replacement(&block)
    replacement_handlers << block
end

#respond_to_missing?(m, include_private) ⇒ Boolean

Returns:

  • (Boolean)


176
177
178
# File 'lib/roby/plan_service.rb', line 176

def respond_to_missing?(m, include_private)
    task.respond_to?(m)
end

#to_sObject

:nodoc:



58
59
60
# File 'lib/roby/plan_service.rb', line 58

def to_s # :nodoc:
    "#<service #{task.to_s}>"
end

#to_taskObject

Returns the underlying task

See Also:



188
189
190
# File 'lib/roby/plan_service.rb', line 188

def to_task
    task
end

#transaction_proxy?Boolean

True if this plan service instance is a transaction proxy, i.e. modifies an already existing service in the frame of a transaction

Returns:

  • (Boolean)


53
54
55
# File 'lib/roby/plan_service.rb', line 53

def transaction_proxy?
    false
end

#when_finalized(&block) ⇒ Object

Defines a finalization handler for this service

This handler will be called when the service itself is finalized



135
136
137
# File 'lib/roby/plan_service.rb', line 135

def when_finalized(&block)
    finalization_handlers << block
end