Need to weak reference the values too if they're going to be collectable. Use Arrays.hashCode to calculate the hash code of a long[] thanks to Ray.

git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@550 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Charlie Groves
2008-06-23 23:50:57 +00:00
parent cd30b42cd8
commit 7b7131bf7c
2 changed files with 18 additions and 16 deletions
@@ -42,6 +42,7 @@ import java.awt.event.ActionListener;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener; import java.awt.event.MouseMotionListener;
import java.lang.ref.WeakReference;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -364,12 +365,11 @@ public class MisoScenePanel extends VirtualMediaPanel
for (SceneBlock block : _blocks.values()) { for (SceneBlock block : _blocks.values()) {
block.computeMemoryUsage(base, fringe, object, usage); block.computeMemoryUsage(base, fringe, object, usage);
} }
log.info("Scene tile memory usage " + log.info("Scene tile memory usage",
"[scene=" + StringUtil.shortClassName(this) + "scene", StringUtil.shortClassName(this),
", base=" + base.size() + "->" + (usage[0] / 1024) + "k" + "base", base.size() + "->" + (usage[0] / 1024) + "k",
", fringe=" + fringe.size() + "->" + (usage[1] / 1024) + "k" + "fringe", fringe.size() + "->" + (usage[1] / 1024) + "k",
", obj=" + object.size() + "obj", object.size() + "->" + (usage[2] / 1024) + "k");
"->" + (usage[2] / 1024) + "k" + "].");
} }
@Override @Override
@@ -1561,7 +1561,8 @@ public class MisoScenePanel extends VirtualMediaPanel
* fully created FringeTile can be extracted from the map using a tile that contains only * fully created FringeTile can be extracted from the map using a tile that contains only
* what's needed for hashCode and equals: id and passability. * what's needed for hashCode and equals: id and passability.
*/ */
protected Map<FringeTile, FringeTile> _fringes = new WeakHashMap<FringeTile, FringeTile>(); protected Map<FringeTile, WeakReference<FringeTile>> _fringes =
new WeakHashMap<FringeTile, WeakReference<FringeTile>>();
/** The dirty sprites and objects that need to be re-painted. */ /** The dirty sprites and objects that need to be re-painted. */
protected DirtyItemList _dirtyItems = new DirtyItemList(); protected DirtyItemList _dirtyItems = new DirtyItemList();
@@ -26,6 +26,7 @@ import static com.threerings.miso.Log.log;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Transparency; import java.awt.Transparency;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -72,10 +73,7 @@ public class AutoFringer
@Override @Override
public int hashCode () public int hashCode ()
{ {
int result = 33; int result = Arrays.hashCode(_fringeId);
for (long key : _fringeId) {
result = result * 37 + (int)(key ^ (key >>> 32));
}
if(_passable) { if(_passable) {
result++; result++;
} }
@@ -109,7 +107,7 @@ public class AutoFringer
* Compute and return the fringe tile to be inserted at the specified location. * Compute and return the fringe tile to be inserted at the specified location.
*/ */
public BaseTile getFringeTile (MisoSceneModel scene, int col, int row, public BaseTile getFringeTile (MisoSceneModel scene, int col, int row,
Map<FringeTile, FringeTile> fringes) Map<FringeTile, WeakReference<FringeTile>> fringes)
{ {
// get the tileset id of the base tile we are considering // get the tileset id of the base tile we are considering
int underset = adjustTileSetId(scene.getBaseTileId(col, row) >> 16); int underset = adjustTileSetId(scene.getBaseTileId(col, row) >> 16);
@@ -183,7 +181,7 @@ public class AutoFringer
* Compose a FringeTile out of the various fringe images needed. * Compose a FringeTile out of the various fringe images needed.
*/ */
protected FringeTile composeFringeTile (FringerRec[] fringers, protected FringeTile composeFringeTile (FringerRec[] fringers,
Map<FringeTile, FringeTile> fringes, int hashValue, boolean passable) Map<FringeTile, WeakReference<FringeTile>> fringes, int hashValue, boolean passable)
{ {
// sort the array so that higher priority fringers get drawn first // sort the array so that higher priority fringers get drawn first
QuickSort.sort(fringers); QuickSort.sort(fringers);
@@ -210,9 +208,12 @@ public class AutoFringer
// If the fringes map contains something with the same fringe identifier, this will pull // If the fringes map contains something with the same fringe identifier, this will pull
// it out and we can use it instead. // it out and we can use it instead.
FringeTile result = fringes.get(frTile); WeakReference<FringeTile> result = fringes.get(frTile);
if (result != null) { if (result != null) {
return result; FringeTile fringe = result.get();
if (fringe != null) {
return fringe;
}
} }
// There's no fringe with he same identifier, so we need to create the tile. // There's no fringe with he same identifier, so we need to create the tile.
@@ -230,7 +231,7 @@ public class AutoFringer
} }
} }
frTile.setImage(new BufferedMirage(img)); frTile.setImage(new BufferedMirage(img));
fringes.put(frTile, frTile); fringes.put(frTile, new WeakReference<FringeTile>(frTile));
return frTile; return frTile;
} }