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