Clean up references in RN_NETs when garbage collecting CN_ITEMs.

This commit is contained in:
Jeff Young 2023-11-01 13:53:30 +00:00
parent d93bb464bf
commit fb59f83683
8 changed files with 60 additions and 20 deletions

View File

@ -213,6 +213,13 @@ bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem )
}
void CN_CONNECTIVITY_ALGO::RemoveInvalidRefs()
{
for( CN_ITEM* item : m_itemList )
item->RemoveInvalidRefs();
}
void CN_CONNECTIVITY_ALGO::searchConnections()
{
#ifdef PROFILE
@ -221,13 +228,12 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
std::vector<CN_ITEM*> garbage;
garbage.reserve( 1024 );
m_itemList.RemoveInvalidItems( garbage );
m_parentConnectivityData->RemoveInvalidRefs();
if( m_isLocal )
{
for( CN_ITEM* item : m_globalConnectivity->m_itemList )
item->RemoveInvalidRefs();
}
m_globalConnectivityData->RemoveInvalidRefs();
m_itemList.RemoveInvalidItems( garbage );
for( CN_ITEM* item : garbage )
delete item;
@ -559,11 +565,11 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
}
void CN_CONNECTIVITY_ALGO::LocalBuild( std::shared_ptr<CN_CONNECTIVITY_ALGO> aGlobalConnectivity,
void CN_CONNECTIVITY_ALGO::LocalBuild( std::shared_ptr<CONNECTIVITY_DATA> aGlobalConnectivity,
const std::vector<BOARD_ITEM*>& aLocalItems )
{
m_isLocal = true;
m_globalConnectivity = aGlobalConnectivity;
m_globalConnectivityData = aGlobalConnectivity;
for( BOARD_ITEM* item : aLocalItems )
{

View File

@ -92,6 +92,15 @@ public:
void SetSourceNode( const std::shared_ptr<const CN_ANCHOR>& aNode ) { m_source = aNode; }
void SetTargetNode( const std::shared_ptr<const CN_ANCHOR>& aNode ) { m_target = aNode; }
void RemoveInvalidRefs()
{
if( m_source && !m_source->Valid() )
m_source.reset();
if( m_target && !m_target->Valid() )
m_target.reset();
}
void SetWeight( unsigned weight ) { m_weight = weight; }
unsigned GetWeight() const { return m_weight; }
@ -158,7 +167,8 @@ public:
std::list<CN_ITEM*> m_items;
};
CN_CONNECTIVITY_ALGO() :
CN_CONNECTIVITY_ALGO( CONNECTIVITY_DATA* aParentConnectivityData ) :
m_parentConnectivityData( aParentConnectivityData ),
m_isLocal( false )
{}
@ -208,7 +218,7 @@ public:
}
void Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter = nullptr );
void LocalBuild( std::shared_ptr<CN_CONNECTIVITY_ALGO> aGlobalConnectivity,
void LocalBuild( std::shared_ptr<CONNECTIVITY_DATA> aGlobalConnectivity,
const std::vector<BOARD_ITEM*>& aLocalItems );
void Clear();
@ -258,6 +268,8 @@ public:
}
void MarkNetAsDirty( int aNet );
void RemoveInvalidRefs();
void SetProgressReporter( PROGRESS_REPORTER* aReporter );
private:
@ -276,6 +288,7 @@ private:
void markItemNetAsDirty( const BOARD_ITEM* aItem );
private:
CONNECTIVITY_DATA* m_parentConnectivityData;
CN_LIST m_itemList;
std::unordered_map<const BOARD_ITEM*, ITEM_MAP_ENTRY> m_itemMap;
@ -284,7 +297,7 @@ private:
std::vector<bool> m_dirtyNets;
bool m_isLocal;
std::shared_ptr<CN_CONNECTIVITY_ALGO> m_globalConnectivity;
std::shared_ptr<CONNECTIVITY_DATA> m_globalConnectivityData;
PROGRESS_REPORTER* m_progressReporter = nullptr;
};

