class Roby::TaskStateMachine

The state machine that can be associate with a task

Attributes

machine[RW]

Underlying state machine

proxy[RW]

The proxy object class the state machine is working on

states[R]

All state of the state machine

transitions[R]

Existing transitions Transition comes with methods: event, from_name, to_name

Public Class Methods

new(machine) click to toggle source
Calls superclass method
# File lib/roby/coordination/task_state_machine.rb, line 66
def initialize(machine)
    # Required to initialize underlying state_machine
    super()

    @proxy       = machine.owner_class.new
    @machine     = machine

    update
end

Public Instance Methods

do_poll(task) click to toggle source

Define general poll handler

# File lib/roby/coordination/task_state_machine.rb, line 120
def do_poll(task)
    begin 
        proxy.poll(task)
    rescue NoMethodError => e
        # poll only if the state has a poll handler defined
    end
end
identify_state(event_list) click to toggle source

Identifies the current state given a list of subsequent events Provides a list with the most recent event being last in the list

# File lib/roby/coordination/task_state_machine.rb, line 131
def identify_state(event_list)
    # initalize with all transitions possible
    paths = {}
    @transitions.each do |transition|
        paths[transition] = []
    end

    paths = []
    new_paths = []
    initialized = false

    while event_list.size > 0 
        current_event = event_list.first
        # expand path
        @transitions.each do |transition|
            # Get transitions that match event
            if current_event == transition.event()
                # expand first set of transactions
                if not initialized
                    new_paths << [ transition ]
                else
                    # find transitions that lead to the last transition
                    paths.each do |path|
                        if path.last.from_name == transition.to_name
                            path << transition
                            new_paths << path 
                        end
                    end
                end
            end
        end
        paths = new_paths
        new_paths = []
        initialized = true
        event_list.delete_at(0)
    end

    if paths.size == 1
        # Retrieve last (by time) transitions target state
        return paths[0].last.to_name
    elsif paths.size > 0
        throw "Event list is ambigious, requiring more events"
    end

    throw "Event list is invalid"
end
initialize_copy(other) click to toggle source
# File lib/roby/coordination/task_state_machine.rb, line 98
def initialize_copy(other)
    other.name = name 
    other.proxy = name.new
    other.machine = machine.dup
    other.update
end
method_missing(m, *args, &block) click to toggle source
Calls superclass method
# File lib/roby/coordination/task_state_machine.rb, line 109
def method_missing(m, *args, &block)
    # If proxy provides missing method, then use the proxy
    if proxy.respond_to?(m)
        proxy.public_send(m, *args, &block)
    else
        # otherwise pass it on
        super
    end
end
respond_to_missing?(m, include_private) click to toggle source
Calls superclass method
# File lib/roby/coordination/task_state_machine.rb, line 105
def respond_to_missing?(m, include_private)
    proxy.respond_to?(m) || super
end
update() click to toggle source
# File lib/roby/coordination/task_state_machine.rb, line 76
def update
    @states = []

    # introspect to retrieve all transactions of the statemachine
    @transitions = []
    collection = @machine.states
    collection.each do |s_o|
        collection.each do |s_i|
            # status_transitions is added to TaskStateMachine using meta programming
            transitions = proxy.status_transitions(from: s_o.name.to_sym, to: s_i.name.to_sym)
            @transitions << transitions
        end
        @transitions.flatten!
    end

    # Infer all available states from existing transitions
    @transitions.each do |t|
        @states << t.from_name unless @states.index(t.from_name)
        @states << t.to_name unless @states.index(t.to_name)
    end
end