1. generic 
  2.     type Entity_Class (<>) is abstract tagged limited private; 
  3.     type Entity_Access is access Entity_Class'Class; 
  4.  
  5.     with procedure Delete( e : in out Entity_Access ); 
  6.  
  7. -- This generic package is used to register an association of entity class 
  8. -- names and allocators. This allows us to instantiate an entity class simply 
  9. -- by name, without ever referencing its implementation in the code. 
  10. package Entity_Factory is 
  11.  
  12.     type Allocator is access function return Entity_Access; 
  13.  
  14.     -- Initializes the factory by name. The name should be the class of entities 
  15.     -- that it manufactures. (ex: "item", "trigger", "player", etc). Classes 
  16.     -- should be registered before the factory is initialized. Template 
  17.     -- instances of each registered class are created at this time. 
  18.     procedure Initialize( factoryName : String ); 
  19.     pragma Precondition( factoryName'Length > 0 ); 
  20.  
  21.     procedure Finalize; 
  22.  
  23.     -- Returns null if no allocator is registered for the given id. 
  24.     function Allocate( id : String ) return Entity_Access; 
  25.     pragma Precondition( id'Length > 0 ); 
  26.  
  27.     -- Iterate over the registered class id strings. 
  28.     procedure Iterate_Classes( examine : access procedure( id : String ) ); 
  29.  
  30.     -- Registers a class allocation function with an id. 
  31.     procedure Register_Class( id : String; allocate : not null Allocator ); 
  32.     pragma Precondition( id'Length > 0 ); 
  33.  
  34.     -- Returns a reference to a template instantiation of the class registered 
  35.     -- with 'id'. Template entities are instantiated when the factory package is 
  36.     -- initialized. If no class is registered for the id, null will be returned. 
  37.     -- Do not modify the entity that is returned! 
  38.     function Template( id : String ) return Entity_Access; 
  39.     pragma Precondition( id'Length > 0 ); 
  40.  
  41. end Entity_Factory;