with Events.Corrals; use Events.Corrals;
with Events.Listeners; use Events.Listeners;
with Objects; use Objects;
with Processes; use Processes;
with Widgets; use Widgets;
with Widgets.Containers.Windows; use Widgets.Containers.Windows;
private with Ada.Containers.Indefinite_Hashed_Maps;
private with Ada.Strings.Hash_Case_Insensitive;
private with Audio_Players;
private with Events;
private with Input_Handlers;
private with Processes.Managers;
private with Renderers;
package Game_Views is
-- The Game_View class is parent object in the View system, which is
-- responsible for managing all user input/output for the game. This
-- includes receiving mouse and keyboard input, rendering the screen and
-- playing audio. No game logic is performed by the view, it only receives
-- input and displays a view of the current game state (graphically and
-- audibly) for the user.
--
-- The Game_View provides a Process_Manager to service the view system, a
-- Corral to receive events sent to listeners in the view, and a various
-- child objects to handle screen drawing, input capturing, and audio
-- playback. The Game_View itself is a Process and Event_Listener that is
-- attached to its own Process_Manager and Corral facilities.
type Game_View is abstract new Limited_Object and
Event_Listener and
Process with private;
type A_Game_View is access all Game_View'Class;
pragma No_Strict_Aliasing( A_Game_View );
-- Creates and returns a new Game_View object using the registered allocator
-- function. An exception will be raised if no allocator is registered.
function Create_Game_View( xres, yres : Positive;
scale : Positive ) return A_Game_View;
pragma Postcondition( Create_Game_View'Result /= null );
-- Attachs a Process to the view's Process_Manager.
procedure Attach( this : not null access Game_View'Class;
process : not null A_Process );
-- Detaches a Process from the view's Process_Manager.
procedure Detach( this : not null access Game_View'Class;
process : not null A_Process );
-- Returns the view's Corral. The view creates its corral at construction.
function Get_Corral( this : not null access Game_View'Class ) return A_Corral;
pragma Postcondition( Get_Corral'Result /= null );
-- Returns a widget in the registry by id. Raises exception ID_NOT_FOUND if
-- the widget does not exist.
function Get_Widget( this : not null access Game_View'Class;
id : String ) return A_Widget;
pragma Postcondition( Get_Widget'Result /= null );
-- Returns the view's Window widget. This will return null if the window has
-- not yet been set.
function Get_Window( this : not null access Game_View'Class ) return A_Window;
-- Adds a widget to the view's widget registry. Raises exception
-- DUPLICATE_ID if a widget with the same id is already registered.
procedure Register( this : not null access Game_View'Class;
widget : not null A_Widget );
-- Sets the view's Window widget. If 'window' is null, the view's Window
-- will be removed. The window can only be set before the view is started.
-- All attempts to change the window after the view has been started will be
-- ignored and 'window' will be deleted. The view's Renderer is deleted and
-- recreated when its Window is changed. If this procedure raises an
-- exception, the view will be left without a Window and the given 'window'
-- reference will remain unchanged.
procedure Set_Window( this : not null access Game_View'Class;
window : in out A_Window );
pragma Postcondition( window = null );
-- Starts the game view, attaching it to the framework. This will attach
-- event listeners, processes, start the view's subsystems (audio, etc)
-- and begin running the view's Process_Manager. If the view has already
-- been started then this will do nothing. Start_View will be called at the
-- end of this procedure.
procedure Start( this : not null access Game_View'Class );
-- Stops the game view, detaching it from the framework. This must be called
-- after Start and before deleting the object. If the view has not been
-- started or has already been stopped, this will do nothing. Stop_View will
-- be called at the beginning of this procedure.
procedure Stop( this : not null access Game_View'Class );
-- Removes a widget from the view's registry. If the widget is not
-- registered, nothing happens.
procedure Unregister( this : not null access Game_View'Class; id : String );
pragma Precondition( id'Length > 0 );
-- Deletes the Game_View.
procedure Delete( this : in out A_Game_View );
pragma Postcondition( this = null );
----------------------------------------------------------------------------
-- raised on attempt to register a widget with a duplicate id
DUPLICATE_ID : exception;
-- raised on attempt to access an registered widget by id
ID_NOT_FOUND : exception;
private
use Audio_Players;
use Events;
use Input_Handlers;
use Processes.Managers;
use Renderers;
-- A Widget_Registry maps widget ids to widget references. The registry will
-- contain references to all created widgets, whether they are parented or
-- not.
package Widget_Registry is new Ada.Containers.Indefinite_Hashed_Maps(
String, A_Widget, Ada.Strings.Hash_Case_Insensitive, "=", "=" );
use Widget_Registry;
-----------------------------------------------------------------------------
type Game_View is abstract new Limited_Object and
Event_Listener and
Process with
record
started,
stopped : Boolean := False;
paused : Boolean := False;
win : A_Window := null;
renderer : A_Renderer := null;
audioPlayer : A_Audio_Player := null;
inhandler : A_Input_Handler := null;
pman : A_Process_Manager := null;
corral : A_Corral := null;
widgets : Widget_Registry.Map;
end record;
procedure Construct( this : access Game_View );
procedure Delete( this : in out Game_View );
function Get_Process_Name( this : access Game_View ) return String;
pragma Postcondition( Get_Process_Name'Result'Length > 0 );
-- Called when the window is requested to close by the OS. The default
-- implementation is to simply queue a Queue_Close_Window message which will
-- exit the application. Override this procedure if a confirmation dialog
-- or some other activity must happen instead.
procedure Handle_Close_Request( this : access Game_View );
-- Handles all events that the Game_View is registered to receive.
procedure Handle_Event( this : access Game_View;
evt : in out A_Event;
resp : out Response_Type );
pragma Precondition( evt /= null );
-- Called when resource loading is beginning and ending. Override this
-- procedure to display a message, etc during loading.
procedure Handle_Loading( this : access Game_View; loading : Boolean ) is null;
-- Called when the game logic is paused or resumed. Override this procedure
-- to perform actions when the game pause state changes.
procedure Handle_Paused( this : access Game_View; paused : Boolean ) is null;
-- Called as part of Start, this procedure can be overridden to add the view
-- as a listener for various events or anything else that needs to be done
-- at start time.
procedure Start_View( this : access Game_View ) is null;
-- Called as part of Stop, this procedure can be overridden to do anything
-- that needs to be done at stop time. For example, any events the view was
-- registered to receive in Start_View should be unregistered here.
procedure Stop_View( this : access Game_View ) is null;
-- Executes the Game_View logic. Overriding implementations must call this
-- first.
procedure Tick( this : access Game_View; time : Tick_Time );
----------------------------------------------------------------------------
-- An allocator function for a concrete Game_View implemenation. 'xres' and
-- 'yres' are the requested application resolution. 'scale' is a multiplier
-- to enlarge small resolutions. For example, if the view requested a
-- 320x200 resolution, a scale of 2 would cause the application to actually
-- display a 640x400 window and upscale the contents. The view would draw to
-- the window as though it were the requested resolution.
type Allocator is
access function( xres, yres : Positive;
scale : Positive ) return A_Game_View;
-- Registers the allocator function used by Create_Game_View to create an
-- instance of the appropriate concrete Game_View subclass. This should be
-- called at elaboration time.
procedure Register_Allocator( allocate : not null Allocator );
end Game_Views;