2 * Copyright (c) 2009-2010 jMonkeyEngine
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without
\r
6 * modification, are permitted provided that the following conditions are
\r
9 * * Redistributions of source code must retain the above copyright
\r
10 * notice, this list of conditions and the following disclaimer.
\r
12 * * Redistributions in binary form must reproduce the above copyright
\r
13 * notice, this list of conditions and the following disclaimer in the
\r
14 * documentation and/or other materials provided with the distribution.
\r
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
\r
17 * may be used to endorse or promote products derived from this software
\r
18 * without specific prior written permission.
\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
\r
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
\r
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
\r
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\r
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
\r
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
\r
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
33 package com.jme3.asset;
\r
35 import com.jme3.asset.AssetCache.SmartAssetInfo;
\r
36 import com.jme3.audio.AudioKey;
\r
37 import com.jme3.audio.AudioData;
\r
38 import com.jme3.font.BitmapFont;
\r
39 import com.jme3.material.Material;
\r
40 import com.jme3.scene.Spatial;
\r
41 import com.jme3.shader.Shader;
\r
42 import com.jme3.shader.ShaderKey;
\r
43 import com.jme3.texture.Texture;
\r
44 import java.io.IOException;
\r
45 import java.io.InputStream;
\r
46 import java.net.URL;
\r
47 import java.util.Arrays;
\r
48 import java.util.logging.Level;
\r
49 import java.util.logging.Logger;
\r
52 * <code>AssetManager</code> is the primary method for managing and loading
\r
53 * assets inside jME.
\r
55 * @author Kirill Vainer
\r
57 public class DesktopAssetManager implements AssetManager {
\r
59 private static final Logger logger = Logger.getLogger(AssetManager.class.getName());
\r
61 private final AssetCache cache = new AssetCache();
\r
62 private final ImplHandler handler = new ImplHandler(this);
\r
64 private AssetEventListener eventListener = null;
\r
66 // private final ThreadingManager threadingMan = new ThreadingManager(this);
\r
67 // private final Set<AssetKey> alreadyLoadingSet = new HashSet<AssetKey>();
\r
69 public DesktopAssetManager(){
\r
74 public DesktopAssetManager(boolean loadDefaults){
\r
75 this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Desktop.cfg"));
\r
78 public DesktopAssetManager(URL configFile){
\r
79 if (configFile != null){
\r
80 InputStream stream = null;
\r
82 AssetConfig cfg = new AssetConfig(this);
\r
83 stream = configFile.openStream();
\r
84 cfg.loadText(stream);
\r
85 }catch (IOException ex){
\r
86 logger.log(Level.SEVERE, "Failed to load asset config", ex);
\r
91 }catch (IOException ex){
\r
95 logger.info("DesktopAssetManager created.");
\r
98 public void setAssetEventListener(AssetEventListener listener){
\r
99 eventListener = listener;
\r
102 public void registerLoader(Class<? extends AssetLoader> loader, String ... extensions){
\r
103 handler.addLoader(loader, extensions);
\r
104 if (logger.isLoggable(Level.FINER)){
\r
105 logger.log(Level.FINER, "Registered loader: {0} for extensions {1}",
\r
106 new Object[]{loader.getSimpleName(), Arrays.toString(extensions)});
\r
110 public void registerLoader(String clsName, String ... extensions){
\r
111 Class<? extends AssetLoader> clazz = null;
\r
113 clazz = (Class<? extends AssetLoader>) Class.forName(clsName);
\r
114 }catch (ClassNotFoundException ex){
\r
115 logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
\r
116 }catch (NoClassDefFoundError ex){
\r
117 logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
\r
119 if (clazz != null){
\r
120 registerLoader(clazz, extensions);
\r
124 public void registerLocator(String rootPath, Class<? extends AssetLocator> locatorClass){
\r
125 handler.addLocator(locatorClass, rootPath);
\r
126 if (logger.isLoggable(Level.FINER)){
\r
127 logger.log(Level.FINER, "Registered locator: {0}",
\r
128 locatorClass.getSimpleName());
\r
132 public void registerLocator(String rootPath, String clsName){
\r
133 Class<? extends AssetLocator> clazz = null;
\r
135 clazz = (Class<? extends AssetLocator>) Class.forName(clsName);
\r
136 }catch (ClassNotFoundException ex){
\r
137 logger.log(Level.WARNING, "Failed to find locator: "+clsName, ex);
\r
138 }catch (NoClassDefFoundError ex){
\r
139 logger.log(Level.WARNING, "Failed to find loader: "+clsName, ex);
\r
141 if (clazz != null){
\r
142 registerLocator(rootPath, clazz);
\r
146 public void unregisterLocator(String rootPath, Class<? extends AssetLocator> clazz){
\r
147 handler.removeLocator(clazz, rootPath);
\r
148 if (logger.isLoggable(Level.FINER)){
\r
149 logger.log(Level.FINER, "Unregistered locator: {0}",
\r
150 clazz.getSimpleName());
\r
154 public void clearCache(){
\r
155 cache.deleteAllAssets();
\r
159 * Delete an asset from the cache, returns true if it was deleted
\r
162 * <font color="red">Thread-safe.</font>
\r
164 public boolean deleteFromCache(AssetKey key){
\r
165 return cache.deleteFromCache(key);
\r
169 * Adds a resource to the cache.
\r
171 * <font color="red">Thread-safe.</font>
\r
173 public void addToCache(AssetKey key, Object asset){
\r
174 cache.addToCache(key, asset);
\r
177 public AssetInfo locateAsset(AssetKey<?> key){
\r
178 if (handler.getLocatorCount() == 0){
\r
179 logger.warning("There are no locators currently"+
\r
180 " registered. Use AssetManager."+
\r
181 "registerLocator() to register a"+
\r
186 AssetInfo info = handler.tryLocate(key);
\r
188 logger.log(Level.WARNING, "Cannot locate resource: {0}", key);
\r
195 * <font color="red">Thread-safe.</font>
\r
201 public <T> T loadAsset(AssetKey<T> key){
\r
203 throw new IllegalArgumentException("key cannot be null");
\r
205 if (eventListener != null)
\r
206 eventListener.assetRequested(key);
\r
208 AssetKey smartKey = null;
\r
210 if (key.shouldCache()){
\r
211 if (key.useSmartCache()){
\r
212 SmartAssetInfo smartInfo = cache.getFromSmartCache(key);
\r
213 if (smartInfo != null){
\r
214 smartKey = smartInfo.smartKey.get();
\r
215 if (smartKey != null){
\r
216 o = smartInfo.asset;
\r
220 o = cache.getFromCache(key);
\r
224 AssetLoader loader = handler.aquireLoader(key);
\r
225 if (loader == null){
\r
226 throw new IllegalStateException("No loader registered for type \"" +
\r
227 key.getExtension() + "\"");
\r
230 if (handler.getLocatorCount() == 0){
\r
231 throw new IllegalStateException("There are no locators currently"+
\r
232 " registered. Use AssetManager."+
\r
233 "registerLocator() to register a"+
\r
237 AssetInfo info = handler.tryLocate(key);
\r
239 throw new AssetNotFoundException(key.toString());
\r
243 o = loader.load(info);
\r
244 } catch (IOException ex) {
\r
245 throw new AssetLoadException("An exception has occured while loading asset: " + key, ex);
\r
248 throw new AssetLoadException("Error occured while loading asset \"" + key + "\" using" + loader.getClass().getSimpleName());
\r
250 if (logger.isLoggable(Level.FINER)){
\r
251 logger.log(Level.FINER, "Loaded {0} with {1}",
\r
252 new Object[]{key, loader.getClass().getSimpleName()});
\r
255 // do processing on asset before caching
\r
256 o = key.postProcess(o);
\r
258 if (key.shouldCache())
\r
259 cache.addToCache(key, o);
\r
261 if (eventListener != null)
\r
262 eventListener.assetLoaded(key);
\r
266 // object o is the asset
\r
267 // create an instance for user
\r
268 T clone = (T) key.createClonedInstance(o);
\r
270 if (key.useSmartCache()){
\r
271 if (smartKey != null){
\r
272 // smart asset was already cached, use original key
\r
273 ((Asset)clone).setKey(smartKey);
\r
275 // smart asset was cached on this call, use our key
\r
276 ((Asset)clone).setKey(key);
\r
283 public Object loadAsset(String name){
\r
284 return loadAsset(new AssetKey(name));
\r
292 public Texture loadTexture(TextureKey key){
\r
293 return (Texture) loadAsset(key);
\r
296 public Material loadMaterial(String name){
\r
297 return (Material) loadAsset(new MaterialKey(name));
\r
304 * @param generateMipmaps Enable if applying texture to 3D objects, disable
\r
305 * for GUI/HUD elements.
\r
308 public Texture loadTexture(String name, boolean generateMipmaps){
\r
309 TextureKey key = new TextureKey(name, true);
\r
310 key.setGenerateMips(generateMipmaps);
\r
311 key.setAsCube(false);
\r
312 return loadTexture(key);
\r
315 public Texture loadTexture(String name, boolean generateMipmaps, boolean flipY, boolean asCube, int aniso){
\r
316 TextureKey key = new TextureKey(name, flipY);
\r
317 key.setGenerateMips(generateMipmaps);
\r
318 key.setAsCube(asCube);
\r
319 key.setAnisotropy(aniso);
\r
320 return loadTexture(key);
\r
323 public Texture loadTexture(String name){
\r
324 return loadTexture(name, true);
\r
327 public AudioData loadAudio(AudioKey key){
\r
328 return (AudioData) loadAsset(key);
\r
331 public AudioData loadAudio(String name){
\r
332 return loadAudio(new AudioKey(name, false));
\r
336 * Loads a bitmap font with the given name.
\r
341 public BitmapFont loadFont(String name){
\r
342 return (BitmapFont) loadAsset(new AssetKey(name));
\r
345 public InputStream loadGLSLLibrary(AssetKey key){
\r
346 return (InputStream) loadAsset(key);
\r
350 * Load a vertex/fragment shader combo.
\r
355 public Shader loadShader(ShaderKey key){
\r
356 // cache abuse in method
\r
357 // that doesn't use loaders/locators
\r
358 Shader s = (Shader) cache.getFromCache(key);
\r
360 String vertName = key.getVertName();
\r
361 String fragName = key.getFragName();
\r
363 String vertSource = (String) loadAsset(new AssetKey(vertName));
\r
364 String fragSource = (String) loadAsset(new AssetKey(fragName));
\r
366 s = new Shader(key.getLanguage());
\r
367 s.addSource(Shader.ShaderType.Vertex, vertName, vertSource, key.getDefines().getCompiled());
\r
368 s.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled());
\r
370 cache.addToCache(key, s);
\r
375 public Spatial loadModel(ModelKey key){
\r
376 return (Spatial) loadAsset(key);
\r
385 public Spatial loadModel(String name){
\r
386 return loadModel(new ModelKey(name));
\r