linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #05849
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2996: change the virtual tree list to a hashed container
------------------------------------------------------------
revno: 2996
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2012-07-13 20:01:50 +0200
message:
change the virtual tree list to a hashed container
modified:
dwt/include/dwt/widgets/VirtualTree.h
dwt/src/widgets/VirtualTree.cpp
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dwt/include/dwt/widgets/VirtualTree.h'
--- dwt/include/dwt/widgets/VirtualTree.h 2012-07-12 21:32:03 +0000
+++ dwt/include/dwt/widgets/VirtualTree.h 2012-07-13 18:01:50 +0000
@@ -32,7 +32,7 @@
#ifndef DWT_VIRTUALTREE_H
#define DWT_VIRTUALTREE_H
-#include <list>
+#include <unordered_set>
#include <boost/optional.hpp>
@@ -90,6 +90,8 @@
Item(TVINSERTSTRUCT& tvis);
HTREEITEM ptr() const;
+ struct Hash { size_t operator()(const Item& item) const; };
+ struct Equal { bool operator()(const Item& a, const Item& b) const; };
void insertBefore(Item* sibling);
void insertAfter(Item* sibling);
@@ -101,7 +103,7 @@
Item* nextVisible() const;
};
- std::list<Item> items;
+ std::unordered_set<Item, Item::Hash, Item::Equal> items;
Item* root;
Item* selected;
=== modified file 'dwt/src/widgets/VirtualTree.cpp'
--- dwt/src/widgets/VirtualTree.cpp 2012-07-12 21:32:03 +0000
+++ dwt/src/widgets/VirtualTree.cpp 2012-07-13 18:01:50 +0000
@@ -174,6 +174,14 @@
return reinterpret_cast<HTREEITEM>(const_cast<Item*>(this));
}
+size_t VirtualTree::Item::Hash::operator()(const Item& item) const {
+ return reinterpret_cast<size_t>(&item) / sizeof(Item);
+}
+
+bool VirtualTree::Item::Equal::operator()(const Item& a, const Item& b) const {
+ return &a == &b;
+}
+
void VirtualTree::Item::insertBefore(Item* sibling) {
if(sibling) {
if(sibling->prev) {
@@ -364,8 +372,7 @@
if(tvis.hParent == TVI_ROOT || !tvis.hParent) {
tvis.hParent = root->ptr();
}
- items.emplace_back(tvis);
- auto& item = items.back();
+ auto& item = const_cast<Item&>(*items.emplace(tvis).first);
if(item.parent->firstChild == item.parent->lastChild) {
updateChildDisplay(item.parent);
}
@@ -401,29 +408,31 @@
}
void VirtualTree::addRoot() {
- items.emplace_back();
- root = &items.back();
+ root = const_cast<Item*>(&*items.emplace().first);
}
bool VirtualTree::validate(Item* item) const {
- return item;
- /* ideally one would check that the item does point to an element of the "items" list, but
- iterating through the list takes too long when it's a large one. */
+ return item && items.find(*item) != items.cend();
}
VirtualTree::Item* VirtualTree::find(HTREEITEM handle) {
if(!handle) { return nullptr; }
- for(auto& i: items) { if(i.handle == handle) { return &i; } }
+ for(auto& i: items) { if(i.handle == handle) { return const_cast<Item*>(&i); } }
return nullptr;
}
void VirtualTree::display(Item& item) {
+ // insert the item in the actual tree control.
if(item.handle) { return; }
+
if(item.parent != root && !item.parent->handle) { display(*item.parent); }
+
+ // don't insert items as expanded; instead expand them manually if they were expanded before.
+ auto expanded = item.expanded();
+ if(expanded) { item.state &= ~TVIS_EXPANDED; }
+
TVINSERTSTRUCT tvis = { item.parent->handle, item.prev ? item.prev->handle : item.next ? TVI_FIRST : TVI_LAST, { {
TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_STATE | TVIF_TEXT } } };
- auto expanded = item.expanded();
- if(expanded) { item.state &= ~TVIS_EXPANDED; }
tvis.itemex.state = item.state;
tvis.itemex.stateMask = item.state;
tvis.itemex.pszText = item.text ? const_cast<TCHAR*>(item.text->c_str()) : LPSTR_TEXTCALLBACK;
@@ -432,10 +441,12 @@
tvis.itemex.cChildren = item.firstChild ? 1 : 0;
tvis.itemex.lParam = item.lParam;
item.handle = reinterpret_cast<HTREEITEM>(sendTreeMsg(TVM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&tvis)));
+
if(expanded) { sendTreeMsg(TVM_EXPAND, TVE_EXPAND, reinterpret_cast<LPARAM>(item.handle)); }
}
void VirtualTree::hide(Item& item) {
+ // remove the item and its children from the actual tree control.
if(!item.handle) { return; }
auto child = item.firstChild;
while(child) {
@@ -464,12 +475,7 @@
if(item->prev) { item->prev->next = item->next; }
if(item->next) { item->next->prev = item->prev; }
if(item == selected) { selected = nullptr; }
- for(auto i = items.begin(), iend = items.end(); i != iend; ++i) {
- if(&*i == item) {
- items.erase(i);
- break;
- }
- }
+ items.erase(*item);
}
void VirtualTree::updateChildDisplay(Item* item) {