class Orocos::Async::TaskContextProxy

Attributes

name_service[R]

Public Class Methods

new(name,options=Hash.new) click to toggle source
Calls superclass method Orocos::Async::ObjectBase.new
# File lib/orocos/async/task_context_proxy.rb, line 463
def initialize(name,options=Hash.new)
    @options,@task_options = Kernel.filter_options options,{:name_service => Orocos::Async.name_service,
                                               :event_loop => Orocos::Async.event_loop,
                                               :reconnect => true,
                                               :retry_period => Orocos::Async::TaskContextBase.default_period,
                                               :use => nil,
                                               :raise => false,
                                               :wait => nil }

    @name_service = @options[:name_service]
    self.namespace,name = split_name(name)
    self.namespace ||= @name_service.namespace
    super(name,@options[:event_loop])

    @task_options[:event_loop] = @event_loop
    @mutex = Mutex.new
    @ports = Hash.new
    @attributes = Hash.new
    @properties = Hash.new
    @resolve_timer = @event_loop.async_every(@name_service.method(:get),
                                             {:period => @options[:retry_period],:start => false},
                                             self.name,@task_options) do |task_context,error|
        if error
            case error
            when Orocos::NotFound, Orocos::ComError
                raise error if @options[:raise]
                :ignore_error
            else
                raise error
            end
        else
            @resolve_timer.stop
            if !task_context.respond_to?(:event_loop)
                raise "TaskProxy is using a name service#{@name_service} which is returning #{task_context.class} but Async::TaskContext was expected."
            end
            @event_loop.async_with_options(method(:reachable!),{:sync_key => self,:known_errors => Orocos::Async::KNOWN_ERRORS},task_context) do |val,error|
                if error
                    @resolve_timer.start
                    :ignore_error
                end
            end
        end
    end

    on_port_reachable(false) do |name|
        p = @ports[name]
        if p && !p.reachable?
            error_callback = Proc.new do |error|
                p.emit_error(error)
            end
            @event_loop.defer :known_errors => Orocos::Async::KNOWN_ERRORS,:on_error => error_callback do
                connect_port(p)
            end
        end
    end
    on_property_reachable(false) do |name|
        p = @properties[name]
        if(p && !p.reachable?)
            error_callback = Proc.new do |error|
                p.emit_error(error)
            end
            @event_loop.defer :known_errors => Orocos::Async::KNOWN_ERRORS,:on_error => error_callback do
                connect_property(p)
            end
        end
    end
    on_attribute_reachable(false) do |name|
        a = @attributes[name]
        if(a && !a.reachable?)
            error_callback = Proc.new do |error|
                a.emit_error(error)
            end
            @event_loop.defer :known_errors => Orocos::Async::KNOWN_ERRORS,:on_error => error_callback do
                connect_attribute(a)
            end
        end
    end

    @resolve_timer.doc = "#{name} reconnect"
    if @options.has_key?(:use)
        reachable!(@options[:use])
    else
        reconnect(@options[:wait])
    end
end

Public Instance Methods

attribute(name,options = Hash.new) click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 604
def attribute(name,options = Hash.new)
    name = name.to_str
    options,other_options = Kernel.filter_options options,:wait => @options[:wait]
    wait if options[:wait]

    a = @mutex.synchronize do
        @attributes[name] ||= AttributeProxy.new(self,name,other_options)
    end

    if other_options.has_key?(:type) && a.type? && other_options[:type] == a.type
        other_options.delete(:type)
    end
    if !other_options.empty? && a.options != other_options
        Orocos.warn "Attribute #{a.full_name}: is already initialized with options: #{a.options}"
        Orocos.warn "ignoring options: #{other_options}"
    end

    return a if !reachable? || a.reachable?
    if options[:wait]
        connect_attribute(a)
        a.wait
    else
        @event_loop.defer :known_errors => Orocos::Async::KNOWN_ERRORS do
            connect_attribute(a)
        end
    end
    a
