Make AIList resilient against invalidating iterators.
This adds a counter and a 'dead' flag to the data stored in the linked list. The counter counts the number of iterators (still) pointing to an element and the dead flag is set to indicate the element was erased when iterators are still pointing to it. As a result, iterators are NEVER invalidated. Of course, such elements are subsequentially skipped when iterating over the list. Assertions protect against dereferencing an erased iterator, but incrementing or decremention still works: it is still well-defined what the next (non erased) element is, assuming the element wasn't erased (yet), but would be erased delayed - or assuming the iterator would have been incremented (decremented) in advance to erasing the element.
This commit is contained in:
@@ -74,9 +74,10 @@ filterResult_t LLCtrlFilter::operator() (const LLView* const view, const viewLis
|
||||
viewList_t LLViewQuery::run(LLView* view) const
|
||||
{
|
||||
viewList_t result;
|
||||
viewList_t const child_list(view->getChildList()->begin(), view->getChildList()->end());
|
||||
|
||||
// prefilter gets immediate children of view
|
||||
filterResult_t pre = runFilters(view, view->getChildList()->get_std_list(), mPreFilters);
|
||||
filterResult_t pre = runFilters(view, child_list, mPreFilters);
|
||||
if(!pre.first && !pre.second)
|
||||
{
|
||||
// not including ourselves or the children
|
||||
@@ -113,14 +114,14 @@ viewList_t LLViewQuery::run(LLView* view) const
|
||||
|
||||
void LLViewQuery::filterChildren(LLView * view, viewList_t & filtered_children) const
|
||||
{
|
||||
viewList_t views(view->getChildList()->get_std_list());
|
||||
viewList_t views(view->getChildList()->begin(), view->getChildList()->end());
|
||||
if (mSorterp)
|
||||
{
|
||||
(*mSorterp)(view, views); // sort the children per the sorter
|
||||
}
|
||||
for(viewList_t::iterator iter = views.begin();
|
||||
iter != views.end();
|
||||
iter++)
|
||||
++iter)
|
||||
{
|
||||
viewList_t indiv_children = this->run(*iter);
|
||||
filtered_children.splice(filtered_children.end(), indiv_children);
|
||||
@@ -132,7 +133,7 @@ filterResult_t LLViewQuery::runFilters(LLView* view, viewList_t const& children,
|
||||
filterResult_t result = filterResult_t(TRUE, TRUE);
|
||||
for(filterList_const_iter_t iter = filters.begin();
|
||||
iter != filters.end();
|
||||
iter++)
|
||||
++iter)
|
||||
{
|
||||
filterResult_t filtered = (**iter)(view, children);
|
||||
result.first = result.first && filtered.first;
|
||||
|
||||
Reference in New Issue
Block a user