with Text_IO; package body Broker is T : array (Nickname) of Terminal_Access; procedure Broadcast (Customer : in Nickname; News : in String) is Item : constant String := Customer & " | " & News; begin for Who in Nickname loop if T(Who) /= null and then Who /= Customer then Text_IO.Put_Line (Item); Term_IF.Notify (T(Who), Item); end if; end loop; end; procedure Register (Customer : in Nickname; Terminal : in Terminal_Access) is begin T (Customer) := Terminal; end; end Broker; with Term_IF; package Broker is pragma Remote_Call_Interface; type Terminal_Access is access all Term_IF.Terminal_Type'Class; subtype Nickname is Character range 'a'..'z'; -- -- Customer Registers at Terminal -- procedure Register (Customer : in Nickname; Terminal : in Terminal_Access); -- -- Customer Broadcasts News to others -- procedure Broadcast (Customer : in Nickname; News : in String); end Broker; with Term_IF; package Term is -- -- Invokes a chat terminal -- procedure Talk (Me : in Character); private type T is new Term_IF.Terminal_Type with null record; -- -- Will be Notified of News through terminal T -- procedure Notify (Terminal : access T; News : in String); end Term; with Text_IO; with Broker; package body Term is procedure Notify (Terminal : access T; News : in String) is begin Text_IO.Put_Line (News); end; My_Terminal : aliased T; procedure Talk (Me : in Character) is Str : String(1..80); Len : Integer; begin Text_IO.Put_Line("Starting " & Me); Broker.Register (Me, My_Terminal'Access); loop Text_IO.Get_Line (Str, Len); Broker.Broadcast (Me, Str(1..Len)); end loop; end; end Term; with Term; with Ada.Command_Line; with Text_IO; procedure Client is Me : Character; begin if Ada.Command_Line.Argument_Count > 0 then Me := Ada.Command_Line.Argument(1) (1); Term.Talk (Me); else Text_IO.Put_Line ("Must input a character nickname."); end if; end; with Broker; procedure Server is begin loop delay 10.0; end loop; end; package Term_IF is pragma Pure; type Terminal_Type is abstract tagged limited private; procedure Notify (Terminal : access Terminal_Type; News : in String) is abstract; private type Terminal_Type is abstract tagged limited null record; end;