aboutsummaryrefslogtreecommitdiff
path: root/engine/src/core/com/jme3/asset
diff options
context:
space:
mode:
authorScott Barta <sbarta@google.com>2012-03-01 12:35:35 -0800
committerScott Barta <sbarta@google.com>2012-03-01 12:40:08 -0800
commit59b2e6871c65f58fdad78cd7229c292f6a177578 (patch)
tree2d4e7bfc05b93f40b34675d77e403dd1c25efafd /engine/src/core/com/jme3/asset
parentf9b30489e75ac1eabc365064959804e99534f7ab (diff)
downloadjmonkeyengine-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')
-rw-r--r--engine/src/core/com/jme3/asset/Asset.java73
-rw-r--r--engine/src/core/com/jme3/asset/AssetCache.java131
-rw-r--r--engine/src/core/com/jme3/asset/AssetConfig.java138
-rw-r--r--engine/src/core/com/jme3/asset/AssetEventListener.java77
-rw-r--r--engine/src/core/com/jme3/asset/AssetInfo.java77
-rw-r--r--engine/src/core/com/jme3/asset/AssetKey.java203
-rw-r--r--engine/src/core/com/jme3/asset/AssetLoadException.java17
-rw-r--r--engine/src/core/com/jme3/asset/AssetLoader.java54
-rw-r--r--engine/src/core/com/jme3/asset/AssetLocator.java60
-rw-r--r--engine/src/core/com/jme3/asset/AssetManager.java265
-rw-r--r--engine/src/core/com/jme3/asset/AssetNotFoundException.java17
-rw-r--r--engine/src/core/com/jme3/asset/Desktop.cfg22
-rw-r--r--engine/src/core/com/jme3/asset/DesktopAssetManager.java421
-rw-r--r--engine/src/core/com/jme3/asset/ImplHandler.java209
-rw-r--r--engine/src/core/com/jme3/asset/MaterialKey.java29
-rw-r--r--engine/src/core/com/jme3/asset/ModelKey.java61
-rw-r--r--engine/src/core/com/jme3/asset/TextureKey.java190
-rw-r--r--engine/src/core/com/jme3/asset/ThreadingManager.java103
-rw-r--r--engine/src/core/com/jme3/asset/package.html37
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>
+