Oh the vast sweeping changes, and they're not even close to complete, but
things compile and most things run so this is a good time to checkpoint. Let me recall: - Refactored the whole scene deal. - Revamped the XML parser stuff (now uses Digester). - Rethought the tile management. - Started tile bundle stuff. - Wrote some tests. - Did a bit of Mike-ification. Onward and moreward. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@621 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// $Id: SwissArmyTileSetRuleSet.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.xml;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.apache.commons.digester.Digester;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.xml.CallMethodSpecialRule;
|
||||
|
||||
import com.threerings.media.tile.TileSet;
|
||||
import com.threerings.media.tile.SwissArmyTileSet;
|
||||
|
||||
/**
|
||||
* Parses {@link SwissArmyTileSet} instances from a tileset description. A
|
||||
* uniform tileset description looks like so:
|
||||
*
|
||||
* <pre>
|
||||
* <tileset name="Sample Swiss Army Tileset">
|
||||
* <imgpath>path/to/image.png</imgpath>
|
||||
* <!-- the widths (per row) of each tile in pixels -->
|
||||
* <widths>64, 64, 64, 64</widths>
|
||||
* <!-- the heights (per row) of each tile in pixels -->
|
||||
* <heights>48, 48, 48, 64</heights>
|
||||
* <!-- the number of tiles in each row -->
|
||||
* <tileCounts>16, 5, 3, 10</tileCounts>
|
||||
* <!-- the offset in pixels to the upper left tile -->
|
||||
* <offset>8, 8</offset>
|
||||
* <!-- the gap between tiles in pixels -->
|
||||
* <gap>12, 12</gap>
|
||||
* </tileset>
|
||||
* </pre>
|
||||
*/
|
||||
public class SwissArmyTileSetRuleSet extends TileSetRuleSet
|
||||
{
|
||||
/**
|
||||
* Constructs a uniform tileset rule set that will match tilesets with
|
||||
* the specified prefix. See the documentation for {@link
|
||||
* TileSetRuleSet#TileSetruleSet} for more info on matching.
|
||||
*/
|
||||
public SwissArmyTileSetRuleSet (String prefix)
|
||||
{
|
||||
super(prefix);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void addRuleInstances (Digester digester)
|
||||
{
|
||||
super.addRuleInstances(digester);
|
||||
|
||||
digester.addRule(
|
||||
_prefix + "/tileset/widths",
|
||||
new CallMethodSpecialRule(digester) {
|
||||
public void parseAndSet (String bodyText, Object target)
|
||||
{
|
||||
int[] widths = StringUtil.parseIntArray(bodyText);
|
||||
((SwissArmyTileSet)target).setWidths(widths);
|
||||
}
|
||||
});
|
||||
|
||||
digester.addRule(
|
||||
_prefix + "/tileset/heights",
|
||||
new CallMethodSpecialRule(digester) {
|
||||
public void parseAndSet (String bodyText, Object target)
|
||||
{
|
||||
int[] heights = StringUtil.parseIntArray(bodyText);
|
||||
((SwissArmyTileSet)target).setHeights(heights);
|
||||
}
|
||||
});
|
||||
|
||||
digester.addRule(
|
||||
_prefix + "/tileset/tileCounts",
|
||||
new CallMethodSpecialRule(digester) {
|
||||
public void parseAndSet (String bodyText, Object target)
|
||||
{
|
||||
int[] tileCounts = StringUtil.parseIntArray(bodyText);
|
||||
((SwissArmyTileSet)target).setTileCounts(tileCounts);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected TileSet createTileSet (Attributes attributes)
|
||||
{
|
||||
// we use uniform tilesets
|
||||
return new SwissArmyTileSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string containing values as (x, y) into the
|
||||
* corresponding integer values and populates the given point
|
||||
* object.
|
||||
*
|
||||
* @param str the point values in string format.
|
||||
* @param point the point object to populate.
|
||||
*/
|
||||
protected void parsePoint (String str, Point point)
|
||||
{
|
||||
int vals[] = StringUtil.parseIntArray(str);
|
||||
point.setLocation(vals[0], vals[1]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// $Id: TileSetRuleSet.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.xml;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import org.apache.commons.digester.Digester;
|
||||
import org.apache.commons.digester.Rule;
|
||||
import org.apache.commons.digester.RuleSetBase;
|
||||
|
||||
import com.threerings.media.tile.TileSet;
|
||||
|
||||
/**
|
||||
* The tileset rule set is used to parse the base attributes of a tileset
|
||||
* instance. Derived classes would extend this and add rules for their own
|
||||
* special tilesets.
|
||||
*/
|
||||
public abstract class TileSetRuleSet extends RuleSetBase
|
||||
{
|
||||
/**
|
||||
* Constructs a tileset rule set which will match tilesets with the
|
||||
* supplied prefix. For example, passing a prefix of
|
||||
* <code>tilesets.objectsets</code> will match tilesets in the
|
||||
* following XML file:
|
||||
*
|
||||
* <pre>
|
||||
* <tilesets>
|
||||
* <objectsets>
|
||||
* <tileset>
|
||||
* // ...
|
||||
* </tileset>
|
||||
* </objectsets>
|
||||
* </tilesets>
|
||||
* </pre>
|
||||
*/
|
||||
public TileSetRuleSet (String prefix)
|
||||
{
|
||||
_prefix = prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the {@link XMLTileSetParser} to initialize this tileset
|
||||
* rule set with the necessary back references to operate properly.
|
||||
*/
|
||||
protected void init (XMLTileSetParser parser)
|
||||
{
|
||||
_parser = parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the necessary rules to the digester to parse our tilesets.
|
||||
* Derived classes should override this method, being sure to call the
|
||||
* superclass method and then adding their own rule instances (which
|
||||
* should register themselves relative to the <code>_prefix</code>
|
||||
* member).
|
||||
*/
|
||||
public void addRuleInstances (Digester digester)
|
||||
{
|
||||
// this creates the appropriate instance when we encounter a
|
||||
// <tileset> tag
|
||||
digester.addRule(_prefix + "/tileset",
|
||||
new TileSetCreateRule(digester));
|
||||
|
||||
// grab the name attribute from the <tileset> tag
|
||||
digester.addSetProperties(_prefix + "/tileset");
|
||||
|
||||
// grab the image path from an element
|
||||
digester.addCallMethod(
|
||||
_prefix + "/tileset/imagePath", "setImagePath", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* When a <tileset> element is encountered, this method is
|
||||
* called to create a new instance of {@link TileSet}. Though the
|
||||
* attributes are supplied (in case an attribute is needed to
|
||||
* determine which derived instance of {@link TileSet} to create, this
|
||||
* method should not configure the created tileset object. It should
|
||||
* instead rely on the set properties rule that will be executed after
|
||||
* this object is created or to custom set property rules registered
|
||||
* in {@link #addDigesterRules}.
|
||||
*/
|
||||
protected abstract TileSet createTileSet (Attributes attributes);
|
||||
|
||||
/**
|
||||
* Used to process a <tileset> element.
|
||||
*/
|
||||
protected class TileSetCreateRule extends Rule
|
||||
{
|
||||
public TileSetCreateRule (Digester digester)
|
||||
{
|
||||
super(digester);
|
||||
}
|
||||
|
||||
public void begin (Attributes attributes)
|
||||
throws Exception
|
||||
{
|
||||
// pass the torch to the XML parser to create the tileset
|
||||
TileSet set = createTileSet(attributes);
|
||||
// then push it onto the stack
|
||||
digester.push(set);
|
||||
}
|
||||
|
||||
public void end ()
|
||||
throws Exception
|
||||
{
|
||||
// pop the tileset off of the stack
|
||||
TileSet set = (TileSet)digester.pop();
|
||||
// and stick it into our tileset map
|
||||
_parser._tilesets.put(set.getName(), set);
|
||||
}
|
||||
}
|
||||
|
||||
/** The prefix at which me match our tilesets. */
|
||||
protected String _prefix;
|
||||
|
||||
/** A reference to the XMLTileSetParser on whose behalf we are
|
||||
* parsing. */
|
||||
protected XMLTileSetParser _parser;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// $Id: UniformTileSetRuleSet.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.xml;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.apache.commons.digester.Digester;
|
||||
|
||||
import com.threerings.media.tile.TileSet;
|
||||
import com.threerings.media.tile.UniformTileSet;
|
||||
|
||||
/**
|
||||
* Parses {@link UniformTileSet} instances from a tileset description. A
|
||||
* uniform tileset description looks like so:
|
||||
*
|
||||
* <pre>
|
||||
* <tileset name="Sample Uniform Tileset">
|
||||
* <imgpath>path/to/image.png</imgpath>
|
||||
* <!-- the width of each tile in pixels -->
|
||||
* <width>64</width>
|
||||
* <!-- the height of each tile in pixels -->
|
||||
* <height>48</height>
|
||||
* <!-- the total number of tiles in the set -->
|
||||
* <tileCount>16</tileCount>
|
||||
* </tileset>
|
||||
* </pre>
|
||||
*/
|
||||
public class UniformTileSetRuleSet extends TileSetRuleSet
|
||||
{
|
||||
/**
|
||||
* Constructs a uniform tileset rule set that will match tilesets with
|
||||
* the specified prefix. See the documentation for {@link
|
||||
* TileSetRuleSet#TileSetruleSet} for more info on matching.
|
||||
*/
|
||||
public UniformTileSetRuleSet (String prefix)
|
||||
{
|
||||
super(prefix);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void addRuleInstances (Digester digester)
|
||||
{
|
||||
super.addRuleInstances(digester);
|
||||
|
||||
digester.addCallMethod(
|
||||
_prefix + "/tileset/width", "setWidth", 0,
|
||||
new Class[] { java.lang.Integer.TYPE });
|
||||
digester.addCallMethod(
|
||||
_prefix + "/tileset/height", "setHeight", 0,
|
||||
new Class[] { java.lang.Integer.TYPE });
|
||||
digester.addCallMethod(
|
||||
_prefix + "/tileset/tileCount", "setTileCount", 0,
|
||||
new Class[] { java.lang.Integer.TYPE });
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected TileSet createTileSet (Attributes attributes)
|
||||
{
|
||||
// we use uniform tilesets
|
||||
return new UniformTileSet();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// $Id: XMLTileSetParser.java,v 1.1 2001/11/18 04:09:22 mdb Exp $
|
||||
|
||||
package com.threerings.media.tile.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import org.apache.commons.digester.Digester;
|
||||
import org.apache.commons.digester.Rule;
|
||||
|
||||
import com.samskivert.util.ConfigUtil;
|
||||
|
||||
import com.threerings.media.Log;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
/**
|
||||
* Constructs an xml tile set parser.
|
||||
*/
|
||||
public XMLTileSetParser ()
|
||||
{
|
||||
// create our digester
|
||||
_digester = new Digester();
|
||||
// _digester.setDebug(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a ruleset to be used when parsing tiles. This should be an
|
||||
* instance of a class derived from {@link TileSetRuleSet} which was
|
||||
* constructed to match a particular kind of tile at a particular
|
||||
* point in the XML hierarchy. For example:
|
||||
*
|
||||
* <pre>
|
||||
* _parser.addRuleSet(new UniformTileSetRuleSet("tilesets"));
|
||||
* </pre>
|
||||
*/
|
||||
public void addRuleSet (TileSetRuleSet ruleset)
|
||||
{
|
||||
// provide a reference to ourselves to the ruleset
|
||||
ruleset.init(this);
|
||||
|
||||
// and have it set itself up with the digester
|
||||
_digester.addRuleSet(ruleset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all of the tilesets specified in the supplied XML tileset
|
||||
* description file and places them into the supplied hashmap indexed
|
||||
* by tileset name.
|
||||
*/
|
||||
public void loadTileSets (String path, HashMap tilesets)
|
||||
throws IOException
|
||||
{
|
||||
// save off the tileset hashtable
|
||||
_tilesets = tilesets;
|
||||
|
||||
// get an input stream for this XML file
|
||||
InputStream is = ConfigUtil.getStream(path);
|
||||
if (is == null) {
|
||||
String errmsg = "Can't load tileset description file from " +
|
||||
"classpath [path=" + path + "].";
|
||||
throw new FileNotFoundException(errmsg);
|
||||
}
|
||||
|
||||
Log.info("Loading from " + path + ".");
|
||||
|
||||
// now fire up the digester to parse the stream
|
||||
try {
|
||||
_digester.parse(is);
|
||||
} catch (SAXException saxe) {
|
||||
Log.warning("Exception parsing tile set descriptions " +
|
||||
"[error=" + saxe + "].");
|
||||
Log.logStackTrace(saxe);
|
||||
}
|
||||
}
|
||||
|
||||
/** Our XML digester. */
|
||||
protected Digester _digester;
|
||||
|
||||
/** The tilesets constructed thus far. */
|
||||
protected HashMap _tilesets;
|
||||
|
||||
/** Default tileset name. */
|
||||
protected static final String DEF_NAME = "Untitled";
|
||||
|
||||
/** String constant denoting an object tile set. */
|
||||
protected static final String LAYER_OBJECT = "object";
|
||||
}
|
||||
Reference in New Issue
Block a user