Joel VanderWerf <vjoel / path.berkeley.edu> wrote:

>> 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