Class AbstractOpImpl

All Implemented Interfaces:
ImageOp, Op<BufferedImage>
Direct Known Subclasses:
AbstractTiledOpImpl, AbstractTileOpImpl

public abstract class AbstractOpImpl extends AbstractOpImpl<BufferedImage> implements ImageOp
An abstract representation of an operation which may be applied to an Image. ImageOp is the base class for all such operations. The results of all operations are memoized (using a memory-sensitive cache), so retrieving results is both fast and memory-efficient.

Warning: For efficiency reasons, the methods getImage() and getTile(java.awt.Point, VASSAL.tools.imageop.ImageOpObserver) do not return Images defensively, nor do the Future<Image>s returned by getFutureImage(VASSAL.tools.imageop.ImageOpObserver) and getFutureTile(java.awt.Point, VASSAL.tools.imageop.ImageOpObserver). That is, the Image returned is possibly the one retained internally by the ImageOp. Therefore, Images obtained from an ImageOp must not be altered, as this might interfere with image caching. If an Image obtained this way needs to be modified, copy the Image first and alter the copy.

Since:
3.1.0
Author:
Joel Uckelman
  • Field Details

    • size

      protected Dimension size
      The cached size of this operation's resulting Image.
    • cache

      protected static final OpCache cache
      The cache which contains calculated Images.
  • Constructor Details

    • AbstractOpImpl

      public AbstractOpImpl()
  • Method Details

    • clearCache

      public static void clearCache()
    • eval

      public abstract BufferedImage eval() throws Exception
      Runs the Op. This method should be called only by the caching framework.
      Specified by:
      eval in interface ImageOp
      Specified by:
      eval in interface Op<BufferedImage>
      Specified by:
      eval in class AbstractOpImpl<BufferedImage>
      Returns:
      the result of running this Op
      Throws:
      Exception - The operation represented by this ImageOp could be anything, so any exception may be thrown.
    • getImage

      public BufferedImage getImage()
      Calculates the BufferedImage produced by this operation. Calls to this method are memoized to prevent redundant computations.

      Warning: BufferedImages returned by this method must not be modified.

      Specified by:
      getImage in interface ImageOp
      Returns:
      the resulting BufferedImage
    • getImage

      Calculates the BufferedImage produced by this operation, and reports completion or failure to the specified ImageOpObserver. Calls to this method are memoized to prevent redundant computations. If a non-null observer is given, then the operation may be done asynchronously. If the observer is null, then this method will block on completion of the operation.

      When a non-blocking call is made (i.e., when obs != null), the cache is checked and if the image is found, it is returned immediately. If the image is already being calculated, obs is notified when the pre-existing request completes. Otherwise, a new request is queued and obs is notified when that completes.

      When a blocking call is made (i.e., when obs == null), the cache is checked and if the image is found, it is returned immediately. If the image is already being calculated, this method blocks on the completion of the existing calculation. Otherwise, a new calculation is started and this method blocks on it. In all cases, when a calculation is completed, the result is cached.

      Warning: BufferedImages returned by this method must not be modified.

      Specified by:
      getImage in interface ImageOp
      Parameters:
      obs - the observer to be notified on completion
      Returns:
      the resulting BufferedImage
      Throws:
      CancellationException - if the operation was cancelled
      InterruptedException - if the operation was interrupted
      ExecutionException - if the operation failed
      See Also:
    • getFutureImage

      public Future<BufferedImage> getFutureImage(ImageOpObserver obs) throws ExecutionException
      Submits a request for the BufferedImage produced by this operation, and returns a reference to that request. If a non-null observer is given, then the operation may be done asynchronously. If the observer is null, then this method will block on completion of the operation.

      This implementation uses a memory-sensitive cache to memoize calls to getFutureImage. It returns a Future<BufferedImage> so that the request may be cancelled if no longer needed.

      Futures are returned immediately, except in the case where the is no observer and no pre-existing Future for this ImageOp's BufferedImage, in which case this method blocks on completion of the computation.

      Warning: BufferedImages obtained from the Futures returned by this method must not be modified.

      Specified by:
      getFutureImage in interface ImageOp
      Parameters:
      obs - the observer to be notified on completion
      Returns:
      a Future for the resulting BufferedImage
      Throws:
      ExecutionException - if the operation failed
      See Also:
    • getSizeFromCache

      protected Dimension getSizeFromCache()
      A utility method for retrieving the size of the computed Image from the cache if the Image is cached.
      Returns:
      the size of the cached Image, or null if the Image isn't cached
    • fixSize

      protected abstract void fixSize()
      Sets the size which is used by getSize(), getHeight(), and getWidth().
    • getSize

      public Dimension getSize()
      Returns the size of the BufferedImage which would be returned by ImageOp.getImage(). The size is cached so that it need not be recalculated on each call.
      Specified by:
      getSize in interface ImageOp
      Returns:
      the size of the resulting BufferedImage in pixels
      See Also:
    • getWidth

      public int getWidth()
      Returns the width of the BufferedImage which would be returned by ImageOp.getImage(). The width is cached so that it need not be recalculated on each call.
      Specified by:
      getWidth in interface ImageOp
      Returns:
      the width of the resulting BufferedImage in pixels
      See Also:
    • getHeight

      public int getHeight()
      Returns the height of the BufferedImage which would be returned by ImageOp.getImage(). The height is cached so that it need not be recalculated on each call.
      Specified by:
      getHeight in interface ImageOp
      Returns:
      the height of the resulting BufferedImage in pixels
      See Also:
    • getTileSize

      public abstract Dimension getTileSize()
      Returns the standard size of the BufferedImage tiles which are returned by ImageOp.getTile(java.awt.Point, VASSAL.tools.imageop.ImageOpObserver). Tiles which are in the extreme right column will not have full width if the BufferedImage width is not an integral multiple of the tile width. Similarly, tiles in the bottom row will not have full height if the BufferedImage height is not an integral multiple of the tile height.
      Specified by:
      getTileSize in interface ImageOp
      Returns:
      the size of BufferedImage tiles in pixels
      See Also:
    • getTileHeight

      public abstract int getTileHeight()
      Returns the standard height of the BufferedImage tiles which are returned by ImageOp.getTile(java.awt.Point, VASSAL.tools.imageop.ImageOpObserver).
      Specified by:
      getTileHeight in interface ImageOp
      Returns:
      the height of BufferedImage tiles in pixels
      See Also:
    • getTileWidth

      public abstract int getTileWidth()
      Returns the standard width of the BufferedImage tiles which are returned by ImageOp.getTile(java.awt.Point, VASSAL.tools.imageop.ImageOpObserver).
      Specified by:
      getTileWidth in interface ImageOp
      Returns:
      the width of BufferedImage tiles in pixels
      See Also:
    • getNumXTiles

      public abstract int getNumXTiles()
      Returns the number of tiles along the x-axis. There will always be at least one column of tiles. The number of columns should equal (int) Math.ceil((double) getWidth() / getTileWidth()).
      Specified by:
      getNumXTiles in interface ImageOp
      Returns:
      the number of tiles along the x-axis
    • getNumYTiles

      public abstract int getNumYTiles()
      Returns the number of tiles along the y-axis. There will always be at least one row of tiles. The number of rows should equal (int) Math.ceil((double) getHeight() / getTileHeight()).
      Specified by:
      getNumYTiles in interface ImageOp
      Returns:
      the number of tiles along the y-axis
    • getTile

      Calculates tile (p.x,p.y), and reports completion or failure to the specified ImageOpObserver. If a non-null observer is given, then the operation may be done asynchronously. If the observer is null, then this method will block on completion of the operation. Tiles are numbered from zero, so the tile in the upper-left corner of the main BufferedImage is (0,0). Note that p.x and p.y are indices into the tile array, not pixel locations.

      This convenience method is equivalent to getTile(p.x, p.y, obs).

      Warning: BufferedImages returned by this method must not be modified.

      Specified by:
      getTile in interface ImageOp
      Parameters:
      p - the position of the requested tile
      obs - the observer
      Returns:
      the resulting BufferedImage
      Throws:
      CancellationException - if the operation was cancelled
      InterruptedException - if the operation was interrupted
      ExecutionException - if the operation failed
    • getTile

      public abstract BufferedImage getTile(int tileX, int tileY, ImageOpObserver obs) throws CancellationException, InterruptedException, ExecutionException
      Calculates tile (tileX,tileY), and reports completion or failure to the specified ImageOpObserver. If a non-null observer is given, then the operation may be done asynchronously. If the observer is null, then this method will block on completion of the operation. Tiles are numbered from zero, so the tile in the upper-left corner of the main BufferedImage is (0,0). Note that tileX and tileY are indices into the tile array, not pixel locations.

      Warning: BufferedImages returned by this method must not be modified.

      Specified by:
      getTile in interface ImageOp
      Parameters:
      tileX - the x position of the requested tile
      tileY - the y position of the requested tile
      obs - the observer to be notified on completion
      Returns:
      the resulting BufferedImage
      Throws:
      CancellationException - if the operation was cancelled
      InterruptedException - if the operation was interrupted
      ExecutionException - if the operation failed
    • getFutureTile

      public Future<BufferedImage> getFutureTile(Point p, ImageOpObserver obs) throws ExecutionException
      Submits a request for tile (tileX,tileY), and returns a reference to that request. If a non-null observer is given, then the operation may be done asynchronously. If the observer is null, then this method will block on completion of the operation. Tiles are numbered from zero, so the tile in the upper-left corner of the main BufferedImage is (0,0). Note that tileX and tileY are indices into the tile array, not pixel locations.

      This convenience method is equivalent to getFutureTile(p.x, p.y, obs).

      Warning: BufferedImages obtained from the Futures returned by this method must not be modified.

      Specified by:
      getFutureTile in interface ImageOp
      Parameters:
      p - the position of the requested tile
      obs - the observer to be notified on completion
      Returns:
      a Future for the resulting BufferedImage
      Throws:
      ExecutionException - if the operation failed
    • getFutureTile

      public abstract Future<BufferedImage> getFutureTile(int tileX, int tileY, ImageOpObserver obs) throws ExecutionException
      Submits a request for tile (tileX,tileY), and returns a reference to that request. If a non-null observer is given, then the operation may be done asynchronously. If the observer is null, then this method will block on completion of the operation. Tiles are numbered from zero, so the tile in the upper-left corner of the main BufferedImage is (0,0). Note that tileX and tileY are indices into the tile array, not pixel locations.

      Warning: BufferedImages obtained from the Futures returned by this method must not be modified.

      Specified by:
      getFutureTile in interface ImageOp
      Parameters:
      tileX - the x position of the requested tile
      tileY - the y position of the requested tile
      obs - the observer to be notified on completion
      Returns:
      a Future for the resulting BufferedImage
      Throws:
      ExecutionException - if the operation failed
    • getTileOp

      public ImageOp getTileOp(Point p)
      Returns an ImageOp which can produce the requested tile.

      This convenience method is equivalent to getTileOp(p.x, p.y).

      Specified by:
      getTileOp in interface ImageOp
      Parameters:
      p - the position of the requested tile
      Returns:
      the ImageOp which produces the requested tile
    • getTileOp

      public abstract ImageOp getTileOp(int tileX, int tileY)
      Returns an ImageOp which can produce the requested tile.
      Specified by:
      getTileOp in interface ImageOp
      Parameters:
      tileX - the x position of the requested tile
      tileY - the y position of the requested tile
      Returns:
      the ImageOp which produces the requested tile
    • getTileIndices

      public abstract Point[] getTileIndices(Rectangle rect)
      Returns an array of Points representing the tiles intersecting the given Rectangle.
      Specified by:
      getTileIndices in interface ImageOp
      Parameters:
      rect - the rectangle
      Returns:
      the positions of the tiles hit by the rectangle