Mercurial > projects > dynamin
comparison dynamin/core/list.d @ 55:c138461bf845
Add focusing and other changes that are related
like descendantAdded/Removed events, Window.activated event, and updating List.
Window.state was also added, even though focusing does not depend on it.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Sat, 08 Aug 2009 15:42:27 -0500 |
parents | aa4efef0f0b1 |
children | c2566ab82535 |
comparison
equal
deleted
inserted
replaced
54:3738a2d0bac3 | 55:c138461bf845 |
---|---|
35 // MUST use (high + low) >>> 1 to find the average | 35 // MUST use (high + low) >>> 1 to find the average |
36 // TODO: Search() | 36 // TODO: Search() |
37 // TODO: QuickSort() | 37 // TODO: QuickSort() |
38 // TODO: HeapSort() | 38 // TODO: HeapSort() |
39 // TODO: Sort() - calls HeapSort() so stable sort is default | 39 // TODO: Sort() - calls HeapSort() so stable sort is default |
40 // TODO: when D has template inheritance, have separate const_List and List | 40 class List(T, bool hasDelegates = false) { |
41 class List(T) { | |
42 protected: | 41 protected: |
43 T[] _data; | 42 T[] _data; |
44 uint _count; | 43 uint _count; |
45 void delegate() whenChanged; // TODO: have an index and length... | 44 static if(hasDelegates) { |
45 void delegate(T, int) whenAdded; | |
46 void delegate(T, int) whenRemoved; | |
47 } | |
46 public: | 48 public: |
47 this() { | 49 this() { |
48 this(16, {}); | 50 this(16); |
49 } | 51 } |
50 this(uint capacity) { | 52 this(uint capacity) { |
51 this(capacity, {}); | |
52 } | |
53 this(void delegate() whenChanged) { | |
54 this(16, whenChanged); | |
55 } | |
56 this(uint capacity, void delegate() whenChanged) { | |
57 _data = new T[capacity]; | 53 _data = new T[capacity]; |
58 this.whenChanged = whenChanged; | 54 } |
59 } | 55 static if(hasDelegates) { |
60 static List fromArray(T[] arr...) { | 56 /// whenAdded or whenRemoved is called right after an item is added |
61 List list = new List!(T)(); | 57 /// or removed |
58 this(void delegate(T, int) whenAdded, | |
59 void delegate(T, int) whenRemoved) { | |
60 this(16, whenAdded, whenRemoved); | |
61 } | |
62 this(uint capacity, void delegate(T, int) whenAdded, | |
63 void delegate(T, int) whenRemoved) { | |
64 this(capacity); | |
65 this.whenAdded = whenAdded; | |
66 this.whenRemoved = whenRemoved; | |
67 } | |
68 } | |
69 static List!(T) fromArray(T[] arr...) { | |
70 auto list = new List!(T)(); | |
62 list._data = arr.dup; | 71 list._data = arr.dup; |
63 list._count = arr.length; | 72 list._count = arr.length; |
64 return list; | 73 return list; |
65 } | 74 } |
66 uint count() { | 75 uint count() { |
103 T item = _data[_count-1]; | 112 T item = _data[_count-1]; |
104 // must null out to allow to be collected | 113 // must null out to allow to be collected |
105 static if(is(T == class) || is(T == interface)) | 114 static if(is(T == class) || is(T == interface)) |
106 _data[_count-1] = cast(T)null; | 115 _data[_count-1] = cast(T)null; |
107 --_count; | 116 --_count; |
108 whenChanged(); | 117 static if(hasDelegates) |
118 whenRemoved(item, _count); | |
109 return item; | 119 return item; |
110 } | 120 } |
111 void add(T item) { | 121 void add(T item) { |
112 insert(_count, item); | 122 insert(item, _count); |
113 } | 123 } |
114 // TODO: AddRange? | 124 // TODO: AddRange? |
115 void remove(T item) { | 125 void remove(T item) { |
116 uint i = find(item); | 126 uint i = find(item); |
117 if(i == -1) | 127 if(i == -1) |
118 return; | 128 return; |
119 removeRange(i); | 129 |
120 } | 130 for(++i; i < _count; ++i) |
121 void removeRange(uint index, uint length = 1) { | 131 _data[i-1] = _data[i]; |
122 arrayCopy!(T)(_data, index+length, _data, index, _count - (index+length)); | |
123 // must null out to allow to be collected | 132 // must null out to allow to be collected |
124 static if(is(T == class) || is(T == interface)) | 133 static if(is(T == class) || is(T == interface)) |
125 for(uint i = _count-length; i < _count; ++i) | 134 _data[_count-1] = cast(T)null; |
126 _data[i] = cast(T)null; | 135 --_count; |
127 _count -= length; | 136 |
128 whenChanged(); | 137 static if(hasDelegates) |
129 } | 138 whenRemoved(item, i); |
130 void insert(uint index, T item) { | 139 } |
140 void insert(T item, uint index) { | |
131 maybeEnlarge(_count+1); | 141 maybeEnlarge(_count+1); |
132 arrayCopy!(T)(_data, index, _data, index+1, _count - index); | 142 arrayCopy!(T)(_data, index, _data, index+1, _count - index); |
133 _data[index] = item; | 143 _data[index] = item; |
134 ++_count; | 144 ++_count; |
135 whenChanged(); | 145 static if(hasDelegates) |
146 whenAdded(item, index); | |
136 } | 147 } |
137 // TODO: InsertRange? | 148 // TODO: InsertRange? |
138 void clear() { | 149 void clear() { |
139 // must null out to allow to be collected | 150 for(; _count > 0; --_count) { |
140 static if(is(T == class) || is(T == interface)) | 151 static if(hasDelegates) |
141 for(uint i = 0; i < count; ++i) | 152 whenRemoved(_data[_count-1], _count-1); |
142 data[i] = cast(T)null; | 153 // must null out to allow to be collected |
143 _count = 0; | 154 static if(is(T == class) || is(T == interface)) |
144 whenChanged(); | 155 data[_count-1] = cast(T)null; |
156 } | |
145 } | 157 } |
146 uint find(T item) { | 158 uint find(T item) { |
147 foreach(i, item2; _data) | 159 foreach(i, item2; _data) |
148 if(item == item2) // if(item2 == item) would crash on a null item | 160 if(item == item2) // if(item2 == item) would crash on a null item |
149 return i; | 161 return i; |
177 unittest { | 189 unittest { |
178 auto list = List!(char).fromArray("Hello, Mat"); | 190 auto list = List!(char).fromArray("Hello, Mat"); |
179 list.add('t'); | 191 list.add('t'); |
180 assert(list.data == "Hello, Matt"); | 192 assert(list.data == "Hello, Matt"); |
181 assert(list.pop() == 't'); | 193 assert(list.pop() == 't'); |
182 list.removeRange(1, 7); | 194 assert(list.data == "Hello, Mat"); |
183 assert(list.data == "Hat"); | 195 list.insert('!', 5); |
196 assert(list.data == "Hello!, Mat"); | |
197 list.remove('l'); | |
198 assert(list.data == "Helo!, Mat"); | |
184 list.clear(); | 199 list.clear(); |
185 assert(list.data == ""); | 200 assert(list.data == ""); |
186 auto list2 = new List!(string); | 201 |
202 int a = 0, r = 0; | |
203 void added(string, int) { a++; }; | |
204 void removed(string, int) { r++; }; | |
205 auto list2 = new List!(string, true)(&added, &removed); | |
206 assert(a == 0 && r == 0); | |
187 list2.add("hello"); | 207 list2.add("hello"); |
208 assert(a == 1 && r == 0); | |
188 assert(list2.pop() == "hello"); | 209 assert(list2.pop() == "hello"); |
210 assert(a == 1 && r == 1); | |
211 | |
212 list2.add("Hi"); | |
213 list2.add("Jacob!"); | |
214 assert(a == 3 && r == 1); | |
215 list2.clear(); | |
216 assert(a == 3 && r == 3); | |
189 } | 217 } |
190 | 218 |