View File

@ -47,7 +47,7 @@
CONNECTIVITY_DATA::CONNECTIVITY_DATA() :
m_skipRatsnestUpdate( false )
{
m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
m_connAlgo.reset( new CN_CONNECTIVITY_ALGO( this ) );
m_progressReporter = nullptr;
m_fromToCache.reset( new FROM_TO_CACHE );
}
@ -112,7 +112,7 @@ bool CONNECTIVITY_DATA::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
std::shared_ptr<NET_SETTINGS>& netSettings = aBoard->GetDesignSettings().m_NetSettings;
m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
m_connAlgo.reset( new CN_CONNECTIVITY_ALGO( this ) );
m_connAlgo->Build( aBoard, aReporter );
m_netclassMap.clear();
@ -151,8 +151,8 @@ void CONNECTIVITY_DATA::Build( std::shared_ptr<CONNECTIVITY_DATA>& aGlobalConnec
if( !lock )
return;
m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
m_connAlgo->LocalBuild( aGlobalConnectivity->GetConnectivityAlgo(), aLocalItems );
m_connAlgo.reset( new CN_CONNECTIVITY_ALGO( this ) );
m_connAlgo->LocalBuild( aGlobalConnectivity, aLocalItems );
internalRecalculateRatsnest();
}
@ -932,6 +932,15 @@ void CONNECTIVITY_DATA::MarkItemNetAsDirty( BOARD_ITEM *aItem )
}
void CONNECTIVITY_DATA::RemoveInvalidRefs()
{
m_connAlgo->RemoveInvalidRefs();
for( RN_NET* rnNet : m_nets )
rnNet->RemoveInvalidRefs();
}
void CONNECTIVITY_DATA::SetProgressReporter( PROGRESS_REPORTER* aReporter )
{
m_progressReporter = aReporter;

View File

@ -268,6 +268,8 @@ public:
KISPINLOCK& GetLock() { return m_lock; }
void MarkItemNetAsDirty( BOARD_ITEM* aItem );
void RemoveInvalidRefs();
void SetProgressReporter( PROGRESS_REPORTER* aReporter );
const std::map<int, wxString>& GetNetclassMap() const { return m_netclassMap; }

View File

@ -288,9 +288,6 @@ void CN_LIST::RemoveInvalidItems( std::vector<CN_ITEM*>& aGarbage )
m_items.resize( lastItem - m_items.begin() );
for( CN_ITEM* item : m_items )
item->RemoveInvalidRefs();
for( CN_ITEM* item : aGarbage )
m_index.Remove( item );

View File

@ -456,6 +456,16 @@ void RN_NET::UpdateNet()
}
void RN_NET::RemoveInvalidRefs()
{
for( CN_EDGE& edge : m_rnEdges )
edge.RemoveInvalidRefs();
for( CN_EDGE& edge : m_boardEdges )
edge.RemoveInvalidRefs();
}
void RN_NET::Clear()
{
m_rnEdges.clear();

View File

@ -77,6 +77,8 @@ public:
*/
void UpdateNet();
void RemoveInvalidRefs();
/**
* Find optimal ends of RNEdges. The MST will have found the closest anchors, but when
* zones are involved we might have points closer than the anchors.

View File

@ -198,12 +198,13 @@ void RATSNEST_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
const std::shared_ptr<const CN_ANCHOR>& sourceNode = edge.GetSourceNode();
const std::shared_ptr<const CN_ANCHOR>& targetNode = edge.GetTargetNode();
const VECTOR2I source( sourceNode->Pos() );
const VECTOR2I target( targetNode->Pos() );
if( !sourceNode->Valid() || !targetNode->Valid() )
if( !sourceNode || !sourceNode->Valid() || !targetNode || !targetNode->Valid() )
continue;
const VECTOR2I source( sourceNode->Pos() );
const VECTOR2I target( targetNode->Pos() );
bool enable = !sourceNode->GetNoLine() && !targetNode->GetNoLine();
bool show;