From cb4d268139f2c5f0ac0cec19dcf39b9d33ac509f Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Tue, 17 Jul 2001 17:21:33 +0000 Subject: [PATCH] Load tileset descriptions from an XML file. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@57 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/media/tile/TileManager.java | 42 ++++++- .../com/threerings/media/tile/TileSet.java | 38 ++---- .../threerings/media/tile/TileSetManager.java | 21 ++-- .../media/tile/TileSetManagerImpl.java | 38 ++---- .../threerings/media/tile/TileSetParser.java | 30 +++++ .../media/tile/XMLTileSetParser.java | 118 ++++++++++++++++++ .../miso/client/DisplayMisoSceneImpl.java | 4 +- .../miso/client/SceneManagerImpl.java | 4 +- .../miso/tile/CompiledTileSetManager.java | 9 +- .../miso/tile/EditableTileSetManager.java | 35 +++++- 10 files changed, 258 insertions(+), 81 deletions(-) create mode 100644 src/java/com/threerings/media/tile/TileSetParser.java create mode 100644 src/java/com/threerings/media/tile/XMLTileSetParser.java diff --git a/src/java/com/threerings/media/tile/TileManager.java b/src/java/com/threerings/media/tile/TileManager.java index e0bb4b934..75fc1f692 100644 --- a/src/java/com/threerings/media/tile/TileManager.java +++ b/src/java/com/threerings/media/tile/TileManager.java @@ -1,13 +1,16 @@ // -// $Id: TileManager.java,v 1.4 2001/07/16 22:12:01 shaper Exp $ +// $Id: TileManager.java,v 1.5 2001/07/17 17:21:33 shaper Exp $ package com.threerings.cocktail.miso.tile; import com.threerings.cocktail.miso.Log; +import com.samskivert.util.ConfigUtil; import com.samskivert.util.IntMap; import java.awt.*; +import java.io.*; +import java.util.ArrayList; /** * Provides a simplified interface for managing multiple tilesets and @@ -34,12 +37,11 @@ public class TileManager } /** - * Return a String array of all tileset names ordered by ascending - * tileset id. + * Return a list of all tilesets available for use. */ - public String[] getTileSetNames () + public ArrayList getTileSets () { - return _tsmgr.getTileSetNames(); + return _tsmgr.getTileSets(); } /** @@ -60,10 +62,17 @@ public class TileManager // retrieve the tileset containing the tile TileSet tset = _tsmgr.getTileSet(tsid); + if (tset == null) { + Log.warning("Can't create tile due to unknown tileset " + + "[tsid=" + tsid + ", tid=" + tid + "]."); + return null; + } // retrieve the tile image from the tileset tile = new Tile(tsid, tid); - tile.img = tset.getTileImage(tid); + if ((tile.img = tset.getTileImage(tid)) == null) { + Log.warning("Null tile image [tsid="+tsid+", tid="+tid+"]."); + } _tiles.put(utid, tile); @@ -72,6 +81,27 @@ public class TileManager return tile; } + /** + * Load all tileset objects described in the specified file into + * the set of available tilesets. + */ + public void loadTileSets (String fname) + { + try { + InputStream tis = ConfigUtil.getStream(fname); + if (tis == null) { + Log.warning("Couldn't find file [fname=" + fname + "]."); + return; + } + + _tsmgr.loadTileSets(tis); + + } catch (IOException ioe) { + Log.warning("Exception loading tileset [fname=" + fname + + ", ioe=" + ioe + "]."); + } + } + // mapping from (tsid << 16 | tid) to tile objects protected IntMap _tiles = new IntMap(); diff --git a/src/java/com/threerings/media/tile/TileSet.java b/src/java/com/threerings/media/tile/TileSet.java index 3a8911d5e..653c42499 100644 --- a/src/java/com/threerings/media/tile/TileSet.java +++ b/src/java/com/threerings/media/tile/TileSet.java @@ -1,13 +1,11 @@ // -// $Id: TileSet.java,v 1.5 2001/07/16 22:12:01 shaper Exp $ +// $Id: TileSet.java,v 1.6 2001/07/17 17:21:33 shaper Exp $ package com.threerings.cocktail.miso.tile; import com.threerings.cocktail.miso.Log; import com.threerings.cocktail.miso.media.ImageManager; -import com.samskivert.util.Config; - import java.awt.Image; import java.awt.Graphics2D; import java.awt.image.*; @@ -31,19 +29,14 @@ import java.awt.image.*; */ public class TileSet { - public TileSet (Config config, int tsid) + public TileSet (String name, int tsid, String imgFile, + int[] rowHeight, int[] tileCount) { + _name = name; _tsid = tsid; - - // get the tileset name - _name = config.getValue(PREFIX + CONF_NAME, (String)null); - - // get the tile image file name - _file = config.getValue(PREFIX + CONF_FILE, (String)null); - - // get the row height and tile count for each row - _rowHeight = config.getValue(PREFIX + CONF_ROWHEIGHT, (int[])null); - _tileCount = config.getValue(PREFIX + CONF_TILECOUNT, (int[])null); + _imgFile = imgFile; + _rowHeight = rowHeight; + _tileCount = tileCount; // determine the total number of tiles in the set for (int ii = 0; ii < _tileCount.length; ii++) @@ -73,13 +66,13 @@ public class TileSet { // load the full tile image if we don't already have it if (_imgTiles == null) { - if ((_imgTiles = ImageManager.getImage(_file)) == null) { + if ((_imgTiles = ImageManager.getImage(_imgFile)) == null) { Log.warning("Failed to retrieve full tileset image " + - "[file=" + _file + "]."); + "[file=" + _imgFile + "]."); return null; } } - + // find the row number containing the sought-after tile int ridx, tcount, ty, tx; ridx = tcount = ty = tx = 0; @@ -108,7 +101,7 @@ public class TileSet StringBuffer buf = new StringBuffer(); buf.append("[name=").append(_name); - buf.append(", file=").append(_file); + buf.append(", file=").append(_imgFile); buf.append(", tsid=").append(_tsid); buf.append(", numtiles=").append(_numTiles); @@ -127,15 +120,8 @@ public class TileSet return buf.append("}]").toString(); } - protected static final String PREFIX = "miso.tileset."; - - protected static final String CONF_FILE = "file"; - protected static final String CONF_NAME = "name"; - protected static final String CONF_ROWHEIGHT = "rowheight"; - protected static final String CONF_TILECOUNT = "tilecount"; - protected String _name; // the tileset name - protected String _file; // the file containing the tile images + protected String _imgFile; // the file containing the tile images protected int _tsid; // the tileset unique identifier protected int _rowHeight[]; // the height of each row in pixels protected int _tileCount[]; // the number of tiles in each row diff --git a/src/java/com/threerings/media/tile/TileSetManager.java b/src/java/com/threerings/media/tile/TileSetManager.java index 6ac04fb30..a58ab697a 100644 --- a/src/java/com/threerings/media/tile/TileSetManager.java +++ b/src/java/com/threerings/media/tile/TileSetManager.java @@ -1,8 +1,12 @@ // -// $Id: TileSetManager.java,v 1.2 2001/07/16 18:59:31 shaper Exp $ +// $Id: TileSetManager.java,v 1.3 2001/07/17 17:21:33 shaper Exp $ package com.threerings.cocktail.miso.tile; +import java.io.InputStream; +import java.io.IOException; +import java.util.ArrayList; + public interface TileSetManager { /** @@ -11,17 +15,18 @@ public interface TileSetManager public TileSet getTileSet (int tsid); /** - * Return a String array of all tileset names. + * Return a list of all tilesets available for use. */ - public String[] getTileSetNames (); - - /** - * Return the tileset id associated with the named tileset. - */ - public int getTileSetId (String name); + public ArrayList getTileSets (); /** * Return the total number of tilesets. */ public int getNumTileSets (); + + /** + * Load the tilesets described in the specified input stream into + * the set of available tilesets. + */ + public void loadTileSets (InputStream tis) throws IOException; } diff --git a/src/java/com/threerings/media/tile/TileSetManagerImpl.java b/src/java/com/threerings/media/tile/TileSetManagerImpl.java index b98102966..c827fdf02 100644 --- a/src/java/com/threerings/media/tile/TileSetManagerImpl.java +++ b/src/java/com/threerings/media/tile/TileSetManagerImpl.java @@ -1,52 +1,33 @@ // -// $Id: TileSetManagerImpl.java,v 1.1 2001/07/16 18:59:31 shaper Exp $ +// $Id: TileSetManagerImpl.java,v 1.2 2001/07/17 17:21:33 shaper Exp $ package com.threerings.cocktail.miso.tile; -import com.samskivert.util.Config; import com.samskivert.util.IntMap; +import java.util.ArrayList; import java.util.Enumeration; -public class TileSetManagerImpl implements TileSetManager +public abstract class TileSetManagerImpl implements TileSetManager { - public TileSetManagerImpl (Config config) - { - _config = config; - } - public TileSet getTileSet (int tsid) { - TileSet tset = (TileSet)_tilesets.get(tsid); - if (tset != null) return tset; - - _tilesets.put(tsid, tset = new TileSet(_config, tsid)); - return tset; + return (TileSet)_tilesets.get(tsid); } - public String[] getTileSetNames () + public ArrayList getTileSets () { int size = _tilesets.size(); if (size == 0) return null; - String[] names = new String[size]; + ArrayList list = new ArrayList(); + Enumeration sets = _tilesets.elements(); for (int ii = 0; ii < size; ii++) { - names[ii] = ((TileSet)sets.nextElement()).getName(); + list.add(sets.nextElement()); } - return names; - } - - public int getTileSetId (String name) - { - Enumeration sets = _tilesets.elements(); - while (sets.hasMoreElements()) { - TileSet tset = (TileSet)sets.nextElement(); - if (tset.getName().equals(name)) return tset.getId(); - } - - return -1; + return list; } public int getNumTileSets () @@ -54,6 +35,5 @@ public class TileSetManagerImpl implements TileSetManager return _tilesets.size(); } - protected Config _config; protected IntMap _tilesets = new IntMap(); } diff --git a/src/java/com/threerings/media/tile/TileSetParser.java b/src/java/com/threerings/media/tile/TileSetParser.java new file mode 100644 index 000000000..87e2e38e7 --- /dev/null +++ b/src/java/com/threerings/media/tile/TileSetParser.java @@ -0,0 +1,30 @@ +// +// $Id: TileSetParser.java,v 1.1 2001/07/17 17:21:33 shaper Exp $ + +package com.threerings.cocktail.miso.tile; + +import java.io.InputStream; +import java.io.IOException; +import java.util.ArrayList; + +/** + * An interface to be implemented by classes that wish to provide a + * general interface to load tileset description information from an + * input stream. + */ +public interface TileSetParser +{ + /** + * Return all tileset objects constructed from any previous + * parsing activity. + */ + public ArrayList getTileSets (); + + /** + * Construct tileset objects from the tileset description data on + * the given input stream. Classes that implement this method + * should store the tileset objects for later retrieval via the + * getTileSets() method. + */ + public void loadTileSets (InputStream tis) throws IOException; +} diff --git a/src/java/com/threerings/media/tile/XMLTileSetParser.java b/src/java/com/threerings/media/tile/XMLTileSetParser.java new file mode 100644 index 000000000..1a02ef40b --- /dev/null +++ b/src/java/com/threerings/media/tile/XMLTileSetParser.java @@ -0,0 +1,118 @@ +// +// $Id: XMLTileSetParser.java,v 1.1 2001/07/17 17:21:33 shaper Exp $ + +package com.threerings.cocktail.miso.tile; + +import com.threerings.cocktail.miso.Log; + +import com.samskivert.util.StringUtil; + +import org.xml.sax.*; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.helpers.XMLReaderFactory; + +import java.io.*; +import javax.xml.parsers.*; +import java.util.ArrayList; + +/** + * Parse an XML tileset description file and construct tileset objects + * for each valid description. Does not currently perform validation + * on the input XML stream, though the parsing code assumes the XML + * document is well-formed. + */ +public class XMLTileSetParser extends DefaultHandler + implements TileSetParser +{ + public void startElement (String uri, String localName, + String qName, Attributes attributes) + { + _tag = qName; + } + + public void endElement (String uri, String localName, String qName) + { + // construct the tileset object on tag close + if (qName.equals("tileset")) { + TileSet tset = new TileSet( + _tsName, _tsTsid, _tsImgFile, _tsRowHeight, _tsTileCount); + _tilesets.add(tset); + } + + // note that we're not within a tag to avoid considering any + // characters during this quiescent time + _tag = null; + } + + public void characters (char ch[], int start, int length) + { + // bail if we're not within a meaningful tag + if (_tag == null) return; + + String str = String.copyValueOf(ch, start, length); + + // store the value associated with the current tag for use + // when we construct the tileset object. + if (_tag.equals("name")) { + _tsName = str; + + } else if (_tag.equals("tsid")) { + try { + _tsTsid = Integer.parseInt(str); + } catch (NumberFormatException nfe) { + Log.warning("Malformed integer tilesetid [str=" + str + "]."); + _tsTsid = -1; + } + + } else if (_tag.equals("imagefile")) { + _tsImgFile = str; + + } else if (_tag.equals("rowheight")) { + _tsRowHeight = StringUtil.parseIntArray(str); + + } else if (_tag.equals("tilecount")) { + _tsTileCount = StringUtil.parseIntArray(str); + } + } + + public void loadTileSets (InputStream tis) throws IOException + { + try { + XMLReader xr = _pfactory.newSAXParser().getXMLReader(); + + xr.setContentHandler(this); + xr.setErrorHandler(this); + + xr.parse(new InputSource(tis)); + + } catch (ParserConfigurationException pce) { + throw new IOException(pce.toString()); + + } catch (SAXException saxe) { + throw new IOException(saxe.toString()); + } + } + + public ArrayList getTileSets () + { + if (_tilesets.size() == 0) return null; + return _tilesets; + } + + protected String _tag; + protected ArrayList _tilesets = new ArrayList(); + + // temporary storage of tileset object values + protected String _tsName; + protected int _tsTsid; + protected String _tsImgFile; + protected int[] _tsRowHeight, _tsTileCount; + + // the slithy tove from whence came the XMLReader object + protected static SAXParserFactory _pfactory; + + static { + _pfactory = SAXParserFactory.newInstance(); + _pfactory.setValidating(false); + } +} diff --git a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java index 2bc40d31d..1e8b260ae 100644 --- a/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java +++ b/src/java/com/threerings/miso/client/DisplayMisoSceneImpl.java @@ -1,5 +1,5 @@ // -// $Id: DisplayMisoSceneImpl.java,v 1.4 2001/07/16 22:12:01 shaper Exp $ +// $Id: DisplayMisoSceneImpl.java,v 1.5 2001/07/17 17:21:33 shaper Exp $ package com.threerings.cocktail.miso.scene; @@ -216,7 +216,7 @@ public class Scene protected static final String DEF_SCENE_NAME = "Untitled Scene"; - protected static final short DEF_TSID = 0; + protected static final short DEF_TSID = 1000; protected static final short DEF_TID = 1; protected String _name; // the scene name diff --git a/src/java/com/threerings/miso/client/SceneManagerImpl.java b/src/java/com/threerings/miso/client/SceneManagerImpl.java index 4ae6e3c42..c269d0783 100644 --- a/src/java/com/threerings/miso/client/SceneManagerImpl.java +++ b/src/java/com/threerings/miso/client/SceneManagerImpl.java @@ -1,9 +1,9 @@ // -// $Id: SceneManagerImpl.java,v 1.1 2001/07/16 22:12:01 shaper Exp $ +// $Id: SceneManagerImpl.java,v 1.2 2001/07/17 17:21:33 shaper Exp $ package com.threerings.cocktail.miso.scene; -public class SceneManagerImpl implements SceneManager +public abstract class SceneManagerImpl implements SceneManager { public Scene getScene (int sid) { diff --git a/src/java/com/threerings/miso/tile/CompiledTileSetManager.java b/src/java/com/threerings/miso/tile/CompiledTileSetManager.java index 677bd4419..a6f7d2a44 100644 --- a/src/java/com/threerings/miso/tile/CompiledTileSetManager.java +++ b/src/java/com/threerings/miso/tile/CompiledTileSetManager.java @@ -1,14 +1,15 @@ // -// $Id: CompiledTileSetManager.java,v 1.2 2001/07/16 18:59:31 shaper Exp $ +// $Id: CompiledTileSetManager.java,v 1.3 2001/07/17 17:21:33 shaper Exp $ package com.threerings.cocktail.miso.tile; -import com.samskivert.util.Config; +import java.io.InputStream; +import java.io.IOException; public class CompiledTileSetManager extends TileSetManagerImpl { - public CompiledTileSetManager (Config config) + public void loadTileSets (InputStream tis) throws IOException { - super(config); + // TBD } } diff --git a/src/java/com/threerings/miso/tile/EditableTileSetManager.java b/src/java/com/threerings/miso/tile/EditableTileSetManager.java index 8eeec951d..32ecd418c 100644 --- a/src/java/com/threerings/miso/tile/EditableTileSetManager.java +++ b/src/java/com/threerings/miso/tile/EditableTileSetManager.java @@ -1,14 +1,41 @@ // -// $Id: EditableTileSetManager.java,v 1.2 2001/07/16 18:59:31 shaper Exp $ +// $Id: EditableTileSetManager.java,v 1.3 2001/07/17 17:21:33 shaper Exp $ package com.threerings.cocktail.miso.tile; -import com.samskivert.util.Config; +import com.threerings.cocktail.miso.Log; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; + +/** + * Extends general tileset manager functionality to allow reading + * tileset information from XML files. The XML file format allows for + * improved version-control, and makes tilesets easier to view, edit, + * and re-use than might otherwise be the case. + */ public class EditableTileSetManager extends TileSetManagerImpl { - public EditableTileSetManager (Config config) + public void loadTileSets (InputStream tis) throws IOException { - super(config); + // read all tileset descriptions from the XML input stream + XMLTileSetParser parser = new XMLTileSetParser(); + parser.loadTileSets(tis); + + // grab any resulting tileset objects + ArrayList tsets = parser.getTileSets(); + if (tsets == null) { + Log.warning("No tileset descriptions found [tis=" + tis + "]."); + return; + } + + // and copy them into the main tileset hashtable + int size = tsets.size(); + for (int ii = 0; ii < size; ii++) { + TileSet tset = (TileSet)tsets.get(ii); + _tilesets.put(tset.getId(), tset); + Log.info("Adding tileset to cache [tset=" + tset + "]."); + } } }