1. -- 
  2. -- Copyright (c) 2012 Kevin Wellwood 
  3. -- All rights reserved. 
  4. -- 
  5. -- This source code is distributed under the Modified BSD License. For terms and 
  6. -- conditions, see license.txt. 
  7. -- 
  8.  
  9. with Events.Corrals;                    use Events.Corrals; 
  10. with Events.Listeners;                  use Events.Listeners; 
  11. with Objects;                           use Objects; 
  12. with Processes;                         use Processes; 
  13.  
  14. private with Ada.Containers.Doubly_Linked_Lists; 
  15. private with Ada.Containers.Ordered_Maps; 
  16. private with Entities; 
  17. private with Events; 
  18. private with Physics.Bodies; 
  19. private with Physics.Clip_Maps; 
  20.  
  21. package Physics.Managers is 
  22.  
  23.     -- The Physics_Manager class is responsible for simulating physical 
  24.     -- interaction between the entities and between entities and the world. A 
  25.     -- physics manager listens for world and entity events. It represents the 
  26.     -- world's tile map with a Clip_Map object contains physical information 
  27.     -- about the world based on tile attributes: solid walls, slopes, etc. 
  28.     -- Entities in the world are represented as Corpus objects, modelling only 
  29.     -- the location, size, and physical attributes of their corresponding 
  30.     -- entities. The physics manager runs as a Process that updates position, 
  31.     -- velocity, and acceleration of entities, simulates the effects of gravity 
  32.     -- and friction, and generates events when entities collide and separate. 
  33.     type Physics_Manager is new Object and Process and Event_Listener with private; 
  34.     type A_Physics is access all Physics_Manager'Class; 
  35.  
  36.     -- Creates a new physics manager attached to the given Corral. 
  37.     function Create_Physics( corral : not null A_Corral ) return A_Physics; 
  38.     pragma Postcondition( Create_Physics'Result /= null ); 
  39.  
  40.     -- Sets the friction in the X axis for entities handled by this physics 
  41.     -- manager. 
  42.     function Friction_X( this : not null access Physics_Manager'Class ) return Float; 
  43.  
  44.     -- Sets the friction in the Y axis for entities handled by this physics 
  45.     -- manager. 
  46.     function Friction_Y( this : not null access Physics_Manager'Class ) return Float; 
  47.  
  48.     -- Sets the gravitional acceleration for entities handled by this physics 
  49.     -- manager. 
  50.     function Gravity( this : not null access Physics_Manager'Class ) return Float; 
  51.  
  52.     -- Sets the maximum velocity in the X axis for entities handled by this 
  53.     -- physics manager. 
  54.     function Max_VX( this : not null access Physics_Manager'Class ) return Float; 
  55.  
  56.     -- Sets the maximum velocity in the Y axis for entities handled by this 
  57.     -- physics manager. 
  58.     function Max_VY( this : not null access Physics_Manager'Class ) return Float; 
  59.  
  60.     -- Deletes the physics manager and all its data (clip map, corps, etc.) 
  61.     procedure Delete( this : in out A_Physics ); 
  62.     pragma Postcondition( this = null ); 
  63.  
  64. private 
  65.  
  66.     use Entities; 
  67.     use Events; 
  68.     use Physics.Bodies; 
  69.     use Physics.Clip_Maps; 
  70.  
  71.     package Corpus_Map is new 
  72.         Ada.Containers.Ordered_Maps( Entity_Id, A_Corpus, "<", "=" ); 
  73.  
  74.     package Corpus_Lists is new 
  75.         Ada.Containers.Doubly_Linked_Lists( A_Corpus, "=" ); 
  76.  
  77.     ---------------------------------------------------------------------------- 
  78.  
  79.     type Physics_Manager is new Object and Process and Event_Listener with 
  80.         record 
  81.             corral : A_Corral := null; 
  82.             map    : A_Clip_Map := null; 
  83.             corps  : Corpus_Map.Map; 
  84.             grav   : Float := 0.0; 
  85.             fricX, 
  86.             fricY  : Float := 0.0; 
  87.             maxVX, 
  88.             maxVY  : Float := 0.0; 
  89.         end record; 
  90.  
  91.     procedure Construct( this   : access Physics_Manager; 
  92.                          corral : not null A_Corral ); 
  93.  
  94.     procedure Delete( this : in out Physics_Manager ); 
  95.  
  96.     -- Returns a name identifying the physics manager as a process. 
  97.     function Get_Process_Name( this : access Physics_Manager ) return String; 
  98.     pragma Postcondition( Get_Process_Name'Result'Length > 0 ); 
  99.  
  100.     -- Handles an event received by the physics manager, dispatching it to the 
  101.     -- appropriate Handle procedure. 
  102.     procedure Handle_Event( this : access Physics_Manager; 
  103.                             evt  : in out A_Event; 
  104.                             resp : out Response_Type ); 
  105.     pragma Precondition( evt /= null ); 
  106.  
  107.     -- Ticks every Corpus to update its state and then detects collisions. 
  108.     procedure Tick( this : access Physics_Manager; time : Tick_Time ); 
  109.  
  110. end Physics.Managers;