1. with Tiles.Matrices;                    use Tiles.Matrices; 
  2.  
  3. private with Ada.Containers; 
  4. private with Ada.Containers.Hashed_Maps; 
  5. private with Ada.Containers.Vectors; 
  6. private with Ada.Unchecked_Conversion; 
  7.  
  8. private package Tiles.Indices is 
  9.  
  10.     type Tile_Index is private; 
  11.     type A_Tile_Index is access all Tile_Index; 
  12.     pragma No_Strict_Aliasing( A_Tile_Index ); 
  13.  
  14.     -- Creates a new empty tile index. 
  15.     function Create_Tile_Index return A_Tile_Index; 
  16.     pragma Postcondition( Create_Tile_Index'Result /= null ); 
  17.  
  18.     -- Loads a tile index from an archive. Null will be returned if an error 
  19.     -- occurs. 
  20.     function Load_Index( archive  : not null A_Archive; 
  21.                          filename : String ) return A_Tile_Index; 
  22.     pragma Postcondition( filename'Length > 0 ); 
  23.  
  24.     -- Adds a new tile matrix to the index. 'matrix' will be consumed. 
  25.     procedure Add_Matrix( index : not null A_Tile_Index; matrix : in out A_Tile_Matrix ); 
  26.     pragma Precondition( matrix /= null ); 
  27.     pragma Postcondition( matrix = null ); 
  28.  
  29.     -- Adds a new tile to the index. 'tile' is consumed. If 'tile' is passed as 
  30.     -- null, a null tile is added to the tile list as a place holder. 
  31.     procedure Add_Tile( index : not null A_Tile_Index; tile : in out A_Tile ); 
  32.     pragma Postcondition( tile = null ); 
  33.  
  34.     -- Deletes a tile index. 
  35.     procedure Delete( index : in out A_Tile_Index ); 
  36.     pragma Postcondition( index = null ); 
  37.  
  38.     -- Returns a reference to a matrix in the index by ordinal number. If there 
  39.     -- is no matrix for 'num' the null will be returned. 
  40.     function Get_Matrix( index : not null A_Tile_Index; num : Natural ) return A_Tile_Matrix; 
  41.  
  42.     -- Returns the number of matrices in the index. 
  43.     function Get_Matrix_Count( index : not null A_Tile_Index ) return Natural; 
  44.  
  45.     -- Returns the load completion for the index in the range of 0..100 
  46.     function Get_Progress( index : not null A_Tile_Index ) return Natural; 
  47.     pragma Postcondition( Get_Progress'Result <= 100 ); 
  48.  
  49.     -- Returns the slot number of a tile by id. The slot is determined by the 
  50.     -- order of the tiles in the index. The first tile is at slot 1. Zero will 
  51.     -- be returned if 'id' is not found in the index. 
  52.     function Get_Slot( index : not null A_Tile_Index; id : Natural ) return Natural; 
  53.  
  54.     -- Returns a tile reference by tile id. Do not modify the tile, it belongs 
  55.     -- to the index. Null will be returned if the tile is not found. 
  56.     function Get_Tile( index : not null A_Tile_Index; id : Natural ) return A_Tile; 
  57.  
  58.     -- Returns a tile reference by name. Do not modify the tile, it belongs to 
  59.     -- the index. Null will be returned if the tile is not found. 
  60.     function Get_Tile( index : not null A_Tile_Index; name : String ) return A_Tile; 
  61.     pragma Precondition( name'Length > 0 ); 
  62.  
  63.     -- Returns a tile reference by slot number. Do not modify the tile, it 
  64.     -- belongs to the index. Null will be returned if the tile is not found. 
  65.     function Get_Tile_At_Slot( index : not null A_Tile_Index; 
  66.                                slot  : Natural ) return A_Tile; 
  67.  
  68.     -- Returns the number of tiles in the index. 
  69.     function Get_Tile_Count( index : not null A_Tile_Index ) return Natural; 
  70.  
  71.     -- Iterates across the tiles in the index by order of listing, from first 
  72.     -- to last. 
  73.     procedure Iterate_Tiles( index   : not null A_Tile_Index; 
  74.                              examine : not null access procedure( tile : A_Tile ) ); 
  75.  
  76.     -- Indicates to the index that all tiles have been loaded. This will free up 
  77.     -- any threads waiting for the index to be fully loaded. 
  78.     procedure Load_Complete( index : not null A_Tile_Index ); 
  79.  
  80.     -- Loads all the bitmaps for all the tiles in the index. 
  81.     procedure Load_Images( index   : not null A_Tile_Index; 
  82.                            archive : not null A_Archive ); 
  83.  
  84.     -- Prioritizes a tile to be loaded before non-priority tiles. 
  85.     procedure Prioritize_Tile( index : not null A_Tile_Index; tile : not null A_Tile ); 
  86.  
  87.     -- Writes the index to a file on disk, returning True on success. 
  88.     function Write_Index( index    : not null A_Tile_Index; 
  89.                           filename : String ) return Boolean; 
  90.     pragma Precondition( filename'Length > 0 ); 
  91.  
  92.     ---------------------------------------------------------------------------- 
  93.  
  94.     function Index_Extension return String; 
  95.     pragma Postcondition( Index_Extension'Result'Length > 0 ); 
  96.  
  97.     function Index_Identifier return String; 
  98.     pragma Postcondition( Index_Identifier'Result'Length > 0 ); 
  99.  
  100.     DUPLICATE_TILE : exception; 
  101.  
  102. private 
  103.  
  104.     use Ada.Containers; 
  105.  
  106.     protected type Tile_Queue is 
  107.  
  108.         -- adds to the end of the list. when the library index is read, all 
  109.         -- tiles are added to the back of the queue. this is used to keep track 
  110.         -- of the total number of tiles that must be loaded. 
  111.         procedure Add_Back( tile : not null A_Tile ); 
  112.  
  113.         -- returns a loaded percentage in the range of 0..100 
  114.         function Get_Progress return Natural; 
  115.         pragma Postcondition( Get_Progress'Result <= 100 ); 
  116.  
  117.         -- prioritizes the loading of the tile by adding it to the front of the 
  118.         -- queue. it should already have been added to the back of the queue. 
  119.         procedure Prioritize( tile : not null A_Tile ); 
  120.  
  121.         -- removes and returns first in the list 
  122.         procedure Remove( tile : out A_Tile ); 
  123.  
  124.         -- clears queue and stops accepting tiles 
  125.         procedure Stop; 
  126.  
  127.     private 
  128.         queue   : Tile_Lists.List; 
  129.         total   : Natural := 0;         -- total number of unique tiles to load 
  130.         loaded  : Natural := 0;         -- number of tiles loaded so far 
  131.         stopped : Boolean := False; 
  132.     end Tile_Queue; 
  133.     type A_Tile_Queue is access all Tile_Queue; 
  134.  
  135.     procedure Delete( queue : in out A_Tile_Queue ); 
  136.     pragma Postcondition( queue = null ); 
  137.  
  138.     ---------------------------------------------------------------------------- 
  139.  
  140.     function Hash is new Ada.Unchecked_Conversion( Integer, Hash_Type ); 
  141.  
  142.     package Integer_Vectors is new Ada.Containers.Vectors( Positive, Natural, "=" ); 
  143.     package Matrix_Vectors is new Ada.Containers.Vectors( Positive, A_Tile_Matrix, "=" ); 
  144.     package Tile_Maps is new Ada.Containers.Hashed_Maps( Integer, A_Tile, Hash, "=", "=" ); 
  145.  
  146.     -- The Tile_Index record is loaded from the index file in a library archive. 
  147.     type Tile_Index is 
  148.         record 
  149.             idmap    : Tile_Maps.Map;          -- mapping of id numbers to tiles 
  150.             list     : Integer_Vectors.Vector; -- ordered list of tile ids 
  151.             matlist  : Matrix_Vectors.Vector;  -- ordered list of tile matrices 
  152.             loadlist : A_Tile_Queue;           -- list of remaining tiles to load 
  153.         end record; 
  154.  
  155.     function A_Tile_Index_Input( stream : access Root_Stream_Type'Class ) return A_Tile_Index; 
  156.     for A_Tile_Index'Input use A_Tile_Index_Input; 
  157.  
  158.     procedure A_Tile_Index_Output( stream : access Root_Stream_Type'Class; index : A_Tile_Index ); 
  159.     for A_Tile_Index'Write use A_Tile_Index_Output; 
  160.     for A_Tile_Index'Output use A_Tile_Index_Output; 
  161.  
  162. end Tiles.Indices;