I am trying to write a some code that expresses a series of
Commands/Responses over a serial link.
In pseudocode, this is what I want to accomplish:
conv = Conversation.new(connection) { |x|
x.transmit(:init)
x.wait_for(:ok)
x.transmit(:get_user_input)
x.wait_for(:user_data) { |message| response = message.text }
puts response
rescue TimeoutException => e
x.retry if x.attempts < 3
}
conv.start
I'm guessing #start runs the block? Why not
Thread.new {conv.start}
I am pretty sure that I need Threads, but I think a single 'receiver'-Thread inside the connection instance should be enough.
My main problem at this point is that I don't know how I want the final result to *look* like.
Or does the block get executed during Conversation.new, which just
queues up all the commands so that start can call them in order later?
No, the "conversation" should be an arbitrary program.
My current attempts wrap around an instance of IO, like so:
# Connection wraps protocol details like a notion of "Packets" and
# generates events if specific messages arrive
connection = Connection.new( f = Tempfile.new("example") )
# Add a Packet named :init that can be sent by
# calling "connection.send_packet(:init)"
connection.add_sender(:init, Packet.create(:data_format => "INIT") )
# Add an event called :ok that is generated whenever a packet
# starting with the letter "O" is received
connection.add_receiver(:ok, Packet.create(:header => [?O]) )
# Register an event handler
connection.on_receive(:ok) { |m| puts "received message: OK" }
Given that I could probably do this:
# Resumable from <http://www.all-thing.net/Ruby/coroutines.html>
conversation = Resumable.new { |r|
connection.on_receive(:ok) { r.resume if r.suspended? }
connection.send(:init)
r.suspend
puts "Got an answer!"
}
...
connection.start # start sending/receiving data
conversation.call
...
That's not very pretty though
-Levin
···
Joel VanderWerf <vjoel@path.berkeley.edu> wrote: