1 /** 2 * The Render Engine 3 * HashContainer 4 * 5 * @fileoverview A set of objects which can be used to create a collection 6 * of objects, and to iterate over a container. 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.struct.HashContainer", 37 "requires":[ 38 "R.struct.Container" 39 ] 40 }); 41 42 /** 43 * @class A hash container is a logical collection of objects. A hash container 44 * is a container with a backing object for faster lookups. Objects within 45 * the container must have unique names. When the container is destroyed, none of the 46 * objects within the container are destroyed with it. Call {@link #cleanUp} to 47 * destroy all of the objects in the container. 48 * 49 * @param containerName {String} The name of the container. Default: Container 50 * @extends R.struct.Container 51 * @constructor 52 * @description Create a hashed container object. 53 */ 54 R.struct.HashContainer = function () { 55 return R.struct.Container.extend(/** @scope R.struct.HashContainer.prototype */{ 56 57 objHash:null, 58 59 /** 60 * @private 61 */ 62 constructor:function (containerName) { 63 this.base(containerName || "HashContainer"); 64 this.objHash = {}; 65 }, 66 67 /** 68 * Release the object back into the object pool. 69 */ 70 release:function () { 71 this.base(); 72 this.objHash = null; 73 }, 74 75 /** 76 * Returns <tt>true</tt> if the object name is already in 77 * the hash. 78 * 79 * @param name {String} The name of the hash to check 80 * @return {Boolean} 81 */ 82 isInHash:function (key) { 83 key = (key.charAt(0) === "_" ? key : "_" + String(key)); 84 return (this.objHash[key] != null); 85 }, 86 87 /** 88 * Add an object to the container. 89 * 90 * @param key {String} The name of the object to store. Names must be unique 91 * or the object with that name will be overwritten. 92 * @param obj {BaseObject} The object to add to the container. 93 */ 94 add:function (key, obj) { 95 AssertWarn(!this.isInHash(key), "Object already exists within hash!"); 96 97 if (this.isInHash(key)) { 98 // Remove the old one first 99 this.removeHash(key); 100 } 101 102 // Some keys weren't being accepted (like "MOVE") so added 103 // an underscore to prevent keyword collisions 104 this.objHash["_" + String(key)] = obj; 105 this.base(obj); 106 return this.objHash["_" + String(key)]; 107 }, 108 109 /** @private */ 110 addAll:function () { 111 R._unsupported("addAll()", this); 112 }, 113 114 /** @private */ 115 clone:function () { 116 R._unsupported("clone()", this); 117 }, 118 119 /** @private */ 120 concat:function () { 121 R._unsupported("concat()", this); 122 }, 123 124 /** @private */ 125 reduce:function () { 126 R._unsupported("reduce()", this); 127 }, 128 129 /** 130 * Remove an object from the container. The object is 131 * not destroyed when it is removed from the container. 132 * 133 * @param obj {BaseObject} The object to remove from the container. 134 * @return {Object} The object removed from the container 135 */ 136 remove:function (obj) { 137 for (var o in this.objHash) { 138 if (this.objHash[o] === obj) { 139 // removeHash() takes care of removing the actual object, so we don't 140 // call the base class - otherwise we delete the wrong object 141 this.removeHash(o); 142 break; 143 } 144 } 145 return obj; 146 }, 147 148 /** 149 * Remove the object with the given key name from the container. 150 * 151 * @param name {String} The object to remove 152 * @return {Object} The object removed 153 */ 154 removeHash:function (key) { 155 key = (key.charAt(0) === "_" ? key : "_" + String(key)); 156 var obj = this.objHash[key]; 157 R.engine.Support.arrayRemove(this.objects, obj); 158 delete this.objHash[key]; 159 return obj; 160 }, 161 162 /** 163 * Remove an object from the container at the specified index. 164 * The object is not destroyed when it is removed. 165 * 166 * @param idx {Number} An index between zero and the size of the container minus 1. 167 * @return {Object} The object removed from the container. 168 */ 169 removeAtIndex:function (idx) { 170 var obj = this.base(idx); 171 for (var o in this.objHash) { 172 if (this.objHash[o] === obj) { 173 this.removeHash(o); 174 break; 175 } 176 } 177 178 return obj; 179 }, 180 181 /** 182 * If a number is provided, the request will be passed to the 183 * base object, otherwise a name is assumed and the hash will 184 * be retrieved. 185 * 186 * @param idx {Number|String} The index or hash of the object to get 187 * @return {Object} 188 */ 189 get:function (idx) { 190 if (idx.substr && idx.toLowerCase) { 191 return this.objHash["_" + idx]; 192 } else { 193 return this.base(idx); 194 } 195 }, 196 197 /** 198 * Remove all objects from the container. None of the objects are 199 * destroyed. 200 */ 201 clear:function () { 202 this.base(); 203 this.objHash = {}; 204 }, 205 206 /** 207 * Cleans up the references to the objects (destroys them) within 208 * the container. 209 */ 210 cleanUp:function () { 211 this.base(); 212 } 213 214 }, /** @scope R.struct.HashContainer.prototype */ { 215 /** 216 * Get the class name of this object 217 * 218 * @return {String} "R.struct.HashContainer" 219 */ 220 getClassName:function () { 221 return "R.struct.HashContainer"; 222 } 223 224 }); 225 226 };