Component bundling process now automatically generates trimmed tilesets

and images from the untrimmed source tilesets and images.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1490 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2002-06-19 08:33:14 +00:00
parent fcc65fc4d9
commit 33158f5e8a
3 changed files with 140 additions and 31 deletions
@@ -1,5 +1,5 @@
//
// $Id: BundleUtil.java,v 1.1 2001/11/27 08:09:35 mdb Exp $
// $Id: BundleUtil.java,v 1.2 2002/06/19 08:33:14 mdb Exp $
package com.threerings.cast.bundle;
@@ -33,6 +33,9 @@ public class BundleUtil
/** The file extension of our action tile images. */
public static final String IMAGE_EXTENSION = ".png";
/** The serialized tileset extension for our action tilesets. */
public static final String TILESET_EXTENSION = ".dat";
/**
* Attempts to load an object from the supplied resource bundle with
* the specified path.
@@ -1,5 +1,5 @@
//
// $Id: BundledComponentRepository.java,v 1.12 2002/05/15 23:54:05 mdb Exp $
// $Id: BundledComponentRepository.java,v 1.13 2002/06/19 08:33:14 mdb Exp $
package com.threerings.cast.bundle;
@@ -258,30 +258,19 @@ public class BundledComponentRepository
public ActionFrames getFrames (
CharacterComponent component, String action)
{
// get the tileset for this action
TileSet aset = (TileSet)_actionSets.get(action);
if (aset == null) {
Log.warning("Can't provide animation frames for undefined " +
"action [action=" + action +
", component=" + component + "].");
return null;
}
// construct the appropriate image path for the component
// load up the tileset for this action
String path = component.componentClass.name + "/" +
component.name + "/" + action +
BundleUtil.IMAGE_EXTENSION;
// clone the tileset with this new image path
BundleUtil.TILESET_EXTENSION;
try {
TileSet fset = aset.clone(path);
fset.setImageProvider(this);
return new TileSetFrameImage(fset);
TileSet aset = (TileSet)BundleUtil.loadObject(_bundle, path);
aset.setImageProvider(this);
return new TileSetFrameImage(aset);
} catch (CloneNotSupportedException cnse) {
Log.warning("Unable to clone tileset [action=" + action +
", component=" + component +
", set=" + aset + "].");
} catch (Exception e) {
Log.warning("Error loading tileset for action " +
"[action=" + action + ", component=" + component +
", error=" + e + "].");
return null;
}
}
@@ -1,8 +1,11 @@
//
// $Id: ComponentBundlerTask.java,v 1.8 2002/04/11 01:33:51 mdb Exp $
// $Id: ComponentBundlerTask.java,v 1.9 2002/06/19 08:33:14 mdb Exp $
package com.threerings.cast.bundle.tools;
import java.awt.Image;
import javax.imageio.ImageIO;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
@@ -21,6 +24,9 @@ import java.util.Iterator;
import java.util.jar.JarOutputStream;
import java.util.jar.JarEntry;
import org.xml.sax.SAXException;
import org.apache.commons.digester.Digester;
import com.samskivert.io.PersistenceException;
import com.samskivert.util.HashIntMap;
import com.samskivert.util.StringUtil;
@@ -33,8 +39,15 @@ import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
import com.threerings.media.tile.ImageProvider;
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.util.TileSetTrimmer;
import com.threerings.cast.ComponentIDBroker;
import com.threerings.cast.bundle.BundleUtil;
import com.threerings.cast.tools.xml.ActionRuleSet;
/**
* Ant task for creating component bundles. This task must be configured
@@ -70,6 +83,14 @@ public class ComponentBundlerTask extends Task
_mapfile = mapfile;
}
/**
* Sets the path to the action tilesets definition file.
*/
public void setActiondef (File actiondef)
{
_actionDef = actiondef;
}
/**
* Sets the root path which will be stripped from the image paths
* prior to parsing them to obtain the component class, type and
@@ -98,6 +119,11 @@ public class ComponentBundlerTask extends Task
"file via the 'target' attribute.");
ensureSet(_mapfile, "Must specify the path to the component map " +
"file via the 'mapfile' attribute.");
ensureSet(_actionDef, "Must specify the action sequence " +
"definitions via the 'actiondef' attribute.");
// parse in the action tilesets
HashMap actsets = parseActionTileSets();
// load up our component ID broker
ComponentIDBroker broker = loadBroker(_mapfile);
@@ -107,9 +133,13 @@ public class ComponentBundlerTask extends Task
FileOutputStream fout = new FileOutputStream(_target);
JarOutputStream jout = new JarOutputStream(fout);
// we'll fill this with component id to tuple mappings as we go
// we'll fill this with component id to tuple mappings
HashIntMap mapping = new HashIntMap();
// herein we'll insert trimmed tileset objects that go along
// with each of the trimmed action images
HashIntMap actionSets = new HashIntMap();
// deal with the filesets
for (int i = 0; i < _filesets.size(); i++) {
FileSet fs = (FileSet)_filesets.get(i);
@@ -121,14 +151,49 @@ public class ComponentBundlerTask extends Task
File cfile = new File(fromDir, srcFiles[f]);
// determine the [class, name, action] triplet
String[] info = decomposePath(cfile.getPath());
// make sure we have an action tileset definition
TileSet aset = (TileSet)actsets.get(info[2]);
if (aset == null) {
System.err.println(
"No tileset definition for component action " +
"[class=" + info[0] + ", name=" + info[1] +
", action=" + info[2] + "].");
continue;
}
// obtain the component id from our id broker
int cid = broker.getComponentID(info[0], info[1]);
// add a mapping for this component
mapping.put(cid, new Tuple(info[0], info[1]));
// construct the path that'll go in the jar file and
// stuff the component into the jarfile
jout.putNextEntry(new JarEntry(composePath(info)));
StreamUtils.pipe(new FileInputStream(cfile), jout);
// construct the path that'll go in the jar file
String ipath = composePath(
info, BundleUtil.IMAGE_EXTENSION);
jout.putNextEntry(new JarEntry(ipath));
// create a trimmed tileset based on the source action
// tileset and stuff the new trimmed image into the
// jar file at the same time
aset.setImagePath(cfile.getPath());
aset.setImageProvider(new ImageProvider() {
public Image loadImage (String path)
throws IOException {
return ImageIO.read(new File(path));
}
});
TrimmedTileSet tset =
TileSetTrimmer.trimTileSet(aset, jout);
tset.setImagePath(ipath);
tset.setName(aset.getName());
// also write our trimmed tileset to the jar file
String tpath = composePath(
info, BundleUtil.TILESET_EXTENSION);
jout.putNextEntry(new JarEntry(tpath));
ObjectOutputStream oout = new ObjectOutputStream(jout);
oout.writeObject(tset);
oout.flush();
}
}
@@ -208,10 +273,10 @@ public class ComponentBundlerTask extends Task
* should be supplied to the JarEntry that contains the associated
* image data.
*/
protected String composePath (String[] info)
protected String composePath (String[] info, String extension)
{
return (info[0] + File.separator + info[1] + File.separator +
info[2] + BundleUtil.IMAGE_EXTENSION);
return (info[0] + File.separator + info[1] +
File.separator + info[2] + extension);
}
protected void ensureSet (Object value, String errmsg)
@@ -222,6 +287,55 @@ public class ComponentBundlerTask extends Task
}
}
/**
* Parses the action tileset definitions and puts them into a hash
* map, keyed on action name.
*/
protected HashMap parseActionTileSets ()
{
Digester digester = new Digester();
SwissArmyTileSetRuleSet srules = new SwissArmyTileSetRuleSet();
String aprefix = "actions" + ActionRuleSet.ACTION_PATH;
srules.setPrefix(aprefix);
digester.addRuleSet(srules);
digester.addSetProperties(aprefix);
digester.addSetNext(aprefix + SwissArmyTileSetRuleSet.TILESET_PATH,
"addTileSet", TileSet.class.getName());
HashMap 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;
}
/** Used when parsing action tilesets. */
public static class ActionMap extends HashMap
{
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.
@@ -347,6 +461,9 @@ public class ComponentBundlerTask extends Task
/** The path to our component map file. */
protected File _mapfile;
/** The path to our action tilesets definition file. */
protected File _actionDef;
/** The component directory root. */
protected String _root;