Beginnings of support for asynchronous scene image data resolution.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2462 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2003-04-25 18:22:52 +00:00
parent a03ad10f8d
commit cca2a9cd16
2 changed files with 114 additions and 24 deletions
@@ -1,5 +1,5 @@
//
// $Id: MisoScenePanel.java,v 1.13 2003/04/22 22:00:51 mdb Exp $
// $Id: MisoScenePanel.java,v 1.14 2003/04/25 18:22:52 mdb Exp $
package com.threerings.miso.client;
@@ -89,6 +89,13 @@ public class MisoScenePanel extends VirtualMediaPanel
// handy rectangle
_tbounds = new Rectangle(0, 0, _metrics.tilewid, _metrics.tilehei);
// create the resolver if it's not already around
if (_resolver == null) {
_resolver = new SceneBlockResolver();
_resolver.setDaemon(true);
_resolver.start();
}
}
/**
@@ -107,7 +114,7 @@ public class MisoScenePanel extends VirtualMediaPanel
// recenter and rethink
centerOnTile(0, 0);
rethink();
repaint();
_remgr.invalidateRegion(_vbounds);
}
/**
@@ -380,7 +387,7 @@ public class MisoScenePanel extends VirtualMediaPanel
// clear the highlight tracking data
_hcoords.setLocation(-1, -1);
changeHoverObject(null);
repaint();
_remgr.invalidateRegion(_vbounds);
}
// documentation inherited from interface
@@ -577,8 +584,8 @@ public class MisoScenePanel extends VirtualMediaPanel
*/
protected void rethink ()
{
// Log.info("Rethinking vb:" + StringUtil.toString(_vbounds) +
// " ul:" + StringUtil.toString(_ulpos));
Log.info("Rethinking vb:" + StringUtil.toString(_vbounds) +
" ul:" + StringUtil.toString(_ulpos));
// recompute our "area of influence"
int infborx = _vbounds.width/4;
@@ -614,18 +621,15 @@ public class MisoScenePanel extends VirtualMediaPanel
itb.height = (tpos.y-itb.y+1);
maxy = MathUtil.floorDiv(tpos.y, _metrics.blockhei);
// Log.info("Resolving blocks from " + minx + "," + miny + " to " +
// maxx + "," + maxy + " (" + StringUtil.toString(itb) + ").");
boolean changed = false;
Log.info("Resolving blocks from " + minx + "," + miny + " to " +
maxx + "," + maxy + " (" + StringUtil.toString(itb) + ").");
// prune any blocks that are no longer influential
for (Iterator iter = _blocks.values().iterator(); iter.hasNext(); ) {
SceneBlock block = (SceneBlock)iter.next();
if (!itb.intersects(block.getBounds())) {
// Log.info("Flushing block " + block + ".");
Log.info("Flushing block " + block + ".");
iter.remove();
changed = true;
}
}
@@ -644,8 +648,11 @@ public class MisoScenePanel extends VirtualMediaPanel
this, xx*_metrics.blockwid, yy*_metrics.blockhei,
_metrics.blockwid, _metrics.blockhei);
_blocks.put(bkey, block);
changed = true;
// Log.info("Created new block " + block + ".");
Log.info("Created new block " + block + ".");
// queue the block up to be resolved
_pendingBlocks++;
_resolver.resolveBlock(block);
}
}
}
@@ -654,6 +661,29 @@ public class MisoScenePanel extends VirtualMediaPanel
recomputeVisible();
}
/**
* Called by a scene block when it has completed its resolution
* process.
*/
protected void blockResolved (SceneBlock block)
{
// once all the pending blocks have completed their resolution,
// recompute our visible object set
if (--_pendingBlocks == 0) {
recomputeVisible();
_remgr.invalidateRegion(_vbounds);
}
// if this block has objects that intersect our visible bounds
// (zoiks!) then repaint
Rectangle sbounds = block.getScreenBounds();
if (sbounds.intersects(_vbounds)) {
Log.info("Eek, block came into view during resolution " +
block + ".");
_remgr.invalidateRegion(_vbounds);
}
}
/**
* Recomputes our set of visible objects and their tips.
*/
@@ -668,8 +698,13 @@ public class MisoScenePanel extends VirtualMediaPanel
_vbounds.height+2*_metrics.tilehei);
for (Iterator iter = _blocks.values().iterator(); iter.hasNext(); ) {
// links this block to its neighbors; computes coverage
SceneBlock block = (SceneBlock)iter.next();
if (!block.isResolved()) {
Log.info("Skipping unresolved block " + block + ".");
continue;
}
// links this block to its neighbors; computes coverage
block.update(_blocks);
// see which of this block's objects are visible
@@ -685,8 +720,8 @@ public class MisoScenePanel extends VirtualMediaPanel
// recompute our object tips
computeTips();
// Log.info("Computed " + _vizobjs.size() + " visible objects from " +
// _blocks.size() + " blocks.");
Log.info("Computed " + _vizobjs.size() + " visible objects from " +
_blocks.size() + " blocks.");
// Log.info(StringUtil.listToString(_vizobjs, new StringUtil.Formatter() {
// public String toString (Object object) {
@@ -1240,6 +1275,9 @@ public class MisoScenePanel extends VirtualMediaPanel
/** Contains our scene blocks. See {@link #getBlock} for details. */
protected HashIntMap _blocks = new HashIntMap();
/** A count of blocks in the process of being resolved. */
protected int _pendingBlocks;
/** A list of the potentially visible objects in the scene. */
protected ArrayList _vizobjs = new ArrayList();
@@ -1293,6 +1331,9 @@ public class MisoScenePanel extends VirtualMediaPanel
/** The font to draw tile coordinates. */
protected Font _font = new Font("Arial", Font.PLAIN, 7);
/** A scene block resolver shared by all scene panels. */
protected static SceneBlockResolver _resolver;
/** A debug hook that toggles debug rendering of traversable tiles. */
protected static RuntimeAdjust.BooleanAdjust _traverseDebug =
new RuntimeAdjust.BooleanAdjust(
@@ -1,5 +1,5 @@
//
// $Id: SceneBlock.java,v 1.9 2003/04/24 21:27:23 mdb Exp $
// $Id: SceneBlock.java,v 1.10 2003/04/25 18:22:52 mdb Exp $
package com.threerings.miso.client;
@@ -48,16 +48,30 @@ public class SceneBlock
_footprint = MisoUtil.getFootprintPolygon(
panel.getSceneMetrics(), tx, ty, width, height);
// start with the bounds of the footprint polygon
_sbounds = new Rectangle(_footprint.getBounds());
// the rest of our resolution will happen in resolve()
}
/**
* This method is called by the {@link SceneBlockResolver} on the
* block resolution thread to allow us to load up our image data
* without blocking the AWT thread.
*/
protected synchronized void resolve ()
{
// resolve our base tiles
MisoSceneModel model = panel.getSceneModel();
for (int yy = 0; yy < height; yy++) {
for (int xx = 0; xx < width; xx++) {
int x = tx + xx, y = ty + yy;
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 fqTileId = model.getBaseTileId(x, y);
if (fqTileId <= 0) {
continue;
}
// load up this base tile
updateBaseTile(fqTileId, x, y);
// if there's no tile here, we don't need no fringe
@@ -67,7 +81,7 @@ public class SceneBlock
}
// compute the fringe for this tile
_fringe[tidx] = panel.computeFringeTile(x, y);
_fringe[tidx] = _panel.computeFringeTile(x, y);
}
}
@@ -76,7 +90,8 @@ public class SceneBlock
model.getObjects(_bounds, set);
_objects = new SceneObject[set.size()];
for (int ii = 0; ii < _objects.length; ii++) {
_objects[ii] = new SceneObject(panel, set.get(ii));
_objects[ii] = new SceneObject(_panel, set.get(ii));
_sbounds.add(_objects[ii].bounds);
}
// resolve our default tileset
@@ -91,6 +106,23 @@ public class SceneBlock
}
}
/**
* This is called by the {@link SceneBlockResolver} on the AWT thread
* when our resolution has completed. We inform our containing panel.
*/
protected void wasResolved ()
{
_panel.blockResolved(this);
}
/**
* Returns true if this block has been resolved, false if not.
*/
protected boolean isResolved ()
{
return (_defset != null);
}
/**
* Returns the bounds of this block, in tile coordinates.
*/
@@ -99,6 +131,16 @@ public class SceneBlock
return _bounds;
}
/**
* Returns the bounds of the screen coordinate rectangle that contains
* all pixels that are drawn on by all tiles and objects in this
* block.
*/
public Rectangle getScreenBounds ()
{
return _sbounds;
}
/**
* Returns the screen-coordinate polygon bounding the footprint of
* this block.
@@ -260,7 +302,11 @@ public class SceneBlock
*/
public String toString ()
{
return StringUtil.toString(_bounds) + ":" + _objects.length;
int bx = MathUtil.floorDiv(_bounds.x, _bounds.width);
int by = MathUtil.floorDiv(_bounds.y, _bounds.height);
return StringUtil.coordsToString(bx, by) + ":" +
StringUtil.toString(_bounds) + ":" +
((_objects == null) ? 0 : _objects.length);
}
/**
@@ -356,6 +402,9 @@ public class SceneBlock
/** The bounds of (in tile coordinates) of this block. */
protected Rectangle _bounds;
/** The bounds (in screen coords) of all images rendered by this block. */
protected Rectangle _sbounds;
/** A polygon bounding the footprint of this block. */
protected Polygon _footprint;