1. with Events.Corrals;                    use Events.Corrals; 
  2. with Events.Listeners;                  use Events.Listeners; 
  3. with Game_States;                       use Game_States; 
  4. with Game_Views;                        use Game_Views; 
  5. with Objects;                           use Objects; 
  6. with Processes;                         use Processes; 
  7.  
  8. private with Actors; 
  9. private with Ada.Containers.Indefinite_Doubly_Linked_Lists; 
  10. private with Ada.Containers.Ordered_Maps; 
  11. private with Associations; 
  12. private with Entities; 
  13. private with Events; 
  14. private with Physics.Managers; 
  15. private with Processes.Managers; 
  16. private with Worlds; 
  17.  
  18. package Games is 
  19.  
  20.     -- The Game class is parent object in the Game Logic system, which is 
  21.     -- responsible for managing the game session and all the interactions 
  22.     -- between entities during gameplay. 
  23.     -- 
  24.     -- The Game provides a Process_Manager to run the game logic, a Corral to 
  25.     -- receive events sent to listeners in the game logic, an association of 
  26.     -- modifyable game session variables, and game session persistence. The Game 
  27.     -- object itself is a Process and Event_Listener that is attached to its own 
  28.     -- Process_Manager and Corral facilities. The Game class also provides a 
  29.     -- limited interface, Game_State, which allow objects to reference it and 
  30.     -- access game state information and game session variables without a full 
  31.     -- view of the Game class, which in some cases would cause circular 
  32.     -- dependencies or allow unnecessary exposing of information. 
  33.     type Game is abstract new Limited_Object and 
  34.                               Event_Listener and 
  35.                               Game_State and 
  36.                               Process with private; 
  37.     type A_Game is access all Game'Class; 
  38.  
  39.     -- Creates a new Game object using the registered allocator. If no 
  40.     -- allocator has been registered, an exception will be raised. 
  41.     function Create_Game return A_Game; 
  42.     pragma Postcondition( Create_Game'Result /= null ); 
  43.  
  44.     -- Adds integer 'val' to game session variable 'var'. A Game_Var_Changed 
  45.     -- event is queued. An exception is raised on error. 
  46.     procedure Game_Var_Add( this : not null access Game'Class; 
  47.                             var  : String; 
  48.                             val  : Integer ); 
  49.     pragma Precondition( var'Length > 0 ); 
  50.  
  51.     -- Returns the Game's event Corral. It is created during Game construction. 
  52.     function Get_Corral( this : not null access Game'Class ) return A_Corral; 
  53.     pragma Postcondition( Get_Corral'Result /= null ); 
  54.  
  55.     -- Returns the value of game session var 'var' as an integer. An exception 
  56.     -- will be raised on error. 
  57.     function Get_Game_Var( this : access Game; var  : String ) return Integer; 
  58.  
  59.     -- Unloads the current world and attaches a newly loaded world to the game 
  60.     -- framework. If an error occurs, an exception will be raised and the 
  61.     -- current world will not change. 
  62.     procedure Load_World( this : access Game; name : String ); 
  63.  
  64.     -- Sets the game's view. 'view' is consumed and then owned by the Game 
  65.     -- object. If the view has already been set, a Constraint_Error will be 
  66.     -- raised and 'view' will not be modified. 
  67.     procedure Set_View( this : not null access Game'Class; 
  68.                         view : in out A_Game_View ); 
  69.     pragma Precondition( view /= null ); 
  70.     pragma Postcondition( view = null ); 
  71.  
  72.     -- Starts the game logic and attaches it to the framework. If the Game's 
  73.     -- view has not been set, a Constraint_Error will be raised. 
  74.     procedure Start( this : access Game ); 
  75.  
  76.     -- Stops the game logic and detaches it from the framework. 
  77.     procedure Stop( this : not null access Game'Class ); 
  78.  
  79.     -- Deletes the Game. 
  80.     procedure Delete( this : in out A_Game ); 
  81.     pragma Postcondition( this = null ); 
  82.  
  83. private 
  84.  
  85.     use Actors; 
  86.     use Associations; 
  87.     use Entities; 
  88.     use Events; 
  89.     use Physics.Managers; 
  90.     use Processes.Managers; 
  91.     use Worlds; 
  92.  
  93.     package Actor_Lists is new Ada.Containers.Indefinite_Doubly_Linked_Lists( A_Actor, "=" ); 
  94.  
  95.     package Actor_Maps is new Ada.Containers.Ordered_Maps( Entity_Id, A_Actor, "<", "=" ); 
  96.  
  97.     ---------------------------------------------------------------------------- 
  98.  
  99.     type Game is abstract new Limited_Object and 
  100.                               Event_Listener and 
  101.                               Game_State and 
  102.                               Process with 
  103.         record 
  104.             started, 
  105.             stopped     : Boolean := False; 
  106.             view        : A_Game_View := null; 
  107.             corral      : A_Corral := null; 
  108.             physics     : A_Physics := null; 
  109.             pman        : A_Process_Manager := null; 
  110.             sessionVars : A_Association := null; 
  111.             world       : A_World := null; 
  112.             actors      : Actor_Lists.List; 
  113.             actorIndex  : Actor_Maps.Map; 
  114.             playing     : Boolean := False; 
  115.             paused      : Boolean := False; 
  116.         end record; 
  117.  
  118.     -- Adds the Game object as an event listener for a set of events. Override 
  119.     -- this procedure, calling it first, to listen for additional events. 
  120.     procedure Add_Event_Listeners( this : access Game ); 
  121.  
  122.     procedure Construct( this : access Game ); 
  123.  
  124.     procedure Delete( this : in out Game ); 
  125.  
  126.     -- Ends the current game session. Game logic is stopped and a Game_State 
  127.     -- event is sent. 
  128.     procedure End_Game( this : access Game ); 
  129.  
  130.     -- Returns the Process name of the Game object. 
  131.     function Get_Process_Name( this : access Game ) return String; 
  132.     pragma Postcondition( Get_Process_Name'Result'Length > 0 ); 
  133.  
  134.     -- Handles the events that the Game is registered to receive from its Corral. 
  135.     procedure Handle_Event( this : access Game; 
  136.                             evt  : in out A_Event; 
  137.                             resp : out Response_Type ); 
  138.     pragma Precondition( evt /= null ); 
  139.  
  140.     -- Unloads the current world and attaches 'world' to the game framework. 
  141.     -- 'world' will be consumed. 
  142.     procedure Load_World( this  : not null access Game'Class; 
  143.                           world : in out A_World ); 
  144.     pragma Postcondition( world = null ); 
  145.  
  146.     -- Begins a new game session from the start. Override this procedure to 
  147.     -- setup initial game state and load the first game world. An overriding 
  148.     -- implementation must call this first. 
  149.     procedure New_Game( this : access Game ); 
  150.  
  151.     -- Pauses the gameplay. An overriding implementation must call this first. 
  152.     -- It will set the paused field in the Game to 'enabled'. 
  153.     procedure Pause( this : access Game; enabled : Boolean ); 
  154.  
  155.     -- Removes the Game object as an event listener for a set of events. If 
  156.     -- Add_Event_Listener is overridden, then this should be overridden to 
  157.     -- remove the additional specific events. An overriding implementation must 
  158.     -- call this last. 
  159.     procedure Remove_Event_Listeners( this : access Game ); 
  160.  
  161.     -- Sets game session variable 'var' to integer 'val'. A Game_Var_Changed 
  162.     -- event is queued. 
  163.     procedure Set_Game_Var( this : not null access Game'Class; 
  164.                             var  : String; 
  165.                             val  : Integer ); 
  166.     pragma Precondition( var'Length > 0 ); 
  167.  
  168.     -- Sets game session variable 'var' to boolean 'val'. A Game_Var_Changed 
  169.     -- event is queued. 
  170.     procedure Set_Game_Var( this : not null access Game'Class; 
  171.                             var  : String; 
  172.                             val  : Boolean ); 
  173.     pragma Precondition( var'Length > 0 ); 
  174.  
  175.     -- Executes one frame of Game logic. Implement this procedure to perform 
  176.     -- logic at the Game scope. 
  177.     procedure Tick( this : access Game; time : Tick_Time ) is null; 
  178.  
  179.     -- Unloads the current world, detaching it from the game framework and 
  180.     -- and deleting temporal actors. 
  181.     procedure Unload_World( this : not null access Game'Class ); 
  182.  
  183.     ---------------------------------------------------------------------------- 
  184.  
  185.     -- A allocator for a concrete Game implementation. 
  186.     type Allocator is access function return A_Game; 
  187.  
  188.     -- Registers the allocator function used by Create_Game to create an 
  189.     -- instance of the appropriate concrete Game subclass. This should be called 
  190.     -- at elaboration time. 
  191.     procedure Register_Allocator( allocate : not null Allocator ); 
  192.  
  193. end Games;