class Orocos::Log::OutputPort
Simulates a port based on log files It has the same behavior like Orocos::OutputPorts
Attributes
connections between this port and InputPort ports that support a writer
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)
returns the system time when the port was updated with new data
name of the recorded port
number of readers which are using the port
dedicated stream for simulating the port
parent log task
true –> this port shall be replayed even if there are no connections
name of the type as Typelib::Type object
name of the type as it is used in ruby
Public Class Methods
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
# File lib/orocos/log/task_context.rb, line 408 def add_connection(connection) self.tracked = true @connections << connection end
returns true if Log::Replay is aligned
# File lib/orocos/log/task_context.rb, line 480 def aligned? task.log_replay.aligned? end
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
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
Disconnects all ports and deletes all readers
# File lib/orocos/log/task_context.rb, line 462 def disconnect_all @connections.clear @readers.clear end
# File lib/orocos/log/task_context.rb, line 489 def doc? false end
# File lib/orocos/log/task_context.rb, line 258 def filter=(filter) @filter = filter self.tracked=true end
# File lib/orocos/log/task_context.rb, line 242 def first_sample_pos task.log_replay.first_sample_pos stream end
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
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
# File lib/orocos/log/task_context.rb, line 404 def has_connection?(connection) @connections.include?(connection) end
# File lib/orocos/log/task_context.rb, line 238 def last_sample_pos task.log_replay.last_sample_pos stream end
returns the metadata associated with the underlying stream
# File lib/orocos/log/task_context.rb, line 286 def metadata stream.metadata end
Returns a new sample object
# File lib/orocos/log/task_context.rb, line 468 def new_sample @type.new end
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
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
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
# 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
# File lib/orocos/log/task_context.rb, line 493 def output? true end
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
# 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
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
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
# File lib/orocos/log/task_context.rb, line 413 def remove_connection(connection) @connections.delete connection end
# 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
# File lib/orocos/log/task_context.rb, line 246 def to_orocos_port self end
# 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
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
# 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
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