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.  
  6. private with Ada.Containers.Doubly_Linked_Lists; 
  7. private with Ada.Containers.Ordered_Maps; 
  8. private with Entities; 
  9. private with Events; 
  10. private with Events.Entities; 
  11. private with Events.World; 
  12. private with Physics.Bodies; 
  13. private with Physics.Clip_Maps; 
  14.  
  15. package Physics.Managers is 
  16.  
  17.     -- The Physics_Manager class is responsible for simulating physical 
  18.     -- interaction between the entities and between entities and the world. A 
  19.     -- physics manager listens for world and entity events. It represents the 
  20.     -- world's tile map with a Clip_Map object contains physical information 
  21.     -- about the world based on tile attributes: solid walls, slopes, etc. 
  22.     -- Entities in the world are represented as Corpus objects, modelling only 
  23.     -- the location, size, and physical attributes of their corresponding 
  24.     -- entities. The physics manager runs as a Process that updates position, 
  25.     -- velocity, and acceleration of entities, simulates the effects of gravity 
  26.     -- and friction, and generates events when entities collide and separate. 
  27.     type Physics_Manager is new Object and Process and Event_Listener with private; 
  28.     type A_Physics is access all Physics_Manager'Class; 
  29.  
  30.     -- Creates a new physics manager attached to the given Corral. 
  31.     function Create_Physics( corral : not null A_Corral ) return A_Physics; 
  32.     pragma Postcondition( Create_Physics'Result /= null ); 
  33.  
  34.     -- Sets the friction in the X axis for entities handled by this physics 
  35.     -- manager. 
  36.     function Friction_X( this : not null access Physics_Manager'Class ) return Float; 
  37.  
  38.     -- Sets the friction in the Y axis for entities handled by this physics 
  39.     -- manager. 
  40.     function Friction_Y( this : not null access Physics_Manager'Class ) return Float; 
  41.  
  42.     -- Sets the gravitional acceleration for entities handled by this physics 
  43.     -- manager. 
  44.     function Gravity( this : not null access Physics_Manager'Class ) return Float; 
  45.  
  46.     -- Sets the maximum velocity in the X axis for entities handled by this 
  47.     -- physics manager. 
  48.     function Max_VX( this : not null access Physics_Manager'Class ) return Float; 
  49.  
  50.     -- Sets the maximum velocity in the Y axis for entities handled by this 
  51.     -- physics manager. 
  52.     function Max_VY( this : not null access Physics_Manager'Class ) return Float; 
  53.  
  54.     -- Deletes the physics manager and all its data (clip map, corps, etc.) 
  55.     procedure Delete( this : in out A_Physics ); 
  56.     pragma Postcondition( this = null ); 
  57.  
  58. private 
  59.  
  60.     use Entities; 
  61.     use Events; 
  62.     use Events.Entities; 
  63.     use Events.World; 
  64.     use Physics.Bodies; 
  65.     use Physics.Clip_Maps; 
  66.  
  67.     package Corpus_Map is new 
  68.         Ada.Containers.Ordered_Maps( Entity_Id, A_Corpus, "<", "=" ); 
  69.  
  70.     package Corpus_Lists is new 
  71.         Ada.Containers.Doubly_Linked_Lists( A_Corpus, "=" ); 
  72.  
  73.     ---------------------------------------------------------------------------- 
  74.  
  75.     type Physics_Manager is new Object and Process and Event_Listener with 
  76.         record 
  77.             corral : A_Corral := null; 
  78.             map    : A_Clip_Map := null; 
  79.             corps  : Corpus_Map.Map; 
  80.             grav   : Float := 0.0; 
  81.             fricX, 
  82.             fricY  : Float := 0.0; 
  83.             maxVX, 
  84.             maxVY  : Float := 0.0; 
  85.         end record; 
  86.  
  87.     -- Deletes all Corps from the physics manager. 
  88.     procedure Clear_Corps( this : not null access Physics_Manager'Class ); 
  89.  
  90.     procedure Construct( this   : access Physics_Manager; 
  91.                          corral : not null A_Corral ); 
  92.  
  93.     procedure Delete( this : in out Physics_Manager ); 
  94.  
  95.     -- Finds a Corpus by entity id, or returns null if its not found. 
  96.     function Find( this : not null access Physics_Manager'Class; 
  97.                    id   : Entity_Id ) return A_Corpus; 
  98.  
  99.     -- Returns a name identifying the physics manager as a process. 
  100.     function Get_Process_Name( this : access Physics_Manager ) return String; 
  101.     pragma Postcondition( Get_Process_Name'Result'Length > 0 ); 
  102.  
  103.      -- Handles Accelerate command events. 
  104.     procedure Handle( this : not null access Physics_Manager'Class; 
  105.                       evt  : not null A_Accelerate_Event ); 
  106.  
  107.      -- Handles Entity_Created notification events. 
  108.     procedure Handle( this : not null access Physics_Manager'Class; 
  109.                       evt  : not null A_Entity_Created_Event ); 
  110.  
  111.      -- Handles Entity_Deleted notification events. 
  112.     procedure Handle( this : not null access Physics_Manager'Class; 
  113.                       evt  : not null A_Entity_Deleted_Event ); 
  114.  
  115.      -- Handles Move_Entity command events. 
  116.     procedure Handle( this : not null access Physics_Manager'Class; 
  117.                       evt  : not null A_Move_Entity_Event ); 
  118.  
  119.      -- Handles New_World notification events. 
  120.     procedure Handle( this : not null access Physics_Manager'Class; 
  121.                       evt  : not null A_New_World_Event ); 
  122.  
  123.      -- Handles Resize_Entity command events. 
  124.     procedure Handle( this : not null access Physics_Manager'Class; 
  125.                       evt  : not null A_Resize_Entity_Event ); 
  126.  
  127.      -- Handles Set_Entity_Attribute command events. 
  128.    procedure Handle( this : not null access Physics_Manager'Class; 
  129.                       evt  : not null A_Set_Entity_Attribute_Event ); 
  130.  
  131.     -- Handles Tile_Changed notification events. 
  132.     procedure Handle( this : not null access Physics_Manager'Class; 
  133.                       evt  : not null A_Tile_Changed_Event ); 
  134.  
  135.     -- Handles World_Property_Changed notification events. 
  136.     procedure Handle( this : not null access Physics_Manager'Class; 
  137.                       evt  : not null A_World_Property_Changed_Event ); 
  138.  
  139.     -- Handles an event received by the physics manager, dispatching it to the 
  140.     -- appropriate Handle procedure. 
  141.     procedure Handle_Event( this : access Physics_Manager; 
  142.                             evt  : in out A_Event; 
  143.                             resp : out Response_Type ); 
  144.     pragma Precondition( evt /= null ); 
  145.  
  146.     -- Ticks every Corpus to update its state and then detects collisions. 
  147.     procedure Tick( this : access Physics_Manager; time : Tick_Time ); 
  148.  
  149. end Physics.Managers;