More Miso modifications: support new combined scene interface stuff; new

scene model stuff; other small business.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2271 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2003-02-12 07:21:15 +00:00
parent f1ced5a3c5
commit 14dbc463a2
3 changed files with 227 additions and 177 deletions
@@ -1,23 +1,17 @@
//
// $Id: DisplayMisoScene.java,v 1.9 2003/01/31 23:10:45 mdb Exp $
// $Id: DisplayMisoScene.java,v 1.10 2003/02/12 07:21:15 mdb Exp $
package com.threerings.miso.client;
import java.awt.Rectangle;
import com.threerings.media.tile.ObjectTile;
import com.threerings.media.tile.Tile;
import com.threerings.miso.client.util.ObjectSet;
import com.threerings.miso.data.MisoScene;
import com.threerings.miso.tile.BaseTile;
/**
* Makes available the information from the {@link MisoSceneModel} in a
* form that is amenable to actually displaying the scene in a user
* interface. As with all display scene implementations, the information
* provided is read-only and should never be modified by the caller.
* Extends the {@link MisoScene} with functionality needed only by
* entities that plan to display a miso scene.
*/
public interface DisplayMisoScene
public interface DisplayMisoScene extends MisoScene
{
/**
* Returns the base tile at the specified coordinates.
@@ -29,12 +23,6 @@ public interface DisplayMisoScene
*/
public Tile getFringeTile (int x, int y);
/**
* Populates the supplied object set with info on all objects whose
* origin falls in the requested region.
*/
public void getObjects (Rectangle region, ObjectSet set);
/**
* Returns true if the supplied traverser can traverse the specified
* tile coordinate. The traverser is whatever object is passed along
@@ -1,32 +1,29 @@
//
// $Id: DisplayMisoSceneImpl.java,v 1.66 2003/02/04 21:39:28 mdb Exp $
// $Id: SimpleDisplayMisoSceneImpl.java,v 1.1 2003/02/12 07:21:15 mdb Exp $
package com.threerings.miso.client;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Random;
import java.util.HashMap;
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.TileLayer;
import com.threerings.miso.Log;
import com.threerings.miso.client.util.ObjectSet;
import com.threerings.miso.data.MisoSceneModel;
import com.threerings.miso.data.ObjectInfo;
import com.threerings.miso.data.SimpleMisoSceneImpl;
import com.threerings.miso.data.SimpleMisoSceneModel;
import com.threerings.miso.tile.AutoFringer;
import com.threerings.miso.tile.BaseTile;
import com.threerings.miso.tile.BaseTileLayer;
import com.threerings.miso.tile.MisoTileManager;
/**
* The default implementation of the {@link DisplayMisoScene} interface.
* An implementation of the {@link DisplayMisoScene} interface that uses a
* simple miso scene model.
*/
public class DisplayMisoSceneImpl
public class SimpleDisplayMisoSceneImpl extends SimpleMisoSceneImpl
implements DisplayMisoScene
{
/**
@@ -37,151 +34,28 @@ public class DisplayMisoSceneImpl
* @param model the scene data that we'll be displaying.
* @param tmgr the tile manager from which to load our tiles.
*/
public DisplayMisoSceneImpl (MisoSceneModel model, MisoTileManager tmgr)
public SimpleDisplayMisoSceneImpl (SimpleMisoSceneModel model,
MisoTileManager tmgr)
{
this(model);
setTileManager(tmgr);
}
super(model);
/**
* Constructs an instance that will be used to display the supplied
* miso scene data. The tiles identified by the scene model will not
* be loaded until a tile manager is provided via {@link
* #setTileManager}.
*
* @param model the scene data that we'll be displaying.
*/
public DisplayMisoSceneImpl (MisoSceneModel model)
{
setMisoSceneModel(model);
}
/**
* Provides this display miso scene with a tile manager from which it
* can load up all of its tiles.
*/
public void setTileManager (MisoTileManager tmgr)
{
_tmgr = tmgr;
_fringer = tmgr.getAutoFringer();
populateLayers();
}
// documentation inherited from interface
public BaseTile getBaseTile (int x, int y)
{
return _base.getTile(x, y);
}
// documentation inherited from interface
public Tile getFringeTile (int x, int y)
{
return _fringe.getTile(x, y);
}
// documentation inherited from interface
public void getObjects (Rectangle region, ObjectSet set)
{
// iterate over all of our objects, creating and including scene
// objects for those that intersect the region
int ocount = _objects.size();
for (int ii = 0; ii < ocount; ii++) {
DisplayObjectInfo scobj = (DisplayObjectInfo)_objects.get(ii);
if (region.contains(scobj.x, scobj.y)) {
set.insert(scobj);
}
}
}
// documentation inherited from interface
public boolean canTraverse (Object trav, int x, int y)
{
BaseTile tile = getBaseTile(x, y);
return (((tile == null) || tile.isPassable()) &&
!_covered[y*_model.width+x]);
}
/**
* Return a string representation of this Miso scene object.
*/
public String toString ()
{
StringBuffer buf = new StringBuffer();
buf.append("[width=").append(_base.getWidth());
buf.append(", height=").append(_base.getHeight());
return buf.append("]").toString();
}
/**
* Instructs this miso scene to use the supplied model instead of its
* current model. This should be followed up by a called to {@link
* #setTileManager} or {@link #populateLayers} if a tile manager has
* already been provided.
*/
protected void setMisoSceneModel (MisoSceneModel model)
{
_model = model;
int swid = _model.width;
int shei = _model.height;
// create the individual tile layer objects
_base = new BaseTileLayer(new BaseTile[swid*shei], swid, shei);
_fringe = new TileLayer(new Tile[swid*shei], swid, shei);
_base = new BaseTile[swid*shei];
_fringe = new Tile[swid*shei];
_covered = new boolean[swid*shei];
// create display object infos for our uninteresting objects
int ocount = (_model.objectTileIds == null) ? 0 :
_model.objectTileIds.length;
for (int ii = 0; ii < ocount; ii++) {
_objects.add(new DisplayObjectInfo(_model.objectTileIds[ii],
_model.objectXs[ii],
_model.objectYs[ii]));
}
// create display object infos for our interesting objects
for (int ii = 0, ll = _model.objectInfo.length; ii < ll; ii++) {
_objects.add(new DisplayObjectInfo(_model.objectInfo[ii]));
}
}
/**
* Populates the tile layers with tiles from the tile manager.
*/
protected void populateLayers ()
{
int swid = _base.getWidth();
int shei = _base.getHeight();
// if we have a fringer, fill in our fringe
if (_fringer != null) {
_fringer.fringe(_model, _fringe, _rando);
}
// populate the base and fringe layers
// load up the tiles for our base layer
for (int column = 0; column < shei; column++) {
for (int row = 0; row < swid; row++) {
// first do the base layer
int tsid = _model.getBaseTile(column, row);
if (tsid > 0) {
int tid = (tsid & 0xFFFF);
tsid >>= 16;
// this is a bit magical, but the tile manager will
// fetch tiles from the tileset repository and the
// tile set id from which we request this tile must
// map to a base tile as provided by the repository,
// so we just cast it to a base tile and know that all
// is well
try {
BaseTile mtile = (BaseTile)_tmgr.getTile(tsid, tid);
_base.setTile(column, row, mtile);
} catch (NoSuchTileSetException nste) {
Log.warning("Scene contains non-existent tileset " +
"[tsid=" + tsid + ", tid=" + tid + "].");
} catch (NoSuchTileException nste) {
Log.warning("Scene contains non-existent tile " +
"[tsid=" + tsid + ", tid=" + tid + "].");
}
int fqTileId = getBaseTileId(column, row);
if (fqTileId > 0) {
populateBaseTile(fqTileId, column, row);
}
}
}
@@ -195,9 +69,108 @@ public class DisplayMisoSceneImpl
}
}
// documentation inherited from interface
public void setBaseTile (int fqTileId, int x, int y)
{
super.setBaseTile(fqTileId, x, y);
populateBaseTile(fqTileId, x, y);
}
// documentation inherited from interface
public ObjectInfo addObject (int fqTileId, int x, int y)
{
DisplayObjectInfo info = (DisplayObjectInfo)
super.addObject(fqTileId, x, y);
populateObject(info);
return info;
}
// documentation inherited from interface
public boolean removeObject (ObjectInfo info)
{
if (super.removeObject(info)) {
// clear out this object's "shadow"
DisplayObjectInfo dinfo = (DisplayObjectInfo)info;
setObjectTileFootprint(dinfo.tile, dinfo.x, dinfo.y, false);
return true;
} else {
return false;
}
}
// documentation inherited from interface
public BaseTile getBaseTile (int x, int y)
{
if (x < 0 || y < 0 || x >= _model.width || y >= _model.height) {
return null;
}
return _base[y*_model.width+x];
}
// documentation inherited from interface
public Tile getFringeTile (int x, int y)
{
if (x < 0 || y < 0 || x >= _model.width || y >= _model.height) {
return null;
}
// if we have not yet composed this fringe tile, do so
int idx = y * _model.width + x;
if (_fringe[idx] == null) {
_fringe[idx] = _fringer.getFringeTile(this, x, y, _masks, _rando);
// make a note of non-fringed tiles that have been resolved
// but have no fringe tile
if (_fringe[idx] == null) {
_fringe[idx] = _nullFringe;
}
}
return (_fringe[idx] == _nullFringe) ? null : _fringe[idx];
}
// documentation inherited from interface
public boolean canTraverse (Object trav, int x, int y)
{
BaseTile tile = getBaseTile(x, y);
return (((tile == null) || tile.isPassable()) &&
!_covered[y*_model.width+x]);
}
/**
* Called to populate an object with its object tile when we have been
* configured with a tile manager from which to obtain such things.
* Called to populate a coordinate with its base tile.
*/
protected void populateBaseTile (int fqTileId, int x, int y)
{
if (x < 0 || y < 0 || x >= _model.width || y >= _model.height) {
// nothing doing
return;
}
int tsid = fqTileId >> 16, tid = (fqTileId & 0xFFFF);
// this is a bit magical, but the tile manager will fetch tiles
// from the tileset repository and the tile set id from which we
// request this tile must map to a base tile as provided by the
// repository, so we just cast it to a base tile and know that all
// is well
String errmsg = null;
try {
_base[y*_model.width+x] = (BaseTile)_tmgr.getTile(tsid, tid);
} catch (ClassCastException cce) {
errmsg = "Scene contains non-base tile in base layer";
} catch (NoSuchTileSetException nste) {
errmsg = "Scene contains non-existent tileset";
} catch (NoSuchTileException nste) {
errmsg = "Scene contains non-existent tile";
}
if (errmsg != null) {
Log.warning(errmsg + " [tsid=" + tsid + ", tid=" + tid +
", x=" + x + ", y=" + y + "].");
}
}
/**
* Called to populate an object with its object tile.
*/
protected boolean populateObject (DisplayObjectInfo info)
{
@@ -207,12 +180,10 @@ public class DisplayMisoSceneImpl
return true;
} catch (NoSuchTileException nste) {
Log.warning("Scene contains non-existent object tile " +
"[info=" + info + ", tsid=" + tsid +
", tid=" + tid + "].");
"[info=" + info + "].");
} catch (NoSuchTileSetException te) {
Log.warning("Scene contains non-existent object tile " +
"[info=" + info + ", tsid=" + tsid +
", tid=" + tid + "].");
Log.warning("Scene contains non-existent object tileset " +
"[info=" + info + "].");
}
return false;
}
@@ -284,27 +255,36 @@ public class DisplayMisoSceneImpl
// ", sy=" + y + ", ex=" + endx + ", ey=" + endy + "].");
}
// documentation inherited
protected ObjectInfo createObjectInfo (int tileId, int x, int y)
{
return new DisplayObjectInfo(tileId, x, y);
}
// documentation inherited
protected ObjectInfo createObjectInfo (ObjectInfo source)
{
return new DisplayObjectInfo(source);
}
/** The tile manager from which we load tiles. */
protected MisoTileManager _tmgr;
/** The miso scene model from which we obtain our data. */
protected MisoSceneModel _model;
/** The base layer of tiles. */
protected BaseTileLayer _base;
protected BaseTile[] _base;
/** The fringe layer of tiles. */
protected TileLayer _fringe;
protected Tile[] _fringe;
/** Contains cached fringe mask tiles. TODO: LRU this or something. */
protected HashMap _masks = new HashMap();
/** Used to identify non-existent fringe tiles. */
protected Tile _nullFringe;
/** Information on which tiles are covered by object tiles. */
protected boolean[] _covered;
/** The scene object records. */
protected ArrayList _objects = new ArrayList();
/** The autofringer. */
protected AutoFringer _fringer;
/** A random number generator for filling random base tiles and fringes. */
protected Random _rando = new Random();
}
@@ -0,0 +1,82 @@
//
// $Id: VirtualDisplayMisoSceneImpl.java,v 1.1 2003/02/12 07:21:15 mdb Exp $
package com.threerings.miso.client;
import java.awt.Rectangle;
import com.threerings.media.tile.Tile;
import com.threerings.miso.client.util.ObjectSet;
import com.threerings.miso.data.MisoSceneModel;
import com.threerings.miso.data.ObjectInfo;
import com.threerings.miso.tile.BaseTile;
/**
* Provides a useful base class for "virtual" {@link DisplayMisoScene}
* implementations. These return tiles based on some algorithm rather than
* a repository of predefined tile data.
*/
public class VirtualDisplayMisoSceneImpl
implements DisplayMisoScene
{
// documentation inherited from interface
public int getBaseTileId (int x, int y)
{
return -1;
}
// documentation inherited from interface
public void getObjects (Rectangle region, ObjectSet set)
{
// nothing doing
}
// documentation inherited from interface
public void setBaseTile (int fqTileId, int x, int y)
{
// nothing doing
}
// documentation inherited from interface
public void setBaseTiles (Rectangle r, int setId, int setSize)
{
// nothing doing
}
// documentation inherited from interface
public ObjectInfo addObject (int fqTileId, int x, int y)
{
return null;
}
// documentation inherited from interface
public boolean removeObject (ObjectInfo info)
{
return false;
}
// documentation inherited from interface
public MisoSceneModel getSceneModel ()
{
return null;
}
// documentation inherited from interface
public BaseTile getBaseTile (int x, int y)
{
return null;
}
// documentation inherited from interface
public Tile getFringeTile (int x, int y)
{
return null;
}
// documentation inherited from interface
public boolean canTraverse (Object traverser, int x, int y)
{
return true;
}
}