From 73a4a02aa14baadec3450fea4339315be08bce40 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Sat, 31 May 2003 00:56:38 +0000 Subject: [PATCH] A few substantial changes: - Tiles are initialized after being constructed which makes life simpler for custom tiles which no longer have to have their own constructor that passes Tile's stuff down to it. - Tiles are no longer LRU cached (because we blow through that cache instantly on all but the smallest of scenes), and are now tracked by weak references so that we guarantee that only one instance of a tile is ever in memory. - Added code to track and report memory usage of weak cached tiles as well as "stray" tiles which are created through other means than asking a TileSet for a tile (fringe tiles being the most prolific example). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2628 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/media/image/ImageManager.java | 15 +- .../com/threerings/media/tile/ObjectTile.java | 12 +- .../threerings/media/tile/ObjectTileSet.java | 31 ++-- src/java/com/threerings/media/tile/Tile.java | 98 ++++++++--- .../com/threerings/media/tile/TileSet.java | 163 +++++------------- .../media/tile/TrimmedObjectTileSet.java | 23 ++- .../threerings/media/tile/TrimmedTile.java | 12 +- .../threerings/media/tile/TrimmedTileSet.java | 15 +- .../miso/client/MisoScenePanel.java | 24 ++- .../threerings/miso/client/SceneBlock.java | 63 ++++++- .../miso/client/SceneBlockResolver.java | 10 +- .../com/threerings/miso/tile/AutoFringer.java | 6 +- .../com/threerings/miso/tile/BaseTile.java | 29 +--- .../com/threerings/miso/tile/BaseTileSet.java | 15 +- .../com/threerings/miso/tile/FringeTile.java | 53 ------ 15 files changed, 286 insertions(+), 283 deletions(-) delete mode 100644 src/java/com/threerings/miso/tile/FringeTile.java diff --git a/src/java/com/threerings/media/image/ImageManager.java b/src/java/com/threerings/media/image/ImageManager.java index 86c465255..ef1559b5f 100644 --- a/src/java/com/threerings/media/image/ImageManager.java +++ b/src/java/com/threerings/media/image/ImageManager.java @@ -1,5 +1,5 @@ // -// $Id: ImageManager.java,v 1.55 2003/05/02 23:09:28 mdb Exp $ +// $Id: ImageManager.java,v 1.56 2003/05/31 00:56:38 mdb Exp $ package com.threerings.media.image; @@ -111,19 +111,6 @@ public class ImageManager } } - /** - * Used to disable the flushing of cached images temporarily. If one - * wishes to avoid garbage collection for a short period of time, they - * may disable image flushing during that period. A call to {@link - * System#gc} is probably a good idea once flushing is reenabled. - */ - public void setCanFlushCache (boolean enabled) - { - synchronized (_ccache) { - _ccache.setCanFlush(enabled); - } - } - /** * Creates a buffered image, optimized for display on our graphics * device. diff --git a/src/java/com/threerings/media/tile/ObjectTile.java b/src/java/com/threerings/media/tile/ObjectTile.java index 1de11e541..ac1d311e6 100644 --- a/src/java/com/threerings/media/tile/ObjectTile.java +++ b/src/java/com/threerings/media/tile/ObjectTile.java @@ -1,5 +1,5 @@ // -// $Id: ObjectTile.java,v 1.16 2003/02/12 05:33:18 mdb Exp $ +// $Id: ObjectTile.java,v 1.17 2003/05/31 00:56:38 mdb Exp $ package com.threerings.media.tile; @@ -8,7 +8,6 @@ import java.awt.Point; import com.samskivert.util.StringUtil; -import com.threerings.media.image.Mirage; import com.threerings.util.DirectionUtil; /** @@ -28,15 +27,6 @@ import com.threerings.util.DirectionUtil; */ public class ObjectTile extends Tile { - /** - * Constructs a new object tile with the specified image. The base - * width and height should be set before using this tile. - */ - public ObjectTile (Mirage image) - { - super(image); - } - /** * Returns the object footprint width in tile units. */ diff --git a/src/java/com/threerings/media/tile/ObjectTileSet.java b/src/java/com/threerings/media/tile/ObjectTileSet.java index 048396359..1a04f0152 100644 --- a/src/java/com/threerings/media/tile/ObjectTileSet.java +++ b/src/java/com/threerings/media/tile/ObjectTileSet.java @@ -1,11 +1,10 @@ // -// $Id: ObjectTileSet.java,v 1.16 2003/05/13 02:16:21 mdb Exp $ +// $Id: ObjectTileSet.java,v 1.17 2003/05/31 00:56:38 mdb Exp $ package com.threerings.media.tile; import com.samskivert.util.StringUtil; -import com.threerings.media.image.Mirage; import com.threerings.media.image.Colorization; /** @@ -159,27 +158,31 @@ public class ObjectTileSet extends SwissArmyTileSet return zations; } - /** - * Creates instances of {@link ObjectTile}, which can span more than a - * single tile's space in a display. - */ - protected Tile createTile (int tileIndex, Mirage image) + // documentation inherited + protected Tile createTile () { - ObjectTile tile = new ObjectTile(image); + return new ObjectTile(); + } + + // documentation inherited + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + super.initTile(tile, tileIndex, zations); + + ObjectTile otile = (ObjectTile)tile; if (_owidths != null) { - tile.setBase(_owidths[tileIndex], _oheights[tileIndex]); + otile.setBase(_owidths[tileIndex], _oheights[tileIndex]); } if (_xorigins != null) { - tile.setOrigin(_xorigins[tileIndex], _yorigins[tileIndex]); + otile.setOrigin(_xorigins[tileIndex], _yorigins[tileIndex]); } if (_priorities != null) { - tile.setPriority(_priorities[tileIndex]); + otile.setPriority(_priorities[tileIndex]); } if (_xspots != null) { - tile.setSpot(_xspots[tileIndex], _yspots[tileIndex], - _sorients[tileIndex]); + otile.setSpot(_xspots[tileIndex], _yspots[tileIndex], + _sorients[tileIndex]); } - return tile; } /** The width (in tile units) of our object tiles. */ diff --git a/src/java/com/threerings/media/tile/Tile.java b/src/java/com/threerings/media/tile/Tile.java index 07e737963..a622574ca 100644 --- a/src/java/com/threerings/media/tile/Tile.java +++ b/src/java/com/threerings/media/tile/Tile.java @@ -1,26 +1,71 @@ // -// $Id: Tile.java,v 1.27 2003/01/17 02:30:50 mdb Exp $ +// $Id: Tile.java,v 1.28 2003/05/31 00:56:38 mdb Exp $ package com.threerings.media.tile; import java.awt.Graphics2D; +import java.util.Arrays; +import com.threerings.media.image.Colorization; import com.threerings.media.image.Mirage; /** * A tile represents a single square in a single layer in a scene. */ -public class Tile implements Cloneable +public class Tile // implements Cloneable { - /** - * Constructs a tile with the specified image. - * - * @param image our tile image in mirage form (which is optimized for - * screen rendering). - */ - public Tile (Mirage image) + /** Used when caching tiles. */ + public static class Key { + public TileSet tileSet; + public int tileIndex; + public Colorization[] zations; + + public Key (TileSet tileSet, int tileIndex, Colorization[] zations) { + this.tileSet = tileSet; + this.tileIndex = tileIndex; + this.zations = zations; + } + + public boolean equals (Object other) { + if (other instanceof Key) { + Key okey = (Key)other; + return (tileSet == okey.tileSet && + tileIndex == okey.tileIndex && + Arrays.equals(zations, okey.zations)); + } else { + return false; + } + } + + public int hashCode () { + int code = (tileSet == null) ? tileIndex : + (tileSet.hashCode() ^ tileIndex); + int zcount = (zations == null) ? 0 : zations.length; + for (int ii = 0; ii < zcount; ii++) { + if (zations[ii] != null) { + code ^= zations[ii].hashCode(); + } + } + return code; + } + } + + /** The key associated with this tile. */ + public Key key; + + /** + * Configures this tile with its tile image. + */ + public void setImage (Mirage image) + { + if (_mirage != null) { + _totalTileMemory -= _mirage.getEstimatedMemoryUsage(); + } _mirage = image; + if (_mirage != null) { + _totalTileMemory += _mirage.getEstimatedMemoryUsage(); + } } /** @@ -65,18 +110,18 @@ public class Tile implements Cloneable return _mirage.hitTest(x, y); } - /** - * Creates a shallow copy of this tile object. - */ - public Object clone () - { - try { - return (Tile)super.clone(); - } catch (CloneNotSupportedException cnse) { - String errmsg = "All is wrong with the universe: " + cnse; - throw new RuntimeException(errmsg); - } - } +// /** +// * Creates a shallow copy of this tile object. +// */ +// public Object clone () +// { +// try { +// return (Tile)super.clone(); +// } catch (CloneNotSupportedException cnse) { +// String errmsg = "All is wrong with the universe: " + cnse; +// throw new RuntimeException(errmsg); +// } +// } /** * Return a string representation of this tile. @@ -99,6 +144,17 @@ public class Tile implements Cloneable buf.append(_mirage.getHeight()); } + /** Decrement total tile memory by our value. */ + protected void finalize () + { + if (_mirage != null) { + _totalTileMemory -= _mirage.getEstimatedMemoryUsage(); + } + } + /** Our tileset image. */ protected Mirage _mirage; + + /** Used to track total (estimated) memory in use by tiles. */ + protected static long _totalTileMemory = 0L; } diff --git a/src/java/com/threerings/media/tile/TileSet.java b/src/java/com/threerings/media/tile/TileSet.java index b85375925..c10f82031 100644 --- a/src/java/com/threerings/media/tile/TileSet.java +++ b/src/java/com/threerings/media/tile/TileSet.java @@ -1,5 +1,5 @@ // -// $Id: TileSet.java,v 1.53 2003/05/17 18:39:26 mdb Exp $ +// $Id: TileSet.java,v 1.54 2003/05/31 00:56:38 mdb Exp $ package com.threerings.media.tile; @@ -8,11 +8,11 @@ import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.Serializable; -import java.util.Arrays; +import java.lang.ref.WeakReference; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import com.samskivert.util.LRUHashMap; import com.samskivert.util.RuntimeAdjust; import com.samskivert.util.StringUtil; import com.samskivert.util.Throttle; @@ -191,21 +191,25 @@ public abstract class TileSet */ public Tile getTile (int tileIndex, Colorization[] zations) { - TileKey key = new TileKey(this, tileIndex, zations); + Tile.Key key = new Tile.Key(this, tileIndex, zations); Tile tile = null; - synchronized (_tiles) { - tile = (Tile)_tiles.get(key); + + // first look in the active set; if it's in use by anyone or in + // the cache, it will be in the active set + synchronized (_atiles) { + WeakReference wref = (WeakReference)_atiles.get(key); + if (wref != null) { + tile = (Tile)wref.get(); + } } + + // if it's not in the active set, it's not in memory; so load it if (tile == null) { - tile = createTile(tileIndex, getTileMirage(tileIndex, zations)); - initTile(tile); - synchronized (_tiles) { - _tiles.put(key, tile); - if (_keySet != null) { - _keySet.add(key); - } else { - Log.warning("What in the fuck is going on?"); - } + tile = createTile(); + tile.key = key; + initTile(tile, tileIndex, zations); + synchronized (_atiles) { + _atiles.put(key, new WeakReference(tile)); } } @@ -314,16 +318,14 @@ public abstract class TileSet protected abstract Rectangle computeTileBounds (int tileIndex); /** - * Creates a tile for the specified tile index. + * Creates a blank tile of the appropriate type for this tileset. * - * @param tileIndex the index of the tile to be created. - * @param image the tile image in the form of a {@link Mirage}. - * - * @return a configured tile. + * @return a blank tile ready to be populated with its image and + * metadata. */ - protected Tile createTile (int tileIndex, Mirage image) + protected Tile createTile () { - return new Tile(image); + return new Tile(); } /** @@ -332,10 +334,13 @@ public abstract class TileSet * call super.initTile(). * * @param tile the tile to initialize. + * @param tileIndex the index of the tile. + * @param zations the colorizations to be used when generating the + * tile image. */ - protected void initTile (Tile tile) + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) { - // nothing for now + tile.setImage(getTileMirage(tileIndex, zations)); } /** @@ -348,21 +353,6 @@ public abstract class TileSet return buf.append("]").toString(); } - /** - * Used to disable the flushing of cached tiles temporarily. If one - * wishes to avoid garbage collection for a short period of time, they - * may disable tile flushing during that period. A call to {@link - * System#gc} is probably a good idea once flushing is reenabled. - */ - public static void setCanFlushCache (boolean enabled) - { - if (_tiles != null) { - synchronized (_tiles) { - _tiles.setCanFlush(enabled); - } - } - } - /** * Reports statistics detailing the image manager cache performance * and the current size of the cached images. @@ -374,20 +364,26 @@ public abstract class TileSet return; } - // compute our estimated memory usage - long size = 0; + System.gc(); - int[] eff = null; - synchronized (_tiles) { - Iterator iter = _tiles.values().iterator(); + // compute our estimated memory usage + long amem = 0; + int asize = 0; + synchronized (_atiles) { + // first total up the active tiles + Iterator iter = _atiles.values().iterator(); while (iter.hasNext()) { - size += ((Tile)iter.next()).getEstimatedMemoryUsage(); + WeakReference wref = (WeakReference)iter.next(); + Tile tile = (Tile)wref.get(); + if (tile != null) { + asize++; + amem += tile.getEstimatedMemoryUsage(); + } } - eff = _tiles.getTrackedEffectiveness(); } - Log.info("TileSet LRU [mem=" + (size / 1024) + "k" + - ", size=" + _tiles.size() + ", hits=" + eff[0] + - ", misses=" + eff[1] + ", totalKeys=" + _keySet.size() + "]."); + Log.info("Tile caches [amem=" + (amem / 1024) + "k" + + ", tmem=" + (Tile._totalTileMemory / 1024) + "k" + + ", seen=" + _atiles.size() + ", asize=" + asize + "]."); } /** @@ -402,49 +398,6 @@ public abstract class TileSet buf.append(", tileCount=").append(getTileCount()); } - /** Used when caching tiles. */ - protected static class TileKey - { - /** - * Creates a new tile key. - */ - public TileKey (TileSet tileSet, int tileIndex, Colorization[] zations) - { - _tset = tileSet; - _tidx = tileIndex; - _zations = zations; - } - - // documentation inherited - public boolean equals (Object other) - { - if (other instanceof TileKey) { - TileKey okey = (TileKey)other; - return (_tset == okey._tset && _tidx == okey._tidx && - Arrays.equals(_zations, okey._zations)); - } else { - return false; - } - } - - // documentation inherited - public int hashCode () - { - int code = _tset.hashCode() ^ _tidx; - int zcount = (_zations == null) ? 0 : _zations.length; - for (int ii = 0; ii < zcount; ii++) { - if (_zations[ii] != null) { - code ^= _zations[ii].hashCode(); - } - } - return code; - } - - protected TileSet _tset; - protected int _tidx; - protected Colorization[] _zations; - } - /** The path to the file containing the tile images. */ protected String _imagePath; @@ -461,31 +414,9 @@ public abstract class TileSet * a class change (modification of fields, inheritance). */ private static final long serialVersionUID = 1; - /** A weak cache of our tiles. */ - protected static LRUHashMap _tiles; - - /** The set of all keys we've ever seen. */ - protected static HashSet _keySet = new HashSet(); + /** A map containing weak references to all "active" tiles. */ + protected static HashMap _atiles = new HashMap(); /** Throttle our cache status logging to once every 30 seconds. */ protected static Throttle _cacheStatThrottle = new Throttle(1, 30000L); - - /** Register our tile cache size with the runtime adjustments - * framework. */ - protected static RuntimeAdjust.IntAdjust _cacheSize = - new RuntimeAdjust.IntAdjust( - "Size (in kb of memory used) of the tile LRU cache " + - "[requires restart]", "narya.media.tile.cache_size", - MediaPrefs.config, 2048); - - static { - int tcsize = _cacheSize.getValue(); - Log.debug("Creating tile cache [size=" + tcsize + "k]."); - _tiles = new LRUHashMap(tcsize*1024, new LRUHashMap.ItemSizer() { - public int computeSize (Object value) { - return (int)((Tile)value).getEstimatedMemoryUsage(); - } - }); - _tiles.setTracking(true); - } } diff --git a/src/java/com/threerings/media/tile/TrimmedObjectTileSet.java b/src/java/com/threerings/media/tile/TrimmedObjectTileSet.java index ad65ccfa3..79ee517e4 100644 --- a/src/java/com/threerings/media/tile/TrimmedObjectTileSet.java +++ b/src/java/com/threerings/media/tile/TrimmedObjectTileSet.java @@ -1,5 +1,5 @@ // -// $Id: TrimmedObjectTileSet.java,v 1.12 2003/05/27 18:25:04 mdb Exp $ +// $Id: TrimmedObjectTileSet.java,v 1.13 2003/05/31 00:56:38 mdb Exp $ package com.threerings.media.tile; @@ -104,19 +104,26 @@ public class TrimmedObjectTileSet extends TileSet } // documentation inherited - protected Tile createTile (int tileIndex, Mirage tileImage) + protected Tile createTile () { - ObjectTile tile = new ObjectTile(tileImage); - tile.setBase(_ometrics[tileIndex].width, _ometrics[tileIndex].height); - tile.setOrigin(_ometrics[tileIndex].x, _ometrics[tileIndex].y); + return new ObjectTile(); + } + + // documentation inherited + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + super.initTile(tile, tileIndex, zations); + + ObjectTile otile = (ObjectTile)tile; + otile.setBase(_ometrics[tileIndex].width, _ometrics[tileIndex].height); + otile.setOrigin(_ometrics[tileIndex].x, _ometrics[tileIndex].y); if (_bits != null) { Bits bits = _bits[tileIndex]; - tile.setPriority(bits.priority); + otile.setPriority(bits.priority); if (bits.sorient != -1) { - tile.setSpot(bits.xspot, bits.yspot, bits.sorient); + otile.setSpot(bits.xspot, bits.yspot, bits.sorient); } } - return tile; } // documentation inherited diff --git a/src/java/com/threerings/media/tile/TrimmedTile.java b/src/java/com/threerings/media/tile/TrimmedTile.java index 9fb102f7c..790e5249f 100644 --- a/src/java/com/threerings/media/tile/TrimmedTile.java +++ b/src/java/com/threerings/media/tile/TrimmedTile.java @@ -1,5 +1,5 @@ // -// $Id: TrimmedTile.java,v 1.5 2003/01/13 22:49:46 mdb Exp $ +// $Id: TrimmedTile.java,v 1.6 2003/05/31 00:56:38 mdb Exp $ package com.threerings.media.tile; @@ -8,8 +8,6 @@ import java.awt.Rectangle; import com.samskivert.util.StringUtil; -import com.threerings.media.image.Mirage; - /** * Behaves just like a regular tile, but contains a "trimmed" image which * is one where the source image has been trimmed to the smallest @@ -19,18 +17,14 @@ import com.threerings.media.image.Mirage; public class TrimmedTile extends Tile { /** - * Creates a trimmed tile using the supplied tileset image with the - * specified bounds and coordinates. + * Sets the trimmed bounds of this tile. * - * @param tilesetSource the tileset image that contains our trimmed - * tile image. * @param tbounds contains the width and height of the * untrimmed tile, but the x and y offset of the * trimmed tile image in the original untrimmed tile image. */ - public TrimmedTile (Mirage image, Rectangle tbounds) + public void setTrimmedBounds (Rectangle tbounds) { - super(image); _tbounds = tbounds; } diff --git a/src/java/com/threerings/media/tile/TrimmedTileSet.java b/src/java/com/threerings/media/tile/TrimmedTileSet.java index 9fbef6c1d..b5bd0a474 100644 --- a/src/java/com/threerings/media/tile/TrimmedTileSet.java +++ b/src/java/com/threerings/media/tile/TrimmedTileSet.java @@ -1,5 +1,5 @@ // -// $Id: TrimmedTileSet.java,v 1.6 2003/01/13 22:49:46 mdb Exp $ +// $Id: TrimmedTileSet.java,v 1.7 2003/05/31 00:56:38 mdb Exp $ package com.threerings.media.tile; @@ -8,7 +8,7 @@ import java.awt.Rectangle; import java.io.IOException; import java.io.OutputStream; -import com.threerings.media.image.Mirage; +import com.threerings.media.image.Colorization; import com.threerings.media.tile.util.TileSetTrimmer; /** @@ -30,9 +30,16 @@ public class TrimmedTileSet extends TileSet } // documentation inherited - protected Tile createTile (int tileIndex, Mirage image) + protected Tile createTile () { - return new TrimmedTile(image, _tbounds[tileIndex]); + return new TrimmedTile(); + } + + // documentation inherited + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + super.initTile(tile, tileIndex, zations); + ((TrimmedTile)tile).setTrimmedBounds(_tbounds[tileIndex]); } /** diff --git a/src/java/com/threerings/miso/client/MisoScenePanel.java b/src/java/com/threerings/miso/client/MisoScenePanel.java index cd180c396..ab9f3dffe 100644 --- a/src/java/com/threerings/miso/client/MisoScenePanel.java +++ b/src/java/com/threerings/miso/client/MisoScenePanel.java @@ -1,5 +1,5 @@ // -// $Id: MisoScenePanel.java,v 1.40 2003/05/29 01:04:58 ray Exp $ +// $Id: MisoScenePanel.java,v 1.41 2003/05/31 00:56:38 mdb Exp $ package com.threerings.miso.client; @@ -280,6 +280,27 @@ public class MisoScenePanel extends VirtualMediaPanel } } + /** + * Reports the memory usage of the resolved tiles in the current scene + * block. + */ + public void reportMemoryUsage () + { + HashMap base = new HashMap(); + HashSet fringe = new HashSet(); + HashMap object = new HashMap(); + long[] usage = new long[3]; + for (Iterator iter = _blocks.values().iterator(); iter.hasNext(); ) { + SceneBlock block = (SceneBlock)iter.next(); + block.computeMemoryUsage(base, fringe, object, usage); + } + Log.info("Scene tile memory usage [base=" + base.size() + + "->" + (usage[0] / 1024) + "k" + + ", fringe=" + fringe.size() + "->" + (usage[1] / 1024) + "k" + + ", fmasks=" + _masks.size() + ", obj=" + object.size() + + "->" + (usage[2] / 1024) + "k" + "]."); + } + // documentation inherited public void addNotify () { @@ -803,6 +824,7 @@ public class MisoScenePanel extends VirtualMediaPanel if (_pendingBlocks == 0) { Log.info("Finished resolving pending blocks " + "[view=" + StringUtil.toString(_vbounds) + "]."); + reportMemoryUsage(); } // once all the visible pending blocks have completed their diff --git a/src/java/com/threerings/miso/client/SceneBlock.java b/src/java/com/threerings/miso/client/SceneBlock.java index e66aba091..46485d5ce 100644 --- a/src/java/com/threerings/miso/client/SceneBlock.java +++ b/src/java/com/threerings/miso/client/SceneBlock.java @@ -1,11 +1,13 @@ // -// $Id: SceneBlock.java,v 1.18 2003/05/29 01:59:17 ray Exp $ +// $Id: SceneBlock.java,v 1.19 2003/05/31 00:56:38 mdb Exp $ package com.threerings.miso.client; import java.awt.Polygon; import java.awt.Rectangle; import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; import com.samskivert.util.ArrayUtil; import com.samskivert.util.HashIntMap; @@ -14,6 +16,7 @@ import com.samskivert.util.StringUtil; import com.threerings.geom.GeomUtil; import com.threerings.media.tile.NoSuchTileException; import com.threerings.media.tile.NoSuchTileSetException; +import com.threerings.media.tile.ObjectTile; import com.threerings.media.tile.Tile; import com.threerings.media.tile.TileManager; import com.threerings.media.tile.TileSet; @@ -335,6 +338,64 @@ public class SceneBlock return !_covered[index(tx, ty)] && (base != null && base.isPassable()); } + /** + * Computes the memory usage of the base and object tiles in this + * scene block; registering counted tiles in the hash map so that + * other blocks can be sure not to double count them. Base tile usage + * is placed into the zeroth array element, fringe tile usage into the + * first and object tile usage into the second. + */ + public void computeMemoryUsage ( + HashMap bases, HashSet fringes, HashMap objects, long[] usage) + { + // account for our base tiles + MisoSceneModel model = _panel.getSceneModel(); + for (int yy = 0; yy < _bounds.height; yy++) { + for (int xx = 0; xx < _bounds.width; xx++) { + int x = _bounds.x + xx, y = _bounds.y + yy; + int tidx = index(x, y); + BaseTile base = _base[tidx]; + if (base == null) { + continue; + } + + BaseTile sbase = (BaseTile)bases.get(base.key); + if (sbase == null) { + bases.put(base.key, base); + usage[0] += base.getEstimatedMemoryUsage(); + } else if (base != _base[tidx]) { + Log.warning("Multiple instances of same base tile " + + "[base=" + base + + ", x=" + xx + ", y=" + yy + "]."); + usage[0] += base.getEstimatedMemoryUsage(); + } + + // now account for the fringe + if (_fringe[tidx] == null) { + continue; + } else if (!fringes.contains(_fringe[tidx])) { + fringes.add(_fringe[tidx]); + usage[1] += _fringe[tidx].getEstimatedMemoryUsage(); + } + } + } + + // now get the object tiles + int ocount = (_objects == null) ? 0 : _objects.length; + for (int ii = 0; ii < ocount; ii++) { + SceneObject scobj = _objects[ii]; + ObjectTile tile = (ObjectTile)objects.get(scobj.tile.key); + if (tile == null) { + objects.put(scobj.tile.key, scobj.tile); + usage[2] += scobj.tile.getEstimatedMemoryUsage(); + } else if (tile != scobj.tile) { + Log.warning("Multiple instances of same object tile: " + + scobj.info + "."); + usage[2] += scobj.tile.getEstimatedMemoryUsage(); + } + } + } + /** * Returns a string representation of this instance. */ diff --git a/src/java/com/threerings/miso/client/SceneBlockResolver.java b/src/java/com/threerings/miso/client/SceneBlockResolver.java index f3e8a60f8..7b17a1ef0 100644 --- a/src/java/com/threerings/miso/client/SceneBlockResolver.java +++ b/src/java/com/threerings/miso/client/SceneBlockResolver.java @@ -1,5 +1,5 @@ // -// $Id: SceneBlockResolver.java,v 1.8 2003/05/23 19:35:11 mdb Exp $ +// $Id: SceneBlockResolver.java,v 1.9 2003/05/31 00:56:38 mdb Exp $ package com.threerings.miso.client; @@ -93,10 +93,10 @@ public class SceneBlockResolver extends LoopingThread // let the block's panel know that it is resolved block.wasResolved(); // report statistics - if (report) { - Log.info("Resolution histogram " + - _histo.summarize() + "."); - } +// if (report) { +// Log.info("Resolution histogram " + +// _histo.summarize() + "."); +// } } }); diff --git a/src/java/com/threerings/miso/tile/AutoFringer.java b/src/java/com/threerings/miso/tile/AutoFringer.java index 2775438b8..59c9636e3 100644 --- a/src/java/com/threerings/miso/tile/AutoFringer.java +++ b/src/java/com/threerings/miso/tile/AutoFringer.java @@ -1,5 +1,5 @@ // -// $Id: AutoFringer.java,v 1.24 2003/05/29 01:58:06 ray Exp $ +// $Id: AutoFringer.java,v 1.25 2003/05/31 00:56:38 mdb Exp $ package com.threerings.miso.tile; @@ -140,7 +140,9 @@ public class AutoFringer } } - return new Tile(new BufferedMirage(ftimg)); + Tile tile = new Tile(); + tile.setImage(new BufferedMirage(ftimg)); + return tile; } /** diff --git a/src/java/com/threerings/miso/tile/BaseTile.java b/src/java/com/threerings/miso/tile/BaseTile.java index 5eee9286b..14e36b76d 100644 --- a/src/java/com/threerings/miso/tile/BaseTile.java +++ b/src/java/com/threerings/miso/tile/BaseTile.java @@ -1,9 +1,8 @@ // -// $Id: BaseTile.java,v 1.7 2003/01/13 22:55:12 mdb Exp $ +// $Id: BaseTile.java,v 1.8 2003/05/31 00:56:38 mdb Exp $ package com.threerings.miso.tile; -import com.threerings.media.image.Mirage; import com.threerings.media.tile.Tile; /** @@ -13,24 +12,6 @@ import com.threerings.media.tile.Tile; */ public class BaseTile extends Tile { - /** - * Constructs a new base tile with the specified image. Passability - * will be assumed to be true. - */ - public BaseTile (Mirage image) - { - this(image, true); - } - - /** - * Constructs a new base tile with the specified passability. - */ - public BaseTile (Mirage image, boolean passable) - { - super(image); - _passable = passable; - } - /** * Returns whether or not this tile can be walked upon by character * sprites. @@ -40,6 +21,14 @@ public class BaseTile extends Tile return _passable; } + /** + * Configures this base tile as passable or impassable. + */ + public void setPassable (boolean passable) + { + _passable = passable; + } + /** Whether the tile is passable. */ protected boolean _passable = true; } diff --git a/src/java/com/threerings/miso/tile/BaseTileSet.java b/src/java/com/threerings/miso/tile/BaseTileSet.java index 77758df0b..84f50217b 100644 --- a/src/java/com/threerings/miso/tile/BaseTileSet.java +++ b/src/java/com/threerings/miso/tile/BaseTileSet.java @@ -1,11 +1,11 @@ // -// $Id: BaseTileSet.java,v 1.12 2003/01/15 09:11:37 mdb Exp $ +// $Id: BaseTileSet.java,v 1.13 2003/05/31 00:56:38 mdb Exp $ package com.threerings.miso.tile; import com.samskivert.util.StringUtil; -import com.threerings.media.image.Mirage; +import com.threerings.media.image.Colorization; import com.threerings.media.tile.SwissArmyTileSet; import com.threerings.media.tile.Tile; @@ -35,9 +35,16 @@ public class BaseTileSet extends SwissArmyTileSet } // documentation inherited - protected Tile createTile (int tileIndex, Mirage tileImage) + protected Tile createTile () { - return new BaseTile(tileImage, _passable[tileIndex]); + return new BaseTile(); + } + + // documentation inherited + protected void initTile (Tile tile, int tileIndex, Colorization[] zations) + { + super.initTile(tile, tileIndex, zations); + ((BaseTile)tile).setPassable(_passable[tileIndex]); } // documentation inherited diff --git a/src/java/com/threerings/miso/tile/FringeTile.java b/src/java/com/threerings/miso/tile/FringeTile.java deleted file mode 100644 index 5371af284..000000000 --- a/src/java/com/threerings/miso/tile/FringeTile.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// $Id: FringeTile.java,v 1.4 2003/01/13 22:55:12 mdb Exp $ - -package com.threerings.miso.tile; - -import java.awt.Graphics2D; -import java.util.ArrayList; - -import com.threerings.media.tile.Tile; -import com.threerings.media.image.Mirage; - -/** - * A fringe tile may be composed of multiple images. - */ -public class FringeTile extends Tile -{ - /** - * Construct a fringe tile with the specified image. - */ - public FringeTile (Mirage mirage) - { - super(mirage); - } - - /** - * Add another image to this fringe tile. - */ - public void addExtraImage (Mirage mirage) - { - if (_extras == null) { - _extras = new ArrayList(); - } - _extras.add(mirage); - } - - // documentation inherited - public void paint (Graphics2D gfx, int x, int y) - { - // paint our main image - super.paint(gfx, x, y); - - if (_extras != null) { - int size = _extras.size(); - for (int ii = 0; ii < size; ii++) { - Mirage image = (Mirage)_extras.get(ii); - image.paint(gfx, x, y); - } - } - } - - /** Extra fringe images beyond the one stored in our superclass. */ - protected ArrayList _extras = null; -}