159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.asset;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.AssetCache.SmartAssetInfo;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.audio.AudioData;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.audio.AudioKey;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.font.BitmapFont;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.material.Material;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Spatial;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.shader.Shader;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.shader.ShaderKey;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Texture;
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.InputStream;
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.net.URL;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList;
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Arrays;
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Collections;
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.List;
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Level;
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>AssetManager</code> is the primary method for managing and loading
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * assets inside jME.
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Kirill Vainer
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class DesktopAssetManager implements AssetManager {
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final Logger logger = Logger.getLogger(AssetManager.class.getName());
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final AssetCache cache = new AssetCache();
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final ImplHandler handler = new ImplHandler(this);
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private AssetEventListener eventListener = null;
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private List<ClassLoader> classLoaders;
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//    private final ThreadingManager threadingMan = new ThreadingManager(this);
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//    private final Set<AssetKey> alreadyLoadingSet = new HashSet<AssetKey>();
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public DesktopAssetManager(){
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this(null);
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Deprecated
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public DesktopAssetManager(boolean loadDefaults){
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Desktop.cfg"));
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public DesktopAssetManager(URL configFile){
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (configFile != null){
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            InputStream stream = null;
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            try{
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                AssetConfig cfg = new AssetConfig(this);
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                stream = configFile.openStream();
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                cfg.loadText(stream);
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }catch (IOException ex){
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.SEVERE, "Failed to load asset config", ex);
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }finally{
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (stream != null)
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    try{
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        stream.close();
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }catch (IOException ex){
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.info("DesktopAssetManager created.");
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addClassLoader(ClassLoader loader){
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if(classLoaders == null)
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            classLoaders = Collections.synchronizedList(new ArrayList<ClassLoader>());
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        synchronized(classLoaders) {
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            classLoaders.add(loader);
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void removeClassLoader(ClassLoader loader){
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if(classLoaders != null) synchronized(classLoaders) {
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                classLoaders.remove(loader);
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public List<ClassLoader> getClassLoaders(){
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return classLoaders;
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setAssetEventListener(AssetEventListener listener){
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        eventListener = listener;
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void registerLoader(Class<? extends AssetLoader> loader, String ... extensions){
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        handler.addLoader(loader, extensions);
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (logger.isLoggable(Level.FINER)){
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.FINER, "Registered loader: {0} for extensions {1}",
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta              new Object[]{loader.getSimpleName(), Arrays.toString(extensions)});
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void registerLoader(String clsName, String ... extensions){
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Class<? extends AssetLoader> clazz = null;
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        try{
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clazz = (Class<? extends AssetLoader>) Class.forName(clsName);
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }catch (ClassNotFoundException ex){
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }catch (NoClassDefFoundError ex){
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (clazz != null){
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            registerLoader(clazz, extensions);
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void registerLocator(String rootPath, Class<? extends AssetLocator> locatorClass){
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        handler.addLocator(locatorClass, rootPath);
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (logger.isLoggable(Level.FINER)){
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.FINER, "Registered locator: {0}",
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    locatorClass.getSimpleName());
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void registerLocator(String rootPath, String clsName){
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Class<? extends AssetLocator> clazz = null;
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        try{
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clazz = (Class<? extends AssetLocator>) Class.forName(clsName);
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }catch (ClassNotFoundException ex){
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.WARNING, "Failed to find locator: "+clsName, ex);
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }catch (NoClassDefFoundError ex){
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (clazz != null){
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            registerLocator(rootPath, clazz);
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void unregisterLocator(String rootPath, Class<? extends AssetLocator> clazz){
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        handler.removeLocator(clazz, rootPath);
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (logger.isLoggable(Level.FINER)){
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.FINER, "Unregistered locator: {0}",
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    clazz.getSimpleName());
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void clearCache(){
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cache.deleteAllAssets();
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Delete an asset from the cache, returns true if it was deleted
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * successfully.
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <br/><br/>
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <font color="red">Thread-safe.</font>
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean deleteFromCache(AssetKey key){
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return cache.deleteFromCache(key);
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Adds a resource to the cache.
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <br/><br/>
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <font color="red">Thread-safe.</font>
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addToCache(AssetKey key, Object asset){
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cache.addToCache(key, asset);
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AssetInfo locateAsset(AssetKey<?> key){
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (handler.getLocatorCount() == 0){
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("There are no locators currently"+
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                           " registered. Use AssetManager."+
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                           "registerLocator() to register a"+
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                           " locator.");
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return null;
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        AssetInfo info = handler.tryLocate(key);
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (info == null){
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.WARNING, "Cannot locate resource: {0}", key);
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return info;
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <font color="red">Thread-safe.</font>
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param <T>
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param key
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta      public <T> T loadAsset(AssetKey<T> key){
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (key == null)
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("key cannot be null");
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (eventListener != null)
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            eventListener.assetRequested(key);
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        AssetKey smartKey = null;
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Object o = null;
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (key.shouldCache()){
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (key.useSmartCache()){
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                SmartAssetInfo smartInfo = cache.getFromSmartCache(key);
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (smartInfo != null){
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    smartKey = smartInfo.smartKey.get();
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (smartKey != null){
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        o = smartInfo.asset;
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                o = cache.getFromCache(key);
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (o == null){
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            AssetLoader loader = handler.aquireLoader(key);
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (loader == null){
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalStateException("No loader registered for type \"" +
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                key.getExtension() + "\"");
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (handler.getLocatorCount() == 0){
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalStateException("There are no locators currently"+
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                " registered. Use AssetManager."+
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                "registerLocator() to register a"+
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                                " locator.");
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            AssetInfo info = handler.tryLocate(key);
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (info == null){
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (handler.getParentKey() != null && eventListener != null){
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    // Inform event listener that an asset has failed to load.
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    // If the parent AssetLoader chooses not to propagate
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    // the exception, this is the only means of finding
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    // that something went wrong.
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    eventListener.assetDependencyNotFound(handler.getParentKey(), key);
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new AssetNotFoundException(key.toString());
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            try {
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                handler.establishParentKey(key);
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                o = loader.load(info);
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } catch (IOException ex) {
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new AssetLoadException("An exception has occured while loading asset: " + key, ex);
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } finally {
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                handler.releaseParentKey(key);
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (o == null){
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new AssetLoadException("Error occured while loading asset \"" + key + "\" using" + loader.getClass().getSimpleName());
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (logger.isLoggable(Level.FINER)){
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.FINER, "Loaded {0} with {1}",
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            new Object[]{key, loader.getClass().getSimpleName()});
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // do processing on asset before caching
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                o = key.postProcess(o);
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (key.shouldCache())
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    cache.addToCache(key, o);
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (eventListener != null)
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    eventListener.assetLoaded(key);
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // object o is the asset
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // create an instance for user
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        T clone = (T) key.createClonedInstance(o);
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (key.useSmartCache()){
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (smartKey != null){
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // smart asset was already cached, use original key
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ((Asset)clone).setKey(smartKey);
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }else{
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // smart asset was cached on this call, use our key
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                ((Asset)clone).setKey(key);
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return clone;
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Object loadAsset(String name){
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return loadAsset(new AssetKey(name));
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Loads a texture.
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Texture loadTexture(TextureKey key){
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (Texture) loadAsset(key);
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Material loadMaterial(String name){
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (Material) loadAsset(new MaterialKey(name));
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Loads a texture.
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param generateMipmaps Enable if applying texture to 3D objects, disable
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * for GUI/HUD elements.
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Texture loadTexture(String name, boolean generateMipmaps){
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TextureKey key = new TextureKey(name, true);
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        key.setGenerateMips(generateMipmaps);
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        key.setAsCube(false);
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return loadTexture(key);
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Texture loadTexture(String name, boolean generateMipmaps, boolean flipY, boolean asCube, int aniso){
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TextureKey key = new TextureKey(name, flipY);
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        key.setGenerateMips(generateMipmaps);
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        key.setAsCube(asCube);
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        key.setAnisotropy(aniso);
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return loadTexture(key);
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Texture loadTexture(String name){
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return loadTexture(name, true);
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioData loadAudio(AudioKey key){
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (AudioData) loadAsset(key);
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioData loadAudio(String name){
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return loadAudio(new AudioKey(name, false));
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Loads a bitmap font with the given name.
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public BitmapFont loadFont(String name){
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (BitmapFont) loadAsset(new AssetKey(name));
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public InputStream loadGLSLLibrary(AssetKey key){
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (InputStream) loadAsset(key);
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Load a vertex/fragment shader combo.
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param key
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Shader loadShader(ShaderKey key){
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // cache abuse in method
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // that doesn't use loaders/locators
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Shader s = (Shader) cache.getFromCache(key);
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (s == null){
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            String vertName = key.getVertName();
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            String fragName = key.getFragName();
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            String vertSource = (String) loadAsset(new AssetKey(vertName));
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            String fragSource = (String) loadAsset(new AssetKey(fragName));
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            s = new Shader(key.getLanguage());
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            s.addSource(Shader.ShaderType.Vertex,   vertName, vertSource, key.getDefines().getCompiled());
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            s.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled());
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            cache.addToCache(key, s);
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return s;
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Spatial loadModel(ModelKey key){
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (Spatial) loadAsset(key);
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Load a model.
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Spatial loadModel(String name){
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return loadModel(new ModelKey(name));
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
422