1 /** 2 * The Render Engine 3 * AbstractResourceLoader 4 * 5 * @fileoverview The base class for all resource loaders. It has the functionality 6 * for managing a local cache of loaded objects. 7 * 8 * @author: Brett Fattori (brettf@renderengine.com) 9 * @author: $Author: bfattori $ 10 * @version: $Revision: 1555 $ 11 * 12 * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com) 13 * 14 * Permission is hereby granted, free of charge, to any person obtaining a copy 15 * of this software and associated documentation files (the "Software"), to deal 16 * in the Software without restriction, including without limitation the rights 17 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 * copies of the Software, and to permit persons to whom the Software is 19 * furnished to do so, subject to the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be included in 22 * all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 * THE SOFTWARE. 31 * 32 */ 33 34 // The class this file defines and its required classes 35 R.Engine.define({ 36 "class":"R.resources.loaders.AbstractResourceLoader", 37 "requires":[ 38 "R.engine.BaseObject" 39 ] 40 }); 41 42 /** 43 * @class A resource loader is a generalized interface used by all resource 44 * loaders. It is designed to provide a common set of routines for 45 * loading resources (fonts, images, game data, etc...) from some 46 * location. Additionally, objects are cached by this base class, 47 * although some classes make use of other methods to enhance the 48 * caching, such as the {@link R.resources.loaders.ImageLoader} class. 49 * 50 * @param [name=ResourceLoader] {String} The name of the resource loader. 51 * @constructor 52 * @extends R.engine.BaseObject 53 * @description Create a resource loader 54 */ 55 R.resources.loaders.AbstractResourceLoader = function () { 56 return R.engine.BaseObject.extend(/** @scope R.resources.loaders.AbstractResourceLoader.prototype */{ 57 58 cache:null, 59 length:0, 60 loadTimeout:null, 61 62 /** @private */ 63 constructor:function (name) { 64 this.base(name || "ResourceLoader"); 65 this.cache = {}; 66 this.loadTimeout = null; 67 }, 68 69 /** 70 * Releases the resource loader back into the pool 71 */ 72 release:function () { 73 this.base(); 74 this.cache = null; 75 this.length = 0; 76 }, 77 78 /** 79 * Destroy the resource loader and all cached resources. 80 */ 81 destroy:function () { 82 this.clear(); 83 this.base(); 84 }, 85 86 /** 87 * Load an object via this resource loader, and add it to the cache. When 88 * all resources being loaded by this resource loader are ready, fires the 89 * <code>isready</code> event. 90 * 91 * @param name {String} The name to refer to the loaded object 92 * @param data {Object} The data to store in the cache 93 * @param isReady {Boolean} A flag that states whether or not a resource 94 * is ready to use. 95 */ 96 load:function (name, data, isReady) { 97 var obj = { data:data, ready:isReady || false}; 98 this.cache[name] = obj; 99 this.length++; 100 R.debug.Console.log("Loading " + this.getResourceType() + ": " + name); 101 102 // The event trigger when all resources are loaded and ready 103 var self = this; 104 if (!this.loadTimeout) { 105 this.loadTimeout = R.lang.Timeout.create("LoadTimeout", 100, function () { 106 if (self.isReady()) { 107 this.destroy(); 108 self.fireReadyEvent(); 109 } else { 110 this.restart(); 111 } 112 }); 113 } 114 return obj.data; 115 }, 116 117 /** 118 * Set the "ready" state of the resource. When a resource has been completely 119 * loaded, set the resource "ready" state to <tt>true</tt> to allow objects 120 * waiting for those resources to utilize them. Fires the <code>resourceready</code> 121 * event, with the name of the resource, when the resource is ready to use. 122 * 123 * @param name {String} The name of the resource 124 * @param isReady {Boolean} <tt>true</tt> to set the resource to "ready for use" 125 */ 126 setReady:function (name, isReady) { 127 this.cache[name].ready = isReady; 128 if (isReady) { 129 this.triggerEvent("resourceready", [name]); 130 R.debug.Console.log(this.getResourceType() + " " + name + " ready..."); 131 } 132 }, 133 134 /** 135 * Check to see if a named resource is, or all resources are, "ready for use". 136 * @param name {String} The name of the resource to check ready status for, 137 * or <tt>null</tt> for all resources in loader. 138 * @return {Boolean} <tt>true</tt> if the resource is loaded and ready to use 139 */ 140 isReady:function (name) { 141 if (name) { 142 return this.cache[name] ? this.cache[name].ready : false; 143 } else { 144 // Check the status of all loader elements 145 var rList = this.getResources(); 146 if (rList.length == 0) { 147 // Early out, no resources to load 148 return true; 149 } 150 for (var r in rList) { 151 if (!this.isReady(rList[r])) { 152 return false; 153 } 154 } 155 return true; 156 } 157 }, 158 159 /** 160 * Fires an event when all of the resources being loaded by this loader are 161 * ready for use. 162 * @private 163 */ 164 fireReadyEvent:function () { 165 this.triggerEvent("isready"); 166 this.loadTimeout = null; 167 }, 168 169 /** 170 * Unload an object from this resource loader. Removes the object 171 * from the cache. 172 * 173 * @param name {String} The name of the object to remove 174 */ 175 unload:function (name) { 176 if (this.cache[name].data.destroy) { 177 // Make sure that cached objects have a chance to clean up 178 this.cache[name].data.destroy(); 179 } 180 181 this.cache[name] = null; 182 delete this.cache[name]; 183 this.length--; 184 }, 185 186 /** 187 * Get the object with the specified name from the cache. 188 * 189 * @param name {String} The name of the object to retrieve 190 * @return {Object} The object stored within the cache 191 */ 192 get:function (name) { 193 if (this.cache[name]) { 194 return this.cache[name].data; 195 } else { 196 return null; 197 } 198 }, 199 200 /** 201 * Get the specific resource supported by the resource loader. 202 * @param name {String} The name of the resource 203 * @return {Object} 204 */ 205 getResourceObject:function (name) { 206 return this.get(name); 207 }, 208 209 /** 210 * Set the data associated with the name. The ready state is set 211 * to <tt>false</tt>, so it will be up to the developer to call 212 * {@link #setReady} on the object if the object is truly ready for use. 213 * @param name {String} The name of the cache record 214 * @param data {Object} Data to store 215 */ 216 set:function (name, data) { 217 var obj = { data:data, ready:false}; 218 this.cache[name] = obj; 219 }, 220 221 /** 222 * Returns the cache. You should not manipulate the cache directly. 223 * instead, call methods to update the cache. 224 * @return {Object} The cache 225 */ 226 getCachedObjects:function () { 227 return this.cache; 228 }, 229 230 /** 231 * Clear the objects contained in the cache. 232 */ 233 clear:function () { 234 for (var o in this.cache) { 235 this.cache[o] = null; 236 } 237 238 this.cache = {}; 239 this.length = 0; 240 }, 241 242 /** 243 * Get the names of all the resources available in this resource loader. 244 * @return {Array} An array of resource names 245 */ 246 getResources:function () { 247 var n = []; 248 for (var i in this.cache) { 249 n.push(i); 250 } 251 return n; 252 }, 253 254 /** 255 * Export all of the resources in this loader, as a JavaScript object, with the 256 * resource name as the key and the corresponding object as the value. 257 * @param [resourceNames] {Array} An optional array of resources to export, by name, 258 * or <code>null</tt> to export all resources 259 */ 260 exportAll:function (resourceNames) { 261 var o = {}; 262 var resources = this.getResources(); 263 for (var i in resources) { 264 if (!resourceNames || R.engine.Support.indexOf(resourceNames, resources[i]) != -1) { 265 o[resources[i]] = this.getResourceObject(resources[i]); 266 } 267 } 268 return o; 269 }, 270 271 /** 272 * The name of the resource this loader will get. 273 * @return {String} The string "default" 274 */ 275 getResourceType:function () { 276 return "default"; 277 } 278 }, /** @scope R.resources.loaders.AbstractResourceLoader.prototype */{ 279 280 /** 281 * Get the class name of this object 282 * @return {String} "R.resources.loaders.AbstractResourceLoader" 283 */ 284 getClassName:function () { 285 return "R.resources.loaders.AbstractResourceLoader"; 286 } 287 288 }); 289 290 }