More safety around ratsnest state.

Fixes https://gitlab.com/kicad/code/kicad/issues/13011
This commit is contained in:
Jeff Young 2022-11-30 12:18:58 +00:00
parent 9fa8b9e49f
commit 19eab62516
14 changed files with 51 additions and 42 deletions

View File

@ -397,6 +397,8 @@ protected:
virtual void unitsChangeRefresh() override; virtual void unitsChangeRefresh() override;
void rebuildConnectivity();
protected: protected:
BOARD* m_pcb; BOARD* m_pcb;
PCB_DISPLAY_OPTIONS m_displayOptions; PCB_DISPLAY_OPTIONS m_displayOptions;

View File

@ -175,6 +175,8 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
if( Empty() ) if( Empty() )
return; return;
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
// Note: // Note:
// frame == nullptr happens in QA tests // frame == nullptr happens in QA tests
// in this case m_isBoardEditor and m_isFootprintEditor are set to false // in this case m_isBoardEditor and m_isFootprintEditor are set to false
@ -448,8 +450,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
if( !( aCommitFlags & SKIP_CONNECTIVITY ) ) if( !( aCommitFlags & SKIP_CONNECTIVITY ) )
{ {
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
if( ent.m_copy ) if( ent.m_copy )
connectivity->MarkItemNetAsDirty( static_cast<BOARD_ITEM*>( ent.m_copy ) ); connectivity->MarkItemNetAsDirty( static_cast<BOARD_ITEM*>( ent.m_copy ) );
@ -504,24 +504,28 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
{ {
size_t num_changes = m_changes.size(); size_t num_changes = m_changes.size();
if( !( aCommitFlags & SKIP_CONNECTIVITY ) ) if( aCommitFlags & SKIP_CONNECTIVITY )
{
connectivity->ClearRatsnest();
connectivity->ClearLocalRatsnest();
}
else
{ {
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
if( m_resolveNetConflicts ) if( m_resolveNetConflicts )
connectivity->PropagateNets( this, PROPAGATE_MODE::RESOLVE_CONFLICTS ); connectivity->PropagateNets( this, PROPAGATE_MODE::RESOLVE_CONFLICTS );
connectivity->RecalculateRatsnest( this ); connectivity->RecalculateRatsnest( this );
board->UpdateRatsnestExclusions(); board->UpdateRatsnestExclusions();
connectivity->ClearLocalRatsnest(); connectivity->ClearLocalRatsnest();
if( frame )
frame->GetCanvas()->RedrawRatsnest();
} }
if( frame ) if( solderMaskDirty )
{ {
if( solderMaskDirty ) if( frame )
frame->HideSolderMask(); frame->HideSolderMask();
frame->GetCanvas()->RedrawRatsnest();
} }
// Log undo items for any connectivity changes // Log undo items for any connectivity changes

View File

@ -63,7 +63,10 @@ CONNECTIVITY_DATA::CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems, bo
CONNECTIVITY_DATA::~CONNECTIVITY_DATA() CONNECTIVITY_DATA::~CONNECTIVITY_DATA()
{ {
Clear(); for( RN_NET* net : m_nets )
delete net;
m_nets.clear();
} }
@ -494,12 +497,10 @@ unsigned int CONNECTIVITY_DATA::GetUnconnectedCount( bool aVisibleOnly ) const
} }
void CONNECTIVITY_DATA::Clear() void CONNECTIVITY_DATA::ClearRatsnest()
{ {
for( RN_NET* net : m_nets ) for( RN_NET* net : m_nets )
delete net; net->Clear();
m_nets.clear();
} }

View File

@ -154,7 +154,7 @@ public:
* Function Clear() * Function Clear()
* Erases the connectivity database. * Erases the connectivity database.
*/ */
void Clear(); void ClearRatsnest();
/** /**
* Function GetNetCount() * Function GetNetCount()

View File

@ -83,7 +83,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
} }
// Rebuild (from scratch, ignoring dirty flags) just in case. This really needs to be reliable. // Rebuild (from scratch, ignoring dirty flags) just in case. This really needs to be reliable.
connectivity->Clear(); connectivity->ClearRatsnest();
connectivity->Build( board, m_drcEngine->GetProgressReporter() ); connectivity->Build( board, m_drcEngine->GetProgressReporter() );
connectivity->FindIsolatedCopperIslands( islandsList, true ); connectivity->FindIsolatedCopperIslands( islandsList, true );

View File

@ -104,8 +104,7 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( ZONE* aZone )
commit.Stage( pickedList ); commit.Stage( pickedList );
commit.Push( _( "Modify zone properties" ), SKIP_CONNECTIVITY ); commit.Push( _( "Modify zone properties" ), SKIP_CONNECTIVITY );
GetBoard()->BuildConnectivity(); rebuildConnectivity();
GetToolManager()->PostEvent( EVENTS::ConnectivityChangedEvent );
pickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items pickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items
} }

View File

@ -987,8 +987,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
if( filler.Fill( toFill ) ) if( filler.Fill( toFill ) )
commit.Push( _( "Convert Zone(s)" ), SKIP_CONNECTIVITY ); commit.Push( _( "Convert Zone(s)" ), SKIP_CONNECTIVITY );
GetBoard()->BuildConnectivity( &progressReporter ); rebuildConnectivity();
GetToolManager()->PostEvent( EVENTS::ConnectivityChangedEvent );
} }
// from EDA_APPL which was first loaded BOARD only: // from EDA_APPL which was first loaded BOARD only:

View File

@ -1006,6 +1006,14 @@ void PCB_BASE_FRAME::OnModify()
} }
void PCB_BASE_FRAME::rebuildConnectivity()
{
GetBoard()->BuildConnectivity();
GetToolManager()->PostEvent( EVENTS::ConnectivityChangedEvent );
GetCanvas()->RedrawRatsnest();
}
PCB_DRAW_PANEL_GAL* PCB_BASE_FRAME::GetCanvas() const PCB_DRAW_PANEL_GAL* PCB_BASE_FRAME::GetCanvas() const
{ {
return static_cast<PCB_DRAW_PANEL_GAL*>( EDA_DRAW_FRAME::GetCanvas() ); return static_cast<PCB_DRAW_PANEL_GAL*>( EDA_DRAW_FRAME::GetCanvas() );

View File

@ -980,7 +980,7 @@ void PCB_EDIT_FRAME::ResolveDRCExclusions()
commit.Add( marker ); commit.Add( marker );
} }
commit.Push( wxEmptyString, SKIP_UNDO | SKIP_SET_DIRTY | SKIP_CONNECTIVITY ); commit.Push( wxEmptyString, SKIP_UNDO | SKIP_SET_DIRTY );
for( PCB_MARKER* marker : GetBoard()->Markers() ) for( PCB_MARKER* marker : GetBoard()->Markers() )
{ {

View File

@ -64,11 +64,6 @@ class RN_NET
public: public:
RN_NET(); RN_NET();
/**
* Mark ratsnest for given net as 'dirty', i.e. requiring recomputation.
*/
void MarkDirty() { m_dirty = true; }
/** /**
* Return state of the 'dirty' flag, indicating that ratsnest for a given net is invalid * Return state of the 'dirty' flag, indicating that ratsnest for a given net is invalid
* and requires an update. * and requires an update.

View File

@ -81,7 +81,7 @@ bool PCB_EDIT_FRAME::ImportSpecctraSession( const wxString& fullFileName )
return false; return false;
} }
GetBoard()->GetConnectivity()->Clear(); GetBoard()->GetConnectivity()->ClearRatsnest();
GetBoard()->BuildConnectivity(); GetBoard()->BuildConnectivity();
OnModify(); OnModify();

View File

@ -97,9 +97,7 @@ void ZONE_FILLER_TOOL::CheckAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRep
commit.Revert(); commit.Revert();
} }
board()->BuildConnectivity(); rebuildConnectivity();
m_toolMgr->PostEvent( EVENTS::ConnectivityChangedEvent );
refresh(); refresh();
m_fillInProgress = false; m_fillInProgress = false;
@ -174,14 +172,12 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo
commit.Revert(); commit.Revert();
} }
board()->BuildConnectivity( reporter.get() ); rebuildConnectivity();
m_toolMgr->PostEvent( EVENTS::ConnectivityChangedEvent ); refresh();
if( filler.IsDebug() ) if( filler.IsDebug() )
frame->UpdateUserInterface(); frame->UpdateUserInterface();
refresh();
m_fillInProgress = false; m_fillInProgress = false;
// wxWidgets has keyboard focus issues after the progress reporter. Re-setting the focus // wxWidgets has keyboard focus issues after the progress reporter. Re-setting the focus
@ -259,8 +255,8 @@ int ZONE_FILLER_TOOL::ZoneFillDirty( const TOOL_EVENT& aEvent )
else else
commit.Revert(); commit.Revert();
board()->BuildConnectivity( reporter.get() ); rebuildConnectivity();
m_toolMgr->PostEvent( EVENTS::ConnectivityChangedEvent ); refresh();
if( GetRunningMicroSecs() - startTime > 1000000 ) if( GetRunningMicroSecs() - startTime > 1000000 )
{ {
@ -286,8 +282,6 @@ int ZONE_FILLER_TOOL::ZoneFillDirty( const TOOL_EVENT& aEvent )
if( filler.IsDebug() ) if( filler.IsDebug() )
frame->UpdateUserInterface(); frame->UpdateUserInterface();
refresh();
m_fillInProgress = false; m_fillInProgress = false;
// wxWidgets has keyboard focus issues after the progress reporter. Re-setting the focus // wxWidgets has keyboard focus issues after the progress reporter. Re-setting the focus
@ -340,9 +334,7 @@ int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent )
commit.Revert(); commit.Revert();
} }
board()->BuildConnectivity( reporter.get() ); rebuildConnectivity();
m_toolMgr->PostEvent( EVENTS::ConnectivityChangedEvent );
refresh(); refresh();
m_fillInProgress = false; m_fillInProgress = false;
@ -399,6 +391,14 @@ int ZONE_FILLER_TOOL::ZoneUnfillAll( const TOOL_EVENT& aEvent )
} }
void ZONE_FILLER_TOOL::rebuildConnectivity()
{
board()->BuildConnectivity();
m_toolMgr->PostEvent( EVENTS::ConnectivityChangedEvent );
canvas()->RedrawRatsnest();
}
void ZONE_FILLER_TOOL::refresh() void ZONE_FILLER_TOOL::refresh()
{ {
canvas()->GetView()->UpdateAllItemsConditionally( KIGFX::REPAINT, canvas()->GetView()->UpdateAllItemsConditionally( KIGFX::REPAINT,

View File

@ -70,6 +70,7 @@ private:
///< Refocus on an idle event (used after the Progress Reporter messes up the focus). ///< Refocus on an idle event (used after the Progress Reporter messes up the focus).
void singleShotRefocus( wxIdleEvent& ); void singleShotRefocus( wxIdleEvent& );
void rebuildConnectivity();
void refresh(); void refresh();
///< Set up handlers for various events. ///< Set up handlers for various events.

View File

@ -97,7 +97,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity(); std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
// Rebuild (from scratch, ignoring dirty flags) just in case. This really needs to be reliable. // Rebuild (from scratch, ignoring dirty flags) just in case. This really needs to be reliable.
connectivity->Clear(); connectivity->ClearRatsnest();
connectivity->Build( m_board, m_progressReporter ); connectivity->Build( m_board, m_progressReporter );
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();