1. with Events.Corrals;                    use Events.Corrals; 
  2. with Events.Listeners;                  use Events.Listeners; 
  3. with Objects;                           use Objects; 
  4. with Processes;                         use Processes; 
  5. with Widgets;                           use Widgets; 
  6. with Widgets.Containers.Windows;        use Widgets.Containers.Windows; 
  7.  
  8. private with Ada.Containers.Indefinite_Hashed_Maps; 
  9. private with Ada.Strings.Hash_Case_Insensitive; 
  10. private with Audio_Players; 
  11. private with Events; 
  12. private with Input_Handlers; 
  13. private with Processes.Managers; 
  14. private with Renderers; 
  15.  
  16. package Game_Views is 
  17.  
  18.     -- The Game_View class is parent object in the View system, which is 
  19.     -- responsible for managing all user input/output for the game. This 
  20.     -- includes receiving mouse and keyboard input, rendering the screen and 
  21.     -- playing audio. No game logic is performed by the view, it only receives 
  22.     -- input and displays a view of the current game state (graphically and 
  23.     -- audibly) for the user. 
  24.     -- 
  25.     -- The Game_View provides a Process_Manager to service the view system, a 
  26.     -- Corral to receive events sent to listeners in the view, and a various 
  27.     -- child objects to handle screen drawing, input capturing, and audio 
  28.     -- playback. The Game_View itself is a Process and Event_Listener that is 
  29.     -- attached to its own Process_Manager and Corral facilities. 
  30.     type Game_View is abstract new Limited_Object and 
  31.                                    Event_Listener and 
  32.                                    Process with private; 
  33.     type A_Game_View is access all Game_View'Class; 
  34.     pragma No_Strict_Aliasing( A_Game_View ); 
  35.  
  36.     -- Creates and returns a new Game_View object using the registered allocator 
  37.     -- function. An exception will be raised if no allocator is registered. 
  38.     function Create_Game_View( xres, yres : Positive; 
  39.                                scale      : Positive ) return A_Game_View; 
  40.     pragma Postcondition( Create_Game_View'Result /= null ); 
  41.  
  42.     -- Attachs a Process to the view's Process_Manager. 
  43.     procedure Attach( this    : not null access Game_View'Class; 
  44.                       process : not null A_Process ); 
  45.  
  46.     -- Detaches a Process from the view's Process_Manager. 
  47.     procedure Detach( this    : not null access Game_View'Class; 
  48.                       process : not null A_Process ); 
  49.  
  50.     -- Returns the view's Corral. The view creates its corral at construction. 
  51.     function Get_Corral( this : not null access Game_View'Class ) return A_Corral; 
  52.     pragma Postcondition( Get_Corral'Result /= null ); 
  53.  
  54.     -- Returns a widget in the registry by id. Raises exception ID_NOT_FOUND if 
  55.     -- the widget does not exist. 
  56.     function Get_Widget( this : not null access Game_View'Class; 
  57.                          id   : String ) return A_Widget; 
  58.     pragma Postcondition( Get_Widget'Result /= null ); 
  59.  
  60.     -- Returns the view's Window widget. This will return null if the window has 
  61.     -- not yet been set. 
  62.     function Get_Window( this : not null access Game_View'Class ) return A_Window; 
  63.  
  64.     -- Adds a widget to the view's widget registry. Raises exception 
  65.     -- DUPLICATE_ID if a widget with the same id is already registered. 
  66.     procedure Register( this   : not null access Game_View'Class; 
  67.                         widget : not null A_Widget ); 
  68.  
  69.     -- Sets the view's Window widget. If 'window' is null, the view's Window 
  70.     -- will be removed. The window can only be set before the view is started. 
  71.     -- All attempts to change the window after the view has been started will be 
  72.     -- ignored and 'window' will be deleted. The view's Renderer is deleted and 
  73.     -- recreated when its Window is changed. If this procedure raises an 
  74.     -- exception, the view will be left without a Window and the given 'window' 
  75.     -- reference will remain unchanged. 
  76.     procedure Set_Window( this   : not null access Game_View'Class; 
  77.                           window : in out A_Window ); 
  78.     pragma Postcondition( window = null ); 
  79.  
  80.     -- Starts the game view, attaching it to the framework. This will attach 
  81.     -- event listeners, processes, start the view's subsystems (audio, etc) 
  82.     -- and begin running the view's Process_Manager. If the view has already 
  83.     -- been started then this will do nothing. Start_View will be called at the 
  84.     -- end of this procedure. 
  85.     procedure Start( this : not null access Game_View'Class ); 
  86.  
  87.     -- Stops the game view, detaching it from the framework. This must be called 
  88.     -- after Start and before deleting the object. If the view has not been 
  89.     -- started or has already been stopped, this will do nothing. Stop_View will 
  90.     -- be called at the beginning of this procedure. 
  91.     procedure Stop( this : not null access Game_View'Class ); 
  92.  
  93.     -- Removes a widget from the view's registry. If the widget is not 
  94.     -- registered, nothing happens. 
  95.     procedure Unregister( this : not null access Game_View'Class; id : String ); 
  96.     pragma Precondition( id'Length > 0 ); 
  97.  
  98.     -- Deletes the Game_View. 
  99.     procedure Delete( this : in out A_Game_View ); 
  100.     pragma Postcondition( this = null ); 
  101.  
  102.     ---------------------------------------------------------------------------- 
  103.  
  104.     -- raised on attempt to register a widget with a duplicate id 
  105.     DUPLICATE_ID : exception; 
  106.  
  107.     -- raised on attempt to access an registered widget by id 
  108.     ID_NOT_FOUND : exception; 
  109.  
  110. private 
  111.  
  112.     use Audio_Players; 
  113.     use Events; 
  114.     use Input_Handlers; 
  115.     use Processes.Managers; 
  116.     use Renderers; 
  117.  
  118.     -- A Widget_Registry maps widget ids to widget references. The registry will 
  119.     -- contain references to all created widgets, whether they are parented or 
  120.     -- not. 
  121.     package Widget_Registry is new Ada.Containers.Indefinite_Hashed_Maps( 
  122.         String, A_Widget, Ada.Strings.Hash_Case_Insensitive, "=", "=" ); 
  123.     use Widget_Registry; 
  124.  
  125.     ----------------------------------------------------------------------------- 
  126.  
  127.     type Game_View is abstract new Limited_Object and 
  128.                                    Event_Listener and 
  129.                                    Process with 
  130.         record 
  131.             started, 
  132.             stopped     : Boolean := False; 
  133.             paused      : Boolean := False; 
  134.             win         : A_Window := null; 
  135.             renderer    : A_Renderer := null; 
  136.             audioPlayer : A_Audio_Player := null; 
  137.             inhandler   : A_Input_Handler := null; 
  138.             pman        : A_Process_Manager := null; 
  139.             corral      : A_Corral := null; 
  140.             widgets     : Widget_Registry.Map; 
  141.         end record; 
  142.  
  143.     procedure Construct( this : access Game_View ); 
  144.  
  145.     procedure Delete( this : in out Game_View ); 
  146.  
  147.     function Get_Process_Name( this : access Game_View ) return String; 
  148.     pragma Postcondition( Get_Process_Name'Result'Length > 0 ); 
  149.  
  150.     -- Called when the window is requested to close by the OS. The default 
  151.     -- implementation is to simply queue a Queue_Close_Window message which will 
  152.     -- exit the application. Override this procedure if a confirmation dialog 
  153.     -- or some other activity must happen instead. 
  154.     procedure Handle_Close_Request( this : access Game_View ); 
  155.  
  156.     -- Handles all events that the Game_View is registered to receive. 
  157.     procedure Handle_Event( this : access Game_View; 
  158.                             evt  : in out A_Event; 
  159.                             resp : out Response_Type ); 
  160.     pragma Precondition( evt /= null ); 
  161.  
  162.     -- Called when resource loading is beginning and ending. Override this 
  163.     -- procedure to display a message, etc during loading. 
  164.     procedure Handle_Loading( this : access Game_View; loading : Boolean ) is null; 
  165.  
  166.     -- Called when the game logic is paused or resumed. Override this procedure 
  167.     -- to perform actions when the game pause state changes. 
  168.     procedure Handle_Paused( this : access Game_View; paused : Boolean ) is null; 
  169.  
  170.     -- Called as part of Start, this procedure can be overridden to add the view 
  171.     -- as a listener for various events or anything else that needs to be done 
  172.     -- at start time. 
  173.     procedure Start_View( this : access Game_View ) is null; 
  174.  
  175.     -- Called as part of Stop, this procedure can be overridden to do anything 
  176.     -- that needs to be done at stop time. For example, any events the view was 
  177.     -- registered to receive in Start_View should be unregistered here. 
  178.     procedure Stop_View( this : access Game_View ) is null; 
  179.  
  180.     -- Executes the Game_View logic. Overriding implementations must call this 
  181.     -- first. 
  182.     procedure Tick( this : access Game_View; time : Tick_Time ); 
  183.  
  184.     ---------------------------------------------------------------------------- 
  185.  
  186.     -- An allocator function for a concrete Game_View implemenation. 'xres' and 
  187.     -- 'yres' are the requested application resolution. 'scale' is a multiplier 
  188.     -- to enlarge small resolutions. For example, if the view requested a 
  189.     -- 320x200 resolution, a scale of 2 would cause the application to actually 
  190.     -- display a 640x400 window and upscale the contents. The view would draw to 
  191.     -- the window as though it were the requested resolution. 
  192.     type Allocator is 
  193.         access function( xres, yres : Positive; 
  194.                          scale      : Positive ) return A_Game_View; 
  195.  
  196.     -- Registers the allocator function used by Create_Game_View to create an 
  197.     -- instance of the appropriate concrete Game_View subclass. This should be 
  198.     -- called at elaboration time. 
  199.     procedure Register_Allocator( allocate : not null Allocator ); 
  200.  
  201. end Game_Views;