/* * Call this when a tile is no longer needed. * If the number of users of the tile is 0 then the tile will be moved from the used to the unused cache */ public void PutTile(Tile tile) { if (tile == null) { return; } tile.DecrementUsers(); //if there are no more users of this tile move the tile from the used cahce to the unused cache if (tile.GetUsers() <= 0) { Tile.TId id = tile.GetTId(); if (m_usedTiles.ContainsKey(id)) { m_usedTiles.Remove(id); } if (!m_unusedTiles.ContainsKey(id)) { m_unusedTiles.AddLast(id, tile); } } }
/* * Finds a tile based on its Tid. If includeUnusedCache is true then will also look in * the unused cache but be warned that tiles in the unused cache maybe evicted and have there slot recylced as any time */ public Tile FindTile(int producerId, int level, int tx, int ty, bool includeUnusedCache) { Tile.TId id = Tile.GetTId(producerId, level, tx, ty); Tile tile = null; // looks for the requested tile in the used tiles list if (m_usedTiles.ContainsKey(id)) { tile = m_usedTiles[id]; } // looks for the requested tile in the unused tiles list (if includeUnusedCache is true) if (tile == null && includeUnusedCache) { if (m_unusedTiles.ContainsKey(id)) { tile = m_unusedTiles.Get(id); } } return(tile); }
/* * Call this if a tile is needed. Will move the tile from the unused to the used cache if its is found there. * If the tile is not found then a new tile will be created with a new slot. If there are no more free * slots then the cache capacity has not been set to a high enough value and the program must abort. */ public Tile GetTile(int producerId, int level, int tx, int ty) { //If this producer id does not exist can not create tile. if (!m_producers.ContainsKey(producerId)) { Debug.Log("Proland::TileCache::GetTile - Producer id not been inserted into cache"); return(null); } Tile.TId id = Tile.GetTId(producerId, level, tx, ty); Tile tile = null; //If tile is not in the used cache if (!m_usedTiles.ContainsKey(id)) { //If tile is also not in the unused cache if (!m_unusedTiles.ContainsKey(id)) { List <TileStorage.Slot> slot = NewSlot(); //if there are no more free slots then start recyling slots from the unused tiles if (slot == null && !m_unusedTiles.Empty()) { //Remove the tile and recylce its slot slot = m_unusedTiles.RemoveFirst().GetSlot(); } //If a slot is found create a new tile with a new task if (slot != null) { CreateTileTask task = m_producers[producerId].CreateTile(level, tx, ty, slot); tile = new Tile(producerId, level, tx, ty, task); } //If a free slot is not found then program has must abort. Try setting the cache capacity to higher value. if (slot == null) { throw new CacheCapacityException("No more free slots found. Insufficient storage capacity for cache " + name); } } else { //else if the tile is in the unused cache remove it and keep a reference to it tile = m_unusedTiles.Remove(id); } if (tile != null) { m_usedTiles.Add(id, tile); } } else { tile = m_usedTiles[id]; } //Should never be null be this stage if (tile == null) { throw new System.ArgumentNullException("Tile should not be null"); } //Keep track of the max number of tiles ever used for debug purposes if (m_usedTiles.Count > m_maxUsedTiles) { m_maxUsedTiles = m_usedTiles.Count; } //inc the num of users tile.IncrementUsers(); return(tile); }