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.



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

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

Instance Attribute Details

#nameObject

Returns the value of attribute name.



78
79
80
# File 'lib/rflow/component/port.rb', line 78

def name
  @name
end

#uuidObject

Returns the value of attribute uuid.



78
79
80
# File 'lib/rflow/component/port.rb', line 78

def uuid
  @uuid
end

Instance Method Details

#[](key) ⇒ Object

Get the subport for a given key, which can be used to send messages or direct connection



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

def [](key)
  HashSubPort.new(self, key)
end

#add_connection(key, connection) ⇒ Object

Adds a connection for a given key



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

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



160
161
162
# File 'lib/rflow/component/port.rb', line 160

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

#collect_messages(key, receiver) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/rflow/component/port.rb', line 121

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)


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

def connect!; raise NotImplementedError, 'Raw ports do not know which direction to connect'; end

#connections_for(key) ⇒ Object

Returns an Array of all the connections that should be sent/received on this subport. 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.



100
101
102
103
104
105
# File 'lib/rflow/component/port.rb', line 100

def connections_for(key)
  case key
  when nil; @connections_for[nil]
  else @connections_for[key] + @connections_for[nil]
  end
end

#direct_connect(key = nil, other_port) ⇒ Object



135
136
137
138
139
140
141
# File 'lib/rflow/component/port.rb', line 135

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

#eachObject



148
149
150
# File 'lib/rflow/component/port.rb', line 148

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

#keysObject

Return a list of connected keys



144
145
146
# File 'lib/rflow/component/port.rb', line 144

def keys
  @connections_for.keys
end

#remove_connection(key, connection) ⇒ Object

Removes a connection from a given key



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

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

Raises:

  • (NotImplementedError)


152
153
154
# File 'lib/rflow/component/port.rb', line 152

def send_message(message)
  raise NotImplementedError, 'Raw ports do not know how to send messages'
end