Mercurial > projects > dynamin
diff 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 |
line wrap: on
line diff
--- a/dynamin/core/list.d Sat Aug 08 15:31:24 2009 -0500 +++ b/dynamin/core/list.d Sat Aug 08 15:42:27 2009 -0500 @@ -37,28 +37,37 @@ // TODO: QuickSort() // TODO: HeapSort() // TODO: Sort() - calls HeapSort() so stable sort is default -// TODO: when D has template inheritance, have separate const_List and List -class List(T) { +class List(T, bool hasDelegates = false) { protected: T[] _data; uint _count; - void delegate() whenChanged; // TODO: have an index and length... + static if(hasDelegates) { + void delegate(T, int) whenAdded; + void delegate(T, int) whenRemoved; + } public: this() { - this(16, {}); + this(16); } this(uint capacity) { - this(capacity, {}); - } - this(void delegate() whenChanged) { - this(16, whenChanged); + _data = new T[capacity]; } - this(uint capacity, void delegate() whenChanged) { - _data = new T[capacity]; - this.whenChanged = whenChanged; + static if(hasDelegates) { + /// whenAdded or whenRemoved is called right after an item is added + /// or removed + this(void delegate(T, int) whenAdded, + void delegate(T, int) whenRemoved) { + this(16, whenAdded, whenRemoved); + } + this(uint capacity, void delegate(T, int) whenAdded, + void delegate(T, int) whenRemoved) { + this(capacity); + this.whenAdded = whenAdded; + this.whenRemoved = whenRemoved; + } } - static List fromArray(T[] arr...) { - List list = new List!(T)(); + static List!(T) fromArray(T[] arr...) { + auto list = new List!(T)(); list._data = arr.dup; list._count = arr.length; return list; @@ -105,43 +114,46 @@ static if(is(T == class) || is(T == interface)) _data[_count-1] = cast(T)null; --_count; - whenChanged(); + static if(hasDelegates) + whenRemoved(item, _count); return item; } void add(T item) { - insert(_count, item); + insert(item, _count); } // TODO: AddRange? void remove(T item) { uint i = find(item); if(i == -1) return; - removeRange(i); - } - void removeRange(uint index, uint length = 1) { - arrayCopy!(T)(_data, index+length, _data, index, _count - (index+length)); + + for(++i; i < _count; ++i) + _data[i-1] = _data[i]; // must null out to allow to be collected static if(is(T == class) || is(T == interface)) - for(uint i = _count-length; i < _count; ++i) - _data[i] = cast(T)null; - _count -= length; - whenChanged(); + _data[_count-1] = cast(T)null; + --_count; + + static if(hasDelegates) + whenRemoved(item, i); } - void insert(uint index, T item) { + void insert(T item, uint index) { maybeEnlarge(_count+1); arrayCopy!(T)(_data, index, _data, index+1, _count - index); _data[index] = item; ++_count; - whenChanged(); + static if(hasDelegates) + whenAdded(item, index); } // TODO: InsertRange? void clear() { - // must null out to allow to be collected - static if(is(T == class) || is(T == interface)) - for(uint i = 0; i < count; ++i) - data[i] = cast(T)null; - _count = 0; - whenChanged(); + for(; _count > 0; --_count) { + static if(hasDelegates) + whenRemoved(_data[_count-1], _count-1); + // must null out to allow to be collected + static if(is(T == class) || is(T == interface)) + data[_count-1] = cast(T)null; + } } uint find(T item) { foreach(i, item2; _data) @@ -179,12 +191,28 @@ list.add('t'); assert(list.data == "Hello, Matt"); assert(list.pop() == 't'); - list.removeRange(1, 7); - assert(list.data == "Hat"); + assert(list.data == "Hello, Mat"); + list.insert('!', 5); + assert(list.data == "Hello!, Mat"); + list.remove('l'); + assert(list.data == "Helo!, Mat"); list.clear(); assert(list.data == ""); - auto list2 = new List!(string); + + int a = 0, r = 0; + void added(string, int) { a++; }; + void removed(string, int) { r++; }; + auto list2 = new List!(string, true)(&added, &removed); + assert(a == 0 && r == 0); list2.add("hello"); + assert(a == 1 && r == 0); assert(list2.pop() == "hello"); + assert(a == 1 && r == 1); + + list2.add("Hi"); + list2.add("Jacob!"); + assert(a == 3 && r == 1); + list2.clear(); + assert(a == 3 && r == 3); }