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.



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

def initialize(task)
    @event_handlers = {}
    @finalization_handlers = []
    @replacement_handlers = []
    @plan_status_handlers = []
    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



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

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:



27
28
29
# File 'lib/roby/plan_service.rb', line 27

def event_handlers
  @event_handlers
end

#finalization_handlersObject (readonly)

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

See Also:



20
21
22
# File 'lib/roby/plan_service.rb', line 20

def finalization_handlers
  @finalization_handlers
end

#plan_status_handlersObject (readonly)

The set of handlers for mission/permanent status change



33
34
35
# File 'lib/roby/plan_service.rb', line 33

def plan_status_handlers
  @plan_status_handlers
end

#replacement_handlersObject (readonly)

The set of handlers for replacments

See Also:



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

def replacement_handlers
  @replacement_handlers
end

#taskRoby::Task

The underlying task

Returns:



16
17
18
# File 'lib/roby/plan_service.rb', line 16

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.



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

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



115
116
117
118
119
120
121
122
123
124
# File 'lib/roby/plan_service.rb', line 115

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



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

alias __to_s__ to_s

#create_transaction_proxy(transaction) ⇒ Object



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

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



127
128
129
130
131
# File 'lib/roby/plan_service.rb', line 127

def finalized!
    if task.plan.executable?
        finalization_handlers.each(&:call)
    end
end

#initialize_copy(source) ⇒ Object



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

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)


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

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



94
95
96
97
98
# File 'lib/roby/plan_service.rb', line 94

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.



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

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] = []) << 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



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

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



68
69
70
# File 'lib/roby/plan_service.rb', line 68

def on_replacement(&block)
    replacement_handlers << block
end

#respond_to_missing?(m, include_private) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#to_sObject

:nodoc:



60
61
62
# File 'lib/roby/plan_service.rb', line 60

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

#to_taskObject

Returns the underlying task

See Also:



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

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)


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

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



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

def when_finalized(&block)
    finalization_handlers << block
end