class Orocos::Log::OutputPort

Simulates a port based on log files It has the same behavior like Orocos::OutputPorts

Attributes

default_policy[RW]
connections[R]

connections between this port and InputPort ports that support a writer

current_data[R]
filter[RW]

filter for log data the filter is applied before all connections and readers are updated if you want to apply a filter only for one connection or one reader do not set the filter here. the filter must be a proc, lambda, method or object with a function named call. the signature must be: new_massage call(old_message)

last_update[R]

returns the system time when the port was updated with new data

name[R]

name of the recorded port

readers[R]

number of readers which are using the port

stream[R]

dedicated stream for simulating the port

task[R]

parent log task

tracked[RW]

true –> this port shall be replayed even if there are no connections

type[R]

name of the type as Typelib::Type object

type_name[R]

name of the type as it is used in ruby

Public Class Methods

new(task,stream) click to toggle source

Creates a new object of OutputPort

task => simulated task for which the port shall be created stream => stream from which the port shall be created

# File lib/orocos/log/task_context.rb, line 299
def initialize(task,stream)
    if !stream.respond_to?(:name) || !stream.respond_to?(:type) || !stream.respond_to?(:typename) || !stream.respond_to?(:metadata)
        raise "Cannot create OutputPort out of #{stream.class}"
    end
    @stream = stream
    @name = if stream.metadata.has_key? "rock_task_object_name"
                name = stream.metadata["rock_task_object_name"]
                if !name || name.empty?
                    name = "#{stream.name.to_s}"
                    Log.warn "Stream name (#{stream.name}) has empty meta data assuming as PORTNAME \"#{name}\""
                end
                name
            else
                # backward compatibility
                name = stream.name.to_s.match(/\.(.*$)/)
                if name == nil
                    name = "#{stream.name.to_s}"
                    Log.warn "Stream name (#{stream.name}) does not follow the convention TASKNAME.PORTNAME, assuming as PORTNAME \"#{name}\""
                    name
                else
                    name[1]
                end
            end
    begin
        @type = stream.type
    rescue Exception => e
        raise InitializePortError.new( e.message, @name )
    end
    @type_name = stream.typename
    @task = task
    @connections = Set.new
    @current_data = nil
    @tracked = false
    @readers = Array.new
    @last_update = Time.now
end

Public Instance Methods

add_connection(connection) click to toggle source
# File lib/orocos/log/task_context.rb, line 408
def add_connection(connection)
    self.tracked = true
    @connections << connection
end
aligned?() click to toggle source

returns true if Log::Replay is aligned

# File lib/orocos/log/task_context.rb, line 480
def aligned?
    task.log_replay.aligned?
end
clear_reader_buffers() click to toggle source

Clears all reader buffers

# File lib/orocos/log/task_context.rb, line 473
def clear_reader_buffers
    @readers.each do |reader|
        reader.clear_buffer
    end
end
connect_to(port=nil,policy = OutputPort::default_policy,&block) click to toggle source

Register InputPort which is updated each time write is called

# File lib/orocos/log/task_context.rb, line 418
def connect_to(port=nil,policy = OutputPort::default_policy,&block)
    port = if port.respond_to? :find_input_port
               #assuming port is a TaskContext
               if !(result = port.find_input_port(type,nil))
                   raise NotFound, "port #{name} does not match any port of the TaskContext #{port.name}."
               end
               result.to_orocos_port
           elsif port
               port.to_orocos_port 
           end

    if block && !port
        Orocos::Log.warn "connect_to to a code block { |data| ... } is deprecated. Use #on_data instead."
    end

    self.tracked = true
    policy[:filter] = block if block
    if !port 
      raise "Cannot set up connection no code block or port is given" unless block
      @connections << CodeBlockConnection::OnData.new(self,block)
    else
      raise "Cannot connect to #{port.class}" if(!port.instance_of?(Orocos::InputPort))
      @connections << Connection.new(self,port,policy)
      Log.info "setting connection: #{task.name}.#{name} --> #{port.task.name}.#{port.name}"
    end
end
disconnect_all() click to toggle source

Disconnects all ports and deletes all readers

# File lib/orocos/log/task_context.rb, line 462
def disconnect_all
    @connections.clear
    @readers.clear
end
doc?() click to toggle source
# File lib/orocos/log/task_context.rb, line 489
def doc?
    false
end
filter=(filter) click to toggle source
# File lib/orocos/log/task_context.rb, line 258
def filter=(filter)
    @filter = filter
    self.tracked=true
end
first_sample_pos() click to toggle source
# File lib/orocos/log/task_context.rb, line 242
def first_sample_pos 
    task.log_replay.first_sample_pos stream
end
force_local?() click to toggle source

if force_local? returns true this port will never be proxied by an orogen port proxy

# File lib/orocos/log/task_context.rb, line 234
def force_local?
    return true
end
full_name() click to toggle source

Give the full name for this port. It is the stream name.

# File lib/orocos/log/task_context.rb, line 291
def full_name
    stream.name
end
has_connection?(connection) click to toggle source
# File lib/orocos/log/task_context.rb, line 404
def has_connection?(connection)
    @connections.include?(connection)
end
last_sample_pos() click to toggle source
# File lib/orocos/log/task_context.rb, line 238
def last_sample_pos
    task.log_replay.last_sample_pos stream