end
attributes(&block) click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 706
def attributes(&block)
   p = proc do |names|
       names.map{|name| attribute(name)}
   end
   if block
       attribute_names(&p)
   else
       p.call(attribute_names)
   end
end
basename() click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 553
def basename
    @name
end
each_attribute { |a| ... } → task click to toggle source

Enumerates the attributes that are available on this task, as instances of Orocos::Attribute

# File lib/orocos/async/task_context_proxy.rb, line 737
def each_attribute(&block)
    if !block_given?
        return enum_for(:each_attribute)
    end

    names = attribute_names
    names.each do |name|
        yield(attribute(name))
    end
end
each_port { |p| ... } → task click to toggle source

Enumerates the ports that are available on this task, as instances of either Orocos::InputPort or Orocos::OutputPort

# File lib/orocos/async/task_context_proxy.rb, line 753
def each_port(&block)
    if !block_given?
        return enum_for(:each_port)
    end

    port_names.each do |name|
        yield(port(name))
    end
    self
end
each_property { |a| ... } → task click to toggle source

Enumerates the properties that are available on this task, as instances of Orocos::Attribute

# File lib/orocos/async/task_context_proxy.rb, line 722
def each_property(&block)
    if !block_given?
        return enum_for(:each_property)
    end
    names = property_names
    names.each do |name|
        yield(property(name))
    end
end
name() click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 549
def name
    map_to_namespace(@name)
end
port(name,options = Hash.new) click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 633
def port(name,options = Hash.new)
    name = name.to_str
    options,other_options = Kernel.filter_options options,:wait => @options[:wait]
    wait if options[:wait]

    # support for subports
    fields = name.split(".")
    name = if fields.empty?
               name
           elsif name[0] == "/"
               # special case for log ports like: logger_name.port("/task_name.port_name")
               fields = []
               name
           else
               fields.shift
           end
    type = if !fields.empty?
               other_options.delete(:type)
           else
               nil
           end

    p = @mutex.synchronize do
        @ports[name] ||= PortProxy.new(self,name,other_options)
    end

    if other_options.has_key?(:type) && p.type? && other_options[:type] == p.type
        other_options.delete(:type)
    end
    if !other_options.empty? && p.options != other_options
        Orocos.warn "Port #{p.full_name}: is already initialized with options: #{p.options}"
        Orocos.warn "ignoring options: #{other_options}"
    end

    if reachable? && !p.reachable?
        if options[:wait]
            connect_port(p)
            p.wait
        else
            @event_loop.defer :known_errors => KNOWN_ERRORS do
                connect_port(p)
            end
        end
    end
    if fields.empty?
        p
    else
        p.sub_port(fields)
    end
end
ports(options = Hash.new,&block) click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 684
def ports(options = Hash.new,&block)
   p = proc do |names|
       names.map{|name| port(name,options)}
   end
   if block
       port_names(&p)
   else
       p.call(port_names)
   end
end
properties(&block) click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 695
def properties(&block)
   p = proc do |names|
       names.map{|name| property(name)}
   end
   if block
       property_names(&p)
   else
       p.call(property_names)
   end
end
property(name,options = Hash.new) click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 575
def property(name,options = Hash.new)
    name = name.to_str
    options,other_options = Kernel.filter_options options,:wait => @options[:wait]
    wait if options[:wait]

    p = @mutex.synchronize do
        @properties[name] ||= PropertyProxy.new(self,name,other_options)
    end

    if other_options.has_key?(:type) && p.type? && other_options[:type] == p.type
        other_options.delete(:type)
    end
    if !other_options.empty? && p.options != other_options
        Orocos.warn "Property #{p.full_name}: is already initialized with options: #{p.options}"
        Orocos.warn "ignoring options: #{other_options}"
    end

    return p if !reachable? || p.reachable?
    if options[:wait]
        connect_property(p)
        p.wait
    else
        @event_loop.defer :known_errors => Orocos::Async::KNOWN_ERRORS do
            connect_property(p)
        end
    end
    p
