Apparently only yohoho ever uses the runtimeadjust stuff, so we don't care about backwards compatibility and this naming scheme is better. We now have ClientImageManager and ImageManager.
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@434 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -35,7 +35,7 @@ import com.samskivert.util.Throttle;
|
||||
import com.samskivert.util.Tuple;
|
||||
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.util.DirectionCodes;
|
||||
|
||||
import com.threerings.cast.CompositedActionFrames.ComponentFrames;
|
||||
@@ -52,7 +52,7 @@ public class CharacterManager
|
||||
/**
|
||||
* Constructs the character manager.
|
||||
*/
|
||||
public CharacterManager (BaseImageManager imgr, ComponentRepository crepo)
|
||||
public CharacterManager (ImageManager imgr, ComponentRepository crepo)
|
||||
{
|
||||
// keep these around
|
||||
_imgr = imgr;
|
||||
@@ -421,7 +421,7 @@ public class CharacterManager
|
||||
}
|
||||
|
||||
/** The image manager with whom we interact. */
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** The component repository. */
|
||||
protected ComponentRepository _crepo;
|
||||
|
||||
@@ -24,7 +24,7 @@ package com.threerings.cast;
|
||||
import com.samskivert.util.LRUHashMap;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.util.MultiFrameImage;
|
||||
|
||||
@@ -65,7 +65,7 @@ public class CompositedActionFrames
|
||||
* source frames and colorization configuration. The actual component
|
||||
* frame images will not be composited until they are requested.
|
||||
*/
|
||||
public CompositedActionFrames (BaseImageManager imgr, LRUHashMap frameCache,
|
||||
public CompositedActionFrames (ImageManager imgr, LRUHashMap frameCache,
|
||||
String action, ComponentFrames[] sources)
|
||||
{
|
||||
// sanity check
|
||||
@@ -177,7 +177,7 @@ public class CompositedActionFrames
|
||||
|
||||
/** The image manager from whom we can obtain prepared volatile images
|
||||
* onto which to render our composited actions. */
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** Used to cache our composited action frame images. */
|
||||
protected LRUHashMap _frameCache;
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.Mirage;
|
||||
import com.threerings.media.image.VolatileMirage;
|
||||
|
||||
@@ -40,7 +40,7 @@ import com.threerings.cast.CompositedActionFrames.ComponentFrames;
|
||||
public class CompositedMaskedImage extends CompositedMultiFrameImage
|
||||
{
|
||||
public CompositedMaskedImage (
|
||||
BaseImageManager imgr, ComponentFrames[] sources, String action,
|
||||
ImageManager imgr, ComponentFrames[] sources, String action,
|
||||
int orient)
|
||||
{
|
||||
super(imgr, sources, action, orient);
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.Comparator;
|
||||
|
||||
import com.threerings.cast.CompositedActionFrames.ComponentFrames;
|
||||
import com.threerings.cast.bundle.BundledComponentRepository.TileSetFrameImage;
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.Mirage;
|
||||
import com.threerings.media.image.VolatileMirage;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class CompositedMultiFrameImage
|
||||
implements TrimmedMultiFrameImage
|
||||
{
|
||||
public CompositedMultiFrameImage (
|
||||
BaseImageManager imgr, ComponentFrames[] sources,
|
||||
ImageManager imgr, ComponentFrames[] sources,
|
||||
String action, int orient)
|
||||
{
|
||||
_imgr = imgr;
|
||||
@@ -190,7 +190,7 @@ public class CompositedMultiFrameImage
|
||||
}
|
||||
|
||||
/** The image manager from whom we load our images. */
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** The action frames from which we obtain our source imagery. */
|
||||
protected ComponentFrames[] _sources;
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.Mirage;
|
||||
import com.threerings.media.image.VolatileMirage;
|
||||
|
||||
@@ -38,7 +38,7 @@ import com.threerings.cast.CompositedActionFrames.ComponentFrames;
|
||||
*/
|
||||
public class CompositedShadowImage extends CompositedMultiFrameImage
|
||||
{
|
||||
public CompositedShadowImage (BaseImageManager imgr, ComponentFrames[] sources,
|
||||
public CompositedShadowImage (ImageManager imgr, ComponentFrames[] sources,
|
||||
String action, int orient, float shadowAlpha)
|
||||
{
|
||||
super(imgr, sources, action, orient);
|
||||
|
||||
@@ -40,7 +40,7 @@ import com.threerings.resource.FileResourceBundle;
|
||||
import com.threerings.resource.ResourceBundle;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.BufferedMirage;
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.ImageDataProvider;
|
||||
@@ -85,7 +85,7 @@ public class BundledComponentRepository
|
||||
* resource bundles.
|
||||
*/
|
||||
public BundledComponentRepository (
|
||||
ResourceManager rmgr, BaseImageManager imgr, String name)
|
||||
ResourceManager rmgr, ImageManager imgr, String name)
|
||||
throws IOException
|
||||
{
|
||||
// keep this guy around
|
||||
@@ -261,7 +261,7 @@ public class BundledComponentRepository
|
||||
/**
|
||||
* Constructs an instance that will obtain image data from the specified resource bundle.
|
||||
*/
|
||||
public ResourceBundleProvider (BaseImageManager imgr, ResourceBundle bundle)
|
||||
public ResourceBundleProvider (ImageManager imgr, ResourceBundle bundle)
|
||||
{
|
||||
super(imgr, (String)null);
|
||||
_dprov = this;
|
||||
@@ -508,7 +508,7 @@ public class BundledComponentRepository
|
||||
}
|
||||
|
||||
/** We use the image manager to decode and cache images. */
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** A table of action sequences. */
|
||||
protected HashMap _actions;
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.awt.image.BufferedImage;
|
||||
* AWT to determine the optimal image format.
|
||||
*/
|
||||
public class AWTImageCreator
|
||||
implements BaseImageManager.OptimalImageCreator
|
||||
implements ImageManager.OptimalImageCreator
|
||||
{
|
||||
/**
|
||||
* Create an image creator that will rely on the AWT to determine the
|
||||
|
||||
@@ -39,7 +39,7 @@ public class BackedVolatileMirage extends VolatileMirage
|
||||
* Creates a mirage with the supplied regeneration informoation and
|
||||
* prepared image.
|
||||
*/
|
||||
public BackedVolatileMirage (BaseImageManager imgr, BufferedImage source)
|
||||
public BackedVolatileMirage (ImageManager imgr, BufferedImage source)
|
||||
{
|
||||
super(imgr, new Rectangle(0, 0, source.getWidth(), source.getHeight()));
|
||||
_source = source;
|
||||
|
||||
@@ -1,538 +0,0 @@
|
||||
// $Id$
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.util.LRUHashMap;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.util.Throttle;
|
||||
import com.samskivert.util.Tuple;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
/**
|
||||
* Provides a single point of access for image retrieval and caching. This does not include
|
||||
* any tie-in to runtime adjustments to control caching and mirage creation.
|
||||
*/
|
||||
public class BaseImageManager
|
||||
implements ImageUtil.ImageCreator
|
||||
{
|
||||
/**
|
||||
* Used to identify an image for caching and reconstruction.
|
||||
*/
|
||||
public static class ImageKey
|
||||
{
|
||||
/** The data provider from which this image's data is loaded. */
|
||||
public ImageDataProvider daprov;
|
||||
|
||||
/** The path used to identify the image to the data provider. */
|
||||
public String path;
|
||||
|
||||
protected ImageKey (ImageDataProvider daprov, String path)
|
||||
{
|
||||
this.daprov = daprov;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public int hashCode ()
|
||||
{
|
||||
return path.hashCode() ^ daprov.getIdent().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other == null || !(other instanceof ImageKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageKey okey = (ImageKey)other;
|
||||
return ((okey.daprov.getIdent().equals(daprov.getIdent())) &&
|
||||
(okey.path.equals(path)));
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return daprov.getIdent() + ":" + path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This interface allows the image manager to create images that are in a format optimal for
|
||||
* rendering to the screen.
|
||||
*/
|
||||
public interface OptimalImageCreator
|
||||
{
|
||||
/**
|
||||
* Requests that a blank image be created that is in a format and of a depth that are
|
||||
* optimal for rendering to the screen.
|
||||
*/
|
||||
public BufferedImage createImage (int width, int height, int trans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an image manager with the specified {@link ResourceManager} from which it will
|
||||
* obtain its data.
|
||||
*/
|
||||
public BaseImageManager (ResourceManager rmgr, OptimalImageCreator icreator)
|
||||
{
|
||||
_rmgr = rmgr;
|
||||
_icreator = icreator;
|
||||
|
||||
// create our image cache
|
||||
int icsize = getCacheSize();
|
||||
Log.debug("Creating image cache [size=" + icsize + "k].");
|
||||
_ccache = new LRUHashMap(icsize * 1024, new LRUHashMap.ItemSizer() {
|
||||
public int computeSize (Object value) {
|
||||
return (int)((CacheRecord)value).getEstimatedMemoryUsage();
|
||||
}
|
||||
});
|
||||
_ccache.setTracking(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience constructor that creates an {@link AWTImageCreator} for use by the image
|
||||
* manager.
|
||||
*/
|
||||
public BaseImageManager (ResourceManager rmgr, Component context)
|
||||
{
|
||||
this(rmgr, new AWTImageCreator(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how much space we're willing to use for caching images.
|
||||
*/
|
||||
public int getCacheSize ()
|
||||
{
|
||||
return DEFAULT_CACHE_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all images out of the cache.
|
||||
*/
|
||||
public void clearCache ()
|
||||
{
|
||||
Log.info("Clearing image manager cache.");
|
||||
|
||||
_ccache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a buffered image, optimized for display on our graphics device.
|
||||
*/
|
||||
public BufferedImage createImage (int width, int height, int transparency)
|
||||
{
|
||||
return _icreator.createImage(width, height, transparency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager using the supplied path to
|
||||
* identify the image.
|
||||
*/
|
||||
public BufferedImage getImage (String path)
|
||||
{
|
||||
return getImage(null, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String)} but the specified colorizations are applied to the image
|
||||
* before it is returned.
|
||||
*/
|
||||
public BufferedImage getImage (String path, Colorization[] zations)
|
||||
{
|
||||
return getImage(null, path, zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String)} but the image is loaded from the specified resource set
|
||||
* rathern than the default resource set.
|
||||
*/
|
||||
public BufferedImage getImage (String rset, String path)
|
||||
{
|
||||
return getImage(rset, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String,String)} but the specified colorizations are applied to the
|
||||
* image before it is returned.
|
||||
*/
|
||||
public BufferedImage getImage (String rset, String path, Colorization[] zations)
|
||||
{
|
||||
if (StringUtil.isBlank(path)) {
|
||||
String errmsg = "Invalid image path [rset=" + rset + ", path=" + path + "]";
|
||||
throw new IllegalArgumentException(errmsg);
|
||||
}
|
||||
return getImage(getImageKey(rset, path), zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager using the supplied path to
|
||||
* identify the image.
|
||||
*
|
||||
* <p> Additionally the image is optimized for display in the current graphics
|
||||
* configuration. Consider using {@link #getMirage(ImageKey)} instead of prepared images as
|
||||
* they (some day) will automatically use volatile images to increase performance.
|
||||
*/
|
||||
public BufferedImage getPreparedImage (String path)
|
||||
{
|
||||
return getPreparedImage(null, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager, obtaining the image from
|
||||
* the supplied resource set.
|
||||
*
|
||||
* <p> Additionally the image is optimized for display in the current graphics
|
||||
* configuration. Consider using {@link #getMirage(ImageKey)} instead of prepared images as
|
||||
* they (some day) will automatically use volatile images to increase performance.
|
||||
*/
|
||||
public BufferedImage getPreparedImage (String rset, String path)
|
||||
{
|
||||
return getPreparedImage(rset, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager, obtaining the image from
|
||||
* the supplied resource set and applying the using the supplied path to identify the image.
|
||||
*
|
||||
* <p> Additionally the image is optimized for display in the current graphics
|
||||
* configuration. Consider using {@link #getMirage(ImageKey,Colorization[])} instead of
|
||||
* prepared images as they (some day) will automatically use volatile images to increase
|
||||
* performance.
|
||||
*/
|
||||
public BufferedImage getPreparedImage (String rset, String path, Colorization[] zations)
|
||||
{
|
||||
BufferedImage image = getImage(rset, path, zations);
|
||||
BufferedImage prepped = null;
|
||||
if (image != null) {
|
||||
prepped = createImage(image.getWidth(), image.getHeight(),
|
||||
image.getColorModel().getTransparency());
|
||||
Graphics2D pg = prepped.createGraphics();
|
||||
pg.drawImage(image, 0, 0, null);
|
||||
pg.dispose();
|
||||
}
|
||||
return prepped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image key that can be used to fetch the image identified by the specified
|
||||
* resource set and image path.
|
||||
*/
|
||||
public ImageKey getImageKey (String rset, String path)
|
||||
{
|
||||
return getImageKey(getDataProvider(rset), path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image key that can be used to fetch the image identified by the specified data
|
||||
* provider and image path.
|
||||
*/
|
||||
public ImageKey getImageKey (ImageDataProvider daprov, String path)
|
||||
{
|
||||
return new ImageKey(daprov, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the image identified by the specified key, caching if possible. The image will be
|
||||
* recolored using the supplied colorizations if requested.
|
||||
*/
|
||||
public BufferedImage getImage (ImageKey key, Colorization[] zations)
|
||||
{
|
||||
CacheRecord crec = null;
|
||||
synchronized (_ccache) {
|
||||
crec = (CacheRecord)_ccache.get(key);
|
||||
}
|
||||
if (crec != null) {
|
||||
// Log.info("Cache hit [key=" + key + ", crec=" + crec + "].");
|
||||
return crec.getImage(zations, _ccache);
|
||||
}
|
||||
// Log.info("Cache miss [key=" + key + ", crec=" + crec + "].");
|
||||
|
||||
// load up the raw image
|
||||
BufferedImage image = loadImage(key);
|
||||
if (image == null) {
|
||||
Log.warning("Failed to load image " + key + ".");
|
||||
// create a blank image instead
|
||||
image = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_INDEXED);
|
||||
}
|
||||
|
||||
// Log.info("Loaded " + key.path + ", image=" + image +
|
||||
// ", size=" + ImageUtil.getEstimatedMemoryUsage(image));
|
||||
|
||||
// create a cache record
|
||||
crec = new CacheRecord(key, image);
|
||||
synchronized (_ccache) {
|
||||
_ccache.put(key, crec);
|
||||
}
|
||||
_keySet.add(key);
|
||||
|
||||
// periodically report our image cache performance
|
||||
reportCachePerformance();
|
||||
|
||||
return crec.getImage(zations, _ccache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mirage which is an image optimized for display on our current display device and
|
||||
* which will be stored into video memory if possible.
|
||||
*/
|
||||
public Mirage getMirage (String rsrcPath)
|
||||
{
|
||||
return getMirage(getImageKey(_defaultProvider, rsrcPath), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mirage which is an image optimized for display on our current display device and
|
||||
* which will be stored into video memory if possible.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key)
|
||||
{
|
||||
return getMirage(key, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey)} but that only the specified subimage of the source image
|
||||
* is used to build the mirage.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Rectangle bounds)
|
||||
{
|
||||
return getMirage(key, bounds, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey)} but the supplied colorizations are applied to the source
|
||||
* image before creating the mirage.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Colorization[] zations)
|
||||
{
|
||||
return getMirage(key, null, zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey,Colorization[])} except that the mirage is created using
|
||||
* only the specified subset of the original image.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Rectangle bounds, Colorization[] zations)
|
||||
{
|
||||
BufferedImage src = null;
|
||||
|
||||
float percentageOfDataBuffer = 1;
|
||||
if (bounds == null) {
|
||||
// if they specified no bounds, we need to load up the raw image and determine its
|
||||
// bounds so that we can pass those along to the created mirage
|
||||
src = getImage(key, zations);
|
||||
bounds = new Rectangle(0, 0, src.getWidth(), src.getHeight());
|
||||
|
||||
}
|
||||
|
||||
return new CachedVolatileMirage(this, key, bounds, zations);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image creator that can be used to create buffered images optimized for rendering
|
||||
* to the screen.
|
||||
*/
|
||||
public OptimalImageCreator getImageCreator ()
|
||||
{
|
||||
return _icreator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data provider configured to obtain image data from the specified resource set.
|
||||
*/
|
||||
protected ImageDataProvider getDataProvider (final String rset)
|
||||
{
|
||||
if (rset == null) {
|
||||
return _defaultProvider;
|
||||
}
|
||||
|
||||
ImageDataProvider dprov = (ImageDataProvider)_providers.get(rset);
|
||||
if (dprov == null) {
|
||||
dprov = new ImageDataProvider() {
|
||||
public BufferedImage loadImage (String path)
|
||||
throws IOException {
|
||||
// first attempt to load the image from the specified resource set
|
||||
try {
|
||||
return _rmgr.getImageResource(rset, path);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
// fall back to trying the classpath
|
||||
return _rmgr.getImageResource(path);
|
||||
}
|
||||
}
|
||||
|
||||
public String getIdent () {
|
||||
return "rmgr:" + rset;
|
||||
}
|
||||
};
|
||||
_providers.put(rset, dprov);
|
||||
}
|
||||
|
||||
return dprov;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and returns the image with the specified key from the supplied data provider.
|
||||
*/
|
||||
protected BufferedImage loadImage (ImageKey key)
|
||||
{
|
||||
// if (EventQueue.isDispatchThread()) {
|
||||
// Log.info("Loading image on AWT thread " + key + ".");
|
||||
// }
|
||||
|
||||
BufferedImage image = null;
|
||||
try {
|
||||
Log.debug("Loading image " + key + ".");
|
||||
image = key.daprov.loadImage(key.path);
|
||||
if (image == null) {
|
||||
Log.warning("ImageDataProvider.loadImage(" + key + ") returned null.");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to load image '" + key + "'.");
|
||||
Log.logStackTrace(e);
|
||||
|
||||
// create a blank image in its stead
|
||||
image = createImage(1, 1, Transparency.OPAQUE);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports statistics detailing the image manager cache performance and the current size of the
|
||||
* cached images.
|
||||
*/
|
||||
protected void reportCachePerformance ()
|
||||
{
|
||||
if (/* Log.getLevel() != Log.log.DEBUG || */
|
||||
_cacheStatThrottle.throttleOp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute our estimated memory usage
|
||||
long size = 0;
|
||||
|
||||
int[] eff = null;
|
||||
synchronized (_ccache) {
|
||||
Iterator iter = _ccache.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
size += ((CacheRecord)iter.next()).getEstimatedMemoryUsage();
|
||||
}
|
||||
eff = _ccache.getTrackedEffectiveness();
|
||||
}
|
||||
Log.info("ImageManager LRU [mem=" + (size / 1024) + "k, size=" + _ccache.size() +
|
||||
", hits=" + eff[0] + ", misses=" + eff[1] + ", totalKeys=" + _keySet.size() + "].");
|
||||
}
|
||||
|
||||
/** Maintains a source image and a set of colorized versions in the image cache. */
|
||||
protected static class CacheRecord
|
||||
{
|
||||
public CacheRecord (ImageKey key, BufferedImage source)
|
||||
{
|
||||
_key = key;
|
||||
_source = source;
|
||||
}
|
||||
|
||||
public BufferedImage getImage (Colorization[] zations, LRUHashMap cache)
|
||||
{
|
||||
if (zations == null) {
|
||||
return _source;
|
||||
}
|
||||
|
||||
if (_colorized == null) {
|
||||
_colorized = new ArrayList<Tuple<Colorization[], BufferedImage>>();
|
||||
}
|
||||
|
||||
// we search linearly through our list of colorized copies because it is not likely to
|
||||
// be very long
|
||||
int csize = _colorized.size();
|
||||
for (int ii = 0; ii < csize; ii++) {
|
||||
Tuple<Colorization[], BufferedImage> tup = _colorized.get(ii);
|
||||
Colorization[] tzations = tup.left;
|
||||
if (Arrays.equals(zations, tzations)) {
|
||||
return tup.right;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
BufferedImage cimage = ImageUtil.recolorImage(_source, zations);
|
||||
_colorized.add(new Tuple<Colorization[], BufferedImage>(zations, cimage));
|
||||
cache.adjustSize((int)ImageUtil.getEstimatedMemoryUsage(cimage));
|
||||
return cimage;
|
||||
|
||||
} catch (Exception re) {
|
||||
Log.warning("Failure recoloring image [source" + _key +
|
||||
", zations=" + StringUtil.toString(zations) + ", error=" + re + "].");
|
||||
// return the uncolorized version
|
||||
return _source;
|
||||
}
|
||||
}
|
||||
|
||||
public long getEstimatedMemoryUsage ()
|
||||
{
|
||||
long usage = ImageUtil.getEstimatedMemoryUsage(_source);
|
||||
if (_colorized != null) {
|
||||
for (Tuple<Colorization[], BufferedImage> tup : _colorized) {
|
||||
usage += ImageUtil.getEstimatedMemoryUsage(tup.right);
|
||||
}
|
||||
}
|
||||
return usage;
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "[key=" + _key + ", wid=" + _source.getWidth() + ", hei=" + _source.getHeight() +
|
||||
", ccount=" + ((_colorized == null) ? 0 : _colorized.size()) + "]";
|
||||
}
|
||||
|
||||
protected ImageKey _key;
|
||||
protected BufferedImage _source;
|
||||
protected ArrayList<Tuple<Colorization[], BufferedImage>> _colorized;
|
||||
}
|
||||
|
||||
/** A reference to the resource manager via which we load image data by default. */
|
||||
protected ResourceManager _rmgr;
|
||||
|
||||
/** We use this to create images optimized for rendering. */
|
||||
protected OptimalImageCreator _icreator;
|
||||
|
||||
/** A cache of loaded images. */
|
||||
protected LRUHashMap _ccache;
|
||||
|
||||
/** The set of all keys we've ever seen. */
|
||||
protected HashSet _keySet = new HashSet();
|
||||
|
||||
/** Throttle our cache status logging to once every 300 seconds. */
|
||||
protected Throttle _cacheStatThrottle = new Throttle(1, 300000L);
|
||||
|
||||
/** Our default data provider. */
|
||||
protected ImageDataProvider _defaultProvider = new ImageDataProvider() {
|
||||
public BufferedImage loadImage (String path) throws IOException {
|
||||
return _rmgr.getImageResource(path);
|
||||
}
|
||||
public String getIdent () {
|
||||
return "rmgr:default";
|
||||
}
|
||||
};
|
||||
|
||||
/** Data providers for different resource sets. */
|
||||
protected HashMap _providers = new HashMap();
|
||||
|
||||
/** Default amount of data we'll store in our image cache. */
|
||||
protected static int DEFAULT_CACHE_SIZE = 32768;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ import com.threerings.media.Log;
|
||||
* for some other reason.
|
||||
*
|
||||
* <p> These objects are never created directly, but always obtained from
|
||||
* the {@link BaseImageManager}.
|
||||
* the {@link ImageManager}.
|
||||
*/
|
||||
public class CachedVolatileMirage extends VolatileMirage
|
||||
{
|
||||
@@ -44,7 +44,7 @@ public class CachedVolatileMirage extends VolatileMirage
|
||||
* prepared image.
|
||||
*/
|
||||
protected CachedVolatileMirage (
|
||||
BaseImageManager imgr, BaseImageManager.ImageKey source,
|
||||
ImageManager imgr, ImageManager.ImageKey source,
|
||||
Rectangle bounds, Colorization[] zations)
|
||||
{
|
||||
super(imgr, bounds);
|
||||
@@ -96,7 +96,7 @@ public class CachedVolatileMirage extends VolatileMirage
|
||||
|
||||
/** The key that identifies the image data used to create our volatile
|
||||
* image. */
|
||||
protected BaseImageManager.ImageKey _source;
|
||||
protected ImageManager.ImageKey _source;
|
||||
|
||||
/** Optional colorizations that are applied to our source image when
|
||||
* creating our mirage. */
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// $Id: ImageManager.java 433 2008-03-06 18:31:04Z mthomas $
|
||||
//
|
||||
// Nenya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/nenya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.samskivert.swing.RuntimeAdjust;
|
||||
import com.threerings.media.MediaPrefs;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
/**
|
||||
* Provides a single point of access for image retrieval and caching - just like the
|
||||
* ImageManager but adds a tie in to the RuntimeAdjust system to control caching and
|
||||
* mirage creation.
|
||||
*/
|
||||
public class ClientImageManager extends ImageManager
|
||||
{
|
||||
public ClientImageManager (ResourceManager rmgr, OptimalImageCreator icreator)
|
||||
{
|
||||
super(rmgr, icreator);
|
||||
}
|
||||
|
||||
public ClientImageManager (ResourceManager rmgr, Component context)
|
||||
{
|
||||
super(rmgr, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCacheSize ()
|
||||
{
|
||||
return _cacheSize.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mirage getMirage (ImageKey key, Rectangle bounds, Colorization[] zations)
|
||||
{
|
||||
// We need to do something more complicated than the BaseImageManager because our
|
||||
// runtime adjustments may affect how we create our mirages.
|
||||
|
||||
BufferedImage src = null;
|
||||
|
||||
float percentageOfDataBuffer = 1;
|
||||
if (bounds == null) {
|
||||
// if they specified no bounds, we need to load up the raw image and determine its
|
||||
// bounds so that we can pass those along to the created mirage
|
||||
src = getImage(key, zations);
|
||||
bounds = new Rectangle(0, 0, src.getWidth(), src.getHeight());
|
||||
|
||||
} else if (!_prepareImages.getValue()) {
|
||||
src = getImage(key, zations);
|
||||
percentageOfDataBuffer =
|
||||
(bounds.width * bounds.height)/(float)(src.getHeight() * src.getWidth());
|
||||
src = src.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
if (_runBlank.getValue()) {
|
||||
return new BlankMirage(bounds.width, bounds.height);
|
||||
} else if (_prepareImages.getValue()) {
|
||||
return new CachedVolatileMirage(this, key, bounds, zations);
|
||||
} else {
|
||||
return new BufferedMirage(src, percentageOfDataBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/** Register our image cache size with the runtime adjustments framework. */
|
||||
protected static RuntimeAdjust.IntAdjust _cacheSize = new RuntimeAdjust.IntAdjust(
|
||||
"Size (in kb of memory used) of the image manager LRU cache [requires restart]",
|
||||
"narya.media.image.cache_size", MediaPrefs.config, DEFAULT_CACHE_SIZE);
|
||||
|
||||
/** Controls whether or not we prepare images or use raw versions. */
|
||||
protected static RuntimeAdjust.BooleanAdjust _prepareImages = new RuntimeAdjust.BooleanAdjust(
|
||||
"Cause image manager to optimize all images for display.",
|
||||
"narya.media.image.prep_images", MediaPrefs.config, true);
|
||||
|
||||
/** A debug toggle for running entirely without rendering images. */
|
||||
protected static RuntimeAdjust.BooleanAdjust _runBlank = new RuntimeAdjust.BooleanAdjust(
|
||||
"Cause image manager to return blank images.",
|
||||
"narya.media.image.run_blank", MediaPrefs.config, false);
|
||||
}
|
||||
@@ -1,63 +1,333 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Nenya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/nenya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.media.image;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.samskivert.swing.RuntimeAdjust;
|
||||
import com.threerings.media.MediaPrefs;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.util.LRUHashMap;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.util.Throttle;
|
||||
import com.samskivert.util.Tuple;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
/**
|
||||
* Provides a single point of access for image retrieval and caching - just like the
|
||||
* BaseImageManager but adds a tie in to the RuntimeAdjust system to control caching and
|
||||
* mirage creation.
|
||||
* Provides a single point of access for image retrieval and caching. This does not include
|
||||
* any tie-in to runtime adjustments to control caching and mirage creation.
|
||||
*/
|
||||
public class ImageManager extends BaseImageManager
|
||||
public class ImageManager
|
||||
implements ImageUtil.ImageCreator
|
||||
{
|
||||
/**
|
||||
* Used to identify an image for caching and reconstruction.
|
||||
*/
|
||||
public static class ImageKey
|
||||
{
|
||||
/** The data provider from which this image's data is loaded. */
|
||||
public ImageDataProvider daprov;
|
||||
|
||||
/** The path used to identify the image to the data provider. */
|
||||
public String path;
|
||||
|
||||
protected ImageKey (ImageDataProvider daprov, String path)
|
||||
{
|
||||
this.daprov = daprov;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public int hashCode ()
|
||||
{
|
||||
return path.hashCode() ^ daprov.getIdent().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other == null || !(other instanceof ImageKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageKey okey = (ImageKey)other;
|
||||
return ((okey.daprov.getIdent().equals(daprov.getIdent())) &&
|
||||
(okey.path.equals(path)));
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return daprov.getIdent() + ":" + path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This interface allows the image manager to create images that are in a format optimal for
|
||||
* rendering to the screen.
|
||||
*/
|
||||
public interface OptimalImageCreator
|
||||
{
|
||||
/**
|
||||
* Requests that a blank image be created that is in a format and of a depth that are
|
||||
* optimal for rendering to the screen.
|
||||
*/
|
||||
public BufferedImage createImage (int width, int height, int trans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an image manager with the specified {@link ResourceManager} from which it will
|
||||
* obtain its data.
|
||||
*/
|
||||
public ImageManager (ResourceManager rmgr, OptimalImageCreator icreator)
|
||||
{
|
||||
super(rmgr, icreator);
|
||||
_rmgr = rmgr;
|
||||
_icreator = icreator;
|
||||
|
||||
// create our image cache
|
||||
int icsize = getCacheSize();
|
||||
Log.debug("Creating image cache [size=" + icsize + "k].");
|
||||
_ccache = new LRUHashMap(icsize * 1024, new LRUHashMap.ItemSizer() {
|
||||
public int computeSize (Object value) {
|
||||
return (int)((CacheRecord)value).getEstimatedMemoryUsage();
|
||||
}
|
||||
});
|
||||
_ccache.setTracking(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience constructor that creates an {@link AWTImageCreator} for use by the image
|
||||
* manager.
|
||||
*/
|
||||
public ImageManager (ResourceManager rmgr, Component context)
|
||||
{
|
||||
super(rmgr, context);
|
||||
this(rmgr, new AWTImageCreator(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Returns how much space we're willing to use for caching images.
|
||||
*/
|
||||
public int getCacheSize ()
|
||||
{
|
||||
return _cacheSize.getValue();
|
||||
return DEFAULT_CACHE_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Clears all images out of the cache.
|
||||
*/
|
||||
public void clearCache ()
|
||||
{
|
||||
Log.info("Clearing image manager cache.");
|
||||
|
||||
_ccache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a buffered image, optimized for display on our graphics device.
|
||||
*/
|
||||
public BufferedImage createImage (int width, int height, int transparency)
|
||||
{
|
||||
return _icreator.createImage(width, height, transparency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager using the supplied path to
|
||||
* identify the image.
|
||||
*/
|
||||
public BufferedImage getImage (String path)
|
||||
{
|
||||
return getImage(null, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String)} but the specified colorizations are applied to the image
|
||||
* before it is returned.
|
||||
*/
|
||||
public BufferedImage getImage (String path, Colorization[] zations)
|
||||
{
|
||||
return getImage(null, path, zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String)} but the image is loaded from the specified resource set
|
||||
* rathern than the default resource set.
|
||||
*/
|
||||
public BufferedImage getImage (String rset, String path)
|
||||
{
|
||||
return getImage(rset, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getImage(String,String)} but the specified colorizations are applied to the
|
||||
* image before it is returned.
|
||||
*/
|
||||
public BufferedImage getImage (String rset, String path, Colorization[] zations)
|
||||
{
|
||||
if (StringUtil.isBlank(path)) {
|
||||
String errmsg = "Invalid image path [rset=" + rset + ", path=" + path + "]";
|
||||
throw new IllegalArgumentException(errmsg);
|
||||
}
|
||||
return getImage(getImageKey(rset, path), zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager using the supplied path to
|
||||
* identify the image.
|
||||
*
|
||||
* <p> Additionally the image is optimized for display in the current graphics
|
||||
* configuration. Consider using {@link #getMirage(ImageKey)} instead of prepared images as
|
||||
* they (some day) will automatically use volatile images to increase performance.
|
||||
*/
|
||||
public BufferedImage getPreparedImage (String path)
|
||||
{
|
||||
return getPreparedImage(null, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager, obtaining the image from
|
||||
* the supplied resource set.
|
||||
*
|
||||
* <p> Additionally the image is optimized for display in the current graphics
|
||||
* configuration. Consider using {@link #getMirage(ImageKey)} instead of prepared images as
|
||||
* they (some day) will automatically use volatile images to increase performance.
|
||||
*/
|
||||
public BufferedImage getPreparedImage (String rset, String path)
|
||||
{
|
||||
return getPreparedImage(rset, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (and caches) the specified image from the resource manager, obtaining the image from
|
||||
* the supplied resource set and applying the using the supplied path to identify the image.
|
||||
*
|
||||
* <p> Additionally the image is optimized for display in the current graphics
|
||||
* configuration. Consider using {@link #getMirage(ImageKey,Colorization[])} instead of
|
||||
* prepared images as they (some day) will automatically use volatile images to increase
|
||||
* performance.
|
||||
*/
|
||||
public BufferedImage getPreparedImage (String rset, String path, Colorization[] zations)
|
||||
{
|
||||
BufferedImage image = getImage(rset, path, zations);
|
||||
BufferedImage prepped = null;
|
||||
if (image != null) {
|
||||
prepped = createImage(image.getWidth(), image.getHeight(),
|
||||
image.getColorModel().getTransparency());
|
||||
Graphics2D pg = prepped.createGraphics();
|
||||
pg.drawImage(image, 0, 0, null);
|
||||
pg.dispose();
|
||||
}
|
||||
return prepped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image key that can be used to fetch the image identified by the specified
|
||||
* resource set and image path.
|
||||
*/
|
||||
public ImageKey getImageKey (String rset, String path)
|
||||
{
|
||||
return getImageKey(getDataProvider(rset), path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image key that can be used to fetch the image identified by the specified data
|
||||
* provider and image path.
|
||||
*/
|
||||
public ImageKey getImageKey (ImageDataProvider daprov, String path)
|
||||
{
|
||||
return new ImageKey(daprov, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the image identified by the specified key, caching if possible. The image will be
|
||||
* recolored using the supplied colorizations if requested.
|
||||
*/
|
||||
public BufferedImage getImage (ImageKey key, Colorization[] zations)
|
||||
{
|
||||
CacheRecord crec = null;
|
||||
synchronized (_ccache) {
|
||||
crec = (CacheRecord)_ccache.get(key);
|
||||
}
|
||||
if (crec != null) {
|
||||
// Log.info("Cache hit [key=" + key + ", crec=" + crec + "].");
|
||||
return crec.getImage(zations, _ccache);
|
||||
}
|
||||
// Log.info("Cache miss [key=" + key + ", crec=" + crec + "].");
|
||||
|
||||
// load up the raw image
|
||||
BufferedImage image = loadImage(key);
|
||||
if (image == null) {
|
||||
Log.warning("Failed to load image " + key + ".");
|
||||
// create a blank image instead
|
||||
image = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_INDEXED);
|
||||
}
|
||||
|
||||
// Log.info("Loaded " + key.path + ", image=" + image +
|
||||
// ", size=" + ImageUtil.getEstimatedMemoryUsage(image));
|
||||
|
||||
// create a cache record
|
||||
crec = new CacheRecord(key, image);
|
||||
synchronized (_ccache) {
|
||||
_ccache.put(key, crec);
|
||||
}
|
||||
_keySet.add(key);
|
||||
|
||||
// periodically report our image cache performance
|
||||
reportCachePerformance();
|
||||
|
||||
return crec.getImage(zations, _ccache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mirage which is an image optimized for display on our current display device and
|
||||
* which will be stored into video memory if possible.
|
||||
*/
|
||||
public Mirage getMirage (String rsrcPath)
|
||||
{
|
||||
return getMirage(getImageKey(_defaultProvider, rsrcPath), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mirage which is an image optimized for display on our current display device and
|
||||
* which will be stored into video memory if possible.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key)
|
||||
{
|
||||
return getMirage(key, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey)} but that only the specified subimage of the source image
|
||||
* is used to build the mirage.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Rectangle bounds)
|
||||
{
|
||||
return getMirage(key, bounds, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey)} but the supplied colorizations are applied to the source
|
||||
* image before creating the mirage.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Colorization[] zations)
|
||||
{
|
||||
return getMirage(key, null, zations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getMirage(ImageKey,Colorization[])} except that the mirage is created using
|
||||
* only the specified subset of the original image.
|
||||
*/
|
||||
public Mirage getMirage (ImageKey key, Rectangle bounds, Colorization[] zations)
|
||||
{
|
||||
// We need to do something more complicated than the BaseImageManager because our
|
||||
// runtime adjustments may affect how we create our mirages.
|
||||
|
||||
BufferedImage src = null;
|
||||
|
||||
float percentageOfDataBuffer = 1;
|
||||
@@ -67,34 +337,202 @@ public class ImageManager extends BaseImageManager
|
||||
src = getImage(key, zations);
|
||||
bounds = new Rectangle(0, 0, src.getWidth(), src.getHeight());
|
||||
|
||||
} else if (!_prepareImages.getValue()) {
|
||||
src = getImage(key, zations);
|
||||
percentageOfDataBuffer =
|
||||
(bounds.width * bounds.height)/(float)(src.getHeight() * src.getWidth());
|
||||
src = src.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
if (_runBlank.getValue()) {
|
||||
return new BlankMirage(bounds.width, bounds.height);
|
||||
} else if (_prepareImages.getValue()) {
|
||||
return new CachedVolatileMirage(this, key, bounds, zations);
|
||||
} else {
|
||||
return new BufferedMirage(src, percentageOfDataBuffer);
|
||||
}
|
||||
return new CachedVolatileMirage(this, key, bounds, zations);
|
||||
|
||||
}
|
||||
|
||||
/** Register our image cache size with the runtime adjustments framework. */
|
||||
protected static RuntimeAdjust.IntAdjust _cacheSize = new RuntimeAdjust.IntAdjust(
|
||||
"Size (in kb of memory used) of the image manager LRU cache [requires restart]",
|
||||
"narya.media.image.cache_size", MediaPrefs.config, DEFAULT_CACHE_SIZE);
|
||||
/**
|
||||
* Returns the image creator that can be used to create buffered images optimized for rendering
|
||||
* to the screen.
|
||||
*/
|
||||
public OptimalImageCreator getImageCreator ()
|
||||
{
|
||||
return _icreator;
|
||||
}
|
||||
|
||||
/** Controls whether or not we prepare images or use raw versions. */
|
||||
protected static RuntimeAdjust.BooleanAdjust _prepareImages = new RuntimeAdjust.BooleanAdjust(
|
||||
"Cause image manager to optimize all images for display.",
|
||||
"narya.media.image.prep_images", MediaPrefs.config, true);
|
||||
/**
|
||||
* Returns the data provider configured to obtain image data from the specified resource set.
|
||||
*/
|
||||
protected ImageDataProvider getDataProvider (final String rset)
|
||||
{
|
||||
if (rset == null) {
|
||||
return _defaultProvider;
|
||||
}
|
||||
|
||||
/** A debug toggle for running entirely without rendering images. */
|
||||
protected static RuntimeAdjust.BooleanAdjust _runBlank = new RuntimeAdjust.BooleanAdjust(
|
||||
"Cause image manager to return blank images.",
|
||||
"narya.media.image.run_blank", MediaPrefs.config, false);
|
||||
}
|
||||
ImageDataProvider dprov = (ImageDataProvider)_providers.get(rset);
|
||||
if (dprov == null) {
|
||||
dprov = new ImageDataProvider() {
|
||||
public BufferedImage loadImage (String path)
|
||||
throws IOException {
|
||||
// first attempt to load the image from the specified resource set
|
||||
try {
|
||||
return _rmgr.getImageResource(rset, path);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
// fall back to trying the classpath
|
||||
return _rmgr.getImageResource(path);
|
||||
}
|
||||
}
|
||||
|
||||
public String getIdent () {
|
||||
return "rmgr:" + rset;
|
||||
}
|
||||
};
|
||||
_providers.put(rset, dprov);
|
||||
}
|
||||
|
||||
return dprov;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and returns the image with the specified key from the supplied data provider.
|
||||
*/
|
||||
protected BufferedImage loadImage (ImageKey key)
|
||||
{
|
||||
// if (EventQueue.isDispatchThread()) {
|
||||
// Log.info("Loading image on AWT thread " + key + ".");
|
||||
// }
|
||||
|
||||
BufferedImage image = null;
|
||||
try {
|
||||
Log.debug("Loading image " + key + ".");
|
||||
image = key.daprov.loadImage(key.path);
|
||||
if (image == null) {
|
||||
Log.warning("ImageDataProvider.loadImage(" + key + ") returned null.");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to load image '" + key + "'.");
|
||||
Log.logStackTrace(e);
|
||||
|
||||
// create a blank image in its stead
|
||||
image = createImage(1, 1, Transparency.OPAQUE);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports statistics detailing the image manager cache performance and the current size of the
|
||||
* cached images.
|
||||
*/
|
||||
protected void reportCachePerformance ()
|
||||
{
|
||||
if (/* Log.getLevel() != Log.log.DEBUG || */
|
||||
_cacheStatThrottle.throttleOp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute our estimated memory usage
|
||||
long size = 0;
|
||||
|
||||
int[] eff = null;
|
||||
synchronized (_ccache) {
|
||||
Iterator iter = _ccache.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
size += ((CacheRecord)iter.next()).getEstimatedMemoryUsage();
|
||||
}
|
||||
eff = _ccache.getTrackedEffectiveness();
|
||||
}
|
||||
Log.info("ImageManager LRU [mem=" + (size / 1024) + "k, size=" + _ccache.size() +
|
||||
", hits=" + eff[0] + ", misses=" + eff[1] + ", totalKeys=" + _keySet.size() + "].");
|
||||
}
|
||||
|
||||
/** Maintains a source image and a set of colorized versions in the image cache. */
|
||||
protected static class CacheRecord
|
||||
{
|
||||
public CacheRecord (ImageKey key, BufferedImage source)
|
||||
{
|
||||
_key = key;
|
||||
_source = source;
|
||||
}
|
||||
|
||||
public BufferedImage getImage (Colorization[] zations, LRUHashMap cache)
|
||||
{
|
||||
if (zations == null) {
|
||||
return _source;
|
||||
}
|
||||
|
||||
if (_colorized == null) {
|
||||
_colorized = new ArrayList<Tuple<Colorization[], BufferedImage>>();
|
||||
}
|
||||
|
||||
// we search linearly through our list of colorized copies because it is not likely to
|
||||
// be very long
|
||||
int csize = _colorized.size();
|
||||
for (int ii = 0; ii < csize; ii++) {
|
||||
Tuple<Colorization[], BufferedImage> tup = _colorized.get(ii);
|
||||
Colorization[] tzations = tup.left;
|
||||
if (Arrays.equals(zations, tzations)) {
|
||||
return tup.right;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
BufferedImage cimage = ImageUtil.recolorImage(_source, zations);
|
||||
_colorized.add(new Tuple<Colorization[], BufferedImage>(zations, cimage));
|
||||
cache.adjustSize((int)ImageUtil.getEstimatedMemoryUsage(cimage));
|
||||
return cimage;
|
||||
|
||||
} catch (Exception re) {
|
||||
Log.warning("Failure recoloring image [source" + _key +
|
||||
", zations=" + StringUtil.toString(zations) + ", error=" + re + "].");
|
||||
// return the uncolorized version
|
||||
return _source;
|
||||
}
|
||||
}
|
||||
|
||||
public long getEstimatedMemoryUsage ()
|
||||
{
|
||||
long usage = ImageUtil.getEstimatedMemoryUsage(_source);
|
||||
if (_colorized != null) {
|
||||
for (Tuple<Colorization[], BufferedImage> tup : _colorized) {
|
||||
usage += ImageUtil.getEstimatedMemoryUsage(tup.right);
|
||||
}
|
||||
}
|
||||
return usage;
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "[key=" + _key + ", wid=" + _source.getWidth() + ", hei=" + _source.getHeight() +
|
||||
", ccount=" + ((_colorized == null) ? 0 : _colorized.size()) + "]";
|
||||
}
|
||||
|
||||
protected ImageKey _key;
|
||||
protected BufferedImage _source;
|
||||
protected ArrayList<Tuple<Colorization[], BufferedImage>> _colorized;
|
||||
}
|
||||
|
||||
/** A reference to the resource manager via which we load image data by default. */
|
||||
protected ResourceManager _rmgr;
|
||||
|
||||
/** We use this to create images optimized for rendering. */
|
||||
protected OptimalImageCreator _icreator;
|
||||
|
||||
/** A cache of loaded images. */
|
||||
protected LRUHashMap _ccache;
|
||||
|
||||
/** The set of all keys we've ever seen. */
|
||||
protected HashSet _keySet = new HashSet();
|
||||
|
||||
/** Throttle our cache status logging to once every 300 seconds. */
|
||||
protected Throttle _cacheStatThrottle = new Throttle(1, 300000L);
|
||||
|
||||
/** Our default data provider. */
|
||||
protected ImageDataProvider _defaultProvider = new ImageDataProvider() {
|
||||
public BufferedImage loadImage (String path) throws IOException {
|
||||
return _rmgr.getImageResource(path);
|
||||
}
|
||||
public String getIdent () {
|
||||
return "rmgr:default";
|
||||
}
|
||||
};
|
||||
|
||||
/** Data providers for different resource sets. */
|
||||
protected HashMap _providers = new HashMap();
|
||||
|
||||
/** Default amount of data we'll store in our image cache. */
|
||||
protected static int DEFAULT_CACHE_SIZE = 32768;
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public abstract class VolatileMirage implements Mirage
|
||||
/**
|
||||
* Informs the base class of its image manager and image bounds.
|
||||
*/
|
||||
protected VolatileMirage (BaseImageManager imgr, Rectangle bounds)
|
||||
protected VolatileMirage (ImageManager imgr, Rectangle bounds)
|
||||
{
|
||||
_imgr = imgr;
|
||||
_bounds = bounds;
|
||||
@@ -186,7 +186,7 @@ public abstract class VolatileMirage implements Mirage
|
||||
}
|
||||
|
||||
/** The image manager with whom we interoperate. */
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** The bounds of the region of our source image which we desire for
|
||||
* this mirage (possibly the whole thing). */
|
||||
|
||||
@@ -24,7 +24,7 @@ package com.threerings.media.tile;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.ImageDataProvider;
|
||||
import com.threerings.media.image.Mirage;
|
||||
@@ -35,13 +35,13 @@ import com.threerings.media.image.Mirage;
|
||||
*/
|
||||
public class IMImageProvider implements ImageProvider
|
||||
{
|
||||
public IMImageProvider (BaseImageManager imgr, ImageDataProvider dprov)
|
||||
public IMImageProvider (ImageManager imgr, ImageDataProvider dprov)
|
||||
{
|
||||
_imgr = imgr;
|
||||
_dprov = dprov;
|
||||
}
|
||||
|
||||
public IMImageProvider (BaseImageManager imgr, String rset)
|
||||
public IMImageProvider (ImageManager imgr, String rset)
|
||||
{
|
||||
_imgr = imgr;
|
||||
_rset = rset;
|
||||
@@ -59,12 +59,12 @@ public class IMImageProvider implements ImageProvider
|
||||
return _imgr.getMirage(getImageKey(path), bounds, zations);
|
||||
}
|
||||
|
||||
protected final BaseImageManager.ImageKey getImageKey (String path)
|
||||
protected final ImageManager.ImageKey getImageKey (String path)
|
||||
{
|
||||
return (_dprov == null) ? _imgr.getImageKey(_rset, path) : _imgr.getImageKey(_dprov, path);
|
||||
}
|
||||
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
protected ImageDataProvider _dprov;
|
||||
protected String _rset;
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.threerings.media.image.Colorization;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.media.image.Mirage;
|
||||
|
||||
/**
|
||||
* Provides a generic interface via which tileset images may be loaded. In most cases, a running
|
||||
* application will want to obtain images via the {@link ImageManager}, but in some circumstances a
|
||||
* application will want to obtain images via the {@link ClientImageManager}, but in some circumstances a
|
||||
* simpler image provider may be desirable to avoid the overhead of the image manager
|
||||
* infrastructure when simple image loading is all that is desired.
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.HashMap;
|
||||
import com.samskivert.io.PersistenceException;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
|
||||
/**
|
||||
* The tile manager provides a simplified interface for retrieving and
|
||||
@@ -55,7 +55,7 @@ public class TileManager
|
||||
* @param imgr the image manager via which the tile manager will
|
||||
* decode and cache images.
|
||||
*/
|
||||
public TileManager (BaseImageManager imgr)
|
||||
public TileManager (ImageManager imgr)
|
||||
{
|
||||
_imgr = imgr;
|
||||
_defaultProvider = new IMImageProvider(_imgr, (String)null);
|
||||
@@ -242,7 +242,7 @@ public class TileManager
|
||||
}
|
||||
|
||||
/** The entity through which we decode and cache images. */
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** A cache of tilesets that have been loaded by hand. */
|
||||
protected HashMap _handcache = new HashMap();
|
||||
|
||||
@@ -30,7 +30,7 @@ import com.threerings.resource.ResourceBundle;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.tile.IMImageProvider;
|
||||
import com.threerings.media.tile.NoSuchTileSetException;
|
||||
import com.threerings.media.tile.TileSet;
|
||||
@@ -57,7 +57,7 @@ public class BundledTileSetRepository
|
||||
* loading our tile data.
|
||||
*/
|
||||
public BundledTileSetRepository (final ResourceManager rmgr,
|
||||
final BaseImageManager imgr,
|
||||
final ImageManager imgr,
|
||||
final String name)
|
||||
{
|
||||
_imgr = imgr;
|
||||
@@ -222,7 +222,7 @@ public class BundledTileSetRepository
|
||||
}
|
||||
|
||||
/** The image manager via which we load our images. */
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
|
||||
/** A mapping from tileset id to tileset. */
|
||||
protected HashIntMap _idmap;
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.HashMap;
|
||||
import com.samskivert.util.CheapIntMap;
|
||||
import com.samskivert.util.QuickSort;
|
||||
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.BufferedMirage;
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
|
||||
@@ -53,7 +53,7 @@ public class AutoFringer
|
||||
* Constructs an instance that will fringe according to the rules in
|
||||
* the supplied fringe configuration.
|
||||
*/
|
||||
public AutoFringer (FringeConfiguration fringeconf, BaseImageManager imgr,
|
||||
public AutoFringer (FringeConfiguration fringeconf, ImageManager imgr,
|
||||
TileManager tmgr)
|
||||
{
|
||||
_fringeconf = fringeconf;
|
||||
@@ -399,7 +399,7 @@ public class AutoFringer
|
||||
}
|
||||
}
|
||||
|
||||
protected BaseImageManager _imgr;
|
||||
protected ImageManager _imgr;
|
||||
protected TileManager _tmgr;
|
||||
protected FringeConfiguration _fringeconf;
|
||||
protected CheapIntMap _fringers = new CheapIntMap(16);
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.samskivert.io.StreamUtil;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
import com.threerings.util.CompiledConfig;
|
||||
|
||||
import com.threerings.media.image.BaseImageManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.tile.TileManager;
|
||||
|
||||
import com.threerings.miso.Log;
|
||||
@@ -47,7 +47,7 @@ public class MisoTileManager extends TileManager
|
||||
* @param imgr the image manager via which the tile manager will
|
||||
* decode and cache images.
|
||||
*/
|
||||
public MisoTileManager (ResourceManager rmgr, BaseImageManager imgr)
|
||||
public MisoTileManager (ResourceManager rmgr, ImageManager imgr)
|
||||
{
|
||||
super(imgr);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import javax.swing.JPanel;
|
||||
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
import com.threerings.util.DirectionCodes;
|
||||
import com.threerings.util.DirectionUtil;
|
||||
@@ -123,7 +123,7 @@ public class CharSpriteViz extends JPanel
|
||||
ResourceManager rmgr = new ResourceManager("rsrc");
|
||||
rmgr.initBundles(
|
||||
null, "config/resource/manager.properties", null);
|
||||
ImageManager imgr = new ImageManager(rmgr, frame);
|
||||
ClientImageManager imgr = new ClientImageManager(rmgr, frame);
|
||||
ComponentRepository crepo =
|
||||
new BundledComponentRepository(rmgr, imgr, "components");
|
||||
CharacterManager charmgr = new CharacterManager(imgr, crepo);
|
||||
|
||||
@@ -26,7 +26,7 @@ import javax.swing.JFrame;
|
||||
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
import com.threerings.cast.CharacterManager;
|
||||
@@ -45,7 +45,7 @@ public class TestApp
|
||||
ResourceManager rmgr = new ResourceManager("rsrc");
|
||||
rmgr.initBundles(
|
||||
null, "config/resource/manager.properties", null);
|
||||
ImageManager imgr = new ImageManager(rmgr, _frame);
|
||||
ClientImageManager imgr = new ClientImageManager(rmgr, _frame);
|
||||
|
||||
ComponentRepository crepo =
|
||||
new BundledComponentRepository(rmgr, imgr, "components");
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.awt.Component;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.threerings.cast.ComponentClass;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
import junit.framework.Test;
|
||||
@@ -44,7 +44,7 @@ public class BundledComponentRepositoryTest extends TestCase
|
||||
ResourceManager rmgr = new ResourceManager("rsrc");
|
||||
rmgr.initBundles(
|
||||
null, "config/resource/manager.properties", null);
|
||||
ImageManager imgr = new ImageManager(rmgr, (Component)null);
|
||||
ClientImageManager imgr = new ClientImageManager(rmgr, (Component)null);
|
||||
BundledComponentRepository repo =
|
||||
new BundledComponentRepository(rmgr, imgr, "components");
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import javax.swing.*;
|
||||
import com.samskivert.swing.HGroupLayout;
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.media.tile.TileManager;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class TestIconManager
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
ResourceManager rmgr = new ResourceManager("rsrc");
|
||||
ImageManager imgr = new ImageManager(rmgr, frame);
|
||||
ClientImageManager imgr = new ClientImageManager(rmgr, frame);
|
||||
TileManager tmgr = new TileManager(imgr);
|
||||
IconManager iconmgr = new IconManager(
|
||||
tmgr, "rsrc/config/media/iconmgr.properties");
|
||||
|
||||
@@ -24,7 +24,7 @@ package com.threerings.media.tile.bundle;
|
||||
import java.awt.Component;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
import junit.framework.Test;
|
||||
@@ -44,7 +44,7 @@ public class BundledTileSetRepositoryTest extends TestCase
|
||||
rmgr.initBundles(
|
||||
null, "config/resource/manager.properties", null);
|
||||
BundledTileSetRepository repo = new BundledTileSetRepository(
|
||||
rmgr, new ImageManager(rmgr, (Component)null), "tilesets");
|
||||
rmgr, new ClientImageManager(rmgr, (Component)null), "tilesets");
|
||||
Iterator sets = repo.enumerateTileSets();
|
||||
while (sets.hasNext()) {
|
||||
sets.next();
|
||||
|
||||
@@ -39,7 +39,7 @@ import com.samskivert.swing.VGroupLayout;
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.media.image.ImageUtil;
|
||||
|
||||
/**
|
||||
@@ -53,7 +53,7 @@ public class TraceViz
|
||||
// create the frame and image manager
|
||||
_frame = new JFrame();
|
||||
_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
ImageManager imgr = new ImageManager(null, _frame);
|
||||
ClientImageManager imgr = new ClientImageManager(null, _frame);
|
||||
|
||||
// set up the content panel
|
||||
JPanel content = (JPanel)_frame.getContentPane();
|
||||
|
||||
@@ -34,7 +34,7 @@ import com.samskivert.util.Config;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
import com.threerings.media.FrameManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.media.util.LinePath;
|
||||
import com.threerings.media.util.Path;
|
||||
|
||||
@@ -94,7 +94,7 @@ public class ScrollingTestApp
|
||||
ResourceManager rmgr = new ResourceManager("rsrc");
|
||||
rmgr.initBundles(
|
||||
null, "config/resource/manager.properties", null);
|
||||
ImageManager imgr = new ImageManager(rmgr, _frame);
|
||||
ClientImageManager imgr = new ClientImageManager(rmgr, _frame);
|
||||
_tilemgr = new MisoTileManager(rmgr, imgr);
|
||||
_tilemgr.setTileSetRepository(
|
||||
new BundledTileSetRepository(rmgr, imgr, "tilesets"));
|
||||
|
||||
@@ -32,7 +32,7 @@ import com.samskivert.swing.util.SwingUtil;
|
||||
import com.threerings.resource.ResourceManager;
|
||||
|
||||
import com.threerings.media.FrameManager;
|
||||
import com.threerings.media.image.ImageManager;
|
||||
import com.threerings.media.image.ClientImageManager;
|
||||
import com.threerings.media.tile.bundle.BundledTileSetRepository;
|
||||
|
||||
import com.threerings.cast.CharacterManager;
|
||||
@@ -87,7 +87,7 @@ public class ViewerApp
|
||||
ResourceManager rmgr = new ResourceManager("rsrc");
|
||||
rmgr.initBundles(
|
||||
null, "config/resource/manager.properties", null);
|
||||
ImageManager imgr = new ImageManager(rmgr, _frame);
|
||||
ClientImageManager imgr = new ClientImageManager(rmgr, _frame);
|
||||
_tilemgr = new MisoTileManager(rmgr, imgr);
|
||||
_tilemgr.setTileSetRepository(
|
||||
new BundledTileSetRepository(rmgr, imgr, "tilesets"));
|
||||
|
||||
Reference in New Issue
Block a user