public LoadingTile(ITaskHandle taskHandle, Tile tile) { this.taskHandle = taskHandle; this.tile = tile; }
public TileHandle GetTile(int index, int priority) { if(index < 0) { string message = "The specified index cannot be less than 0."; throw new ArgumentException(message, "index"); } LoadingTile loadingTile = null; // Check to see if the tile is already loaded or is currently loading lock(SyncRoot) { if(tiles.Contains(index)) { if(releasedTiles.Contains(index)) releasedTiles.Remove(index); return new TileHandle(tiles[index]); } else if(loadingTiles.Contains(index)) { loadingTile = loadingTiles[index]; taskThread.PromoteTask(loadingTile.taskHandle, priority); return new TileHandle(loadingTile.tile); } } // Load the tile Tile tile = new Tile(tileType, index); EventHandler tile_Release = delegate(object sender, EventArgs args) { Tile senderTile = (Tile)sender; if(senderTile.Loaded) { // Add the tile to the disposal queue lock(SyncRoot) releasedTiles.Add(senderTile.Index); } else { // The tile was released prematurely lock(SyncRoot) { try { LoadingTile senderLoadingTile = loadingTiles[senderTile.Index]; taskThread.CancelTask(senderLoadingTile.taskHandle); loadingTiles.Remove(senderTile.Index); } catch(NoSuchItemException) { Debug.Fail("Prematurely released tile could not be found in the " + "loadingTiles collection."); } } } }; EventHandler tile_Load = delegate(object sender, EventArgs args) { Tile senderTile = (Tile)sender; lock(SyncRoot) { loadingTiles.Remove(senderTile.Index); if(tiles.Contains(senderTile.Index)) { if(tiles[senderTile.Index].Refcount != 0) { Debug.Fail("A tile has been loaded twice, but the second copy cannot be" + " disposed because it is in use."); } else tiles[senderTile.Index].Dispose(); } tiles[senderTile.Index] = senderTile; } }; tile.Release += tile_Release; tile.Load += tile_Load; ITaskHandle taskHandle = taskThread.AddTask( delegate() { return graphicLoader.LoadGraphic(index); }, delegate(object arg) { tile.Create((Image)arg); }, priority); loadingTile = new LoadingTile(taskHandle, tile); lock(SyncRoot) loadingTiles.Add(tile.Index, loadingTile); return new TileHandle(tile); }
internal TileHandle(Tile tile) { this.tile = tile; ++tile.Refcount; }
public TileManager(TileType tileType, string sourceTag, int sourceCount) { ReleaseTimerTick += delegate(object sender, EventArgs args) { ReleaseTiles(); }; this.tileType = tileType; // TODO: Clean up the API for this shit? string dataPath = Settings.Global.Default.DataPath; string archivePath = Path.Combine(dataPath, "tile.dat"); string paletteCollectionName = sourceTag + "." + PaletteCollection.FileExtension, paletteTableName = sourceTag + "." + PaletteTable.FileExtension; PaletteCollection paletteCollection; PaletteTable paletteTable; using(FileStream archiveStream = new FileStream(archivePath, FileMode.Open)) { ArchiveHeader archive = new ArchiveHeader(archiveStream); archiveStream.Seek(archive.GetEntry(paletteCollectionName).Offset, SeekOrigin.Begin); paletteCollection = PaletteCollection.FromStream(archiveStream); archiveStream.Seek(archive.GetEntry(paletteTableName).Offset, SeekOrigin.Begin); paletteTable = PaletteTable.FromStream(archiveStream); } GraphicLoader.ISourceProvider sourceProvider = new GraphicLoader.SourceProvider(sourceCount, Path.Combine(dataPath, sourceTag)); graphicLoader = new GraphicLoader(paletteCollection, paletteTable, sourceProvider); BlankTile = new Tile(tileType, 0); // Use a clone because the Create method transfers ownership BlankTile.Create((Image)BlankImage.Clone()); tiles.Add(0, BlankTile); // Artificially increment the refcount for blankTile so it is never disposed until it // is garbage collected. ++BlankTile.Refcount; }
public static void DrawInverted(Tile tile, Graphics graphics, Point point) { lock(tile.SyncRoot) { if(tile.Image != null) GraphicsUtil.DrawImageInverted(graphics, tile.Image, point); else graphics.FillRectangle(Brushes.Black, new Rectangle(point, Size)); } }