6c1051abed
Here's the policy: Every top-level package has a tools package under which all subpackages exist with their tools additions. For example: com.threerings.media.tile.TileSet com.threerings.media.tools.tile.XMLTileSetRuleSet com.threerings.miso.scene.MisoScene com.threerings.miso.tools.scene.EditableMisoScene git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@630 542714f4-19e9-0310-aa3c-eee0fc999fb1
250 lines
8.0 KiB
Java
250 lines
8.0 KiB
Java
//
|
|
// $Id: XMLComponentParser.java,v 1.5 2001/11/20 04:15:43 mdb Exp $
|
|
|
|
package com.threerings.cast.tools.xml;
|
|
|
|
import java.awt.Point;
|
|
import java.io.IOException;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
|
|
import org.xml.sax.*;
|
|
|
|
import com.samskivert.util.*;
|
|
import com.samskivert.xml.SimpleParser;
|
|
|
|
import com.threerings.media.tile.TileSet;
|
|
import com.threerings.media.tools.tile.xml.XMLTileSetParser;
|
|
|
|
import com.threerings.cast.Log;
|
|
import com.threerings.cast.ActionSequence;
|
|
import com.threerings.cast.ComponentClass;
|
|
import com.threerings.cast.CharacterComponent;
|
|
|
|
/**
|
|
* Parses an XML character component description file and populates
|
|
* hashtables with {@link ActionSequence}, {@link ComponentClass}, and the
|
|
* information necessary to construct {@link CharacterComponent} objects.
|
|
*
|
|
* <p> Does not currently perform validation on the input XML stream,
|
|
* though the parsing code assumes the XML document is well-formed.
|
|
*/
|
|
public class XMLComponentParser extends SimpleParser
|
|
{
|
|
// documentation inherited
|
|
public void startElement (
|
|
String uri, String localName, String qName, Attributes attributes)
|
|
{
|
|
if (qName.equals("charactercomponents")) {
|
|
// save off the image directory
|
|
_imagedir = attributes.getValue("imagedir");
|
|
// load the tile sets
|
|
loadTileSets(attributes.getValue("tilesets"));
|
|
|
|
} else if (qName.equals("action")) {
|
|
// construct and save off the action sequence object
|
|
ActionSequence as = getActionSequence(attributes);
|
|
_actions.put(as.asid, as);
|
|
|
|
} else if (qName.equals("class")) {
|
|
// construct and save off the component class object
|
|
ComponentClass cclass = getComponentClass(attributes);
|
|
_classes.put(cclass.clid, cclass);
|
|
|
|
} else if (qName.equals("component")) {
|
|
// construct and save off the character component
|
|
CharacterComponent component = getComponent(attributes);
|
|
_components.put(component.getId(), component);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads the component descriptions in the given file into the
|
|
* given component data hashtables.
|
|
*/
|
|
public void loadComponents (String file, HashIntMap actions,
|
|
HashIntMap classes, HashIntMap components)
|
|
throws IOException
|
|
{
|
|
// save off hashtables for reference while parsing
|
|
_actions = actions;
|
|
_classes = classes;
|
|
_components = components;
|
|
|
|
// clear out remnants of any previous parsing antics
|
|
_imagedir = null;
|
|
_tilesets.clear();
|
|
|
|
// parse the file
|
|
parseFile(file);
|
|
}
|
|
|
|
/**
|
|
* Returns the image directory the component tile images reside
|
|
* within.
|
|
*/
|
|
public String getImageDir ()
|
|
{
|
|
return _imagedir;
|
|
}
|
|
|
|
/**
|
|
* Loads the tile sets in the XML file at the given path into the
|
|
* tile sets available for reference by the action sequences.
|
|
*/
|
|
protected void loadTileSets (String path)
|
|
{
|
|
// make sure we have a reasonable path
|
|
if (path == null) {
|
|
Log.warning("Null component tile set description file path.");
|
|
return;
|
|
}
|
|
|
|
// parse the tile set description file
|
|
XMLTileSetParser p = new XMLTileSetParser();
|
|
try {
|
|
p.loadTileSets(path, _tilesets);
|
|
} catch (IOException e) {
|
|
Log.warning("Exception loading component tile set descriptions " +
|
|
"[path=" + path + "].");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a new action sequence object as described by the given
|
|
* attributes.
|
|
*/
|
|
protected ActionSequence getActionSequence (Attributes attrs)
|
|
{
|
|
ActionSequence as = new ActionSequence();
|
|
|
|
as.asid = parseInt(attrs.getValue("asid"));
|
|
as.name = attrs.getValue("name");
|
|
as.fileid = attrs.getValue("fileid");
|
|
|
|
String tileset = attrs.getValue("tileset");
|
|
as.tileset = (TileSet)_tilesets.get(tileset);
|
|
if (as.tileset == null) {
|
|
Log.warning("Action sequence references non-existent " +
|
|
"tile set [asid=" + as.asid +
|
|
", tileset=" + tileset + "].");
|
|
}
|
|
|
|
as.fps = parseInt(attrs.getValue("fps"));
|
|
parsePoint(attrs.getValue("origin"), as.origin);
|
|
|
|
return as;
|
|
}
|
|
|
|
/**
|
|
* Returns a new component class object as described by the given
|
|
* attributes.
|
|
*/
|
|
protected ComponentClass getComponentClass (Attributes attrs)
|
|
{
|
|
ComponentClass cclass = new ComponentClass();
|
|
cclass.clid = parseInt(attrs.getValue("clid"));
|
|
cclass.name = attrs.getValue("name");
|
|
cclass.render = parseInt(attrs.getValue("render"));
|
|
return cclass;
|
|
}
|
|
|
|
/**
|
|
* Returns a new character component object as described by the
|
|
* given attributes.
|
|
*/
|
|
protected CharacterComponent getComponent (Attributes attrs)
|
|
{
|
|
// retrieve the component attributes
|
|
int cid = parseInt(attrs.getValue("cid"));
|
|
String fileid = attrs.getValue("fileid");
|
|
String val = attrs.getValue("asids");
|
|
int asids[] = StringUtil.parseIntArray(val);
|
|
int clid = parseInt(attrs.getValue("clid"));
|
|
ComponentClass cclass = (ComponentClass)_classes.get(clid);
|
|
|
|
// gather the array of relevant action sequences
|
|
ActionSequence seqs[] = getActionSequences(asids);
|
|
|
|
// construct the component sans frames for now
|
|
CharacterComponent component =
|
|
new CharacterComponent(cid, fileid, seqs, cclass);
|
|
|
|
// warn if the component has notably invalid attributes
|
|
validateComponent(cid, asids, clid);
|
|
|
|
return component;
|
|
}
|
|
|
|
/**
|
|
* Outputs a warning regarding the given component id if the given
|
|
* action sequence ids and component class id for that component
|
|
* don't exist.
|
|
*/
|
|
protected void validateComponent (int cid, int asids[], int clid)
|
|
{
|
|
// check the action sequence ids
|
|
for (int ii = 0; ii < asids.length; ii++) {
|
|
int asid = asids[ii];
|
|
if (_actions.get(asid) == null) {
|
|
Log.warning(
|
|
"Component references non-existent action sequence " +
|
|
"[cid=" + cid + ", asid=" + asid + "].");
|
|
}
|
|
}
|
|
|
|
// check the class id
|
|
if (_classes.get(clid) == null) {
|
|
Log.warning("Component references non-existent class " +
|
|
"[cid=" + cid + ", clid=" + clid + "].");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns an array of action sequence objects corresponding to
|
|
* the action sequence ids in the given array.
|
|
*/
|
|
protected ActionSequence[] getActionSequences (int asids[])
|
|
{
|
|
// sort the action sequence ids for better regularity
|
|
Arrays.sort(asids);
|
|
|
|
// create and populate the array
|
|
ActionSequence[] seqs = new ActionSequence[asids.length];
|
|
for (int ii = 0; ii < asids.length; ii++) {
|
|
seqs[ii] = (ActionSequence)_actions.get(asids[ii]);
|
|
}
|
|
|
|
return seqs;
|
|
}
|
|
|
|
/**
|
|
* 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]);
|
|
}
|
|
|
|
/** The image directory containing the component image files. */
|
|
protected String _imagedir;
|
|
|
|
/** The hashtable of component tile sets. */
|
|
protected HashMap _tilesets = new HashMap();
|
|
|
|
/** The hashtable of action sequences gathered while parsing. */
|
|
protected HashIntMap _actions;
|
|
|
|
/** The hashtable of component classes gathered while parsing. */
|
|
protected HashIntMap _classes;
|
|
|
|
/** The hashtable of character components gathered while parsing. */
|
|
protected HashIntMap _components;
|
|
}
|