From a07282b2d2890286fe1c2f2b0f2088051f769082 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 30 Jan 2002 18:28:32 +0000 Subject: [PATCH] Added support for associating an action with any of the object tiles in the scene. This will eventually be interpreted by the scene rendering code to allow objects to be clickable. Also rewrote scene serialization code using new Java buffer services which are much more efficient at reading and writing arrays of integers. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@894 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../miso/client/DisplayMisoScene.java | 10 ++- .../miso/client/DisplayMisoSceneImpl.java | 40 +++++++++- .../threerings/miso/data/MisoSceneModel.java | 73 ++++++++++++++----- .../miso/tools/EditableMisoScene.java | 18 ++++- .../miso/tools/EditableMisoSceneImpl.java | 25 ++++++- .../miso/tools/xml/MisoSceneRuleSet.java | 4 +- .../miso/tools/xml/MisoSceneWriter.java | 4 +- 7 files changed, 147 insertions(+), 27 deletions(-) diff --git a/src/java/com/threerings/miso/client/DisplayMisoScene.java b/src/java/com/threerings/miso/client/DisplayMisoScene.java index a3cad01a2..d2318a310 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoScene.java +++ b/src/java/com/threerings/miso/client/DisplayMisoScene.java @@ -1,5 +1,5 @@ // -// $Id: DisplayMisoScene.java,v 1.2 2001/11/27 22:17:42 mdb Exp $ +// $Id: DisplayMisoScene.java,v 1.3 2002/01/30 18:28:32 mdb Exp $ package com.threerings.miso.scene; @@ -32,4 +32,12 @@ public interface DisplayMisoScene * This layer is read-only and not to be modified. */ public ObjectTileLayer getObjectLayer (); + + /** + * Returns the action associated with the object tile at the specified + * column and row. Null is returned if no object tile exists at that + * column and row or if the object tile that does exist does not have + * an associated action. + */ + public String getObjectAction (int column, int row); } diff --git a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java index 8752d9dfb..489a57e67 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java +++ b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java @@ -1,8 +1,11 @@ // -// $Id: DisplayMisoSceneImpl.java,v 1.48 2001/12/05 07:29:06 mdb Exp $ +// $Id: DisplayMisoSceneImpl.java,v 1.49 2002/01/30 18:28:32 mdb Exp $ package com.threerings.miso.scene; +import com.samskivert.util.HashIntMap; +import com.samskivert.util.StringUtil; + import com.threerings.media.tile.NoSuchTileException; import com.threerings.media.tile.NoSuchTileSetException; import com.threerings.media.tile.ObjectTile; @@ -73,6 +76,19 @@ public class DisplayMisoSceneImpl _base = new BaseTileLayer(new BaseTile[swid*shei], swid, shei); _fringe = new TileLayer(new Tile[swid*shei], swid, shei); _object = new ObjectTileLayer(new ObjectTile[swid*shei], swid, shei); + + // create a mapping for the action strings and populate it + _actions = new HashIntMap(); + for (int i = 0; i < model.objectActions.length; i++) { + String action = model.objectActions[i]; + // skip null or blank actions + if (StringUtil.blank(action)) { + continue; + } + // the key is the composite of the column and row + _actions.put(objectKey(model.objectTileIds[3*i], + model.objectTileIds[3*i+1]), action); + } } /** @@ -175,6 +191,16 @@ public class DisplayMisoSceneImpl return _object; } + // documentation inherited from interface + public String getObjectAction (int column, int row) + { + if (_actions != null) { + return (String)_actions.get(objectKey(column, row)); + } else { + return null; + } + } + /** * Return a string representation of this Miso scene object. */ @@ -211,6 +237,15 @@ public class DisplayMisoSceneImpl // ", sy=" + y + ", ex=" + endx + ", ey=" + endy + "]."); } + /** + * Computes the action table key for the object at the specified + * column and row. + */ + protected static int objectKey (int column, int row) + { + return (column << 15) + row; + } + /** The tile manager from which we load tiles. */ protected TileManager _tmgr; @@ -225,4 +260,7 @@ public class DisplayMisoSceneImpl /** The object layer of tiles. */ protected ObjectTileLayer _object; + + /** A map from object tile coordinates to action string. */ + protected HashIntMap _actions; } diff --git a/src/java/com/threerings/miso/data/MisoSceneModel.java b/src/java/com/threerings/miso/data/MisoSceneModel.java index 61bb1fd6e..4f0249064 100644 --- a/src/java/com/threerings/miso/data/MisoSceneModel.java +++ b/src/java/com/threerings/miso/data/MisoSceneModel.java @@ -1,5 +1,5 @@ // -// $Id: MisoSceneModel.java,v 1.4 2001/12/12 02:47:17 mdb Exp $ +// $Id: MisoSceneModel.java,v 1.5 2002/01/30 18:28:32 mdb Exp $ package com.threerings.miso.scene; @@ -7,6 +7,9 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + import com.samskivert.util.StringUtil; /** @@ -35,25 +38,43 @@ public class MisoSceneModel * the object layer in (x, y, tile id) format. */ public int[] objectTileIds; + /** The action strings associated with the object tiles in the order + * that the tiles are specified in the {@link #objectTileIds} array. + * Elements of this array may be null but will be converted to the + * empty string during serialization. */ + public String[] objectActions; + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { - out.writeInt(width); - out.writeInt(height); - - // write out the base and fringe layers int tcount = width*height; - for (int i = 0; i < tcount; i++) { - out.writeInt(baseTileIds[i]); - out.writeInt(fringeTileIds[i]); - } - - // write out the object layer int otc = objectTileIds.length; - out.writeInt(otc); - for (int i = 0; i < otc; i++) { - out.writeInt(objectTileIds[i]); + + // write everything into a ByteBuffer, viewed as an IntBuffer and + // then write the bytes from those operations out to the output + // stream + ByteBuffer bbuf = ByteBuffer.allocate(8*tcount + 4*otc + 4*3); + IntBuffer ibuf = bbuf.asIntBuffer(); + + // insert the dimensions + ibuf.put(width); + ibuf.put(height); + ibuf.put(otc); + + // insert the layer data + ibuf.put(baseTileIds); + ibuf.put(fringeTileIds); + ibuf.put(objectTileIds); + + // now write the binary data out to the output stream + out.write(bbuf.array()); + + // next write out the object action strings + int acount = otc/3; + for (int i = 0; i < acount; i++) { + String action = objectActions[i]; + out.writeUTF((action == null) ? "" : action); } } @@ -61,24 +82,37 @@ public class MisoSceneModel public void readFrom (DataInputStream in) throws IOException { + // we can read these directly because the byte order of the byte + // buffer we created to write out the data is big endian which is + // what the data input stream expects width = in.readInt(); height = in.readInt(); + int otc = in.readInt(); - // read in the base and fringe layers + // read in the base layer int tcount = width*height; baseTileIds = new int[tcount]; - fringeTileIds = new int[tcount]; for (int i = 0; i < tcount; i++) { baseTileIds[i] = in.readInt(); + } + + // read in the fringe layer + fringeTileIds = new int[tcount]; + for (int i = 0; i < tcount; i++) { fringeTileIds[i] = in.readInt(); } // read in the object layer - int otc = in.readInt(); objectTileIds = new int[otc]; for (int i = 0; i < otc; i++) { objectTileIds[i] = in.readInt(); } + + // read in the object action strings + objectActions = new String[otc/3]; + for (int i = 0; i < otc/3; i++) { + objectActions[i] = in.readUTF(); + } } /** @@ -89,7 +123,8 @@ public class MisoSceneModel return "[width=" + width + ", height=" + height + ", baseTileIds=" + StringUtil.toString(baseTileIds) + ", fringeTileIds=" + StringUtil.toString(fringeTileIds) + - ", objectTileIds=" + StringUtil.toString(objectTileIds) + "]"; + ", objectTileIds=" + StringUtil.toString(objectTileIds) + + ", objectActions=" + StringUtil.toString(objectActions) + "]"; } /** @@ -102,6 +137,7 @@ public class MisoSceneModel model.baseTileIds = (int[])baseTileIds.clone(); model.fringeTileIds = (int[])fringeTileIds.clone(); model.objectTileIds = (int[])objectTileIds.clone(); + model.objectActions = (String[])objectActions.clone(); return model; } @@ -138,5 +174,6 @@ public class MisoSceneModel model.baseTileIds = new int[width*height]; model.fringeTileIds = new int[width*height]; model.objectTileIds = new int[0]; + model.objectActions = new String[0]; } } diff --git a/src/java/com/threerings/miso/tools/EditableMisoScene.java b/src/java/com/threerings/miso/tools/EditableMisoScene.java index 68d25d50f..24cd4e3d6 100644 --- a/src/java/com/threerings/miso/tools/EditableMisoScene.java +++ b/src/java/com/threerings/miso/tools/EditableMisoScene.java @@ -1,5 +1,5 @@ // -// $Id: EditableMisoScene.java,v 1.9 2001/12/05 07:29:06 mdb Exp $ +// $Id: EditableMisoScene.java,v 1.10 2002/01/30 18:28:32 mdb Exp $ package com.threerings.miso.tools.scene; @@ -77,6 +77,14 @@ public interface EditableMisoScene */ public void setObjectTile (int x, int y, ObjectTile tile, int fqTileId); + /** + * Sets the action string for the object tile at the specified + * coordinates. It may be assumed by the implementation that an object + * tile exists in the scene at the specified coordinates, thus callers + * should be sure only to call this method accordingly. + */ + public void setObjectAction (int x, int y, String action); + /** * Clears out the tile at the specified location in the base layer. */ @@ -92,6 +100,14 @@ public interface EditableMisoScene */ public void clearObjectTile (int x, int y); + /** + * Clears the action string for the object tile at the specified + * coordinates. It may be assumed by the implementation that an object + * tile exists in the scene at the specified coordinates, thus callers + * should be sure only to call this method accordingly. + */ + public void clearObjectAction (int x, int y); + /** * Returns a reference to the miso scene model that reflects the * changes that have been made to this editable miso scene. diff --git a/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java b/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java index 336333a1e..af995e5bf 100644 --- a/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java +++ b/src/java/com/threerings/miso/tools/EditableMisoSceneImpl.java @@ -1,5 +1,5 @@ // -// $Id: EditableMisoSceneImpl.java,v 1.6 2001/12/05 07:29:06 mdb Exp $ +// $Id: EditableMisoSceneImpl.java,v 1.7 2002/01/30 18:28:32 mdb Exp $ package com.threerings.miso.tools.scene; @@ -109,6 +109,12 @@ public class EditableMisoSceneImpl // the default tiles } + // documentation inherited from interface + public void setObjectAction (int x, int y, String action) + { + _actions.put(objectKey(x, y), action); + } + // documentation inherited public void clearBaseTile (int x, int y) { @@ -137,6 +143,14 @@ public class EditableMisoSceneImpl } // clear it out in our non-sparse array _objectTileIds[_model.width*y + x] = 0; + // clear out any action for this tile as well + _actions.remove(objectKey(x, y)); + } + + // documentation inherited from interface + public void clearObjectAction (int x, int y) + { + _actions.remove(objectKey(x, y)); } // documentation inherited @@ -155,9 +169,10 @@ public class EditableMisoSceneImpl } } - // now create and populate the new tileid array + // now create and populate the new tileid and actions arrays int[] otids = new int[otileCount*3]; - int otidx = 0; + String[] actions = new String[otileCount]; + int otidx = 0, actidx = 0; for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { int tsid = _objectTileIds[_model.width*r + c]; @@ -167,11 +182,13 @@ public class EditableMisoSceneImpl otids[otidx++] = c; otids[otidx++] = r; otids[otidx++] = tsid; + actions[actidx++] = (String)_actions.get(objectKey(c, r)); } } - // stuff the new array into the model + // stuff the new arrays into the model _model.objectTileIds = otids; + _model.objectActions = actions; // and we're ready to roll return _model; diff --git a/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java b/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java index d3309ebd4..ffe044852 100644 --- a/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java +++ b/src/java/com/threerings/miso/tools/xml/MisoSceneRuleSet.java @@ -1,5 +1,5 @@ // -// $Id: MisoSceneRuleSet.java,v 1.4 2001/11/29 19:31:12 mdb Exp $ +// $Id: MisoSceneRuleSet.java,v 1.5 2002/01/30 18:28:32 mdb Exp $ package com.threerings.miso.tools.scene.xml; @@ -56,6 +56,8 @@ public class MisoSceneRuleSet extends RuleSetBase new SetFieldRule(digester, "fringeTileIds")); digester.addRule(_prefix + "/object", new SetFieldRule(digester, "objectTileIds")); + digester.addRule(_prefix + "/actions", + new SetFieldRule(digester, "objectActions")); } /** The prefix at which me match our scenes. */ diff --git a/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java b/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java index e75f8c3f7..82f21906c 100644 --- a/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java +++ b/src/java/com/threerings/miso/tools/xml/MisoSceneWriter.java @@ -1,5 +1,5 @@ // -// $Id: MisoSceneWriter.java,v 1.3 2001/11/29 06:36:28 mdb Exp $ +// $Id: MisoSceneWriter.java,v 1.4 2002/01/30 18:28:32 mdb Exp $ package com.threerings.miso.tools.scene.xml; @@ -44,5 +44,7 @@ public class MisoSceneWriter StringUtil.toString(model.fringeTileIds, "", "")); writer.dataElement("object", StringUtil.toString(model.objectTileIds, "", "")); + writer.dataElement("actions", + StringUtil.joinEscaped(model.objectActions)); } }