comp.lang.ada
 help / color / mirror / Atom feed
From: wtwolfe@hubcap.clemson.edu (Bill Wolfe)
Subject: Interactive I/O in Ada
Date: 19 Jan 90 04:01:52 GMT	[thread overview]
Message-ID: <7701@hubcap.clemson.edu> (raw)


  In the current issue of ACM SIGAda Ada Letters, Doug Bryan provides
  a simple answer to a commonly asked question: How does one do keyboard
  input in Ada while having other tasks do some work in the background
  in between keystrokes?  Since Text_IO generally is not implemented so
  as to permit this to be done trivially, it is necessary to isolate the
  task which is handling the keyboard; the keyboard-handling task repeatedly 
  calls Text_IO.Get to obtain a character and deposits it into a virtual 
  keyboard.  The tasks which are to run in the background can then make 
  their entry calls to the virtual keyboard, such that a rendezvous will 
  only occur if a character is waiting to be consumed.

  Sample code (Bryan's solution, with improved documentation) follows:


    task Keyboard is    -- Keyboard abstraction, for use by other tasks 
       entry Read  (Next_Character : in  Character); -- Other tasks call... 
       entry Write (Next_Character : out Character); -- Only handler calls... 
    end Keyboard;


    task Keyboard_Handler;

    with Text_IO;

    task body Keyboard_Handler is 
       Character_Buffer : Character;
    begin
       loop
          Text_IO.Get (Character_Buffer);
          Keyboard.Write (Character_Buffer);
       end loop;
    end Keyboard_Handler;
 

    with Generic_Queue;   -- You'll need to write this generic package, to
                          --  provide type Queue with operations Enqueue, 
                          --  Dequeue, and Empty.

    task body Keyboard is
       package Character_Queue_Handler is new Generic_Queue (Character);
       use Character_Queue_Handler;
       Character_Queue : Character_Queue_Handler.Queue;
    begin
       loop
          select
             accept Write (Next_Character : in Character) do
                Enqueue (Character_Queue, Next_Character); 
             end Write;
          or when not Empty (Character_Queue) =>
             accept Read (Next_Character : out Character) do
                Dequeue (Character_Queue, Next_Character);
             end Read;
          or 
             terminate;
          end select;
       end loop;
    end Keyboard;
 

    -- To use this keyboard abstraction, write code along these lines:
    --    
    -- loop    
    --    select
    --       Keyboard.Read (Keystroke);   -- Keystroke is of type Character
    --       -- code to process a keystroke
    --    else
    --       -- code to do other work "in the background"
    --    end select;
    -- end loop;
    --
    -- On each pass through the loop, if a character is available for
    --   immediate consumption, the code to process a keystroke will be 
    --   executed.  If a character is not immediately available, then the
    --   code to do other work "in the background" will be executed.  The
    --   code to process a keystroke will normally contain an exit statement
    --   whereby the loop is exited once continued monitoring of the keyboard
    --   is no longer desired (e.g., the user indicates a wish to exit this
    --   mode of interaction).  The code to do other work in the background
    --   will normally be set up to do small increments of work in order to 
    --   maintain a reasonable level of user responsiveness.


   Bill Wolfe, wtwolfe@hubcap.clemson.edu

             reply	other threads:[~1990-01-19  4:01 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1990-01-19  4:01 Bill Wolfe [this message]
  -- strict thread matches above, loose matches on Subject: below --
1990-01-23 21:25 Interactive I/O in Ada Harold Rabbie
1990-01-24 18:12 ` Edward Falis
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox