From f9cbb6f984e278bd11ec6b0b869ad1bd11628d47 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 15 Sep 2008 20:14:46 +0000 Subject: [PATCH] sort MouseWatcherGroup regions. Maybe fix for scroll bar getting stuck. --- panda/src/tform/mouseWatcher.cxx | 5 ++ panda/src/tform/mouseWatcherGroup.cxx | 81 ++++++++++++++++++++++----- panda/src/tform/mouseWatcherGroup.h | 5 ++ 3 files changed, 77 insertions(+), 14 deletions(-) diff --git a/panda/src/tform/mouseWatcher.cxx b/panda/src/tform/mouseWatcher.cxx index 6b21bd4ffb..301a6148bb 100644 --- a/panda/src/tform/mouseWatcher.cxx +++ b/panda/src/tform/mouseWatcher.cxx @@ -199,6 +199,8 @@ remove_group(MouseWatcherGroup *group) { MutexHolder holder(_lock); MutexHolder holder2(group->_lock); + group->do_sort_regions(); + Regions only_a, only_b, both; intersect_regions(only_a, only_b, both, _current_regions, group->_regions); @@ -258,6 +260,9 @@ replace_group(MouseWatcherGroup *old_group, MouseWatcherGroup *new_group) { MutexHolder holder2(old_group->_lock); MutexHolder holder3(new_group->_lock); + old_group->do_sort_regions(); + new_group->do_sort_regions(); + #ifndef NDEBUG if (!_show_regions_render2d.is_empty()) { old_group->do_hide_regions(); diff --git a/panda/src/tform/mouseWatcherGroup.cxx b/panda/src/tform/mouseWatcherGroup.cxx index ec67862fb8..baae78b872 100644 --- a/panda/src/tform/mouseWatcherGroup.cxx +++ b/panda/src/tform/mouseWatcherGroup.cxx @@ -28,6 +28,7 @@ MouseWatcherGroup:: MouseWatcherGroup() : _lock("MouseWatcherGroup") { + _sorted = true; #ifndef NDEBUG _show_regions = false; _color.set(0.4f, 0.6f, 1.0f, 1.0f); @@ -59,12 +60,14 @@ add_region(MouseWatcherRegion *region) { // We will only bother to check for duplicates in the region list if // we are building a development Panda. The overhead for doing this // may be too high if we have many regions. -#ifndef NDEBUG +#ifdef _DEBUG // See if the region is in the set/vector already Regions::const_iterator ri = find(_regions.begin(), _regions.end(), pt); nassertv(ri == _regions.end()); +#endif // _DEBUG +#ifndef NDEBUG // Also add it to the vizzes if we have them. if (_show_regions) { nassertv(_vizzes.size() == _regions.size()); @@ -73,6 +76,7 @@ add_region(MouseWatcherRegion *region) { #endif // NDEBUG _regions.push_back(pt); + _sorted = false; } //////////////////////////////////////////////////////////////////// @@ -85,16 +89,17 @@ bool MouseWatcherGroup:: has_region(MouseWatcherRegion *region) const { MutexHolder holder(_lock); - // See if the region is in the vector. - PT(MouseWatcherRegion) pt = region; - Regions::const_iterator ri = - find(_regions.begin(), _regions.end(), pt); - if (ri != _regions.end()) { - // Found it - return true; + PT(MouseWatcherRegion) ptr = region; + + if (_sorted) { + // If the vector is already sorted, we can do this the quick way. + Regions::const_iterator ri = lower_bound(_regions.begin(), _regions.end(), ptr); + return (ri != _regions.end() && (*ri) == ptr); } - // Did not find the region - return false; + + // If the vector isn't sorted, do a linear scan. + Regions::const_iterator ri = find(_regions.begin(), _regions.end(), ptr); + return (ri != _regions.end()); } //////////////////////////////////////////////////////////////////// @@ -142,6 +147,7 @@ clear_regions() { MutexHolder holder(_lock); _regions.clear(); + _sorted = true; #ifndef NDEBUG if (_show_regions) { @@ -151,6 +157,31 @@ clear_regions() { #endif // NDEBUG } +//////////////////////////////////////////////////////////////////// +// Function: MouseWatcherGroup::sort_regions +// Access: Published +// Description: Sorts all the regions in this group into pointer +// order. +//////////////////////////////////////////////////////////////////// +void MouseWatcherGroup:: +sort_regions() { + MutexHolder holder(_lock); + do_sort_regions(); +} + +//////////////////////////////////////////////////////////////////// +// Function: MouseWatcherGroup::is_sorted +// Access: Published +// Description: Returns true if the group has already been sorted, +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool MouseWatcherGroup:: +is_sorted() const { + MutexHolder holder(_lock); + + return _sorted; +} + //////////////////////////////////////////////////////////////////// // Function: MouseWatcherGroup::get_num_regions // Access: Published @@ -268,6 +299,20 @@ update_regions() { #endif // NDEBUG +//////////////////////////////////////////////////////////////////// +// Function: MouseWatcherGroup::do_sort_regions +// Access: Protected +// Description: Sorts all the regions in this group into pointer +// order. Assumes the lock is already held. +//////////////////////////////////////////////////////////////////// +void MouseWatcherGroup:: +do_sort_regions() { + if (!_sorted) { + sort(_regions.begin(), _regions.end()); + _sorted = true; + } +} + //////////////////////////////////////////////////////////////////// // Function: MouseWatcherGroup::do_remove_region // Access: Protected @@ -277,10 +322,18 @@ update_regions() { bool MouseWatcherGroup:: do_remove_region(MouseWatcherRegion *region) { // See if the region is in the vector. - PT(MouseWatcherRegion) pt = region; - Regions::iterator ri = - find(_regions.begin(), _regions.end(), pt); - if (ri != _regions.end()) { + PT(MouseWatcherRegion) ptr = region; + Regions::iterator ri; + + if (_sorted) { + // Faster, binary search + ri = lower_bound(_regions.begin(), _regions.end(), ptr); + } else { + // Unsorted, so use slower linear scan + ri = find(_regions.begin(), _regions.end(), ptr); + } + + if (ri != _regions.end() && (*ri) == ptr) { // Found it, now erase it #ifndef NDEBUG // Also remove it from the vizzes. diff --git a/panda/src/tform/mouseWatcherGroup.h b/panda/src/tform/mouseWatcherGroup.h index 0d3553e2b2..dbeb7297a6 100644 --- a/panda/src/tform/mouseWatcherGroup.h +++ b/panda/src/tform/mouseWatcherGroup.h @@ -41,6 +41,9 @@ PUBLISHED: MouseWatcherRegion *find_region(const string &name) const; void clear_regions(); + void sort_regions(); + bool is_sorted() const; + int get_num_regions() const; MouseWatcherRegion *get_region(int n) const; @@ -57,6 +60,7 @@ PUBLISHED: #endif // NDEBUG protected: + void do_sort_regions(); bool do_remove_region(MouseWatcherRegion *region); #ifndef NDEBUG @@ -69,6 +73,7 @@ protected: protected: typedef pvector< PT(MouseWatcherRegion) > Regions; Regions _regions; + bool _sorted; // This mutex protects the above list of regions, as well as the // below list of vizzes. It is also referenced directly by