Moved action tileset parsing into a helper class, so that it can be more easily

tested and debugged. Turns out the problem I was chasing was a digester-2.0
dependency where a digester-1.8 dependency was needed, but I'll go ahead and
commit this anyway.


git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@1123 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Michael Bayne
2011-02-03 20:04:09 +00:00
parent b69202d0ef
commit f648e24f90
3 changed files with 199 additions and 61 deletions
@@ -24,15 +24,14 @@ package com.threerings.cast.bundle.tools;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.Deflater;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
@@ -45,7 +44,6 @@ import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import org.apache.commons.digester.Digester;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
@@ -63,14 +61,10 @@ import com.threerings.media.tile.ImageProvider;
import com.threerings.media.tile.SimpleCachingImageProvider;
import com.threerings.media.tile.TileSet;
import com.threerings.media.tile.TrimmedTileSet;
import com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet;
import com.threerings.media.tile.tools.xml.TileSetRuleSet;
import com.threerings.media.tile.tools.xml.UniformTileSetRuleSet;
import com.threerings.cast.ComponentIDBroker;
import com.threerings.cast.StandardActions;
import com.threerings.cast.bundle.BundleUtil;
import com.threerings.cast.tools.xml.ActionRuleSet;
/**
* Ant task for creating component bundles. This task must be configured
@@ -165,7 +159,15 @@ public class ComponentBundlerTask extends Task
"definitions via the 'actiondef' attribute.");
// parse in the action tilesets
HashMap<String, TileSet> actsets = parseActionTileSets();
Map<String, TileSet> actsets;
try {
actsets = ComponentBundlerUtil.parseActionTileSets(_actionDef);
} catch (FileNotFoundException fnfe) {
throw new BuildException("Unable to load action definition file " +
"[path=" + _actionDef.getPath() + "].", fnfe);
} catch (Exception e) {
throw new BuildException("Parsing error.", e);
}
// load up our component ID broker
ComponentIDBroker broker = loadBroker(_mapfile);
@@ -439,46 +441,6 @@ public class ComponentBundlerTask extends Task
}
}
/**
* Configures <code>ruleSet</code> and hooks it into <code>digester</code>.
*/
protected static void addTileSetRuleSet (Digester digester, TileSetRuleSet ruleSet)
{
ruleSet.setPrefix("actions" + ActionRuleSet.ACTION_PATH);
digester.addRuleSet(ruleSet);
digester.addSetNext(ruleSet.getPath(), "addTileSet", TileSet.class.getName());
}
/**
* Parses the action tileset definitions and puts them into a hash map, keyed on action name.
*/
protected HashMap<String, TileSet> parseActionTileSets ()
{
Digester digester = new Digester();
digester.addSetProperties("actions" + ActionRuleSet.ACTION_PATH);
addTileSetRuleSet(digester, new SwissArmyTileSetRuleSet());
addTileSetRuleSet(digester, new UniformTileSetRuleSet("/uniformTileset"));
HashMap<String, TileSet> actsets = new ActionMap();
digester.push(actsets);
try {
FileInputStream fin = new FileInputStream(_actionDef);
BufferedInputStream bin = new BufferedInputStream(fin);
digester.parse(bin);
} catch (FileNotFoundException fnfe) {
String errmsg = "Unable to load action definition file " +
"[path=" + _actionDef.getPath() + "].";
throw new BuildException(errmsg, fnfe);
} catch (Exception e) {
throw new BuildException("Parsing error.", e);
}
return actsets;
}
/**
* Creates the base output stream to which to write our bundle's files.
*/
@@ -520,19 +482,6 @@ public class ComponentBundlerTask extends Task
return TrimmedTileSet.trimTileSet(aset, fout);
}
/** Used when parsing action tilesets. */
public static class ActionMap extends HashMap<String, TileSet>
{
public void setName (String name) {
_name = name;
}
public void addTileSet (TileSet set) {
set.setName(_name);
put(_name, set);
}
protected String _name;
}
/**
* Loads the hashmap ID broker from its persistent representation in
* the specified file.
@@ -0,0 +1,97 @@
//
// $Id$
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2011 Three Rings Design, Inc., All Rights Reserved
// http://code.google.com/p/nenya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.cast.bundle.tools;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.xml.sax.SAXException;
import org.apache.commons.digester.Digester;
import com.threerings.media.tile.TileSet;
import com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet;
import com.threerings.media.tile.tools.xml.TileSetRuleSet;
import com.threerings.media.tile.tools.xml.UniformTileSetRuleSet;
import com.threerings.cast.tools.xml.ActionRuleSet;
/**
* Utilities needed when building component bundles.
*/
public class ComponentBundlerUtil
{
/**
* Parses the action tileset definitions in the supplied file and puts them into a hash map,
* keyed on action name.
*/
public static Map<String, TileSet> parseActionTileSets (File file)
throws IOException, SAXException
{
return parseActionTileSets(new BufferedInputStream(new FileInputStream(file)));
}
/**
* Parses the action tileset definitions in the supplied input stream, and puts them into a
* hash map, keyed on action name.
*/
public static Map<String, TileSet> parseActionTileSets (InputStream in)
throws IOException, SAXException
{
Digester digester = new Digester();
digester.addSetProperties("actions" + ActionRuleSet.ACTION_PATH);
addTileSetRuleSet(digester, new SwissArmyTileSetRuleSet());
addTileSetRuleSet(digester, new UniformTileSetRuleSet("/uniformTileset"));
Map<String, TileSet> actsets = new ActionMap();
digester.push(actsets);
digester.parse(in);
return actsets;
}
/**
* Configures <code>ruleSet</code> and hooks it into <code>digester</code>.
*/
protected static void addTileSetRuleSet (Digester digester, TileSetRuleSet ruleSet)
{
ruleSet.setPrefix("actions" + ActionRuleSet.ACTION_PATH);
digester.addRuleSet(ruleSet);
digester.addSetNext(ruleSet.getPath(), "addTileSet", TileSet.class.getName());
}
/** Used when parsing action tilesets. (This class must be public for Digester to work.) */
public static class ActionMap extends HashMap<String, TileSet>
{
public void setName (String name) {
_name = name;
}
public void addTileSet (TileSet set) {
set.setName(_name);
put(_name, set);
}
protected String _name;
}
}
@@ -0,0 +1,92 @@
//
// $Id$
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2011 Three Rings Design, Inc., All Rights Reserved
// http://code.google.com/p/nenya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.cast.bundle.tools;
import java.awt.Rectangle;
import java.io.ByteArrayInputStream;
import java.util.Map;
import org.junit.*;
import static org.junit.Assert.*;
import com.threerings.media.tile.SwissArmyTileSet;
import com.threerings.media.tile.TileSet;
/**
* Tests the component bundler utilities.
*/
public class ComponentBundlerUtilTest
{
@Test
public void testParseActionTileSets ()
throws Exception
{
Map<String, TileSet> map = ComponentBundlerUtil.parseActionTileSets(
new ByteArrayInputStream(ACTION_DATA.getBytes()));
SwissArmyTileSet defset = (SwissArmyTileSet)map.get("default");
assertNotNull(defset);
assertEquals("default", defset.getName());
assertEquals(1, defset.getTileCount());
assertArrayEquals(new int[] { 1 }, defset.getTileCounts());
assertEquals(new Rectangle(0, 0, 540, 640), defset.computeTileBounds(0, new Rectangle()));
SwissArmyTileSet statset = (SwissArmyTileSet)map.get("static");
assertNotNull(statset);
assertEquals("static", statset.getName());
assertEquals(1, statset.getTileCount());
assertArrayEquals(new int[] { 1 }, statset.getTileCounts());
assertEquals(new Rectangle(0, 0, 312, 240), statset.computeTileBounds(0, new Rectangle()));
}
protected static final String ACTION_DATA =
"<actions>\n" +
" <!-- actions relating to the face shot components -->\n" +
" <action name=\"default\">\n" +
" <framesPerSecond>1</framesPerSecond>\n" +
" <origin>270,640</origin>\n" +
" <!-- TODO: fix code that requires one array entry for each orientation -->\n" +
" <orients>SW</orients>\n" +
" <tileset>\n" +
" <widths>540</widths>\n" +
" <heights>640</heights>\n" +
" <tileCounts>1</tileCounts>\n" +
" <offsetPos>0, 0</offsetPos>\n" +
" <gapSize>0, 0</gapSize>\n" +
" </tileset>\n" +
" </action>\n" +
"\n" +
" <!-- actions relating to the gang buckle components -->\n" +
" <action name=\"static\">\n" +
" <framesPerSecond>1</framesPerSecond>\n" +
" <origin>156,240</origin>\n" +
" <orients>SW</orients>\n" +
" <tileset>\n" +
" <widths>312</widths>\n" +
" <heights>240</heights>\n" +
" <tileCounts>1</tileCounts>\n" +
" <offsetPos>0, 0</offsetPos>\n" +
" <gapSize>0, 0</gapSize>\n" +
" </tileset>\n" +
" </action>\n" +
"</actions>";
}