Prevent automatic RTree recaching

Calling UpdateItem() may be performed by in a common loop, e.g. for(
SCH_ITEM* item : GetScreen()->Items() ) or similar.  We cannot call
GetScreen()->Update( SCH_ITEM* ) in this routine as it will remove and
re-add the item to the RTree, invalidating iterators.  If needed, the
items need to be cached to an external container before updating

Fixes https://gitlab.com/kicad/code/kicad/issues/9318
This commit is contained in:
Seth Hillbrand
2021-10-05 20:13:15 -07:00
parent 9a8d1246cc
commit 854472d550
14 changed files with 28 additions and 23 deletions
+7 -2
View File
@@ -299,7 +299,7 @@ void SCH_BASE_FRAME::createCanvas()
}
void SCH_BASE_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete )
void SCH_BASE_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aUpdateRtree )
{
EDA_ITEM* parent = aItem->GetParent();
@@ -321,7 +321,12 @@ void SCH_BASE_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete )
GetCanvas()->GetView()->Update( parent, KIGFX::REPAINT );
}
GetScreen()->Update( static_cast<SCH_ITEM*>( aItem ) );
/**
* Be careful when calling this. Update will invalidate RTree iterators, so you cannot call this
* while doing things like `for( SCH_ITEM* item : screen->Items() )`
*/
if( aUpdateRtree)
GetScreen()->Update( static_cast<SCH_ITEM*>( aItem ) );
// Calling Refresh() here introduces a bi-stable state: when doing operations on a
// large number of items if at some point the refresh timer times out and does a