home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / ada_1 / Examples_demos_ada_diners2 < prev    next >
Encoding:
Text File  |  1994-10-15  |  11.8 KB  |  446 lines

  1. --::::::::::
  2. --screen.ads
  3. --::::::::::
  4. PACKAGE Screen IS
  5.  
  6. -- Procedures for drawing pictures on ANSI Terminal Screen
  7.  
  8.   ScreenDepth : CONSTANT Integer := 24;
  9.   ScreenWidth : CONSTANT Integer := 80;
  10.  
  11.   SUBTYPE Depth IS Integer RANGE 1..ScreenDepth;
  12.   SUBTYPE Width IS Integer RANGE 1..ScreenWidth;
  13.  
  14.   PROCEDURE Beep; 
  15.   PROCEDURE ClearScreen; 
  16.   PROCEDURE MoveCursor (Column : Width; Row : Depth);
  17.  
  18. END Screen;   
  19. --::::::::::
  20. --windows.ads
  21. --::::::::::
  22. WITH Screen;
  23. USE Screen;
  24. PACKAGE Windows IS
  25.  
  26.   TYPE Window IS PRIVATE;
  27.  
  28.   PROCEDURE Open (W      : IN OUT Window; -- Window variable returned 
  29.                   Row    : Depth; -- Upper left corner
  30.                   Column : Width;
  31.                   Height : Depth; -- Size of window
  32.                   Width  : Screen.Width);
  33.  
  34.   -- Create a window variable and open the window for writing.  
  35.   -- No checks for overlap of windows are made. 
  36.  
  37.  
  38.   PROCEDURE Close (W : IN OUT Window);
  39.   -- Close window and clear window variable. 
  40.  
  41.  
  42.   PROCEDURE Title (W     : IN OUT Window;
  43.                    Name  : String;
  44.                    Under : Character);
  45.  
  46.   -- Put a title name at the top of the window.  If the parameter 
  47.   -- under <> 0C or ' ', underline the title with the specified character. 
  48.  
  49.  
  50.   PROCEDURE Borders (W                    : IN OUT Window;
  51.                      Corner, Down, Across : Character);
  52.  
  53.   -- Draw border around current writable area in window with characters
  54.   -- specified.  Call this BEFORE Title.  
  55.  
  56.  
  57.   PROCEDURE Gotorowcolumn (W      : IN OUT Window;
  58.                            Row    : Depth;
  59.                            Column : Width);
  60.  
  61.   -- Goto the row and column specified.  Coordinates are relative to the
  62.   -- upper left corner of window, which is (1, 1) 
  63.  
  64.  
  65.   PROCEDURE Put (W  : IN OUT Window;
  66.                  Ch : Character);
  67.  
  68.   -- put one character to the window.
  69.   -- If end of column, go to the next row.
  70.   -- If end of window, go to the top of the window. 
  71.  
  72.  
  73.   PROCEDURE Put_String (W : IN OUT Window;
  74.                         S : String);
  75.  
  76.   -- put a string to window. 
  77.  
  78.  
  79.   PROCEDURE New_Line (W : IN OUT Window);
  80.  
  81.   -- Go to beginning of next line.  Next line is
  82.   -- not blanked until next character is written  
  83.  
  84.  
  85. PRIVATE
  86.   TYPE Window IS
  87.     RECORD
  88.       Currentrow, -- Current cursor row 
  89.       Firstrow,
  90.       Lastrow : Depth;
  91.       Currentcolumn, -- Current cursor column 
  92.       Firstcolumn,
  93.       Lastcolumn : Width;
  94.     END RECORD;
  95.  
  96. END Windows;
  97. --::::::::::
  98. --screen.adb
  99. --::::::::::
  100. WITH Text_IO;
  101. WITH My_Int_IO;
  102. PACKAGE BODY Screen IS
  103.  
  104. -- Procedures for drawing pictures on ANSI Terminal Screen
  105.  
  106.     procedure Ada_WriteI ( Char : in Integer );
  107.     pragma INTERFACE(C, Ada_WriteI);
  108.     
  109.     procedure VDU ( Char : in Character ) is
  110.     begin
  111.        Ada_WriteI ( Character'Pos(Char) );
  112.     end VDU;
  113.  
  114.     procedure VDU ( Vdu_Seq : in String ) is
  115.     begin
  116.        for I in Vdu_Seq'Range loop
  117.           Ada_WriteI ( Character'Pos(Vdu_Seq(I)) );
  118.        end loop;
  119.     end VDU;
  120.  
  121.   PROCEDURE Beep IS
  122.   BEGIN
  123.     VDU (ASCII.BEL);
  124.   END Beep;
  125.  
  126.   PROCEDURE ClearScreen IS
  127.   BEGIN
  128.     VDU ( ASCII.SUB & ASCII.FF );
  129.   END ClearScreen;
  130.  
  131.   PROCEDURE MoveCursor (Column : Width; Row : Depth) IS
  132.   BEGIN                                                
  133.     VDU ( ASCII.US & Character'Val(Column-1) & Character'Val(Row-1) );
  134.   END MoveCursor;  
  135.  
  136. END Screen;
  137. --::::::::::
  138. --windows.adb
  139. --::::::::::
  140. WITH Text_IO, My_Int_IO, Screen;
  141. USE Text_IO, My_Int_IO, Screen;
  142. PACKAGE BODY Windows IS
  143.  
  144.   CursorRow : Depth := 1; -- Current cursor position
  145.   CursorCol : Width := 1;
  146.  
  147.   PROCEDURE Open (W      : IN OUT Window;
  148.                   Row    : Depth;
  149.                   Column : Width;
  150.                   Height : Depth;
  151.                   Width  : Screen.Width) IS
  152.     --Put the Window's cursor in upper left corner
  153.   BEGIN
  154.     W.CurrentRow    := Row;
  155.     W.FirstRow      := Row;
  156.     W.LastRow       := Row + Height - 1;
  157.     W.CurrentColumn := Column;
  158.     W.FirstColumn   := Column;
  159.     W.LastColumn    := Column + Width - 1;
  160.   END Open;
  161.  
  162.   PROCEDURE Close (W : IN OUT Window) IS
  163.   BEGIN
  164.     NULL;
  165.   END Close;
  166.  
  167.   PROCEDURE Title (W     : IN OUT Window;
  168.                    name  : String;
  169.                    under : CHARACTER) IS
  170.     -- Put name at the top of the Window.  If under <>  ' ', underline
  171.     -- the title. 
  172.     i : Width;
  173.   BEGIN
  174.     -- Put name on top line
  175.     W.CurrentColumn := W.FirstColumn;
  176.     W.CurrentRow    := W.FirstRow;
  177.     Put_String (w, name);
  178.     new_line (w);
  179.     -- Underline name if desired, and move the First line of the Window
  180.     -- below the title 
  181.     IF under = ' ' THEN
  182.       W.FirstRow := W.FirstRow + 1;
  183.     ELSE
  184.       FOR i IN W.FirstColumn .. W.LastColumn LOOP
  185.         Put (w, under);
  186.       END LOOP;
  187.       new_line (w);
  188.       W.FirstRow := W.FirstRow + 2;
  189.     END IF;
  190.   END Title;
  191.  
  192.  
  193.   PROCEDURE GotoRowColumn (w      : IN OUT Window;
  194.                            Row    : Depth;
  195.                            Column : Width) IS
  196.     -- Relative to writable Window boundaries, of course
  197.   BEGIN
  198.     W.CurrentRow    := W.FirstRow + Row;
  199.     W.CurrentColumn := W.FirstColumn + Column;
  200.   END GotoRowColumn;
  201.  
  202.  
  203.   PROCEDURE Borders (w                    : IN OUT Window;
  204.                      corner, down, across : CHARACTER) IS
  205.     -- Draw border around current writable area in Window with characters.
  206.     -- Call this BEFORE Title.  
  207.     i : Depth;
  208.     j : Width;
  209.   BEGIN
  210.     -- Put top line of border
  211.     MoveCursor (W.FirstColumn, W.FirstRow);
  212.     Text_IO.Put (corner);
  213.     FOR j IN W.FirstColumn + 1 .. W.LastColumn - 1 LOOP
  214.       Text_IO.Put (across);
  215.     END LOOP;
  216.     Text_IO.Put (corner);
  217.  
  218.     -- Put the two side lines
  219.     FOR i IN W.FirstRow + 1 .. W.LastRow - 1 LOOP
  220.       MoveCursor (W.FirstColumn, i);
  221.       Text_IO.Put (down);
  222.       MoveCursor (W.LastColumn, i);
  223.       Text_IO.Put (down);
  224.     END LOOP;
  225.  
  226.     -- Put the bottom line of the border
  227.     MoveCursor (W.FirstColumn, W.LastRow);
  228.     Text_IO.Put (corner);
  229.     FOR j IN W.FirstColumn + 1 .. W.LastColumn - 1 LOOP
  230.       Text_IO.Put (across);
  231.     END LOOP;
  232.     Text_IO.Put (corner);
  233.  
  234.     -- Put the cursor at the very end of the Window
  235.     CursorRow := W.LastRow;
  236.     CursorCol := W.LastColumn + 1;
  237.  
  238.     -- Make the Window smaller by one character on each side
  239.     W.FirstRow      := W.FirstRow + 1;
  240.     W.CurrentRow    := W.FirstRow;
  241.     W.LastRow       := W.LastRow - 1;
  242.     W.FirstColumn   := W.FirstColumn + 1;
  243.     W.CurrentColumn := W.FirstColumn;
  244.     W.LastColumn    := W.LastColumn - 1;
  245.   END Borders;
  246.  
  247.  
  248.   PROCEDURE EraseToEndOfLine (W : IN OUT Window) IS
  249.     i : Width;
  250.   BEGIN
  251.     MoveCursor (W.CurrentColumn, W.CurrentRow);
  252.     FOR i IN W.CurrentColumn .. W.LastColumn LOOP
  253.       Text_IO.Put (' ');
  254.     END LOOP;
  255.     MoveCursor (W.CurrentColumn, W.CurrentRow);
  256.     CursorCol := W.CurrentColumn;
  257.     CursorRow := W.CurrentRow;
  258.   END EraseToEndOfLine;
  259.  
  260.  
  261.   PROCEDURE Put (W  : IN OUT Window;
  262.                  ch : CHARACTER) IS
  263.  
  264.     -- If after end of line, move to First character of next line
  265.     -- If about to write First character on line, blank rest of line.
  266.     -- Put character.
  267.  
  268.   BEGIN
  269.     IF Ch = ASCII.CR THEN
  270.       New_Line (W);
  271.       RETURN;
  272.     END IF;
  273.  
  274.     -- If at end of current line, move to next line 
  275.     IF W.CurrentColumn > W.LastColumn THEN
  276.       IF W.CurrentRow = W.LastRow THEN
  277.         W.CurrentRow := W.FirstRow;
  278.       ELSE
  279.         W.CurrentRow := W.CurrentRow + 1;
  280.       END IF;
  281.       W.CurrentColumn := W.FirstColumn;
  282.     END IF;
  283.  
  284.     -- If at W.First char, erase line
  285.     IF W.CurrentColumn = W.FirstColumn THEN
  286.       EraseToEndOfLine (W);
  287.     END IF;
  288.  
  289.     -- Put physical cursor at Window's cursor
  290.     IF (CursorCol /= W.CurrentColumn) OR (CursorRow /= W.CurrentRow) THEN
  291.       MoveCursor (W.CurrentColumn, W.CurrentRow);
  292.       CursorRow := W.CurrentRow;
  293.     END IF;
  294.  
  295.     IF Ch = ASCII.BS THEN
  296.       -- Special backspace handling 
  297.       IF W.CurrentColumn /= W.FirstColumn THEN
  298.         Text_IO.Put (Ch);
  299.         W.CurrentColumn := W.CurrentColumn - 1;
  300.       END IF;
  301.     ELSE
  302.       Text_IO.Put (Ch);
  303.       W.CurrentColumn := W.CurrentColumn + 1;
  304.     END IF;
  305.     CursorCol := W.CurrentColumn;
  306.   END Put;
  307.  
  308.  
  309.   PROCEDURE new_line (W : IN OUT Window) IS
  310.     col : Width;
  311.  
  312.     -- If not after line, blank rest of line.
  313.     -- Move to First character of next line
  314.  
  315.   BEGIN
  316.     IF W.CurrentColumn = 0 THEN
  317.       EraseToEndOfLine (W);
  318.     END IF;
  319.     IF W.CurrentRow = W.LastRow THEN
  320.       W.CurrentRow := W.FirstRow;
  321.     ELSE
  322.       W.CurrentRow := W.CurrentRow + 1;
  323.     END IF;
  324.     W.CurrentColumn := W.FirstColumn;
  325.   END new_line;
  326.  
  327.  
  328.   PROCEDURE Put_String (W : IN OUT Window;
  329.                         S : String) IS
  330.   BEGIN
  331.     FOR I IN S'FIRST .. S'LAST LOOP
  332.       Put (W, S (i));
  333.     END LOOP;
  334.   END Put_String;
  335.  
  336.  
  337. BEGIN -- Windows
  338.   ClearScreen;
  339.   MoveCursor (1, 1);
  340. END Windows;
  341. --::::::::::
  342. --roomwind.adb
  343. --::::::::::
  344. WITH Windows;
  345. WITH Chop;
  346. WITH Phil;
  347. WITH Calendar; 
  348. PRAGMA Elaborate(Phil);
  349. PACKAGE BODY Room IS
  350.  
  351.   Phils:      ARRAY(Table_Type) OF Phil.Philosopher;
  352.   Phil_Windows: ARRAY(Table_Type) OF Windows.Window;
  353.  
  354.   TYPE Phil_Names IS (Dijkstra, Texel, Booch, Ichbiah, Stroustrup);
  355.  
  356.   TASK BODY Head_Waiter IS
  357.  
  358.     T : Integer; 
  359.     Start_Time: Calendar.Time;
  360.  
  361.   BEGIN
  362.  
  363.     ACCEPT Open_The_Room;
  364.     Start_Time := Calendar.Clock;
  365.  
  366.     Windows.Open(Phil_Windows(1),1,23,7,30);
  367.     Windows.Borders(Phil_Windows(1),'+','|','-');
  368.     Windows.Title(Phil_Windows(1), "Eddy Dijkstra",'-');
  369.     Phils(1).Come_To_Life(1,1,2);
  370.  
  371.     Windows.Open(Phil_Windows(3),9,50,7,30); 
  372.     Windows.Borders(Phil_Windows(3),'+','|','-');
  373.     Windows.Title(Phil_Windows(3), "Grady Booch",'-');
  374.     Phils(3).Come_To_Life(3,3,4);
  375.  
  376.     Windows.Open(Phil_Windows(2),9,2,7,30); 
  377.     Windows.Borders(Phil_Windows(2),'+','|','-');
  378.     Windows.Title(Phil_Windows(2), "Putnam Texel",'-');
  379.     Phils(2).Come_To_Life(2,2,3);
  380.  
  381.     Windows.Open(Phil_Windows(5),17,41,7,30); 
  382.     Windows.Borders(Phil_Windows(5),'+','|','-');
  383.     Windows.Title(Phil_Windows(5), "Bjarne Stroustrup",'-');
  384.     Phils(5).Come_To_Life(5,1,5);
  385.  
  386.     Windows.Open(Phil_Windows(4),17,8,7,30); 
  387.     Windows.Borders(Phil_Windows(4),'+','|','-');
  388.     Windows.Title(Phil_Windows(4), "Jean Ichbiah",'-');
  389.     Phils(4).Come_To_Life(4,4,5);
  390.  
  391.     LOOP
  392.       SELECT
  393.         ACCEPT Report_State(Which_Phil: Table_Type;
  394.                          State: Phil.States;
  395.                          How_Long: Natural := 0) DO
  396.           T := Integer(Calendar."-"(Calendar.Clock,Start_Time));
  397.           Windows.Put_String(Phil_Windows(Which_Phil),
  398.             "T=" & Integer'Image(T) & " ");
  399.           CASE State IS
  400.             WHEN Phil.Breathing =>
  401.               Windows.Put_String(Phil_Windows(Which_Phil), "Breathing...");
  402.               Windows.New_Line(Phil_Windows(Which_Phil));
  403.  
  404.             WHEN Phil.Thinking =>
  405.               Windows.Put_String(Phil_Windows(Which_Phil),
  406.                          "Thinking"
  407.                          & Integer'Image(How_Long)
  408.                          & " seconds.");
  409.               Windows.New_Line(Phil_Windows(Which_Phil));
  410.  
  411.             WHEN Phil.Eating =>
  412.               Windows.Put_String(Phil_Windows(Which_Phil),
  413.                          "Eating"   
  414.                          & Integer'Image(How_Long)
  415.                          & " seconds.");
  416.               Windows.New_Line(Phil_Windows(Which_Phil));
  417.  
  418.             WHEN Phil.Done_Eating =>
  419.               Windows.Put_String(Phil_Windows(Which_Phil), "Yum-yum (burp)");
  420.               Windows.New_Line(Phil_Windows(Which_Phil));
  421.  
  422.             WHEN Phil.Got_One_Stick =>
  423.               Windows.Put_String(Phil_Windows(Which_Phil), 
  424.                          "First chopstick"
  425.                           & Integer'Image(How_Long));
  426.               Windows.New_Line(Phil_Windows(Which_Phil));
  427.  
  428.             WHEN Phil.Got_Other_Stick =>
  429.               Windows.Put_String(Phil_Windows(Which_Phil), 
  430.                          "Second chopstick"
  431.                           & Integer'Image(How_Long));
  432.               Windows.New_Line(Phil_Windows(Which_Phil));
  433.  
  434.           END CASE;
  435.  
  436.          END Report_State;
  437.         OR
  438.           TERMINATE;
  439.         END SELECT;
  440.  
  441.       END LOOP;
  442.  
  443.     END Head_Waiter;
  444.  
  445. END Room;
  446.