Added the ability to add dynamic bundles which can be downloaded and added
in while the game is running. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2668 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
//
|
//
|
||||||
// $Id: ResourceManager.java,v 1.30 2003/05/29 16:35:59 mdb Exp $
|
// $Id: ResourceManager.java,v 1.31 2003/06/19 01:30:27 ray Exp $
|
||||||
|
|
||||||
package com.threerings.resource;
|
package com.threerings.resource;
|
||||||
|
|
||||||
|
import java.awt.EventQueue;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@@ -27,6 +29,7 @@ import javax.imageio.stream.FileImageInputStream;
|
|||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||||
|
|
||||||
|
import com.samskivert.util.ResultListener;
|
||||||
import com.samskivert.util.StringUtil;
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
import com.threerings.resource.DownloadManager.DownloadDescriptor;
|
import com.threerings.resource.DownloadManager.DownloadDescriptor;
|
||||||
@@ -236,16 +239,15 @@ public class ResourceManager
|
|||||||
resourceURL += "/";
|
resourceURL += "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
URL rurl = null;
|
|
||||||
try {
|
try {
|
||||||
rurl = new URL(resourceURL);
|
_rurl = new URL(resourceURL);
|
||||||
} catch (MalformedURLException mue) {
|
} catch (MalformedURLException mue) {
|
||||||
Log.warning("Invalid resource URL [url=" + resourceURL +
|
Log.warning("Invalid resource URL [url=" + resourceURL +
|
||||||
", error=" + mue + "].");
|
", error=" + mue + "].");
|
||||||
}
|
}
|
||||||
|
|
||||||
// load up our configuration
|
// load up our configuration
|
||||||
Properties config = loadConfig(rurl, configPath);
|
Properties config = loadConfig(configPath);
|
||||||
|
|
||||||
// resolve the configured resource sets
|
// resolve the configured resource sets
|
||||||
ArrayList dlist = new ArrayList();
|
ArrayList dlist = new ArrayList();
|
||||||
@@ -256,7 +258,7 @@ public class ResourceManager
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String setName = key.substring(RESOURCE_SET_PREFIX.length());
|
String setName = key.substring(RESOURCE_SET_PREFIX.length());
|
||||||
resolveResourceSet(rurl, setName, config.getProperty(key), dlist);
|
resolveResourceSet(setName, config.getProperty(key), dlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
// start the download, blocking if we've no observer
|
// start the download, blocking if we've no observer
|
||||||
@@ -268,6 +270,97 @@ public class ResourceManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the resource bundle for the specified set and path.
|
||||||
|
*/
|
||||||
|
protected ResourceBundle createResourceBundle (String setName, String path)
|
||||||
|
{
|
||||||
|
createCacheDirectory(setName);
|
||||||
|
File cfile = new File(genCachePath(setName, path));
|
||||||
|
|
||||||
|
return new ResourceBundle(cfile, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if the specified dynamic bundle is already here
|
||||||
|
* and ready to roll.
|
||||||
|
*/
|
||||||
|
public boolean checkDynamicBundle (String path)
|
||||||
|
{
|
||||||
|
return createResourceBundle(DYNAMIC_BUNDLE_SET, path).isUnpacked();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the specified dynamic bundle and return it on the specified
|
||||||
|
* result listener.
|
||||||
|
*/
|
||||||
|
public void resolveDynamicBundle (String path,
|
||||||
|
final ResultListener listener)
|
||||||
|
{
|
||||||
|
URL burl;
|
||||||
|
try {
|
||||||
|
burl = new URL(_rurl, path);
|
||||||
|
} catch (MalformedURLException mue) {
|
||||||
|
listener.requestFailed(mue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ResourceBundle bundle = createResourceBundle(
|
||||||
|
DYNAMIC_BUNDLE_SET, path);
|
||||||
|
if (bundle.isUnpacked()) {
|
||||||
|
bundle.sourceIsReady();
|
||||||
|
listener.requestCompleted(bundle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// slap this on the list for retrieval or update by the
|
||||||
|
// download manager
|
||||||
|
ArrayList list = new ArrayList();
|
||||||
|
list.add(new DownloadDescriptor(burl, bundle.getSource()));
|
||||||
|
|
||||||
|
// TODO: There should only be one download manager for all dynamic
|
||||||
|
// bundles, with each bundle waiting its turn to use it.
|
||||||
|
DownloadObserver obs = new DownloadObserver() {
|
||||||
|
public boolean notifyOnAWTThread () {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resolvingDownloads () {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadProgress (int percent, long remaining) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postDownloadHook () {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadComplete ()
|
||||||
|
{
|
||||||
|
bundle.sourceIsReady();
|
||||||
|
EventQueue.invokeLater(new Runnable() {
|
||||||
|
public void run () {
|
||||||
|
listener.requestCompleted(bundle);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadFailed (
|
||||||
|
DownloadDescriptor desc, final Exception e)
|
||||||
|
{
|
||||||
|
Log.warning("Failed to download file " +
|
||||||
|
"[desc=" + desc + ", e=" + e + "].");
|
||||||
|
EventQueue.invokeLater(new Runnable() {
|
||||||
|
public void run () {
|
||||||
|
listener.requestFailed(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DownloadManager dlmgr = new DownloadManager();
|
||||||
|
dlmgr.download(list, true, obs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads the files in the supplied download list, blocking the
|
* Downloads the files in the supplied download list, blocking the
|
||||||
* calling thread until the download is complete or a failure has
|
* calling thread until the download is complete or a failure has
|
||||||
@@ -383,20 +476,20 @@ public class ResourceManager
|
|||||||
* Loads up the most recent version of the resource manager
|
* Loads up the most recent version of the resource manager
|
||||||
* configuration.
|
* configuration.
|
||||||
*/
|
*/
|
||||||
protected Properties loadConfig (URL resourceURL, String configPath)
|
protected Properties loadConfig (String configPath)
|
||||||
{
|
{
|
||||||
Properties config = new Properties();
|
Properties config = new Properties();
|
||||||
URL curl = null;
|
URL curl = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (configPath != null) {
|
if (configPath != null) {
|
||||||
curl = new URL(resourceURL, configPath);
|
curl = new URL(_rurl, configPath);
|
||||||
config.load(curl.openStream());
|
config.load(curl.openStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (MalformedURLException mue) {
|
} catch (MalformedURLException mue) {
|
||||||
Log.warning("Unable to construct config URL " +
|
Log.warning("Unable to construct config URL " +
|
||||||
"[resourceURL=" + resourceURL +
|
"[resourceURL=" + _rurl +
|
||||||
", configPath=" + configPath +
|
", configPath=" + configPath +
|
||||||
", error=" + mue + "].");
|
", error=" + mue + "].");
|
||||||
|
|
||||||
@@ -416,7 +509,7 @@ public class ResourceManager
|
|||||||
* @return true if the directory was successfully created (or was
|
* @return true if the directory was successfully created (or was
|
||||||
* already there), false if we failed to create it.
|
* already there), false if we failed to create it.
|
||||||
*/
|
*/
|
||||||
protected boolean createCacheDirectory (URL resourceURL, String setName)
|
protected boolean createCacheDirectory (String setName)
|
||||||
{
|
{
|
||||||
// compute the path to the top-level cache directory if we haven't
|
// compute the path to the top-level cache directory if we haven't
|
||||||
// already been so configured
|
// already been so configured
|
||||||
@@ -430,8 +523,7 @@ public class ResourceManager
|
|||||||
// next incorporate the resource URL into the cache path so
|
// next incorporate the resource URL into the cache path so
|
||||||
// that files fetched from different resource roots do not
|
// that files fetched from different resource roots do not
|
||||||
// overwrite one another
|
// overwrite one another
|
||||||
_cachePath += StringUtil.md5hex(resourceURL.toString()) +
|
_cachePath += StringUtil.md5hex(_rurl.toString()) + File.separator;
|
||||||
File.separator;
|
|
||||||
if (!createDirectory(_cachePath)) {
|
if (!createDirectory(_cachePath)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -473,8 +565,7 @@ public class ResourceManager
|
|||||||
* Generates the name of the bundle cache file given the name of the
|
* Generates the name of the bundle cache file given the name of the
|
||||||
* resource set to which it belongs and the relative path URL.
|
* resource set to which it belongs and the relative path URL.
|
||||||
*/
|
*/
|
||||||
protected String genCachePath (
|
protected String genCachePath (String setName, String resourcePath)
|
||||||
URL resourceURL, String setName, String resourcePath)
|
|
||||||
{
|
{
|
||||||
return _cachePath + setName + File.separator +
|
return _cachePath + setName + File.separator +
|
||||||
StringUtil.replace(resourcePath, "/", "-");
|
StringUtil.replace(resourcePath, "/", "-");
|
||||||
@@ -485,7 +576,7 @@ public class ResourceManager
|
|||||||
* information.
|
* information.
|
||||||
*/
|
*/
|
||||||
protected void resolveResourceSet (
|
protected void resolveResourceSet (
|
||||||
URL resourceURL, String setName, String definition, List dlist)
|
String setName, String definition, List dlist)
|
||||||
{
|
{
|
||||||
StringTokenizer tok = new StringTokenizer(definition, ":");
|
StringTokenizer tok = new StringTokenizer(definition, ":");
|
||||||
ArrayList set = new ArrayList();
|
ArrayList set = new ArrayList();
|
||||||
@@ -495,13 +586,13 @@ public class ResourceManager
|
|||||||
URL burl = null;
|
URL burl = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
burl = new URL(resourceURL, path);
|
burl = new URL(_rurl, path);
|
||||||
|
|
||||||
// make sure the cache directory exists for this set
|
// make sure the cache directory exists for this set
|
||||||
createCacheDirectory(resourceURL, setName);
|
createCacheDirectory(setName);
|
||||||
|
|
||||||
// compute the path to the cache file for this bundle
|
// compute the path to the cache file for this bundle
|
||||||
File cfile = new File(genCachePath(resourceURL, setName, path));
|
File cfile = new File(genCachePath(setName, path));
|
||||||
|
|
||||||
// slap this on the list for retrieval or update by the
|
// slap this on the list for retrieval or update by the
|
||||||
// download manager
|
// download manager
|
||||||
@@ -692,6 +783,9 @@ public class ResourceManager
|
|||||||
/** The classloader we use for classpath-based resource loading. */
|
/** The classloader we use for classpath-based resource loading. */
|
||||||
protected ClassLoader _loader;
|
protected ClassLoader _loader;
|
||||||
|
|
||||||
|
/** The url via which we download our bundles. */
|
||||||
|
protected URL _rurl;
|
||||||
|
|
||||||
/** The prefix we prepend to resource paths before attempting to load
|
/** The prefix we prepend to resource paths before attempting to load
|
||||||
* them from the classpath. */
|
* them from the classpath. */
|
||||||
protected String _rootPath;
|
protected String _rootPath;
|
||||||
@@ -717,4 +811,7 @@ public class ResourceManager
|
|||||||
|
|
||||||
/** The name of our resource bundle cache directory. */
|
/** The name of our resource bundle cache directory. */
|
||||||
protected static final String CACHE_PATH = ".narya";
|
protected static final String CACHE_PATH = ".narya";
|
||||||
|
|
||||||
|
/** The name of the resource set where we store dynamic bundles. */
|
||||||
|
protected static final String DYNAMIC_BUNDLE_SET = "_dynamic";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user