Class: RFlow::Component::HashPort

Inherits:
Port
  • Object
show all
Defined in:
lib/rflow/component/port.rb

Overview

Allows for a list of connections to be assigned to each port/key combination. Note that binding an input port to an un-indexed output port will result in messages from all indexed connections being received. Similarly, sending to an unindexed port will result in the same message being sent to all indexed connections.

Direct Known Subclasses

InputPort, OutputPort

Instance Attribute Summary collapse

Attributes inherited from Port

#component, #connected

Instance Method Summary collapse

Methods inherited from Port

#connected?

Constructor Details

#initialize(component, args = {}) ⇒ HashPort

Returns a new instance of HashPort.



60
61
62
63
64
65
# File 'lib/rflow/component/port.rb', line 60

def initialize(component, args = {})
  super(component)
  self.uuid = args[:uuid]
  self.name = args[:name]
  @connections_for = Hash.new {|hash, key| hash[key] = [].extend(ConnectionCollection)}
end

Instance Attribute Details

#nameObject

Returns the value of attribute name.



54
55
56
# File 'lib/rflow/component/port.rb', line 54

def name
  @name
end

#uuidObject

Returns the value of attribute uuid.



54
55
56
# File 'lib/rflow/component/port.rb', line 54

def uuid
  @uuid
end

Instance Method Details

#[](key) ⇒ Object

Returns an extended Array of all the connections that should be sent/received on this port. Merges the nil-keyed port (i.e. any connections for a port without a key) to those specific for the key, so should only be used to read a list of connections, not to add new ones. Use add_connection to add a new connection for a given key.



73
74
75
76
77
78
# File 'lib/rflow/component/port.rb', line 73

def [](key)
  case key
  when nil; connections_for[nil]
  else connections_for[key] + connections_for[nil]
  end.extend(ConnectionCollection)
end

#add_connection(key, connection) ⇒ Object

Adds a connection for a given key



81
82
83
84
85
# File 'lib/rflow/component/port.rb', line 81

def add_connection(key, connection)
  RFlow.logger.debug "Attaching #{connection.class.name} connection '#{connection.name}' (#{connection.uuid}) to port '#{name}' (#{uuid}), key '#{connection.input_port_key}'"
  connections_for[key] << connection
  @all_connections = nil
end

#all_connectionsObject



135
136
137
# File 'lib/rflow/component/port.rb', line 135

def all_connections
  @all_connections ||= connections_for.values.flatten.uniq.extend(ConnectionCollection)
end

#collect_messages(key, receiver) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/rflow/component/port.rb', line 94

def collect_messages(key, receiver)
  begin
    connection = RFlow::MessageCollectingConnection.new.tap do |c|
      c.messages = receiver
    end
    add_connection key, connection

    yield if block_given?
    connection
  ensure
    remove_connection key, connection if connection && block_given?
  end
end

#connect!Object

Should be overridden. Called when it is time to actually establish the connection

Raises:

  • (NotImplementedError)


133
# File 'lib/rflow/component/port.rb', line 133

def connect!; raise NotImplementedError, "Raw ports do not know how to send messages"; end

#direct_connect(other_port) ⇒ Object



108
109
110
111
112
113
114
# File 'lib/rflow/component/port.rb', line 108

def direct_connect(other_port)
  case other_port
  when InputPort; add_connection nil, ForwardToInputPort.new(other_port)
  when OutputPort; add_connection nil, ForwardToOutputPort.new(other_port)
  else raise ArgumentError, "Unknown port type #{other_port.class.name}"
  end
end

#eachObject

Enumerate through all the ConnectionCollections TODO: simplify with enumerators and procs



123
124
125
# File 'lib/rflow/component/port.rb', line 123

def each
  connections_for.values.each {|connections| yield connections }
end

#keysObject

Return a list of connected keys



117
118
119
# File 'lib/rflow/component/port.rb', line 117

def keys
  connections_for.keys
end

#remove_connection(key, connection) ⇒ Object

Removes a connection from a given key



88
89
90
91
92
# File 'lib/rflow/component/port.rb', line 88

def remove_connection(key, connection)
  RFlow.logger.debug "Removing #{connection.class.name} connection '#{connection.name}' (#{connection.uuid}) from port '#{name}' (#{uuid}), key '#{connection.input_port_key}'"
  connections_for[key].delete(connection)
  @all_connections = nil
end

#send_message(message) ⇒ Object



127
128
129
# File 'lib/rflow/component/port.rb', line 127

def send_message(message)
  def connect!; raise NotImplementedError, "Raw ports do not know how to send messages"; end
end