PageRenderTime 30ms CodeModel.GetById 18ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/flight/utils/Registry.as

https://code.google.com/
ActionScript | 171 lines | 78 code | 19 blank | 74 comment | 28 complexity | 5e779f7a768628298241b9cbe4394380 MD5 | raw file
  1////////////////////////////////////////////////////////////////////////////////
  2//
  3// Copyright (c) 2009 Tyler Wright, Robert Taylor, Jacob Wright
  4// 
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to deal
  7// in the Software without restriction, including without limitation the rights
  8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9// copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11// 
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14// 
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 21// THE SOFTWARE.
 22//
 23////////////////////////////////////////////////////////////////////////////////
 24
 25package flight.utils
 26{
 27	import flash.utils.Dictionary; 
 28	
 29	/**
 30	 * The Registry is a global store for system-wide values and objects.
 31	 * Because Registry represents a static class it provides a single point of
 32	 * access everywhere. 
 33	 */
 34	public class Registry
 35	{
 36		// where system-wide values are stored by scope and index
 37		private static var scopeIndex:Dictionary = new Dictionary(true);
 38		private static var globalIndex:Dictionary = scopeIndex[null] = new Dictionary(true);
 39		private static var watcherByTarget:Dictionary = new Dictionary(true);
 40		private static var watcherByIndex:Dictionary = new Dictionary(true);
 41		
 42		/**
 43		 * Register data with some global identifier for system-wide lookup.
 44		 * 
 45		 * @param	index			String or object identifier with which to
 46		 * 							register and lookup data.
 47		 * @param	value			Data to be registered.
 48		 * @param	scope			Optionally register data to a specific scope
 49		 * 							identifier, creating a localized scope
 50		 * 							within the global space.
 51		 * 
 52		 * @see		#lookup
 53		 */
 54		public static function register(index:Object, value:Object, scope:Object = null):void
 55		{
 56			if (scopeIndex[scope] == null) {
 57				scopeIndex[scope] = new Dictionary(true);
 58			}
 59			
 60			scopeIndex[scope][index] = value;
 61			
 62			// update any "watching" for this particular 'index', on any scope
 63			for each (var syncDetail:Array in watcherByIndex[index]) {
 64				syncDetail[0][ syncDetail[1] ] = lookup(index, syncDetail[3]);
 65			}
 66		}
 67		
 68		/**
 69		 * Remove any data registered at the specified index and scope.
 70		 * 
 71		 * @param	index			String or object identifier with which to
 72		 * 							locate and remove data.
 73		 * @param	scope			Optionally remove data by a specific scope
 74		 * 							identifier, a localized scope within the
 75		 * 							global space.
 76		 * 
 77		 * @see		#register
 78		 */
 79		public static function unregister(index:Object, scope:Object = null):void
 80		{
 81			if (scopeIndex[scope] == null) {
 82				scopeIndex[scope] = new Dictionary(true);
 83			}
 84			
 85			delete scopeIndex[scope][index];
 86		}
 87		
 88		/**
 89		 * Retrieve data registered at the specified index and scope.
 90		 * 
 91		 * @param	index			String or object identifier with which to
 92		 * 							lookup registered data.
 93		 * @param	scope			Optionally lookup data by a specific scope
 94		 * 							identifier, a localized scope within the
 95		 * 							global space.
 96		 * 
 97		 * @return					Registered data.
 98		 * 
 99		 * @see		#register
100		 */
101		public static function lookup(index:Object, scope:Object = null):*
102		{
103			if (scope == null) {
104				return scopeIndex[scope][index];
105			}
106			
107			while (scope != null) {
108				
109				if (scopeIndex[scope] != null && index in scopeIndex[scope]) {
110					return scopeIndex[scope][index];
111				}
112				
113				if ("owner" in scope && scope["owner"] != null) {
114					scope = scope["owner"];
115				} else if ("parent" in scope) {
116					if (scope["parent"] is Function) {
117						scope = scope["parent"]();
118					} else {
119						scope = scope["parent"];
120					}
121				} else {
122					return;
123				}
124			}
125			
126		}
127		
128		/**
129		 * @private
130		 * Possible deprecation.
131		 */
132		public static function sync(target:Object, prop:String, index:Object, scope:Object = null):void
133		{
134			desync(target, prop);
135			var syncDetail:Array = arguments;
136			
137			if (watcherByIndex[index] == null) {
138				watcherByIndex[index] = [];
139			}
140			watcherByIndex[index].push(syncDetail);
141			
142			if (watcherByTarget[target] == null) {
143				watcherByTarget[target] = {};
144			}
145			watcherByTarget[target][prop] = syncDetail;
146			
147			target[prop] = lookup(index, scope);
148		}
149		
150		/**
151		 * @private
152		 * Possible deprecation.
153		 */
154		public static function desync(target:Object, prop:String):void
155		{
156			var byTarget:Object = watcherByTarget[target];
157			if (byTarget == null) {
158				return;
159			}
160			
161			var syncDetail:Array = byTarget[prop];
162			if (syncDetail == null) {
163				return;
164			}
165			
166			var byIndex:Array = watcherByIndex[ syncDetail[2] ];
167			byIndex.splice(byIndex.indexOf(syncDetail), 1);
168			delete watcherByTarget[target][prop];
169		}
170	}
171}