123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705 |
- #ifndef _listwrappers_h_
- #define _listwrappers_h_
- //////////////////////////////////////////////////////////////////////////////
- //
- // ListEventSource
- //
- //////////////////////////////////////////////////////////////////////////////
- class ListEventSource
- {
- TRef<EventSourceImpl> m_peventSource;
- public:
- ListEventSource()
- : m_peventSource(new EventSourceImpl()) {};
- ListEventSource(const ListEventSource& les)
- : m_peventSource(les.m_peventSource) {};
- void operator () ()
- { m_peventSource->Trigger(); };
- virtual IEventSource* GetEvent()
- {
- return m_peventSource;
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Slist_utlListWrapper
- //
- //////////////////////////////////////////////////////////////////////////////
- // these could be implemented much more efficently if it's useful to do so
- template <class T>
- class Slist_utlListWrapper : public List, public Slist_utl<T, ListEventSource> {
- public:
- typedef Slink_utl<T, ListEventSource> Link;
- virtual int GetCount()
- {
- // review: we could change this to O(1)
- int nCount = 0;
- // VSNet 2003 port: resolve error C2475
- #if _MSC_VER >= 1300
- for (Slink_utl<T, ListEventSource>* link = first(); link != NULL; link = (link->next)())
- #else
- for (Slink_utl<T, ListEventSource>* link = first(); link != NULL; link = link->next)
- #endif
- nCount++;
- return nCount;
- }
- virtual ItemID GetItem(int index)
- {
- return (*this)[index];
- }
- virtual int GetIndex(ItemID pitem)
- {
- int nIndex = 0;
- // VSNet 2003 port: resolve error C2475
- #if _MSC_VER >= 1300
- for (Link* link = first(); link != NULL; link = (link->next)())
- #else
- for (Link* link = first(); link != NULL; link = link->next)
- #endif
- {
- if ((ItemID)link == pitem)
- return nIndex;
- nIndex++;
- }
- return -1;
- }
- virtual ItemID GetNext(ItemID pitem)
- {
- return ((Link*)pitem)->next();
- }
- virtual IEventSource* GetChangedEvent()
- {
- return sink.GetEvent();
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // IntItemIDWrapper
- //
- //////////////////////////////////////////////////////////////////////////////
- // unfortunately, ID=0 corresponds to NULL, so we can't use the default casts
- // between ItemID and things like ShipID, since 0 is a valid ShipID
- template <class T>
- class IntItemIDWrapper
- {
- T m_t;
- enum { ZeroValue = ~(1 << (sizeof(T)*8 - 2)) };
- public:
- IntItemIDWrapper() {}
- IntItemIDWrapper(T t) : m_t(t) {}
- IntItemIDWrapper(ItemID pitem) { m_t = ((int)pitem == ZeroValue) ? 0 : (T)pitem; }
- operator = (T t) { m_t = t; }
- operator T () { return m_t; }
- operator ItemID () { return (ItemID)((m_t == 0) ? (T)ZeroValue : m_t); };
- bool operator == (IntItemIDWrapper<T> t) const { return m_t == t; }
- bool operator <= (IntItemIDWrapper<T> t) const { return m_t <= t; }
- bool operator >= (IntItemIDWrapper<T> t) const { return m_t >= t; }
- bool operator < (IntItemIDWrapper<T> t) const { return m_t < t; }
- bool operator > (IntItemIDWrapper<T> t) const { return m_t > t; }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // TListListWrapper
- //
- //////////////////////////////////////////////////////////////////////////////
- // these could be implemented much more efficently if it's useful to do so
- template <
- class T,
- class EqualsType = DefaultEquals,
- class CompareType = DefaultNoCompare
- >
- class TListListWrapper : public List, public TList<T, EqualsType, CompareType, ListEventSource> {
- public:
- TListListWrapper()
- {
- }
- TListListWrapper(EqualsType equals, CompareType compare)
- : TList<T, EqualsType, CompareType, ListEventSource>(equals, compare)
- {
- }
- virtual int GetCount()
- {
- return TList<T, EqualsType, CompareType, ListEventSource>::GetCount();
- }
- virtual ItemID GetItem(int index)
- {
- if (index < 0 || index >= GetCount())
- return NULL;
- else
- return (ItemID)((*this)[index]);
- }
- virtual int GetIndex(ItemID pitem)
- {
- // review: returning the key may be more efficient than returning the value.
- int nIndex = 0;
- for (Iterator iter(*this); !iter.End(); iter.Next())
- {
- if ((ItemID)iter.Value() == pitem)
- return nIndex;
- nIndex++;
- }
- return -1;
- }
- virtual ItemID GetNext(ItemID pitem)
- {
- for (Iterator iter(*this); !iter.End(); iter.Next())
- {
- if ((ItemID)iter.Value() == pitem)
- {
- iter.Next();
- if (iter.End())
- return NULL;
- else
- return (ItemID)iter.Value();
- }
- }
- return NULL;
- }
- virtual IEventSource* GetChangedEvent()
- {
- return GetSink().GetEvent();
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // TMapListWrapper
- //
- //////////////////////////////////////////////////////////////////////////////
- // these could be implemented much more efficently if it's useful to do so
- template <class T, class U>
- class TMapListWrapper : public List, public TMap<T, U, ListEventSource> {
- public:
- virtual int GetCount()
- {
- return Count();
- }
- virtual ItemID GetItem(int index)
- {
- Iterator iter(*this);
- for (int currentIndex = 0; !iter.End() && currentIndex < index; currentIndex++)
- {
- iter.Next();
- }
- if (iter.End())
- return NULL;
- else
- return (ItemID)iter.Value();
- }
- virtual int GetIndex(ItemID pitem)
- {
- // review: returning the key may be more efficient than returning the value.
- int nIndex = 0;
- for (Iterator iter(*this); !iter.End(); iter.Next())
- {
- if ((ItemID)iter.Value() == pitem)
- return nIndex;
- nIndex++;
- }
- return -1;
- }
- virtual ItemID GetNext(ItemID pitem)
- {
- for (Iterator iter(*this); !iter.End(); iter.Next())
- {
- if ((ItemID)iter.Value() == pitem)
- {
- iter.Next();
- if (iter.End())
- return NULL;
- else
- return (ItemID)iter.Value();
- }
- }
- return NULL;
- }
- virtual IEventSource* GetChangedEvent()
- {
- return GetSink().GetEvent();
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // FilteredList
- //
- ///////////////////////////////////////////////////////////////////////////////
- template <class Filter>
- class FilteredList : public List
- {
- TRef<List> m_list;
- Filter m_filter;
- public:
- FilteredList(List* list)
- : m_list(list) {};
- FilteredList(List* list, Filter filter)
- : m_list(list), m_filter(filter) {};
- void SetFilter(Filter filter)
- {
- m_filter = filter;
- }
- virtual int GetCount()
- {
- // this could be O(n) if we hooked the "changed" event
- int nCount = 0;
- ItemID currentItem = m_list->GetItem(0);
- while (currentItem != NULL)
- {
- if (m_filter(currentItem))
- nCount++;
- currentItem = m_list->GetNext(currentItem);
- }
- return nCount;
- }
- virtual ItemID GetItem(int index)
- {
- int nCurrentIndex = 0;
- ItemID currentItem = m_list->GetItem(0);
- while (currentItem != NULL)
- {
- if (m_filter(currentItem))
- {
- if (nCurrentIndex == index)
- break;
- else
- nCurrentIndex++;
- }
- currentItem = m_list->GetNext(currentItem);
- }
- return currentItem;
- }
- virtual int GetIndex(ItemID pitem)
- {
- // review: returning the key may be more efficient than returning the value.
- int nIndex = 0;
- ItemID currentItem = m_list->GetItem(0);
- while (currentItem != NULL)
- {
- if (m_filter(currentItem))
- {
- if (currentItem == pitem)
- return nIndex;
- else
- nIndex++;
- }
- currentItem = m_list->GetNext(currentItem);
- }
- return -1;
- }
- virtual ItemID GetNext(ItemID pitem)
- {
- ItemID currentItem = m_list->GetNext(pitem);
- while (currentItem != NULL)
- {
- if (m_filter(currentItem))
- {
- return currentItem;
- }
- currentItem = m_list->GetNext(currentItem);
- }
- return NULL;
- }
- virtual IEventSource* GetChangedEvent()
- {
- return m_list->GetChangedEvent();
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // ListDelegate
- //
- ///////////////////////////////////////////////////////////////////////////////
- class ListDelegate : public List
- {
- private:
- List* m_plist;
- TRef<IObject> m_pcontainer;
- public:
- ListDelegate(List* plist, IObject* pcontainer = NULL)
- : m_plist(plist), m_pcontainer(pcontainer) {}
- virtual int GetCount()
- {
- return m_plist->GetCount();
- }
- virtual ItemID GetItem(int index)
- {
- return m_plist->GetItem(index);
- }
- virtual int GetIndex(ItemID pitem)
- {
- return m_plist->GetIndex(pitem);
- }
- virtual ItemID GetNext(ItemID pitem)
- {
- return m_plist->GetNext(pitem);
- }
- virtual IEventSource* GetChangedEvent()
- {
- return m_plist->GetChangedEvent();
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // ConcatinatedList
- //
- ///////////////////////////////////////////////////////////////////////////////
- class ConcatinatedList : public List, public IEventSink
- {
- TRef<List> m_list1;
- TRef<List> m_list2;
- ListEventSource m_pfnChanged;
- TRef<IEventSink> m_sinkDelegate;
- public:
- ConcatinatedList(List* list1, List* list2)
- : m_list1(list1), m_list2(list2)
- {
- // add this to the changed notifications of the sublists
- m_sinkDelegate = IEventSink::CreateDelegate(this);
- m_list1->GetChangedEvent()->AddSink(m_sinkDelegate);
- m_list2->GetChangedEvent()->AddSink(m_sinkDelegate);
- };
- ~ConcatinatedList()
- {
- m_list1->GetChangedEvent()->RemoveSink(m_sinkDelegate);
- m_list2->GetChangedEvent()->RemoveSink(m_sinkDelegate);
- }
- virtual int GetCount()
- {
- return m_list1->GetCount() + m_list2->GetCount();
- }
- virtual ItemID GetItem(int index)
- {
- int nList1Count = m_list1->GetCount();
- if (index < nList1Count)
- return m_list1->GetItem(index);
- else
- return m_list2->GetItem(index - nList1Count);
- }
- virtual int GetIndex(ItemID pitem)
- {
- int index = m_list1->GetIndex(pitem);
- if (index == -1)
- {
- index = m_list2->GetIndex(pitem);
- if (index != -1)
- index += m_list1->GetCount();
- }
- return index;
- }
- virtual ItemID GetNext(ItemID pitem)
- {
- // case 1: pitem and pitem->next are in list1
- ItemID next = m_list1->GetNext(pitem);
- if (next == NULL)
- {
- // case 2: pitem and pitem->next are in list2
- next = m_list2->GetNext(pitem);
- if ((next == NULL) && (m_list1->GetIndex(pitem) != -1))
- {
- // case 3: pitem is in list1, pitem next is in list2
- next = m_list2->GetItem(0);
- }
- }
- return next;
- }
- virtual IEventSource* GetChangedEvent()
- {
- return m_pfnChanged.GetEvent();
- }
- virtual bool OnEvent(IEventSource* pevent)
- {
- m_pfnChanged();
- return true;
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // SortedList
- //
- ///////////////////////////////////////////////////////////////////////////////
- typedef bool (*ItemIDCompareFunction)(ItemID id1, ItemID id2);
- template <class CompareFunctionType>
- class SortedList : public List, public IEventSink
- {
- // a sorted list of the items in question
- typedef TList<ItemID, DefaultEquals, CompareFunctionType> SortedListType;
- SortedListType m_listSorted;
-
- TRef<List> m_list;
- bool m_fNeedsSort;
- ListEventSource m_pfnChanged;
- TRef<IEventSink> m_sinkDelegate;
- void CheckSorting()
- {
- if (m_fNeedsSort)
- {
- m_listSorted.SetEmpty();
- // use an insertion sort - O(n^2), but it's a stable sort
- ItemID pitem = m_list->GetItem(0);
- while (pitem) {
- m_listSorted.InsertSorted(pitem);
- pitem = m_list->GetNext(pitem);
- }
-
- m_fNeedsSort = false;
- }
- }
- public:
- SortedList(List* list, CompareFunctionType fnCompare)
- : m_list(list), m_listSorted(DefaultEquals(), fnCompare), m_fNeedsSort(true)
- {
- // add this to the changed notifications of the unsorted list
- m_sinkDelegate = IEventSink::CreateDelegate(this);
- m_list->GetChangedEvent()->AddSink(m_sinkDelegate);
- };
- ~SortedList()
- {
- m_list->GetChangedEvent()->RemoveSink(m_sinkDelegate);
- }
- virtual int GetCount()
- {
- return m_list->GetCount();
- }
- virtual ItemID GetItem(int index)
- {
- CheckSorting();
- SortedListType::Iterator iter(m_listSorted);
- for (int currentIndex = 0; !iter.End() && currentIndex < index; currentIndex++)
- {
- iter.Next();
- }
- if (iter.End())
- return NULL;
- else
- return (ItemID)iter.Value();
- }
- virtual int GetIndex(ItemID pitem)
- {
- CheckSorting();
- int nIndex = 0;
- for (SortedListType::Iterator iter(m_listSorted); !iter.End(); iter.Next())
- {
- if ((ItemID)iter.Value() == pitem)
- return nIndex;
- nIndex++;
- }
- return -1;
- }
- virtual ItemID GetNext(ItemID pitem)
- {
- CheckSorting();
- for (SortedListType::Iterator iter(m_listSorted); !iter.End(); iter.Next())
- {
- if ((ItemID)iter.Value() == pitem)
- {
- iter.Next();
- if (iter.End())
- return NULL;
- else
- return (ItemID)iter.Value();
- }
- }
- return NULL;
- }
- virtual IEventSource* GetChangedEvent()
- {
- return m_pfnChanged.GetEvent();
- }
- virtual bool OnEvent(IEventSource* pevent)
- {
- m_fNeedsSort = true;
- m_pfnChanged();
- return true;
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // SingletonList
- //
- ///////////////////////////////////////////////////////////////////////////////
- class SingletonList : public List
- {
- ListEventSource m_pfnChanged;
- ItemID m_itemID;
- public:
- SingletonList(ItemID itemID = NULL)
- : m_itemID(itemID)
- {
- }
- void SetItem(ItemID itemID)
- {
- m_itemID = itemID;
- m_pfnChanged();
- }
- //
- // List interface:
- //
- virtual int GetCount()
- {
- return 1;
- }
- virtual ItemID GetItem(int index)
- {
- if (index == 0)
- return m_itemID;
- else
- return NULL;
- }
- virtual int GetIndex(ItemID pitem)
- {
- if (pitem = m_itemID)
- return 0;
- else
- return -1;
- }
- virtual ItemID GetNext(ItemID pitem)
- {
- return NULL;
- }
- virtual IEventSource* GetChangedEvent()
- {
- return m_pfnChanged.GetEvent();
- }
- };
- #endif
|