Class: PacketIO
- Inherits:
-
Object
- Object
- PacketIO
- Defined in:
- lib/serial_interface.rb
Overview
PacketIO is used to wrap data in packets and send them over a serial port or some other IO
Instance Attribute Summary collapse
-
#protocol_handler ⇒ Object
Returns the value of attribute protocol_handler.
Instance Method Summary collapse
-
#add_receiver(hash = {}, &block) ⇒ Object
Add a type of packet, that should be checked for in the interface.
- #add_sender(hash = {}) ⇒ Object
-
#initialize(protocol, read, write = read, options = {}) ⇒ PacketIO
constructor
Takes two IO-Objects (uses “readchar” and “<<”) to read and write from.
- #join ⇒ Object
-
#on_receive(&block) ⇒ Object
The block given to this method is called with every received string.
-
#run ⇒ Object
starts the receiver thread.
-
#send_packet(data, *args) ⇒ Object
Data to be wrapped in a packet.
-
#wait_for_packet(num_packets = 1, timeout = 10) ⇒ Object
suspends the current thread, until
num
packets have been received the thread will be resumed after all callbacks were called.
Constructor Details
#initialize(protocol, read, write = read, options = {}) ⇒ PacketIO
Takes two IO-Objects (uses “readchar” and “<<”) to read and write from
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/serial_interface.rb', line 36 def initialize(protocol, read, write = read, = {}) @read, @write = read, write @on_receive = nil # Hashes contain SerialPackets that can be sent and received # @sendable_packets = {} @receivable_packets = [] @waiting_threads = [] @protocol_handler = protocol.new(method(:send_callback),method(:receive_callback), ) # Create the receiver thread, but do not start it yet # @receiver_thread = Thread.new do Thread.abort_on_exception = true Thread.stop loop do begin char = @read.readchar @protocol_handler.add_char_to_packet(char) if char rescue EOFError Thread.pass # there is currently nothing to read end end if @read # no need to loop, if there is nothing to read from end end |
Instance Attribute Details
#protocol_handler ⇒ Object
Returns the value of attribute protocol_handler.
32 33 34 |
# File 'lib/serial_interface.rb', line 32 def protocol_handler @protocol_handler end |
Instance Method Details
#add_receiver(hash = {}, &block) ⇒ Object
Add a type of packet, that should be checked for in the interface
If a packet is received
99 100 101 102 103 104 |
# File 'lib/serial_interface.rb', line 99 def add_receiver(hash = {}, &block) hash.each { |k,v| @receivable_packets << {:packet => v, :block => block} } self end |
#add_sender(hash = {}) ⇒ Object
88 89 90 91 92 93 |
# File 'lib/serial_interface.rb', line 88 def add_sender(hash = {}) hash.each { |k,v| @sendable_packets[k] = v } self end |
#join ⇒ Object
136 137 138 139 |
# File 'lib/serial_interface.rb', line 136 def join @receiver_thread.join self end |
#on_receive(&block) ⇒ Object
The block given to this method is called with every received string
84 85 86 |
# File 'lib/serial_interface.rb', line 84 def on_receive(&block) @on_receive = block end |
#run ⇒ Object
starts the receiver thread
131 132 133 134 |
# File 'lib/serial_interface.rb', line 131 def run @receiver_thread.wakeup self end |
#send_packet(data, *args) ⇒ Object
Data to be wrapped in a packet
there are different ways of using this method:
send_packet(sym, *data) send_packet(sym, options = {}, *data)
looks for a packet-class named sym and creates a new instance of this type
of packet
the optional hash is passed to the protocol layer
send_packet(string, options = {})
sends a raw string
the optional hash is passed to the protocol layer
121 122 123 124 125 126 127 |
# File 'lib/serial_interface.rb', line 121 def send_packet(data, *args) = (Hash === args.first) ? = args.shift : {} data = (Symbol === data) ? @sendable_packets[data].new(*args) : data @protocol_handler.send_packet(data.to_str, ) self end |
#wait_for_packet(num_packets = 1, timeout = 10) ⇒ Object
suspends the current thread, until num
packets have been received the thread will be resumed after all callbacks were called
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/serial_interface.rb', line 69 def wait_for_packet(num_packets = 1, timeout = 10) begin @waiting_threads << {:num => num_packets, :thread => Thread.current} sleep timeout raise Timeout::Error, "Timeout" rescue SerialProtocol::PacketReceived => e ensure # delete all occurrences of the current thread from the list of waiting threads, # as we are obviously not waiting anymore @waiting_threads.delete_if { |h| h[:thread] == Thread.current } end end |