end
reachable!(task_context,options = Hash.new) click to toggle source

must be thread safe

Calls superclass method Orocos::Async::ObjectBase#reachable!
# File lib/orocos/async/task_context_proxy.rb, line 765
def reachable!(task_context,options = Hash.new)
    raise ArgumentError, "task_context must not be instance of TaskContextProxy" if task_context.is_a?(TaskContextProxy)
    raise ArgumentError, "task_context must be an async instance but is #{task_context.class}" if !task_context.respond_to?(:event_names)
    @mutex.synchronize do
        @last_task_class ||= task_context.class
        if @last_task_class != task_context.class
            Vizkit.warn "Class missmatch: TaskContextProxy #{name} was recently connected to #{@last_task_class} and is now connected to #{task_context.class}."
            @last_task_class = task_context.class
        end

        remove_proxy_event(@delegator_obj,@delegator_obj.event_names) if valid_delegator?
        if @delegator_obj_old
            remove_proxy_event(@delegator_obj_old,@delegator_obj_old.event_names)
            @delegator_obj_old = nil
        end
        super(task_context,options)

        # check if the requested ports are available
        @ports.values.each do |port|
            unless task_context.port_names.include? port.name
                Orocos.warn "task #{name} has currently no port called #{port.name} - on_data will be called when the port was added"
            end
        end
        @attributes.values.each do |attribute|
            unless task_context.attribute_names.include? attribute.name
                Orocos.warn "task #{name} has currently no attribute called #{attribute.name} - on_change will be called when the attribute was added"
            end
        end
        @properties.values.each do |property|
            unless task_context.property_names.include? property.name
                Orocos.warn "task #{name} has currently no property called #{property.name} - on_change will be called when the property was added"
            end
        end

        # this is emitting on_port_reachable, on_property_reachable ....
        proxy_event(@delegator_obj,@delegator_obj.event_names-[:reachable])
    end
end
reachable?() click to toggle source
Calls superclass method Orocos::Async::ObjectBase#reachable?
# File lib/orocos/async/task_context_proxy.rb, line 804
def reachable?
    @mutex.synchronize do
        super && @delegator_obj.reachable?
    end
rescue Orocos::NotFound => e
    unreachable! :error => e,:reconnect => @options[:reconnect]
    false
end
reconnect(wait_for_task = false) click to toggle source

asychronsosly tries to connect to the remote task

# File lib/orocos/async/task_context_proxy.rb, line 570
def reconnect(wait_for_task = false)
    @resolve_timer.start options[:retry_period]
    wait if wait_for_task == true
end
to_async(options=Hash.new) click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 557
def to_async(options=Hash.new)
    Orocos::Async.get(name,options)
end
to_proxy(options=Hash.new) click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 561
def to_proxy(options=Hash.new)
    self
end
to_ruby() click to toggle source
# File lib/orocos/async/task_context_proxy.rb, line 565
def to_ruby
    TaskContextBase::to_ruby(self)
end
unreachable!(options = {:reconnect => false}) click to toggle source
Calls superclass method Orocos::Async::ObjectBase#unreachable!
# File lib/orocos/async/task_context_proxy.rb, line 813
def unreachable!(options = {:reconnect => false})
    Kernel.validate_options options,:reconnect,:error
    @mutex.synchronize do
        # do not stop proxing events here (see reachable!)
        # otherwise unrechable event might get lost
        @delegator_obj_old = if valid_delegator?
                                 @delegator_obj
                             else
                                 @delegator_obj_old
                             end

        disable_emitting do
            super(options)
        end
    end
    disconnect_ports
    disconnect_attributes
    disconnect_properties
    re = if options.has_key?(:reconnect)
            options[:reconnect]
         else
            @options[:reconnect]
         end
    reconnect if re
end