~eda-qa/dhlib/main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* <license>
 * This file is part of the dis-Emi-A HaXe Library. Copyright © edA-qa mort-ora-y
 * For full copyright and license information please refer to doc/license.txt.
 * </license> 
 */
#if flash9
import flash.utils.Dictionary;
#elseif neko
#elseif js
#else 
#error	//other targets not tested, though they might work with the default implementation
#end

/**
 * Implements an Object based mapping system.
 *
 * @see Hash -- shares the same functions but the keys are objects now
 * NOTE: has no toString function since the contain objects may not
 * have useful representations.
 *
 * NOTE for Neko/JS: In neko this works by adding an additional field to the hashed object.
 * This shouldn't change the use of most objects, but you must be aware of
 * this if you intend to add an array, or enumerable type, to the ObjectHash.
 * NOTE For Flash9: This implemented using the native Dictionary object since static
 * types cannot have arbitrary values created on them.  It is unfortunate that Flash9
 * doesn't have this ability, since if it did, I wouldn't likely need the ObjectHash at
 * all!
 *
 * NOTE on null: As with arrays and many other structures, the storage of nulls
 * is not really allowed.  They are generally the same as not existing, but in this
 * class the behaviour is undefined (and not allowed).
 */
class ObjectHash<T>
{
#if flash9
	var back : Dictionary;
#else
	var back : IntHash<T>;
	var keyMap : IntHash<Dynamic>;
	static var keyCount : Int = 1;
	
	//use a unique field name in case other people use the same technique
	define(`KEYFIELD',__uuid8476e280dcb411dc95ff0800200c9a66)
	inline function objKey( key : Dynamic ) : Int
	{
		if( key.KEYFIELD == null )
			key.KEYFIELD = keyCount++;
		return key.KEYFIELD;
	}
#end

	public function new() : Void 
	{
#if flash9
		back = new Dictionary( false );
#else
		back = new IntHash<T>();
		keyMap = new IntHash<Dynamic>();
#end
	}
	
	inline public function set( key : Dynamic, value : T ) : Void 
	{
		ASSERT_NOTNULL( value );
		ASSERT_NOTNULL( key );
#if flash9
		untyped back[key] = value;
#else
		back.set( objKey( key ), value );
		keyMap.set( objKey( key ), key );
#end
	}
	
	inline public function get( key : Dynamic ) : Null<T> 
	{	
		ASSERT_NOTNULL( key );
#if flash9
		return untyped back[key];
#else
		return back.get( objKey( key ) ); 
#end
	}
	
	inline public function exists( key : Dynamic ) : Bool 
	{
		ASSERT_NOTNULL( key );
#if flash9
		return untyped back[key] != null;
#else
		return back.exists( objKey( key ) );
#end
	}
		
	inline public function remove( key : Dynamic ) : Bool		
	{
		ASSERT_NOTNULL( key );
#if flash9
		if( untyped back[key] == null )
			return false;
		else
		{
			untyped __delete__(back,key);
			return true;
		}
#else
		keyMap.remove( objKey( key ) );
		return back.remove( objKey( key ) );
#end
	}
	
	public function keys() : Iterator<Dynamic>	
	{
#if flash9	
		return untyped (__keys__(back)).iterator();
#else
		return keyMap.iterator();
#end
	}
	
	public function iterator() : Iterator<T>
	{
#if flash9
		var me = this;
		return untyped 
		{
			keyIter : me.keys(),
			hasNext : function() 
				{ 
					return this.keyIter.hasNext(); 
				},
			next : function() 
				{ 
					var key = untyped this.keyIter.next(); 
					return me.get( key ); 
				}
		};
#else
		return back.iterator();
#end
	}
}