end
metadata() click to toggle source

returns the metadata associated with the underlying stream

# File lib/orocos/log/task_context.rb, line 286
def metadata
    stream.metadata
end
new_sample() click to toggle source

Returns a new sample object

# File lib/orocos/log/task_context.rb, line 468
def new_sample
    @type.new
end
number_of_samples() click to toggle source

Returns the number of samples for the port.

# File lib/orocos/log/task_context.rb, line 485
def number_of_samples
    return @stream.size
end
on_data(&block) click to toggle source

Calls the provided block when data is replayed into this port

# File lib/orocos/log/task_context.rb, line 391
def on_data(&block)
    connection = CodeBlockConnection::OnData.new(self,block)
    add_connection(connection)
    connection
end
on_raw_data(&block) click to toggle source

Calls the provided block when data is replayed into this port

# File lib/orocos/log/task_context.rb, line 398
def on_raw_data(&block)
    connection = CodeBlockConnection::OnRawData.new(self,block)
    add_connection(connection)
    connection
end
orocos_type_name() click to toggle source
# File lib/orocos/log/task_context.rb, line 223
def orocos_type_name
    if metadata && metadata.has_key?(:rock_orocos_type_name)
        metadata[:rock_orocos_type_name]
    elsif type_name =~ /^(.*)_m$/
        $1
    else
        type_name
    end
end
output?() click to toggle source
# File lib/orocos/log/task_context.rb, line 493
def output?
    true
end
pretty_print(pp) click to toggle source

Pretty print for OutputPort.

# File lib/orocos/log/task_context.rb, line 264
def pretty_print(pp)
    pp.text "#{task.name}.#{name}"
    pp.nest(2) do
        pp.breakable
        pp.text "tracked = #{@tracked}"
        pp.breakable
        pp.text "readers = #{@readers.size}"
        pp.breakable
        pp.text "filtered = #{(@filter!=nil).to_s}"
        @connections.each do |connection|
            pp.breakable
            if connection.is_a?(OutputPort::Connection)
              pp.text "connected to #{connection.port.task.name}.#{connection.port.name} (filtered = #{(connection.filter!=nil).to_s})"
            end
            if connection.is_a?(OutputPort::CodeBlockConnection)
              pp.text "connected to code block"
            end
        end
    end
end
raw_read() click to toggle source
# File lib/orocos/log/task_context.rb, line 358
def raw_read
    if !used?
        raise "port #{full_name} is not replayed. Set tracked to true or use a port reader!"
    end
    if @sample_info && !@current_data
        stream, position = *@sample_info
        data = stream.read_one_raw_data_sample(position)
        if @filter
            filtered_data = @filter.call(data)

            if data.class != filtered_data.class 
                Log.error "Filter block for port #{full_name} returned #{@current_data.class.name} but #{data.class.name} was expected."
                Log.error "If a statement like #{name} do |sample,port| or #{name}.connect_to(port) do |sample,port| is used, the code block always needs to return 'sample'!"
                Log.error "Disabling Filter for port #{full_name}"
                @filter = nil
                @current_data = data
            else
                @current_data = filtered_data
            end
        else
            @current_data = data
        end
    end
    @current_data
end
read() click to toggle source

Returns the current sample data.

# File lib/orocos/log/task_context.rb, line 352
def read
    if sample = raw_read
        return Typelib.to_ruby(sample)
    end
end
reader(policy = OutputPort::default_policy,&block) click to toggle source

Creates a new reader for the port.

# File lib/orocos/log/task_context.rb, line 337
def reader(policy = OutputPort::default_policy,&block)
    policy[:filter] = block if block
    self.tracked = true
    new_reader = OutputReader.new(self,policy)
    @readers << new_reader
    return new_reader
end
remove_connection(connection) click to toggle source
# File lib/orocos/log/task_context.rb, line 413
def remove_connection(connection)
    @connections.delete connection
end
to_async(options = Hash.new) click to toggle source
# File lib/orocos/async/orocos.rb, line 4
def to_async(options = Hash.new)
    self.tracked = true
    task.to_async(options).port(name,:type => type).wait
end
to_orocos_port() click to toggle source
# File lib/orocos/log/task_context.rb, line 246
def to_orocos_port
    self
end
to_proxy(options = Hash.new) click to toggle source
# File lib/orocos/async/orocos.rb, line 9
def to_proxy(options = Hash.new)
    self.tracked = true
    task.to_proxy(options).port(name,:type => type).wait
end
tracked=(value) click to toggle source

If set to true the port is replayed.

# File lib/orocos/log/task_context.rb, line 385
def tracked=(value)
    raise "can not track unused port #{stream.name} after the replay has started" if !used? && aligned?
    @tracked = value
end
update(sample_info) click to toggle source
# File lib/orocos/log/task_context.rb, line 445
def update(sample_info)
    @last_update = Time.now
    @current_data = nil
    @sample_info = sample_info

    @connections.each do |connection|
        connection.update
    end
    if !@readers.empty?
        sample = raw_read
        @readers.each do |reader|
            reader.update(sample)
        end
    end
end
used?() click to toggle source

Returns true if the port has at least one connection or tracked is set to true.

# File lib/orocos/log/task_context.rb, line 347
def used?
    return @tracked
end