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
}
}
|