/** * Copyright (c) 2003-2009, Xith3D Project Group all rights reserved. * * Portions based on the Java3D interface, Copyright by Sun Microsystems. * Many thanks to the developers of Java3D and Sun Microsystems for their * innovation and design. * * 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 the 'Xith3D Project Group' 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) A * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE */ package org.xith3d.resources; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; /** * The ResourceLoader loads requested resources and can update a progress. * * @author Marvin Froehlich (aka Qudus) */ public class ResourceLoader { private static class RequestsSorter implements Comparator<ResourceRequest> { public static final RequestsSorter INSTANCE = new RequestsSorter(); public int compare( ResourceRequest o1, ResourceRequest o2 ) { return ( o1.getClass().getSimpleName().compareTo( o2.getClass().getSimpleName() ) ); } public void sort( ArrayList<ResourceRequest> requests ) { Collections.sort( requests, this ); } } private ResourceLocator resLoc; private final ArrayList<ResourceRequest> requests = new ArrayList<ResourceRequest>(); private final ArrayList<ResourceLoaderListener> listeners = new ArrayList<ResourceLoaderListener>(); /** * Sets the ResourceLocator to be used for resource location. * * @param resLoc */ public void setResourceLocator( ResourceLocator resLoc ) { this.resLoc = resLoc; } /** * @return the ResourceLocator to be used for resource location */ public ResourceLocator getResourceLocator() { return ( resLoc ); } public void addResourceLoaderListener( ResourceLoaderListener l ) { listeners.add( l ); } public void removeResourceLoaderListener( ResourceLoaderListener l ) { listeners.remove( l ); } /** * Adds a ResourceRequest to the queue. * * @param resReq */ public void addRequest( ResourceRequest resReq ) { requests.add( resReq ); } /** * @return the number of ResourceRequests queued in this ResourceLoader */ public final int numRequests() { return ( requests.size() ); } /** * Loads one Resource and adds it to the ResourceBag. * * @throws Throwable */ protected boolean loadResource( ResourceRequest resReq, ResourceBag resBag ) { boolean success = true; for ( int i = 0; i < listeners.size(); i++ ) { listeners.get( i ).beforeResourceLoaded( this, resReq ); } Object resource = null; try { resource = resReq.loadResource( resLoc, resBag ); } catch ( Throwable t ) { success = false; t.printStackTrace(); } for ( int i = 0; i < listeners.size(); i++ ) { listeners.get( i ).afterResourceLoaded( this, resReq, resource ); } return ( success ); } /** * Loads all queued resources and puts them into a new ResourceBag. * * @param lsu the LoadingScreenUpdater to notify of progress update * * @return the filled ResourceBag */ public ResourceBag loadResources( LoadingScreenUpdater lsu ) { if ( lsu instanceof ResourceLoaderListener ) { this.addResourceLoaderListener( (ResourceLoaderListener)lsu ); } for ( int i = 0; i < listeners.size(); i++ ) { listeners.get( i ).beforeAnyResourceLoaded( this ); } ResourceBag resBag = new ResourceBag(); if ( lsu != null ) { lsu.init( -numRequests(), null, (String)null ); } if ( !requests.isEmpty() ) { RequestsSorter.INSTANCE.sort( requests ); Class<? extends ResourceRequest> lastRequestType = null; for ( int i = 0; i < requests.size(); i++ ) { if ( requests.get( i ).getClass() != lastRequestType ) { for ( int j = 0; j < listeners.size(); j++ ) { listeners.get( j ).beforeResourceBundleLoaded( this, requests.get( i ).getClass() ); } lastRequestType = requests.get( i ).getClass(); } if ( lsu != null ) lsu.updateOnly( "Loading Texture resource \"" + requests.get( i ).getBagName() + "\"" ); loadResource( requests.get( i ), resBag ); if ( lsu != null ) lsu.update(); if ( ( requests.size() > i + 1 ) && ( requests.get( i + 1 ).getClass() != lastRequestType ) ) { for ( int j = 0; j < listeners.size(); j++ ) { listeners.get( j ).afterResourceBundleLoaded( this, requests.get( i + 1 ).getClass() ); } } } } if ( lsu != null ) lsu.updateOnly( "ready" ); for ( int i = 0; i < listeners.size(); i++ ) { listeners.get( i ).afterAllResourceLoaded( this ); } if ( lsu instanceof ResourceLoaderListener ) { this.removeResourceLoaderListener( (ResourceLoaderListener)lsu ); } return ( resBag ); } /** * Loads all queued resources and puts them into a new ResourceBag. * * @return the filled ResourceBag */ public ResourceBag loadResources() { return ( loadResources( null ) ); } public ResourceLoader( ResourceLocator resLoc ) { this.resLoc = resLoc; } public ResourceLoader() { this( ResourceLocator.getInstance() ); } }