Section 16.5. The example program dist.ada
is not correct. The designated type of a remote access type
must be limited private by E.2.2(9). If you make it limited
private, then the RCI packages are not correct because
they may not define a limited type by E.2.3(11).
You need an extra level of indirection as shown in the following program.
This problem was not caught on version 3.10p of GNAT that I used.
(Jack Flynn.)
--
-- Distributed dispatching.
--
package Root_Event is
pragma Remote_Types;
type Event is abstract tagged limited private;
type Event_Ptr is access all Event'Class;
procedure Simulate(E: in Event) is abstract;
private
type Event is abstract tagged limited null record;
end Root_Event;
with Root_Event;
package Simulation_Server is
pragma Remote_Call_Interface;
procedure Go_Simulate(E_Ptr: Root_Event.Event_Ptr);
end Simulation_Server;
package body Simulation_Server is
procedure Go_Simulate(E_Ptr: Root_Event.Event_Ptr) is
begin
Root_Event.Simulate(E_Ptr.all);
end Go_Simulate;
end Simulation_Server;
package Root_Event.Engine is
type Engine_Event is new Event with private;
function Create(F, O: Natural) return Event_Ptr;
procedure Simulate(E: in Engine_Event);
private
type Engine_Ptr is access all Engine_Event;
type Engine_Event is new Event with
record
Fuel, Oxygen: Natural;
end record;
end Root_Event.Engine;
with Ada.Text_IO; use Ada.Text_IO;
package body Root_Event.Engine is
function Create(F, O: Natural) return Event_Ptr is
E: Engine_Ptr := new Engine_Event;
begin
E.Fuel := F; E.Oxygen := O;
return Event_Ptr(E);
end Create;
procedure Simulate(E: in Engine_Event) is
begin
Put_Line("Engine fuel " & Integer'Image(E.Fuel) &
" L, oxygen " & Integer'Image(E.Oxygen) & " L");
end Simulate;
end Root_Event.Engine;
package Root_Event.Telemetry is
type Telemetry_Event is new Event with private;
type Subsystems is (Engines, Guidance, Communications);
type States is (OK, Failed);
function Create(Sub: Subsystems; St: States) return Event_Ptr;
procedure Simulate(E: in Telemetry_Event);
private
type Telemetry_Ptr is access all Telemetry_Event;
type Telemetry_Event is new Event with
record
ID: Subsystems;
Status: States;
end record;
end Root_Event.Telemetry;
with Ada.Text_IO; use Ada.Text_IO;
package body Root_Event.Telemetry is
function Create(Sub: Subsystems; St: States) return Event_Ptr is
E: Telemetry_Ptr := new Telemetry_Event;
begin
E.ID := Sub; E.Status := St;
return Event_Ptr(E);
end Create;
procedure Simulate(E: in Telemetry_Event) is
begin
Put_Line("Telemetry message " &
Subsystems'Image(E.ID) & " " &
States'Image(E.Status));
end Simulate;
end Root_Event.Telemetry;
with Root_Event;
with Simulation_Server;
with Root_Event.Telemetry; with Root_Event.Engine;
with Ada.Text_IO; use Ada.Text_IO;
procedure Dist is
function Get_Event return Root_Event.Event_Ptr is
C: Character;
begin
Put(" Choose system "); Get(C);
if C = 'e' then
return Root_Event.Engine.Create(500, 600);
else
return Root_Event.Telemetry.Create(
Root_Event.Telemetry.Engines,
Root_Event.Telemetry.Failed);
end if;
end Get_Event;
begin
Simulation_Server.Go_Simulate(Get_Event);
end Dist;