diff options
author | Scott Barta <sbarta@google.com> | 2012-03-01 12:35:35 -0800 |
---|---|---|
committer | Scott Barta <sbarta@google.com> | 2012-03-01 12:40:08 -0800 |
commit | 59b2e6871c65f58fdad78cd7229c292f6a177578 (patch) | |
tree | 2d4e7bfc05b93f40b34675d77e403dd1c25efafd /engine/src/core/com/jme3/asset | |
parent | f9b30489e75ac1eabc365064959804e99534f7ab (diff) | |
download | jmonkeyengine-59b2e6871c65f58fdad78cd7229c292f6a177578.tar.gz |
Adds the jMonkeyEngine library to the build.
Adds the jMonkeyEngine open source 3D game engine to the build. This
is built as a static library and is only used by the Finsky client.
Change-Id: I06a3f054df7b8a67757267d884854f70c5a16ca0
Diffstat (limited to 'engine/src/core/com/jme3/asset')
19 files changed, 2184 insertions, 0 deletions
diff --git a/engine/src/core/com/jme3/asset/Asset.java b/engine/src/core/com/jme3/asset/Asset.java new file mode 100644 index 0000000..f36f963 --- /dev/null +++ b/engine/src/core/com/jme3/asset/Asset.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +/** + * Implementing the asset interface allows use of smart asset management. + * <p> + * Smart asset management requires cooperation from the {@link AssetKey}. + * In particular, the AssetKey should return true in its + * {@link AssetKey#useSmartCache() } method. Also smart assets MUST + * create a clone of the asset and cannot return the same reference, + * e.g. {@link AssetKey#createClonedInstance(java.lang.Object) createCloneInstance(someAsset)} <code>!= someAsset</code>. + * <p> + * If the {@link AssetManager#loadAsset(com.jme3.asset.AssetKey) } method + * is called twice with the same asset key (equals() wise, not necessarily reference wise) + * then both assets will have the same asset key set (reference wise) via + * {@link Asset#setKey(com.jme3.asset.AssetKey) }, then this asset key + * is used to track all instances of that asset. Once all clones of the asset + * are garbage collected, the shared asset key becomes unreachable and at that + * point it is removed from the smart asset cache. + */ +public interface Asset { + + /** + * Set by the {@link AssetManager} to track this asset. + * + * Only clones of the asset has this set, the original copy that + * was loaded has this key set to null so that only the clones are tracked + * for garbage collection. + * + * @param key The AssetKey to set + */ + public void setKey(AssetKey key); + + /** + * Returns the asset key that is used to track this asset for garbage + * collection. + * + * @return the asset key that is used to track this asset for garbage + * collection. + */ + public AssetKey getKey(); +} diff --git a/engine/src/core/com/jme3/asset/AssetCache.java b/engine/src/core/com/jme3/asset/AssetCache.java new file mode 100644 index 0000000..5dde799 --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetCache.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.WeakHashMap; + +/** + * An <code>AssetCache</code> allows storage of loaded resources in order + * to improve their access time if they are requested again in a short period + * of time. The AssetCache stores weak references to the resources, allowing + * Java's garbage collector to request deletion of rarely used resources + * when heap memory is low. + */ +public class AssetCache { + + public static final class SmartAssetInfo { + public WeakReference<AssetKey> smartKey; + public Asset asset; + } + + private final WeakHashMap<AssetKey, SmartAssetInfo> smartCache + = new WeakHashMap<AssetKey, SmartAssetInfo>(); + private final HashMap<AssetKey, Object> regularCache = new HashMap<AssetKey, Object>(); + + /** + * Adds a resource to the cache. + * <br/><br/> + * <font color="red">Thread-safe.</font> + * @see #getFromCache(java.lang.String) + */ + public void addToCache(AssetKey key, Object obj){ + synchronized (regularCache){ + if (obj instanceof Asset && key.useSmartCache()){ + // put in smart cache + Asset asset = (Asset) obj; + asset.setKey(null); // no circular references + SmartAssetInfo smartInfo = new SmartAssetInfo(); + smartInfo.asset = asset; + // use the original key as smart key + smartInfo.smartKey = new WeakReference<AssetKey>(key); + smartCache.put(key, smartInfo); + }else{ + // put in regular cache + regularCache.put(key, obj); + } + } + } + + /** + * Delete an asset from the cache, returns true if it was deleted successfuly. + * <br/><br/> + * <font color="red">Thread-safe.</font> + */ + public boolean deleteFromCache(AssetKey key){ + synchronized (regularCache){ + if (key.useSmartCache()){ + return smartCache.remove(key) != null; + }else{ + return regularCache.remove(key) != null; + } + } + } + + /** + * Gets an object from the cache given an asset key. + * <br/><br/> + * <font color="red">Thread-safe.</font> + * @param key + * @return + */ + public Object getFromCache(AssetKey key){ + synchronized (regularCache){ + if (key.useSmartCache()) { + return smartCache.get(key).asset; + } else { + return regularCache.get(key); + } + } + } + + /** + * Retrieves smart asset info from the cache. + * @param key + * @return + */ + public SmartAssetInfo getFromSmartCache(AssetKey key){ + return smartCache.get(key); + } + + /** + * Deletes all the assets in the regular cache. + */ + public void deleteAllAssets(){ + synchronized (regularCache){ + regularCache.clear(); + smartCache.clear(); + } + } +} diff --git a/engine/src/core/com/jme3/asset/AssetConfig.java b/engine/src/core/com/jme3/asset/AssetConfig.java new file mode 100644 index 0000000..eaf2036 --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetConfig.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import java.io.DataInput; +import java.io.IOException; +import java.io.InputStream; +import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * <code>AssetConfig</code> loads a config file to configure the asset manager. + * <br/><br/> + * The config file is specified with the following format: + * <code> + * "LOADER" <class> : (<extension> ",")* <extension> + * "LOCATOR" <path> <class> : (<extension> ",")* <extension> + * </code> + * + * @author Kirill Vainer + */ +public class AssetConfig { + + private AssetManager manager; + + public AssetConfig(AssetManager manager){ + this.manager = manager; + } + + public void loadText(InputStream in) throws IOException{ + Scanner scan = new Scanner(in); + while (scan.hasNext()){ + String cmd = scan.next(); + if (cmd.equals("LOADER")){ + String loaderClass = scan.next(); + String colon = scan.next(); + if (!colon.equals(":")){ + throw new IOException("Expected ':', got '"+colon+"'"); + } + String extensionsList = scan.nextLine(); + String[] extensions = extensionsList.split(","); + for (int i = 0; i < extensions.length; i++){ + extensions[i] = extensions[i].trim(); + } + if (hasClass(loaderClass)) { + manager.registerLoader(loaderClass, extensions); + } else { + Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot find loader {0}", loaderClass); + } + } else if (cmd.equals("LOCATOR")) { + String rootPath = scan.next(); + String locatorClass = scan.nextLine().trim(); + if (hasClass(locatorClass)) { + manager.registerLocator(rootPath, locatorClass); + } else { + Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot find locator {0}", locatorClass); + } + } else { + throw new IOException("Expected command, got '" + cmd + "'"); + } + } + } + + private boolean hasClass(String name) { + try { + Class clazz = Class.forName(name); + return clazz != null; + } catch (ClassNotFoundException ex) { + return false; + } + } + + private static String readString(DataInput dataIn) throws IOException{ + int length = dataIn.readUnsignedShort(); + char[] chrs = new char[length]; + for (int i = 0; i < length; i++){ + chrs[i] = (char) dataIn.readUnsignedByte(); + } + return String.valueOf(chrs); + } + + /* + public void loadBinary(DataInput dataIn) throws IOException{ + // read signature and version + + // how many locator entries? + int locatorEntries = dataIn.readUnsignedShort(); + for (int i = 0; i < locatorEntries; i++){ + String locatorClazz = readString(dataIn); + String rootPath = readString(dataIn); + manager.registerLocator(rootPath, locatorClazz); + } + + int loaderEntries = dataIn.readUnsignedShort(); + for (int i = 0; i < loaderEntries; i++){ + String loaderClazz = readString(dataIn); + int numExtensions = dataIn.readUnsignedByte(); + String[] extensions = new String[numExtensions]; + for (int j = 0; j < numExtensions; j++){ + extensions[j] = readString(dataIn); + } + + manager.registerLoader(loaderClazz, extensions); + } + } + */ +} diff --git a/engine/src/core/com/jme3/asset/AssetEventListener.java b/engine/src/core/com/jme3/asset/AssetEventListener.java new file mode 100644 index 0000000..6907bcf --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetEventListener.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +/** + * <code>AssetEventListener</code> is an interface for listening to various + * events happening inside {@link AssetManager}. For now, it is possible + * to receive an event when an asset has been requested + * (one of the AssetManager.load***() methods were called), or when + * an asset has been loaded. + * + * @author Kirill Vainer + */ +public interface AssetEventListener { + + /** + * Called when an asset has been successfully loaded (e.g: loaded from + * file system and parsed). + * + * @param key the AssetKey for the asset loaded. + */ + public void assetLoaded(AssetKey key); + + /** + * Called when an asset has been requested (e.g any of the load*** methods + * in AssetManager are called). + * In contrast to the assetLoaded() method, this one will be called even + * if the asset has failed to load, or if it was retrieved from the cache. + * + * @param key + */ + public void assetRequested(AssetKey key); + + /** + * Called when an asset dependency cannot be found for an asset. + * When an asset is loaded, each of its dependent assets that + * have failed to load due to a {@link AssetNotFoundException}, will cause + * an invocation of this callback. + * + * @param parentKey The key of the parent asset that is being loaded + * from within the user application. + * @param dependentAssetKey The asset key of the dependent asset that has + * failed to load. + */ + public void assetDependencyNotFound(AssetKey parentKey, AssetKey dependentAssetKey); + +} diff --git a/engine/src/core/com/jme3/asset/AssetInfo.java b/engine/src/core/com/jme3/asset/AssetInfo.java new file mode 100644 index 0000000..42ee822 --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetInfo.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import java.io.InputStream; + +/** + * The result of locating an asset through an AssetKey. Provides + * a means to read the asset data through an InputStream. + * + * @author Kirill Vainer + */ +public abstract class AssetInfo { + + protected AssetManager manager; + protected AssetKey key; + + public AssetInfo(AssetManager manager, AssetKey key) { + this.manager = manager; + this.key = key; + } + + public AssetKey getKey() { + return key; + } + + public AssetManager getManager() { + return manager; + } + + @Override + public String toString(){ + return getClass().getName() + "[" + "key=" + key + "]"; + } + + /** + * Implementations of this method should return an {@link InputStream} + * allowing access to the data represented by the {@link AssetKey}. + * <p> + * Each invocation of this method should return a new stream to the + * asset data, starting at the beginning of the file. + * + * @return The asset data. + */ + public abstract InputStream openStream(); + +} diff --git a/engine/src/core/com/jme3/asset/AssetKey.java b/engine/src/core/com/jme3/asset/AssetKey.java new file mode 100644 index 0000000..9b6f0cd --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetKey.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import com.jme3.export.*; +import java.io.IOException; +import java.util.LinkedList; + +/** + * <code>AssetKey</code> is a key that is used to + * look up a resource from a cache. + * This class should be immutable. + */ +public class AssetKey<T> implements Savable { + + protected String name; + protected transient String folder; + protected transient String extension; + + public AssetKey(String name){ + this.name = reducePath(name); + this.extension = getExtension(this.name); + } + + public AssetKey(){ + } + + protected static String getExtension(String name){ + int idx = name.lastIndexOf('.'); + //workaround for filenames ending with xml and another dot ending before that (my.mesh.xml) + if (name.toLowerCase().endsWith(".xml")) { + idx = name.substring(0, idx).lastIndexOf('.'); + if (idx == -1) { + idx = name.lastIndexOf('.'); + } + } + if (idx <= 0 || idx == name.length() - 1) + return ""; + else + return name.substring(idx+1).toLowerCase(); + } + + protected static String getFolder(String name){ + int idx = name.lastIndexOf('/'); + if (idx <= 0 || idx == name.length() - 1) + return ""; + else + return name.substring(0, idx+1); + } + + public String getName() { + return name; + } + + /** + * @return The extension of the <code>AssetKey</code>'s name. For example, + * the name "Interface/Logo/Monkey.png" has an extension of "png". + */ + public String getExtension() { + return extension; + } + + public String getFolder(){ + if (folder == null) + folder = getFolder(name); + + return folder; + } + + /** + * Do any post-processing on the resource after it has been loaded. + * @param asset + */ + public Object postProcess(Object asset){ + return asset; + } + + /** + * Create a new instance of the asset, based on a prototype that is stored + * in the cache. Implementations are allowed to return the given parameter + * as-is if it is considered that cloning is not necessary for that particular + * asset type. + * + * @param asset The asset to be cloned. + * @return The asset, possibly cloned. + */ + public Object createClonedInstance(Object asset){ + return asset; + } + + /** + * @return True if the asset for this key should be cached. Subclasses + * should override this method if they want to override caching behavior. + */ + public boolean shouldCache(){ + return true; + } + + /** + * @return Should return true, if the asset objects implement the "Asset" + * interface and want to be removed from the cache when no longer + * referenced in user-code. + */ + public boolean useSmartCache(){ + return false; + } + + /** + * Removes all relative elements of a path (A/B/../C.png and A/./C.png). + * @param path The path containing relative elements + * @return A path without relative elements + */ + public static String reducePath(String path) { + if (path == null || path.indexOf("./") == -1) { + return path; + } + String[] parts = path.split("/"); + LinkedList<String> list = new LinkedList<String>(); + for (int i = 0; i < parts.length; i++) { + String string = parts[i]; + if (string.length() == 0 || string.equals(".")) { + //do nothing + } else if (string.equals("..")) { + if (list.size() > 0) { + list.removeLast(); + } else { + throw new IllegalStateException("Relative path is outside assetmanager root!"); + } + } else { + list.add(string); + } + } + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < list.size(); i++) { + String string = list.get(i); + if (i != 0) { + builder.append("/"); + } + builder.append(string); + } + return builder.toString(); + } + + @Override + public boolean equals(Object other){ + if (!(other instanceof AssetKey)){ + return false; + } + return name.equals(((AssetKey)other).name); + } + + @Override + public int hashCode(){ + return name.hashCode(); + } + + @Override + public String toString(){ + return name; + } + + public void write(JmeExporter ex) throws IOException { + OutputCapsule oc = ex.getCapsule(this); + oc.write(name, "name", null); + } + + public void read(JmeImporter im) throws IOException { + InputCapsule ic = im.getCapsule(this); + name = reducePath(ic.readString("name", null)); + extension = getExtension(name); + } + +} diff --git a/engine/src/core/com/jme3/asset/AssetLoadException.java b/engine/src/core/com/jme3/asset/AssetLoadException.java new file mode 100644 index 0000000..a0139aa --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetLoadException.java @@ -0,0 +1,17 @@ +package com.jme3.asset; + +/** + * <code>AssetLoadException</code> is thrown when the {@link AssetManager} + * is able to find the requested asset, but there was a problem while loading + * it. + * + * @author Kirill Vainer + */ +public class AssetLoadException extends RuntimeException { + public AssetLoadException(String message){ + super(message); + } + public AssetLoadException(String message, Throwable cause){ + super(message, cause); + } +} diff --git a/engine/src/core/com/jme3/asset/AssetLoader.java b/engine/src/core/com/jme3/asset/AssetLoader.java new file mode 100644 index 0000000..4ebffc5 --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetLoader.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import java.io.IOException; + +/** + * An interface for asset loaders. An <code>AssetLoader</code> is responsible + * for loading a certain type of asset associated with file extension(s). + * The loader will load the data in the provided {@link AssetInfo} object by + * calling {@link AssetInfo#openStream() }, returning an object representing + * the parsed data. + */ +public interface AssetLoader { + + /** + * Loads asset from the given input stream, parsing it into + * an application-usable object. + * + * @return An object representing the resource. + * @throws java.io.IOException If an I/O error occurs while loading + */ + public Object load(AssetInfo assetInfo) throws IOException; +} diff --git a/engine/src/core/com/jme3/asset/AssetLocator.java b/engine/src/core/com/jme3/asset/AssetLocator.java new file mode 100644 index 0000000..561e372 --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetLocator.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +/** + * <code>AssetLocator</code> is used to locate a resource based on an AssetKey. + * + * @author Kirill Vainer + */ +public interface AssetLocator { + /** + * @param rootPath The root path where to look for assets. + * Typically this method will only be called once per + * instance of an asset locator. + */ + public void setRootPath(String rootPath); + + /** + * Request to locate an asset. The asset key + * contains a name identifying the asset. + * If an asset was not found, null should be returned. + * The {@link AssetInfo} implementation provided should have a proper + * return value for its {@link AssetInfo#openStream() } method. + * + * @param manager + * @param key + * @return The {@link AssetInfo} that was located, or null if not found. + */ + public AssetInfo locate(AssetManager manager, AssetKey key); +} diff --git a/engine/src/core/com/jme3/asset/AssetManager.java b/engine/src/core/com/jme3/asset/AssetManager.java new file mode 100644 index 0000000..a863ebf --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetManager.java @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import com.jme3.audio.AudioData; +import com.jme3.audio.AudioKey; +import com.jme3.font.BitmapFont; +import com.jme3.material.Material; +import com.jme3.scene.Spatial; +import com.jme3.shader.Shader; +import com.jme3.shader.ShaderKey; +import com.jme3.texture.Texture; +import java.util.List; + +/** + * <code>AssetManager</code> provides an interface for managing the data assets + * of a jME3 application. + */ +public interface AssetManager { + + /** + * Adds a ClassLoader that is used to load *Classes* that are needed for Assets like j3o models. + * This does *not* allow loading assets from that classpath, use registerLocator for that. + * @param loader A ClassLoader that Classes in asset files can be loaded from + */ + public void addClassLoader(ClassLoader loader); + + /** + * Remove a ClassLoader from the list of registered ClassLoaders + */ + public void removeClassLoader(ClassLoader loader); + + /** + * Retrieve the list of registered ClassLoaders that are used for loading Classes from + * asset files. + */ + public List<ClassLoader> getClassLoaders(); + + /** + * Registers a loader for the given extensions. + * @param loaderClassName + * @param extensions + */ + public void registerLoader(String loaderClassName, String ... extensions); + + /** + * Registers an {@link AssetLocator} by using a class name, instead of + * a class instance. See the {@link AssetManager#registerLocator(java.lang.String, java.lang.Class) } + * method for more information. + * + * @param rootPath The root path from which to locate assets, implementation + * dependent. + * @param locatorClassName The full class name of the {@link AssetLocator} + * implementation. + */ + public void registerLocator(String rootPath, String locatorClassName); + + /** + * + * @param loaderClass + * @param extensions + */ + public void registerLoader(Class<? extends AssetLoader> loaderClass, String ... extensions); + + /** + * Registers the given locator class for locating assets with this + * <code>AssetManager</code>. {@link AssetLocator}s are invoked in the order + * they were registered, to locate the asset by the {@link AssetKey}. + * Once an {@link AssetLocator} returns a non-null AssetInfo, it is sent + * to the {@link AssetLoader} to load the asset. + * Once a locator is registered, it can be removed via + * {@link #unregisterLocator(java.lang.String, java.lang.Class) }. + * + * @param rootPath Specifies the root path from which to locate assets + * for the given {@link AssetLocator}. The purpose of this parameter + * depends on the type of the {@link AssetLocator}. + * @param locatorClass The class type of the {@link AssetLocator} to register. + * + * @see AssetLocator#setRootPath(java.lang.String) + * @see AssetLocator#locate(com.jme3.asset.AssetManager, com.jme3.asset.AssetKey) + * @see #unregisterLocator(java.lang.String, java.lang.Class) + */ + public void registerLocator(String rootPath, Class<? extends AssetLocator> locatorClass); + + /** + * Unregisters the given locator class. This essentially undoes the operation + * done by {@link #registerLocator(java.lang.String, java.lang.Class) }. + * + * @param rootPath Should be the same as the root path specified in {@link + * #registerLocator(java.lang.String, java.lang.Class) }. + * @param locatorClass The locator class to unregister + */ + public void unregisterLocator(String rootPath, Class<? extends AssetLocator> locatorClass); + + /** + * Set an {@link AssetEventListener} to receive events from this + * <code>AssetManager</code>. There can only be one {@link AssetEventListener} + * associated with an <code>AssetManager</code> + * + * @param listener + */ + public void setAssetEventListener(AssetEventListener listener); + + /** + * Manually locates an asset with the given {@link AssetKey}. This method + * should be used for debugging or internal uses. <br/> + * The call will attempt to locate the asset by invoking the + * {@link AssetLocator} that are registered with this <code>AssetManager</code>, + * in the same way that the {@link AssetManager#loadAsset(com.jme3.asset.AssetKey) } + * method locates assets. + * + * @param key The {@link AssetKey} to locate. + * @return The {@link AssetInfo} object returned from the {@link AssetLocator} + * that located the asset, or null if the asset cannot be located. + */ + public AssetInfo locateAsset(AssetKey<?> key); + + /** + * Load an asset from a key, the asset will be located + * by one of the {@link AssetLocator} implementations provided in the + * {@link AssetManager#registerLocator(java.lang.String, java.lang.Class) } + * call. If located successfully, it will be loaded via the the appropriate + * {@link AssetLoader} implementation based on the file's extension, as + * specified in the call + * {@link AssetManager#registerLoader(java.lang.Class, java.lang.String[]) }. + * + * @param <T> The object type that will be loaded from the AssetKey instance. + * @param key The AssetKey + * @return The loaded asset, or null if it was failed to be located + * or loaded. + */ + public <T> T loadAsset(AssetKey<T> key); + + /** + * Load a named asset by name, calling this method + * is the same as calling + * <code> + * loadAsset(new AssetKey(name)). + * </code> + * + * @param name The name of the asset to load. + * @return The loaded asset, or null if failed to be loaded. + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public Object loadAsset(String name); + + /** + * Loads texture file, supported types are BMP, JPG, PNG, GIF, + * TGA and DDS. + * + * @param key The {@link TextureKey} to use for loading. + * @return The loaded texture, or null if failed to be loaded. + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public Texture loadTexture(TextureKey key); + + /** + * Loads texture file, supported types are BMP, JPG, PNG, GIF, + * TGA and DDS. + * + * @param name The name of the texture to load. + * @return The texture that was loaded + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public Texture loadTexture(String name); + + /** + * Load audio file, supported types are WAV or OGG. + * @param key + * @return The audio data loaded + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public AudioData loadAudio(AudioKey key); + + /** + * Load audio file, supported types are WAV or OGG. + * The file is loaded without stream-mode. + * @param name + * @return The audio data loaded + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public AudioData loadAudio(String name); + + /** + * Loads a named model. Models can be jME3 object files (J3O) or + * OgreXML/OBJ files. + * @param key + * @return The model that was loaded + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public Spatial loadModel(ModelKey key); + + /** + * Loads a named model. Models can be jME3 object files (J3O) or + * OgreXML/OBJ files. + * @param name + * @return The model that was loaded + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public Spatial loadModel(String name); + + /** + * Load a material (J3M) file. + * @param name + * @return The material that was loaded + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public Material loadMaterial(String name); + + /** + * Loads shader file(s), shouldn't be used by end-user in most cases. + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public Shader loadShader(ShaderKey key); + + /** + * Load a font file. Font files are in AngelCode text format, + * and are with the extension "fnt". + * + * @param name + * @return The font loaded + * + * @see AssetManager#loadAsset(com.jme3.asset.AssetKey) + */ + public BitmapFont loadFont(String name); +} diff --git a/engine/src/core/com/jme3/asset/AssetNotFoundException.java b/engine/src/core/com/jme3/asset/AssetNotFoundException.java new file mode 100644 index 0000000..e04a7fb --- /dev/null +++ b/engine/src/core/com/jme3/asset/AssetNotFoundException.java @@ -0,0 +1,17 @@ +package com.jme3.asset; + +/** + * <code>AssetNotFoundException</code> is thrown when the {@link AssetManager} + * is unable to locate the requested asset using any of the registered + * {@link AssetLocator}s. + * + * @author Kirill Vainer + */ +public class AssetNotFoundException extends RuntimeException { + public AssetNotFoundException(String message){ + super(message); + } + public AssetNotFoundException(String message, Exception ex){ + super(message, ex); + } +} diff --git a/engine/src/core/com/jme3/asset/Desktop.cfg b/engine/src/core/com/jme3/asset/Desktop.cfg new file mode 100644 index 0000000..93dafb7 --- /dev/null +++ b/engine/src/core/com/jme3/asset/Desktop.cfg @@ -0,0 +1,22 @@ +LOCATOR / com.jme3.asset.plugins.ClasspathLocator
+
+LOADER com.jme3.texture.plugins.AWTLoader : jpg, bmp, gif, png, jpeg
+LOADER com.jme3.audio.plugins.WAVLoader : wav
+LOADER com.jme3.audio.plugins.OGGLoader : ogg
+LOADER com.jme3.material.plugins.J3MLoader : j3m
+LOADER com.jme3.material.plugins.J3MLoader : j3md
+LOADER com.jme3.font.plugins.BitmapFontLoader : fnt
+LOADER com.jme3.texture.plugins.DDSLoader : dds
+LOADER com.jme3.texture.plugins.PFMLoader : pfm
+LOADER com.jme3.texture.plugins.HDRLoader : hdr
+LOADER com.jme3.texture.plugins.TGALoader : tga
+LOADER com.jme3.export.binary.BinaryImporter : j3o
+LOADER com.jme3.export.binary.BinaryImporter : j3f
+LOADER com.jme3.scene.plugins.OBJLoader : obj
+LOADER com.jme3.scene.plugins.MTLLoader : mtl
+LOADER com.jme3.scene.plugins.ogre.MeshLoader : meshxml, mesh.xml
+LOADER com.jme3.scene.plugins.ogre.SkeletonLoader : skeletonxml, skeleton.xml
+LOADER com.jme3.scene.plugins.ogre.MaterialLoader : material
+LOADER com.jme3.scene.plugins.ogre.SceneLoader : scene
+LOADER com.jme3.scene.plugins.blender.BlenderModelLoader : blend
+LOADER com.jme3.shader.plugins.GLSLLoader : vert, frag, glsl, glsllib
\ No newline at end of file diff --git a/engine/src/core/com/jme3/asset/DesktopAssetManager.java b/engine/src/core/com/jme3/asset/DesktopAssetManager.java new file mode 100644 index 0000000..e2d8ef8 --- /dev/null +++ b/engine/src/core/com/jme3/asset/DesktopAssetManager.java @@ -0,0 +1,421 @@ +/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.asset;
+
+import com.jme3.asset.AssetCache.SmartAssetInfo;
+import com.jme3.audio.AudioData;
+import com.jme3.audio.AudioKey;
+import com.jme3.font.BitmapFont;
+import com.jme3.material.Material;
+import com.jme3.scene.Spatial;
+import com.jme3.shader.Shader;
+import com.jme3.shader.ShaderKey;
+import com.jme3.texture.Texture;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * <code>AssetManager</code> is the primary method for managing and loading
+ * assets inside jME.
+ *
+ * @author Kirill Vainer
+ */
+public class DesktopAssetManager implements AssetManager {
+
+ private static final Logger logger = Logger.getLogger(AssetManager.class.getName());
+
+ private final AssetCache cache = new AssetCache();
+ private final ImplHandler handler = new ImplHandler(this);
+
+ private AssetEventListener eventListener = null;
+ private List<ClassLoader> classLoaders;
+
+// private final ThreadingManager threadingMan = new ThreadingManager(this);
+// private final Set<AssetKey> alreadyLoadingSet = new HashSet<AssetKey>();
+
+ public DesktopAssetManager(){
+ this(null);
+ }
+
+ @Deprecated
+ public DesktopAssetManager(boolean loadDefaults){
+ this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Desktop.cfg"));
+ }
+
+ public DesktopAssetManager(URL configFile){
+ if (configFile != null){
+ InputStream stream = null;
+ try{
+ AssetConfig cfg = new AssetConfig(this);
+ stream = configFile.openStream();
+ cfg.loadText(stream);
+ }catch (IOException ex){
+ logger.log(Level.SEVERE, "Failed to load asset config", ex);
+ }finally{
+ if (stream != null)
+ try{
+ stream.close();
+ }catch (IOException ex){
+ }
+ }
+ }
+ logger.info("DesktopAssetManager created.");
+ }
+
+ public void addClassLoader(ClassLoader loader){
+ if(classLoaders == null)
+ classLoaders = Collections.synchronizedList(new ArrayList<ClassLoader>());
+ synchronized(classLoaders) {
+ classLoaders.add(loader);
+ }
+ }
+
+ public void removeClassLoader(ClassLoader loader){
+ if(classLoaders != null) synchronized(classLoaders) {
+ classLoaders.remove(loader);
+ }
+ }
+
+ public List<ClassLoader> getClassLoaders(){
+ return classLoaders;
+ }
+
+ public void setAssetEventListener(AssetEventListener listener){
+ eventListener = listener;
+ }
+
+ public void registerLoader(Class<? extends AssetLoader> loader, String ... extensions){
+ handler.addLoader(loader, extensions);
+ if (logger.isLoggable(Level.FINER)){
+ logger.log(Level.FINER, "Registered loader: {0} for extensions {1}",
+ new Object[]{loader.getSimpleName(), Arrays.toString(extensions)});
+ }
+ }
+
+ public void registerLoader(String clsName, String ... extensions){
+ Class<? extends AssetLoader> clazz = null;
+ try{
+ clazz = (Class<? extends AssetLoader>) Class.forName(clsName);
+ }catch (ClassNotFoundException ex){
+ logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
+ }catch (NoClassDefFoundError ex){
+ logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
+ }
+ if (clazz != null){
+ registerLoader(clazz, extensions);
+ }
+ }
+
+ public void registerLocator(String rootPath, Class<? extends AssetLocator> locatorClass){
+ handler.addLocator(locatorClass, rootPath);
+ if (logger.isLoggable(Level.FINER)){
+ logger.log(Level.FINER, "Registered locator: {0}",
+ locatorClass.getSimpleName());
+ }
+ }
+
+ public void registerLocator(String rootPath, String clsName){
+ Class<? extends AssetLocator> clazz = null;
+ try{
+ clazz = (Class<? extends AssetLocator>) Class.forName(clsName);
+ }catch (ClassNotFoundException ex){
+ logger.log(Level.WARNING, "Failed to find locator: "+clsName, ex);
+ }catch (NoClassDefFoundError ex){
+ logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
+ }
+ if (clazz != null){
+ registerLocator(rootPath, clazz);
+ }
+ }
+
+ public void unregisterLocator(String rootPath, Class<? extends AssetLocator> clazz){
+ handler.removeLocator(clazz, rootPath);
+ if (logger.isLoggable(Level.FINER)){
+ logger.log(Level.FINER, "Unregistered locator: {0}",
+ clazz.getSimpleName());
+ }
+ }
+
+ public void clearCache(){
+ cache.deleteAllAssets();
+ }
+
+ /**
+ * Delete an asset from the cache, returns true if it was deleted
+ * successfully.
+ * <br/><br/>
+ * <font color="red">Thread-safe.</font>
+ */
+ public boolean deleteFromCache(AssetKey key){
+ return cache.deleteFromCache(key);
+ }
+
+ /**
+ * Adds a resource to the cache.
+ * <br/><br/>
+ * <font color="red">Thread-safe.</font>
+ */
+ public void addToCache(AssetKey key, Object asset){
+ cache.addToCache(key, asset);
+ }
+
+ public AssetInfo locateAsset(AssetKey<?> key){
+ if (handler.getLocatorCount() == 0){
+ logger.warning("There are no locators currently"+
+ " registered. Use AssetManager."+
+ "registerLocator() to register a"+
+ " locator.");
+ return null;
+ }
+
+ AssetInfo info = handler.tryLocate(key);
+ if (info == null){
+ logger.log(Level.WARNING, "Cannot locate resource: {0}", key);
+ }
+
+ return info;
+ }
+
+ /**
+ * <font color="red">Thread-safe.</font>
+ *
+ * @param <T>
+ * @param key
+ * @return
+ */
+ public <T> T loadAsset(AssetKey<T> key){
+ if (key == null)
+ throw new IllegalArgumentException("key cannot be null");
+
+ if (eventListener != null)
+ eventListener.assetRequested(key);
+
+ AssetKey smartKey = null;
+ Object o = null;
+ if (key.shouldCache()){
+ if (key.useSmartCache()){
+ SmartAssetInfo smartInfo = cache.getFromSmartCache(key);
+ if (smartInfo != null){
+ smartKey = smartInfo.smartKey.get();
+ if (smartKey != null){
+ o = smartInfo.asset;
+ }
+ }
+ }else{
+ o = cache.getFromCache(key);
+ }
+ }
+ if (o == null){
+ AssetLoader loader = handler.aquireLoader(key);
+ if (loader == null){
+ throw new IllegalStateException("No loader registered for type \"" +
+ key.getExtension() + "\"");
+ }
+
+ if (handler.getLocatorCount() == 0){
+ throw new IllegalStateException("There are no locators currently"+
+ " registered. Use AssetManager."+
+ "registerLocator() to register a"+
+ " locator.");
+ }
+
+ AssetInfo info = handler.tryLocate(key);
+ if (info == null){
+ if (handler.getParentKey() != null && eventListener != null){
+ // Inform event listener that an asset has failed to load.
+ // If the parent AssetLoader chooses not to propagate
+ // the exception, this is the only means of finding
+ // that something went wrong.
+ eventListener.assetDependencyNotFound(handler.getParentKey(), key);
+ }
+ throw new AssetNotFoundException(key.toString());
+ }
+
+ try {
+ handler.establishParentKey(key);
+ o = loader.load(info);
+ } catch (IOException ex) {
+ throw new AssetLoadException("An exception has occured while loading asset: " + key, ex);
+ } finally {
+ handler.releaseParentKey(key);
+ }
+ if (o == null){
+ throw new AssetLoadException("Error occured while loading asset \"" + key + "\" using" + loader.getClass().getSimpleName());
+ }else{
+ if (logger.isLoggable(Level.FINER)){
+ logger.log(Level.FINER, "Loaded {0} with {1}",
+ new Object[]{key, loader.getClass().getSimpleName()});
+ }
+
+ // do processing on asset before caching
+ o = key.postProcess(o);
+
+ if (key.shouldCache())
+ cache.addToCache(key, o);
+
+ if (eventListener != null)
+ eventListener.assetLoaded(key);
+ }
+ }
+
+ // object o is the asset
+ // create an instance for user
+ T clone = (T) key.createClonedInstance(o);
+
+ if (key.useSmartCache()){
+ if (smartKey != null){
+ // smart asset was already cached, use original key
+ ((Asset)clone).setKey(smartKey);
+ }else{
+ // smart asset was cached on this call, use our key
+ ((Asset)clone).setKey(key);
+ }
+ }
+
+ return clone;
+ }
+
+ public Object loadAsset(String name){
+ return loadAsset(new AssetKey(name));
+ }
+
+ /**
+ * Loads a texture.
+ *
+ * @return
+ */
+ public Texture loadTexture(TextureKey key){
+ return (Texture) loadAsset(key);
+ }
+
+ public Material loadMaterial(String name){
+ return (Material) loadAsset(new MaterialKey(name));
+ }
+
+ /**
+ * Loads a texture.
+ *
+ * @param name
+ * @param generateMipmaps Enable if applying texture to 3D objects, disable
+ * for GUI/HUD elements.
+ * @return
+ */
+ public Texture loadTexture(String name, boolean generateMipmaps){
+ TextureKey key = new TextureKey(name, true);
+ key.setGenerateMips(generateMipmaps);
+ key.setAsCube(false);
+ return loadTexture(key);
+ }
+
+ public Texture loadTexture(String name, boolean generateMipmaps, boolean flipY, boolean asCube, int aniso){
+ TextureKey key = new TextureKey(name, flipY);
+ key.setGenerateMips(generateMipmaps);
+ key.setAsCube(asCube);
+ key.setAnisotropy(aniso);
+ return loadTexture(key);
+ }
+
+ public Texture loadTexture(String name){
+ return loadTexture(name, true);
+ }
+
+ public AudioData loadAudio(AudioKey key){
+ return (AudioData) loadAsset(key);
+ }
+
+ public AudioData loadAudio(String name){
+ return loadAudio(new AudioKey(name, false));
+ }
+
+ /**
+ * Loads a bitmap font with the given name.
+ *
+ * @param name
+ * @return
+ */
+ public BitmapFont loadFont(String name){
+ return (BitmapFont) loadAsset(new AssetKey(name));
+ }
+
+ public InputStream loadGLSLLibrary(AssetKey key){
+ return (InputStream) loadAsset(key);
+ }
+
+ /**
+ * Load a vertex/fragment shader combo.
+ *
+ * @param key
+ * @return
+ */
+ public Shader loadShader(ShaderKey key){
+ // cache abuse in method
+ // that doesn't use loaders/locators
+ Shader s = (Shader) cache.getFromCache(key);
+ if (s == null){
+ String vertName = key.getVertName();
+ String fragName = key.getFragName();
+
+ String vertSource = (String) loadAsset(new AssetKey(vertName));
+ String fragSource = (String) loadAsset(new AssetKey(fragName));
+
+ s = new Shader(key.getLanguage());
+ s.addSource(Shader.ShaderType.Vertex, vertName, vertSource, key.getDefines().getCompiled());
+ s.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled());
+
+ cache.addToCache(key, s);
+ }
+ return s;
+ }
+
+ public Spatial loadModel(ModelKey key){
+ return (Spatial) loadAsset(key);
+ }
+
+ /**
+ * Load a model.
+ *
+ * @param name
+ * @return
+ */
+ public Spatial loadModel(String name){
+ return loadModel(new ModelKey(name));
+ }
+
+}
diff --git a/engine/src/core/com/jme3/asset/ImplHandler.java b/engine/src/core/com/jme3/asset/ImplHandler.java new file mode 100644 index 0000000..9b0b50a --- /dev/null +++ b/engine/src/core/com/jme3/asset/ImplHandler.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * <code>ImplHandler</code> manages the asset loader and asset locator + * implementations in a thread safe way. This allows implementations + * which store local persistent data to operate with a multi-threaded system. + * This is done by keeping an instance of each asset loader and asset + * locator object in a thread local. + */ +public class ImplHandler { + + private static final Logger logger = Logger.getLogger(ImplHandler.class.getName()); + + private final AssetManager owner; + + private final ThreadLocal<AssetKey> parentAssetKey + = new ThreadLocal<AssetKey>(); + + private final ArrayList<ImplThreadLocal> genericLocators = + new ArrayList<ImplThreadLocal>(); + + private final HashMap<String, ImplThreadLocal> loaders = + new HashMap<String, ImplThreadLocal>(); + + public ImplHandler(AssetManager owner){ + this.owner = owner; + } + + protected class ImplThreadLocal extends ThreadLocal { + + private final Class<?> type; + private final String path; + + public ImplThreadLocal(Class<?> type){ + this.type = type; + path = null; + } + + public ImplThreadLocal(Class<?> type, String path){ + this.type = type; + this.path = path; + } + + public String getPath() { + return path; + } + + public Class<?> getTypeClass(){ + return type; + } + + @Override + protected Object initialValue(){ + try { + return type.newInstance(); + } catch (InstantiationException ex) { + logger.log(Level.SEVERE,"Cannot create locator of type {0}, does" + + " the class have an empty and publically accessible"+ + " constructor?", type.getName()); + logger.throwing(type.getName(), "<init>", ex); + } catch (IllegalAccessException ex) { + logger.log(Level.SEVERE,"Cannot create locator of type {0}, " + + "does the class have an empty and publically " + + "accessible constructor?", type.getName()); + logger.throwing(type.getName(), "<init>", ex); + } + return null; + } + } + + /** + * Establishes the asset key that is used for tracking dependent assets + * that have failed to load. When set, the {@link DesktopAssetManager} + * gets a hint that it should suppress {@link AssetNotFoundException}s + * and instead call the listener callback (if set). + * + * @param parentKey The parent key + */ + public void establishParentKey(AssetKey parentKey){ + if (parentAssetKey.get() == null){ + parentAssetKey.set(parentKey); + } + } + + public void releaseParentKey(AssetKey parentKey){ + if (parentAssetKey.get() == parentKey){ + parentAssetKey.set(null); + } + } + + public AssetKey getParentKey(){ + return parentAssetKey.get(); + } + + /** + * Attempts to locate the given resource name. + * @param key The full name of the resource. + * @return The AssetInfo containing resource information required for + * access, or null if not found. + */ + public AssetInfo tryLocate(AssetKey key){ + synchronized (genericLocators){ + if (genericLocators.isEmpty()) + return null; + + for (ImplThreadLocal local : genericLocators){ + AssetLocator locator = (AssetLocator) local.get(); + if (local.getPath() != null){ + locator.setRootPath((String) local.getPath()); + } + AssetInfo info = locator.locate(owner, key); + if (info != null) + return info; + } + } + return null; + } + + public int getLocatorCount(){ + synchronized (genericLocators){ + return genericLocators.size(); + } + } + + /** + * Returns the AssetLoader registered for the given extension + * of the current thread. + * @return AssetLoader registered with addLoader. + */ + public AssetLoader aquireLoader(AssetKey key){ + synchronized (loaders){ + ImplThreadLocal local = loaders.get(key.getExtension()); + if (local != null){ + AssetLoader loader = (AssetLoader) local.get(); + return loader; + } + return null; + } + } + + public void addLoader(final Class<?> loaderType, String ... extensions){ + ImplThreadLocal local = new ImplThreadLocal(loaderType); + for (String extension : extensions){ + extension = extension.toLowerCase(); + synchronized (loaders){ + loaders.put(extension, local); + } + } + } + + public void addLocator(final Class<?> locatorType, String rootPath){ + ImplThreadLocal local = new ImplThreadLocal(locatorType, rootPath); + synchronized (genericLocators){ + genericLocators.add(local); + } + } + + public void removeLocator(final Class<?> locatorType, String rootPath){ + synchronized (genericLocators){ + Iterator<ImplThreadLocal> it = genericLocators.iterator(); + while (it.hasNext()){ + ImplThreadLocal locator = it.next(); + if (locator.getPath().equals(rootPath) && + locator.getTypeClass().equals(locatorType)){ + it.remove(); + } + } + } + } + +} diff --git a/engine/src/core/com/jme3/asset/MaterialKey.java b/engine/src/core/com/jme3/asset/MaterialKey.java new file mode 100644 index 0000000..cc74fbc --- /dev/null +++ b/engine/src/core/com/jme3/asset/MaterialKey.java @@ -0,0 +1,29 @@ +package com.jme3.asset; + +import com.jme3.material.Material; + +/** + * Used for loading {@link Material materials} only (not material definitions). + * + * @author Kirill Vainer + */ +public class MaterialKey extends AssetKey { + public MaterialKey(String name){ + super(name); + } + + public MaterialKey(){ + super(); + } + + @Override + public boolean useSmartCache(){ + return true; + } + + @Override + public Object createClonedInstance(Object asset){ + Material mat = (Material) asset; + return mat.clone(); + } +} diff --git a/engine/src/core/com/jme3/asset/ModelKey.java b/engine/src/core/com/jme3/asset/ModelKey.java new file mode 100644 index 0000000..fcf5c53 --- /dev/null +++ b/engine/src/core/com/jme3/asset/ModelKey.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import com.jme3.scene.Spatial; + +/** + * + * @author Kirill Vainer + */ +public class ModelKey extends AssetKey<Spatial> { + + public ModelKey(String name){ + super(name); + } + + public ModelKey(){ + super(); + } + @Override + public boolean useSmartCache(){ + return true; + } + + @Override + public Object createClonedInstance(Object asset){ + Spatial model = (Spatial) asset; + return model.clone(); + } + +} diff --git a/engine/src/core/com/jme3/asset/TextureKey.java b/engine/src/core/com/jme3/asset/TextureKey.java new file mode 100644 index 0000000..118c84e --- /dev/null +++ b/engine/src/core/com/jme3/asset/TextureKey.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.asset; + +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.texture.Texture.Type; +import com.jme3.texture.*; +import java.io.IOException; +import java.nio.ByteBuffer; + +public class TextureKey extends AssetKey<Texture> { + + private boolean generateMips; + private boolean flipY; + private boolean asCube; + private boolean asTexture3D; + private int anisotropy; + private Texture.Type textureTypeHint=Texture.Type.TwoDimensional; + + public TextureKey(String name, boolean flipY) { + super(name); + this.flipY = flipY; + } + + public TextureKey(String name) { + super(name); + this.flipY = true; + } + + public TextureKey() { + } + + @Override + public String toString() { + return name + (flipY ? " (Flipped)" : "") + (asCube ? " (Cube)" : "") + (generateMips ? " (Mipmaped)" : ""); + } + + /** + * Enable smart caching for textures + * @return true to enable smart cache + */ + @Override + public boolean useSmartCache() { + return true; + } + + @Override + public Object createClonedInstance(Object asset) { + Texture tex = (Texture) asset; + return tex.createSimpleClone(); + } + + @Override + public Object postProcess(Object asset) { + Image img = (Image) asset; + if (img == null) { + return null; + } + + Texture tex; + if (isAsCube()) { + if (isFlipY()) { + // also flip -y and +y image in cubemap + ByteBuffer pos_y = img.getData(2); + img.setData(2, img.getData(3)); + img.setData(3, pos_y); + } + tex = new TextureCubeMap(); + } else if (isAsTexture3D()) { + tex = new Texture3D(); + } else { + tex = new Texture2D(); + } + + // enable mipmaps if image has them + // or generate them if requested by user + if (img.hasMipmaps() || isGenerateMips()) { + tex.setMinFilter(Texture.MinFilter.Trilinear); + } + + tex.setAnisotropicFilter(getAnisotropy()); + tex.setName(getName()); + tex.setImage(img); + return tex; + } + + public boolean isFlipY() { + return flipY; + } + + public int getAnisotropy() { + return anisotropy; + } + + public void setAnisotropy(int anisotropy) { + this.anisotropy = anisotropy; + } + + public boolean isAsCube() { + return asCube; + } + + public void setAsCube(boolean asCube) { + this.asCube = asCube; + } + + public boolean isGenerateMips() { + return generateMips; + } + + public void setGenerateMips(boolean generateMips) { + this.generateMips = generateMips; + } + + public boolean isAsTexture3D() { + return asTexture3D; + } + + public void setAsTexture3D(boolean asTexture3D) { + this.asTexture3D = asTexture3D; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof TextureKey)) { + return false; + } + return super.equals(other) && isFlipY() == ((TextureKey) other).isFlipY(); + } + + public Type getTextureTypeHint() { + return textureTypeHint; + } + + public void setTextureTypeHint(Type textureTypeHint) { + this.textureTypeHint = textureTypeHint; + } + + + public void write(JmeExporter ex) throws IOException { + super.write(ex); + OutputCapsule oc = ex.getCapsule(this); + oc.write(flipY, "flip_y", false); + oc.write(generateMips, "generate_mips", false); + oc.write(asCube, "as_cubemap", false); + oc.write(anisotropy, "anisotropy", 0); + } + + @Override + public void read(JmeImporter im) throws IOException { + super.read(im); + InputCapsule ic = im.getCapsule(this); + flipY = ic.readBoolean("flip_y", false); + generateMips = ic.readBoolean("generate_mips", false); + asCube = ic.readBoolean("as_cubemap", false); + anisotropy = ic.readInt("anisotropy", 0); + } +} diff --git a/engine/src/core/com/jme3/asset/ThreadingManager.java b/engine/src/core/com/jme3/asset/ThreadingManager.java new file mode 100644 index 0000000..6ed2c74 --- /dev/null +++ b/engine/src/core/com/jme3/asset/ThreadingManager.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.asset; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +/** + * <code>ThreadingManager</code> manages the threads used to load content + * within the Content Manager system. A pool of threads and a task queue + * is used to load resource data and perform I/O while the application's + * render thread is active. + */ +public class ThreadingManager { + + protected final ExecutorService executor = + Executors.newFixedThreadPool(2, + new LoadingThreadFactory()); + + protected final AssetManager owner; + + protected int nextThreadId = 0; + + public ThreadingManager(AssetManager owner){ + this.owner = owner; + } + + protected class LoadingThreadFactory implements ThreadFactory { + public Thread newThread(Runnable r) { + Thread t = new Thread(r, "pool" + (nextThreadId++)); + t.setDaemon(true); + t.setPriority(Thread.MIN_PRIORITY); + return t; + } + } + + protected class LoadingTask implements Callable<Object> { + private final String resourceName; + public LoadingTask(String resourceName){ + this.resourceName = resourceName; + } + public Object call() throws Exception { + return owner.loadAsset(new AssetKey(resourceName)); + } + } + +// protected class MultiLoadingTask implements Callable<Void> { +// private final String[] resourceNames; +// public MultiLoadingTask(String[] resourceNames){ +// this.resourceNames = resourceNames; +// } +// public Void call(){ +// owner.loadContents(resourceNames); +// return null; +// } +// } + +// public Future<Void> loadContents(String ... names){ +// return executor.submit(new MultiLoadingTask(names)); +// } + +// public Future<Object> loadContent(String name) { +// return executor.submit(new LoadingTask(name)); +// } + + public static boolean isLoadingThread() { + return Thread.currentThread().getName().startsWith("pool"); + } + + +} diff --git a/engine/src/core/com/jme3/asset/package.html b/engine/src/core/com/jme3/asset/package.html new file mode 100644 index 0000000..d9e1913 --- /dev/null +++ b/engine/src/core/com/jme3/asset/package.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + +<head> +<title></title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +</head> +<body> + +<code>com.jme3.asset</code> contains the {@link com.jme3.asset.AssetManager}, +a utility class that is used to load assets such as textures, models, and +sound effects in a jME3 application. <br> + +<p> + +<h3>AssetLoaders</h3> +{@link com.jme3.asset.AssetLoader asset loaders} are registered to load +assets of a particular format. For example, an <code>AssetLoader</code> that +loads TGA images should read a stream in .tga format and return an +{@link com.jme3.texture.Image} object as its output. +<code>AssetLoader</code>s are initialized once a file of that format +is loaded, there's only one AssetLoader per thread so +AssetLoader's load() method does not have to be thread safe. + +<h3>AssetLocators</h3> +{@link com.jme3.asset.AssetLocators asset locators} are used to resolve +an asset name (a string) into an {@link java.io.InputStream} which is +contained in an {@link com.jme3.asset.AssetInfo} object. +There are <code>AssetLocators</code> for loading files from the application's +classpath, the local hard drive, a ZIP file, an HTTP server, and more. The user +can implement their own AssetLocators and register them with the <code>AssetManager</code> +to load their resources from their own location. + + +</body> +</html> + |