Shucks, that was a lot more complicated than I thought
The mod time of a target directory can't be reliably checked using the files, so we need to compare the modificaiton times of each source and destination image file as we go.
This commit is contained in:
committed by
Michael Bayne
parent
6ec4fb5c4f
commit
9647cfb968
@@ -77,24 +77,29 @@ public class BundleWriter
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the target is newer than the given time. Note that if we are in directory-mode,
|
||||
* false is returned.
|
||||
* Tests if the target bundle is newer than the given time. Note that if we are in
|
||||
* directory-mode, false is returned.
|
||||
*/
|
||||
public boolean isNewerThan (long newest)
|
||||
{
|
||||
if (_jar != null) {
|
||||
return _target.lastModified() > newest;
|
||||
} else {
|
||||
File []files = _target.listFiles();
|
||||
if (files == null) {
|
||||
return false;
|
||||
}
|
||||
for (File file : files) {
|
||||
if (file.lastModified() < newest) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a given path within the target bundle is newer than a given time. Note that if
|
||||
* we are in jar mode, false is returned.
|
||||
*/
|
||||
public boolean isPathNewerThan (String path, long newest)
|
||||
{
|
||||
if (_jar != null) {
|
||||
return false;
|
||||
} else {
|
||||
File f = new File(_target, path);
|
||||
return f.lastModified() > newest;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.xml.sax.SAXException;
|
||||
import com.samskivert.io.PersistenceException;
|
||||
import com.samskivert.io.StreamUtil;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.IntMap;
|
||||
|
||||
import com.threerings.resource.FastImageIO;
|
||||
|
||||
@@ -131,6 +132,9 @@ public class TileSetBundler
|
||||
/** Loads images for the bundle. */
|
||||
public final ImageProvider improv;
|
||||
|
||||
/** Modification time of the newest source file. */
|
||||
public final long newestSource;
|
||||
|
||||
/**
|
||||
* Creates a new writer.
|
||||
*
|
||||
@@ -138,11 +142,13 @@ public class TileSetBundler
|
||||
* @param bundle contains the tilesets we'd like to save out to the bundle.
|
||||
* @param improv the image provider.
|
||||
*/
|
||||
public Writer (BundleWriter bwriter, TileSetBundle bundle, ImageProvider improv)
|
||||
public Writer (BundleWriter bwriter, TileSetBundle bundle, ImageProvider improv,
|
||||
long newestSource)
|
||||
{
|
||||
this.bundle = bundle;
|
||||
this.bwriter = bwriter;
|
||||
this.improv = improv;
|
||||
this.newestSource = newestSource;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -399,7 +405,7 @@ public class TileSetBundler
|
||||
}
|
||||
};
|
||||
|
||||
return new Writer(target, bundle, improv).imageBase(bundleDesc.getParent());
|
||||
return new Writer(target, bundle, improv, newest).imageBase(bundleDesc.getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,99 +423,11 @@ public class TileSetBundler
|
||||
// bundle till we're done iterating.
|
||||
HashIntMap<TileSet> toUpdate = new HashIntMap<TileSet>();
|
||||
while (iditer.hasNext()) {
|
||||
int tileSetId = iditer.next().intValue();
|
||||
TileSet set = target.bundle.getTileSet(tileSetId);
|
||||
String imagePath = set.getImagePath();
|
||||
|
||||
// sanity checks
|
||||
if (imagePath == null) {
|
||||
log.warning("Tileset contains no image path " +
|
||||
"[set=" + set + "]. It ain't gonna work.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// if this is an object tileset, trim it
|
||||
if (target.trim && (set instanceof ObjectTileSet)) {
|
||||
// set the tileset up with an image provider; we
|
||||
// need to do this so that we can trim it!
|
||||
set.setImageProvider(target.improv);
|
||||
|
||||
// add .raw if requested
|
||||
if (target.raw) {
|
||||
imagePath = adjustImagePath(imagePath);
|
||||
}
|
||||
OutputStream dest = target.bwriter.startNewFile(imagePath);
|
||||
|
||||
try {
|
||||
// create a trimmed object tileset, which will
|
||||
// write the trimmed tileset image to the target file
|
||||
TrimmedObjectTileSet tset =
|
||||
TrimmedObjectTileSet.trimObjectTileSet((ObjectTileSet)set, dest,
|
||||
target.raw ? FastImageIO.FILE_SUFFIX : "png", target.packer.get());
|
||||
tset.setImagePath(imagePath);
|
||||
// replace the original set with the trimmed
|
||||
// tileset in the tileset bundle
|
||||
toUpdate.put(tileSetId, tset);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.err);
|
||||
|
||||
String msg = "Error adding tileset to bundle " + imagePath +
|
||||
", " + set.getName() + ": " + e;
|
||||
throw (IOException) new IOException(msg).initCause(e);
|
||||
}
|
||||
|
||||
} else {
|
||||
// read the image file and convert it to our custom
|
||||
// format in the bundle
|
||||
File ifile = new File(target.imageBase, imagePath);
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(ifile);
|
||||
if (target.raw && FastImageIO.canWrite(image)) {
|
||||
imagePath = adjustImagePath(imagePath);
|
||||
// NOTE: DirectoryTileSetBundler used to check the modification time
|
||||
// of the target image here. There may be something to it, but it
|
||||
// looked unnecessary
|
||||
OutputStream dest = target.bwriter.startNewFile(imagePath);
|
||||
set.setImagePath(imagePath);
|
||||
FastImageIO.write(image, dest);
|
||||
} else {
|
||||
OutputStream dest = target.bwriter.startNewFile(imagePath);
|
||||
FileInputStream imgin = new FileInputStream(ifile);
|
||||
StreamUtil.copy(imgin, dest);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Failure bundling image " + ifile +
|
||||
": " + e;
|
||||
throw (IOException) new IOException(msg).initCause(e);
|
||||
}
|
||||
}
|
||||
processBundleImage(iditer.next().intValue(), target, toUpdate);
|
||||
}
|
||||
target.bundle.putAll(toUpdate);
|
||||
|
||||
// now write a serialized representation of the tileset bundle
|
||||
if (target.json != null) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (Iterator<Integer> tileSetId = target.bundle.enumerateTileSetIds();
|
||||
tileSetId.hasNext(); ) {
|
||||
JSONObject tset = new JSONObject();
|
||||
int id = tileSetId.next();
|
||||
tset.put("id", id);
|
||||
tset.put("set", target.json.convert(target.bundle.get(id)));
|
||||
array.add(tset);
|
||||
}
|
||||
|
||||
// now write a serialized representation of the tileset bundle
|
||||
OutputStream fout = target.bwriter.startNewFile(BundleUtil.METADATA_JSON_PATH);
|
||||
fout.write(array.toString().getBytes());
|
||||
fout.close();
|
||||
} else {
|
||||
// object to the bundle jar file
|
||||
ObjectOutputStream oout = new ObjectOutputStream(
|
||||
target.bwriter.startNewFile(BundleUtil.METADATA_PATH));
|
||||
oout.writeObject(target.bundle);
|
||||
oout.flush();
|
||||
}
|
||||
writeUpdatedBundle(target);
|
||||
|
||||
// finally close up the jar file and call ourself done
|
||||
target.bwriter.close();
|
||||
@@ -525,6 +443,120 @@ public class TileSetBundler
|
||||
}
|
||||
}
|
||||
|
||||
protected static void processBundleImage (
|
||||
int tileSetId, Writer target, IntMap<TileSet> toUpdate) throws IOException
|
||||
{
|
||||
TileSet set = target.bundle.getTileSet(tileSetId);
|
||||
String imagePath = set.getImagePath();
|
||||
|
||||
// sanity checks
|
||||
if (imagePath == null) {
|
||||
log.warning("Tileset contains no image path " +
|
||||
"[set=" + set + "]. It ain't gonna work.");
|
||||
return;
|
||||
}
|
||||
|
||||
File ifile = new File(target.imageBase, imagePath);
|
||||
long sourceTime = Math.max(target.newestSource, ifile.lastModified());
|
||||
|
||||
// if this is an object tileset, trim it
|
||||
if (target.trim && (set instanceof ObjectTileSet)) {
|
||||
// add .raw if requested
|
||||
if (target.raw) {
|
||||
imagePath = adjustImagePath(imagePath);
|
||||
}
|
||||
|
||||
if (target.bwriter.isPathNewerThan(imagePath, sourceTime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
OutputStream dest = target.bwriter.startNewFile(imagePath);
|
||||
|
||||
// set the tileset up with an image provider; we
|
||||
// need to do this so that we can trim it!
|
||||
set.setImageProvider(target.improv);
|
||||
|
||||
try {
|
||||
// create a trimmed object tileset, which will
|
||||
// write the trimmed tileset image to the target file
|
||||
TrimmedObjectTileSet tset =
|
||||
TrimmedObjectTileSet.trimObjectTileSet((ObjectTileSet)set, dest,
|
||||
target.raw ? FastImageIO.FILE_SUFFIX : "png", target.packer.get());
|
||||
tset.setImagePath(imagePath);
|
||||
// replace the original set with the trimmed
|
||||
// tileset in the tileset bundle
|
||||
toUpdate.put(tileSetId, tset);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.err);
|
||||
|
||||
String msg = "Error adding tileset to bundle " + imagePath +
|
||||
", " + set.getName() + ": " + e;
|
||||
throw (IOException) new IOException(msg).initCause(e);
|
||||
}
|
||||
|
||||
} else {
|
||||
// read the image file and convert it to our custom
|
||||
// format in the bundle
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(ifile);
|
||||
if (target.raw && FastImageIO.canWrite(image)) {
|
||||
imagePath = adjustImagePath(imagePath);
|
||||
if (!target.bwriter.isPathNewerThan(imagePath, sourceTime)) {
|
||||
OutputStream dest = target.bwriter.startNewFile(imagePath);
|
||||
set.setImagePath(imagePath);
|
||||
FastImageIO.write(image, dest);
|
||||
}
|
||||
} else {
|
||||
if (!target.bwriter.isPathNewerThan(imagePath, sourceTime)) {
|
||||
OutputStream dest = target.bwriter.startNewFile(imagePath);
|
||||
FileInputStream imgin = new FileInputStream(ifile);
|
||||
StreamUtil.copy(imgin, dest);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Failure bundling image " + ifile +
|
||||
": " + e;
|
||||
throw (IOException) new IOException(msg).initCause(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void writeUpdatedBundle (Writer target)
|
||||
throws IOException
|
||||
{
|
||||
String meta = target.json != null ?
|
||||
BundleUtil.METADATA_JSON_PATH : BundleUtil.METADATA_PATH;
|
||||
|
||||
if (target.bwriter.isPathNewerThan(meta, target.newestSource)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// now write a serialized representation of the tileset bundle
|
||||
if (target.json != null) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (Iterator<Integer> tileSetId = target.bundle.enumerateTileSetIds();
|
||||
tileSetId.hasNext(); ) {
|
||||
JSONObject tset = new JSONObject();
|
||||
int id = tileSetId.next();
|
||||
tset.put("id", id);
|
||||
tset.put("set", target.json.convert(target.bundle.get(id)));
|
||||
array.add(tset);
|
||||
}
|
||||
|
||||
OutputStream fout = target.bwriter.startNewFile(meta);
|
||||
fout.write(array.toString().getBytes());
|
||||
fout.close();
|
||||
|
||||
} else {
|
||||
ObjectOutputStream oout = new ObjectOutputStream(
|
||||
target.bwriter.startNewFile(BundleUtil.METADATA_PATH));
|
||||
oout.writeObject(target.bundle);
|
||||
oout.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Replaces the image suffix with <code>.raw</code>. */
|
||||
protected static String adjustImagePath (String imagePath)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user