The old way I had the Directory-based bundlers checking for out-of-dateness was prone to error in the face of new files or unfortunate subdirectory situations. Now check on an entry-by-entry basis instead, which is much happier.
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@351 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -150,7 +150,8 @@ public class ComponentBundlerTask extends Task
|
|||||||
ArrayList sources = (ArrayList)_filesets.clone();
|
ArrayList sources = (ArrayList)_filesets.clone();
|
||||||
sources.add(_mapfile);
|
sources.add(_mapfile);
|
||||||
sources.add(_actionDef);
|
sources.add(_actionDef);
|
||||||
if (!outOfDate(sources, _target)) {
|
long newest = getNewestDate(sources);
|
||||||
|
if (skipIfTargetNewer() && newest < _target.lastModified()) {
|
||||||
System.out.println(_target.getPath() + " is up to date.");
|
System.out.println(_target.getPath() + " is up to date.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -205,7 +206,7 @@ public class ComponentBundlerTask extends Task
|
|||||||
mapping.put(cid, new Tuple(info[0], info[1]));
|
mapping.put(cid, new Tuple(info[0], info[1]));
|
||||||
|
|
||||||
// process and store the main component image
|
// process and store the main component image
|
||||||
processComponent(info, aset, cfile, fout);
|
processComponent(info, aset, cfile, fout, newest);
|
||||||
|
|
||||||
// pick up any auxiliary images as well like the shadow or
|
// pick up any auxiliary images as well like the shadow or
|
||||||
// crop files
|
// crop files
|
||||||
@@ -216,17 +217,19 @@ public class ComponentBundlerTask extends Task
|
|||||||
FileUtil.resuffix(cfile, ext, AUX_EXTS[aa] + ext));
|
FileUtil.resuffix(cfile, ext, AUX_EXTS[aa] + ext));
|
||||||
if (afile.exists()) {
|
if (afile.exists()) {
|
||||||
info[2] = action + AUX_EXTS[aa];
|
info[2] = action + AUX_EXTS[aa];
|
||||||
processComponent(info, aset, afile, fout);
|
processComponent(info, aset, afile, fout, newest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write our mapping table to the jar file as well
|
// write our mapping table to the jar file as well
|
||||||
fout = nextEntry(fout, BundleUtil.COMPONENTS_PATH);
|
if (!skipEntry(BundleUtil.COMPONENTS_PATH, newest)) {
|
||||||
ObjectOutputStream oout = new ObjectOutputStream(fout);
|
fout = nextEntry(fout, BundleUtil.COMPONENTS_PATH);
|
||||||
oout.writeObject(mapping);
|
ObjectOutputStream oout = new ObjectOutputStream(fout);
|
||||||
oout.flush();
|
oout.writeObject(mapping);
|
||||||
|
oout.flush();
|
||||||
|
}
|
||||||
|
|
||||||
// seal up our jar file
|
// seal up our jar file
|
||||||
fout.close();
|
fout.close();
|
||||||
@@ -245,12 +248,18 @@ public class ComponentBundlerTask extends Task
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void processComponent (
|
protected void processComponent (
|
||||||
String[] info, TileSet aset, File cfile, OutputStream fout)
|
String[] info, TileSet aset, File cfile, OutputStream fout, long newest)
|
||||||
throws IOException, BuildException
|
throws IOException, BuildException
|
||||||
{
|
{
|
||||||
// construct the path that'll go in the jar file
|
// construct the path that'll go in the jar file
|
||||||
String ipath = composePath(
|
String ipath = composePath(
|
||||||
info, BundleUtil.IMAGE_EXTENSION);
|
info, BundleUtil.IMAGE_EXTENSION);
|
||||||
|
|
||||||
|
// If we decide that the entry is up to date and we don't need to process it, bail out.
|
||||||
|
if (skipEntry(ipath, newest)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fout = nextEntry(fout, ipath);
|
fout = nextEntry(fout, ipath);
|
||||||
|
|
||||||
// create a trimmed tileset based on the source action tileset and
|
// create a trimmed tileset based on the source action tileset and
|
||||||
@@ -273,69 +282,59 @@ public class ComponentBundlerTask extends Task
|
|||||||
throw new BuildException(errmsg, t);
|
throw new BuildException(errmsg, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// then write our trimmed tileset to the jar file
|
// then write our trimmed tileset bundle data
|
||||||
if (tset != null) {
|
if (tset != null) {
|
||||||
|
|
||||||
String tpath = composePath(
|
String tpath = composePath(
|
||||||
info, BundleUtil.TILESET_EXTENSION);
|
info, BundleUtil.TILESET_EXTENSION);
|
||||||
fout = nextEntry(fout, tpath);
|
if (!skipEntry(tpath, newest)) {
|
||||||
|
fout = nextEntry(fout, tpath);
|
||||||
|
|
||||||
ObjectOutputStream oout = new ObjectOutputStream(fout);
|
ObjectOutputStream oout = new ObjectOutputStream(fout);
|
||||||
oout.writeObject(tset);
|
oout.writeObject(tset);
|
||||||
oout.flush();
|
oout.flush();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean outOfDate (ArrayList sources, File target)
|
|
||||||
{
|
|
||||||
for (int ii = 0; ii < sources.size(); ii++) {
|
|
||||||
if (outOfDate(sources.get(ii), target)) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean outOfDate (Object source, File target)
|
protected long getNewestDate (ArrayList sources)
|
||||||
|
{
|
||||||
|
long newest = 0L;
|
||||||
|
for (int ii = 0; ii < sources.size(); ii++) {
|
||||||
|
newest = Math.max(newest, getNewestDate(sources.get(ii)));
|
||||||
|
}
|
||||||
|
return newest;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected long getNewestDate (Object source)
|
||||||
{
|
{
|
||||||
if (source instanceof FileSet) {
|
if (source instanceof FileSet) {
|
||||||
FileSet fs = (FileSet)source;
|
FileSet fs = (FileSet)source;
|
||||||
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
|
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
|
||||||
File fromDir = fs.getDir(getProject());
|
File fromDir = fs.getDir(getProject());
|
||||||
String[] srcFiles = ds.getIncludedFiles();
|
String[] srcFiles = ds.getIncludedFiles();
|
||||||
long tgtModificationDate = getTgtModificationDate(target);
|
long newest = 0L;
|
||||||
for (int f = 0; f < srcFiles.length; f++) {
|
for (int f = 0; f < srcFiles.length; f++) {
|
||||||
File cfile = new File(fromDir, srcFiles[f]);
|
File cfile = new File(fromDir, srcFiles[f]);
|
||||||
if (newer(cfile, tgtModificationDate)) {
|
newest = Math.max(newest, cfile.lastModified());
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return newest;
|
||||||
|
|
||||||
} else if (source instanceof File) {
|
} else if (source instanceof File) {
|
||||||
return newer((File)source, getTgtModificationDate(target));
|
return ((File)source).lastModified();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Can't compare " + source +
|
System.err.println("Can't get newest date for source: " + source + ".");
|
||||||
" to " + target + ".");
|
return 0L;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if <code>source</code> is newer than
|
* Returns whether we should skip updating the bundle if the target is newer than any component.
|
||||||
* <code>target</code>.
|
|
||||||
*/
|
*/
|
||||||
protected boolean newer (File source, long tgtModificationDate)
|
protected boolean skipIfTargetNewer ()
|
||||||
{
|
{
|
||||||
return source.lastModified() > tgtModificationDate;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the last modified date of <code>target</code> to be compared for out-of-dateness.
|
|
||||||
*/
|
|
||||||
protected long getTgtModificationDate (File target)
|
|
||||||
{
|
|
||||||
return target.lastModified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -470,6 +469,16 @@ public class ComponentBundlerTask extends Task
|
|||||||
return lastEntry;
|
return lastEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether we should skip the specified entry in the bundle, presumably if it was
|
||||||
|
* already created and up to date.
|
||||||
|
*/
|
||||||
|
protected boolean skipEntry (String path, long newest)
|
||||||
|
{
|
||||||
|
// If we're making the bundle, by default, we don't skip anything.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the tileset to a trimmed tile set and saves it at the specified location.
|
* Converts the tileset to a trimmed tile set and saves it at the specified location.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public class DirectoryComponentBundlerTask extends ComponentBundlerTask
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override // documentation inherited
|
@Override // documentation inherited
|
||||||
protected OutputStream nextEntry (OutputStream lastEntry, String path)
|
protected OutputStream nextEntry (OutputStream lastEntry, String path)
|
||||||
throws IOException
|
throws IOException
|
||||||
@@ -55,6 +57,13 @@ public class DirectoryComponentBundlerTask extends ComponentBundlerTask
|
|||||||
return new FileOutputStream(file);
|
return new FileOutputStream(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // documentation inherited
|
||||||
|
protected boolean skipEntry (String path, long newest)
|
||||||
|
{
|
||||||
|
File file = new File(_target, path);
|
||||||
|
return (file.lastModified() > newest);
|
||||||
|
}
|
||||||
|
|
||||||
@Override // documentation inherited
|
@Override // documentation inherited
|
||||||
protected TrimmedTileSet trim (TileSet aset, OutputStream fout)
|
protected TrimmedTileSet trim (TileSet aset, OutputStream fout)
|
||||||
throws IOException
|
throws IOException
|
||||||
@@ -63,9 +72,9 @@ public class DirectoryComponentBundlerTask extends ComponentBundlerTask
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override // documentation inherited
|
@Override // documentation inherited
|
||||||
protected long getTgtModificationDate (File target)
|
protected boolean skipIfTargetNewer ()
|
||||||
{
|
{
|
||||||
// Return the oldest modification date of anything within the directory.
|
// We have to check modification later on a file-by-file basis, so cannot skip.
|
||||||
return FileUtil.getOldestLastModified(target);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,17 +58,9 @@ public class DirectoryTileSetBundler extends TileSetBundler
|
|||||||
super(configPath);
|
super(configPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override // documentation inherited
|
||||||
* Finish the creation of a tileset bundle jar file.
|
|
||||||
*
|
|
||||||
* @param target the tileset bundle file that will be created.
|
|
||||||
* @param bundle contains the tilesets we'd like to save out to the bundle.
|
|
||||||
* @param improv the image provider.
|
|
||||||
* @param imageBase the base directory for getting images for non
|
|
||||||
* ObjectTileSet tilesets.
|
|
||||||
*/
|
|
||||||
public boolean createBundle (
|
public boolean createBundle (
|
||||||
File target, TileSetBundle bundle, ImageProvider improv, String imageBase)
|
File target, TileSetBundle bundle, ImageProvider improv, String imageBase, long newestMod)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -101,6 +93,10 @@ public class DirectoryTileSetBundler extends TileSetBundler
|
|||||||
// write the trimmed tileset image to the destination
|
// write the trimmed tileset image to the destination
|
||||||
// output stream
|
// output stream
|
||||||
File outFile = new File(target, imagePath);
|
File outFile = new File(target, imagePath);
|
||||||
|
if (outFile.lastModified() > newestMod) {
|
||||||
|
// Our file's newer than the newest bundle mod - up to date.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
outFile.getParentFile().mkdirs();
|
outFile.getParentFile().mkdirs();
|
||||||
FileOutputStream fout = new FileOutputStream(outFile);
|
FileOutputStream fout = new FileOutputStream(outFile);
|
||||||
TrimmedObjectTileSet tset =
|
TrimmedObjectTileSet tset =
|
||||||
@@ -123,9 +119,18 @@ public class DirectoryTileSetBundler extends TileSetBundler
|
|||||||
// read the image file and convert it to our custom
|
// read the image file and convert it to our custom
|
||||||
// format in the bundle
|
// format in the bundle
|
||||||
File ifile = new File(imageBase, imagePath);
|
File ifile = new File(imageBase, imagePath);
|
||||||
|
if (ifile.lastModified() > newestMod) {
|
||||||
|
// Our file's newer than the newest bundle mod - up to date.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BufferedImage image = ImageIO.read(ifile);
|
BufferedImage image = ImageIO.read(ifile);
|
||||||
File outFile = new File(target, imagePath);
|
File outFile = new File(target, imagePath);
|
||||||
|
if (outFile.lastModified() > newestMod) {
|
||||||
|
// Our file's newer than the newest bundle mod - up to date.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
outFile.getParentFile().mkdirs();
|
outFile.getParentFile().mkdirs();
|
||||||
FileOutputStream fout = new FileOutputStream(outFile);
|
FileOutputStream fout = new FileOutputStream(outFile);
|
||||||
FileInputStream imgin = new FileInputStream(ifile);
|
FileInputStream imgin = new FileInputStream(ifile);
|
||||||
@@ -141,6 +146,7 @@ public class DirectoryTileSetBundler extends TileSetBundler
|
|||||||
// now write a serialized representation of the tileset bundle
|
// now write a serialized representation of the tileset bundle
|
||||||
// object to the bundle jar file
|
// object to the bundle jar file
|
||||||
File outFile = new File(target, BundleUtil.METADATA_PATH);
|
File outFile = new File(target, BundleUtil.METADATA_PATH);
|
||||||
|
|
||||||
outFile.getParentFile().mkdirs();
|
outFile.getParentFile().mkdirs();
|
||||||
FileOutputStream fout = new FileOutputStream(outFile);
|
FileOutputStream fout = new FileOutputStream(outFile);
|
||||||
ObjectOutputStream oout = new ObjectOutputStream(fout);
|
ObjectOutputStream oout = new ObjectOutputStream(fout);
|
||||||
@@ -156,9 +162,9 @@ public class DirectoryTileSetBundler extends TileSetBundler
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override // documentation inherited
|
@Override // documentation inherited
|
||||||
protected long getTgtModificationDate (File target)
|
protected boolean skipIfTargetNewer ()
|
||||||
{
|
{
|
||||||
// Return the oldest modification date of anything within the directory.
|
// We have to check modification later on a file-by-file basis, so cannot skip.
|
||||||
return FileUtil.getOldestLastModified(target);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ public class TileSetBundler
|
|||||||
}
|
}
|
||||||
|
|
||||||
// see if our newest file is newer than the tileset bundle
|
// see if our newest file is newer than the tileset bundle
|
||||||
if (newest < getTgtModificationDate(target)) {
|
if (skipIfTargetNewer() && newest < target.lastModified()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ public class TileSetBundler
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return createBundle(target, bundle, improv, bundleDesc.getParent());
|
return createBundle(target, bundle, improv, bundleDesc.getParent(), newest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -332,10 +332,12 @@ public class TileSetBundler
|
|||||||
* @param bundle contains the tilesets we'd like to save out to the bundle.
|
* @param bundle contains the tilesets we'd like to save out to the bundle.
|
||||||
* @param improv the image provider.
|
* @param improv the image provider.
|
||||||
* @param imageBase the base directory for getting images for non
|
* @param imageBase the base directory for getting images for non
|
||||||
|
* @param newestMod the most recent modification to any part of the bundle. By default we
|
||||||
|
* ignore this since we normally duck out if we're up to date.
|
||||||
* ObjectTileSet tilesets.
|
* ObjectTileSet tilesets.
|
||||||
*/
|
*/
|
||||||
public boolean createBundle (
|
public boolean createBundle (
|
||||||
File target, TileSetBundle bundle, ImageProvider improv, String imageBase)
|
File target, TileSetBundle bundle, ImageProvider improv, String imageBase, long newestMod)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
return createBundleJar(target, bundle, improv, imageBase);
|
return createBundleJar(target, bundle, improv, imageBase);
|
||||||
@@ -455,11 +457,11 @@ public class TileSetBundler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the last modified date of <code>target</code> to be compared for out-of-dateness.
|
* Returns whether we should skip updating the bundle if the target is newer than any component.
|
||||||
*/
|
*/
|
||||||
protected long getTgtModificationDate (File target)
|
protected boolean skipIfTargetNewer ()
|
||||||
{
|
{
|
||||||
return target.lastModified();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Replaces the image suffix with <code>.raw</code>. */
|
/** Replaces the image suffix with <code>.raw</code>. */
|
||||||
|
|||||||
Reference in New Issue
Block a user