Performance enhancement: check hierarchy validity only when necessary.

This commit is contained in:
Jeff Young 2020-10-05 13:24:21 +01:00
parent 7a7de027a7
commit 63a0f537d8
11 changed files with 40 additions and 24 deletions

View File

@ -54,7 +54,7 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference,
if( !aSearchHierarchy ) if( !aSearchHierarchy )
sheetList.push_back( m_frame->GetCurrentSheet() ); sheetList.push_back( m_frame->GetCurrentSheet() );
else else
sheetList.BuildSheetList( &m_frame->Schematic().Root() ); sheetList = m_frame->Schematic().GetSheets();
for( SCH_SHEET_PATH& sheet : sheetList ) for( SCH_SHEET_PATH& sheet : sheetList )
{ {

View File

@ -270,6 +270,9 @@ bool DIALOG_SCH_SHEET_PROPS::TransferDataFromWindow()
{ {
if( !onSheetFilenameChanged( newRelativeFilename ) ) if( !onSheetFilenameChanged( newRelativeFilename ) )
return false; return false;
// One last validity check (and potential repair) just to be sure to be sure
SCH_SHEET_LIST repairedList( &m_frame->Schematic().Root(), true );
} }
wxString newSheetname = m_fields->at( SHEETNAME ).GetText(); wxString newSheetname = m_fields->at( SHEETNAME ).GetText();

View File

@ -53,7 +53,7 @@ void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef,
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
if( aPlotAll ) if( aPlotAll )
sheetList.BuildSheetList( &schframe->Schematic().Root() ); sheetList.BuildSheetList( &schframe->Schematic().Root(), true );
else else
sheetList.push_back( schframe->GetCurrentSheet() ); sheetList.push_back( schframe->GetCurrentSheet() );

View File

@ -101,7 +101,7 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef,
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
if( aPlotAll ) if( aPlotAll )
sheetList.BuildSheetList( &m_parent->Schematic().Root() ); sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
else else
sheetList.push_back( m_parent->GetCurrentSheet() ); sheetList.push_back( m_parent->GetCurrentSheet() );

View File

@ -56,7 +56,7 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef,
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
if( aPlotAll ) if( aPlotAll )
sheetList.BuildSheetList( &m_parent->Schematic().Root() ); sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
else else
sheetList.push_back( m_parent->GetCurrentSheet() ); sheetList.push_back( m_parent->GetCurrentSheet() );

View File

@ -52,7 +52,7 @@ void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef,
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
if( aPlotAll ) if( aPlotAll )
sheetList.BuildSheetList( &m_parent->Schematic().Root() ); sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
else else
sheetList.push_back( m_parent->GetCurrentSheet() ); sheetList.push_back( m_parent->GetCurrentSheet() );

View File

@ -52,7 +52,7 @@ void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef,
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
if( aPrintAll ) if( aPrintAll )
sheetList.BuildSheetList( &m_parent->Schematic().Root() ); sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
else else
sheetList.push_back( m_parent->GetCurrentSheet() ); sheetList.push_back( m_parent->GetCurrentSheet() );

View File

@ -700,7 +700,7 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet )
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
m_out->Print( 1, "(symbol_instances\n" ); m_out->Print( 1, "(symbol_instances\n" );
SCH_SHEET_LIST sheetPaths( aSheet ); SCH_SHEET_LIST sheetPaths( aSheet, true );
for( const SCH_SHEET_PATH& sheetPath : sheetPaths ) for( const SCH_SHEET_PATH& sheetPath : sheetPaths )
{ {

View File

@ -396,14 +396,14 @@ bool SCH_SHEET_PATH::TestForRecursion( const wxString& aSrcFileName, const wxStr
} }
SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet ) SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet, bool aCheckIntegrity )
{ {
if( aSheet != NULL ) if( aSheet != NULL )
BuildSheetList( aSheet ); BuildSheetList( aSheet, aCheckIntegrity );
} }
void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet, bool aCheckIntegrity )
{ {
wxCHECK_RET( aSheet != NULL, wxT( "Cannot build sheet list from undefined sheet." ) ); wxCHECK_RET( aSheet != NULL, wxT( "Cannot build sheet list from undefined sheet." ) );
@ -421,25 +421,35 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
if( m_currentSheetPath.LastScreen() ) if( m_currentSheetPath.LastScreen() )
{ {
wxString parentFileName = aSheet->GetFileName();
std::vector<SCH_ITEM*> childSheets; std::vector<SCH_ITEM*> childSheets;
m_currentSheetPath.LastScreen()->GetSheets( &childSheets ); m_currentSheetPath.LastScreen()->GetSheets( &childSheets );
for( SCH_ITEM* item : childSheets ) for( SCH_ITEM* item : childSheets )
{ {
auto sheet = static_cast<SCH_SHEET*>( item ); SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
if( !m_currentSheetPath.TestForRecursion( if( aCheckIntegrity )
sheet->GetFileName(), aSheet->GetFileName() ) ) {
BuildSheetList( sheet ); if( !m_currentSheetPath.TestForRecursion( sheet->GetFileName(), parentFileName ) )
BuildSheetList( sheet, true );
else
badSheets.push_back( sheet );
}
else else
badSheets.push_back( sheet ); {
BuildSheetList( sheet, false );
}
} }
} }
for( auto sheet : badSheets ) if( aCheckIntegrity )
{ {
m_currentSheetPath.LastScreen()->Remove( sheet ); for( SCH_SHEET* sheet : badSheets )
m_currentSheetPath.LastScreen()->SetModify(); {
m_currentSheetPath.LastScreen()->Remove( sheet );
m_currentSheetPath.LastScreen()->SetModify();
}
} }
m_currentSheetPath.pop_back(); m_currentSheetPath.pop_back();

View File

@ -343,7 +343,7 @@ public:
* *
* If aSheet == NULL, then this is an empty hierarchy which the user can populate. * If aSheet == NULL, then this is an empty hierarchy which the user can populate.
*/ */
SCH_SHEET_LIST( SCH_SHEET* aSheet = NULL ); SCH_SHEET_LIST( SCH_SHEET* aSheet = nullptr, bool aCheckIntegrity = false );
~SCH_SHEET_LIST() {} ~SCH_SHEET_LIST() {}
@ -431,7 +431,7 @@ public:
* indicating that g_RootSheet should be used. * indicating that g_RootSheet should be used.
* @throw std::bad_alloc if the memory for the sheet path list could not be allocated. * @throw std::bad_alloc if the memory for the sheet path list could not be allocated.
*/ */
void BuildSheetList( SCH_SHEET* aSheet ); void BuildSheetList( SCH_SHEET* aSheet, bool aCheckIntegrity );
bool NameExists( const wxString& aSheetName ); bool NameExists( const wxString& aSheetName );

View File

@ -1503,11 +1503,14 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item ); SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
bool doClearAnnotation; bool doClearAnnotation;
bool doRefresh = false; bool doRefresh = false;
// Keep track of existing sheet paths. EditSheet() can modify this list
SCH_SHEET_LIST initial_sheetpathList = m_frame->Schematic().GetSheets();
doRefresh = m_frame->EditSheetProperties( // Keep track of existing sheet paths. EditSheet() can modify this list.
sheet, &m_frame->GetCurrentSheet(), &doClearAnnotation ); // Note that we use the validity checking/repairing version here just to make sure
// we've got a valid hierarchy to begin with.
SCH_SHEET_LIST initial_sheetpathList( &m_frame->Schematic().Root(), true );
doRefresh = m_frame->EditSheetProperties( sheet, &m_frame->GetCurrentSheet(),
&doClearAnnotation );
// If the sheet file is changed and new sheet contents are loaded then we have to // If the sheet file is changed and new sheet contents are loaded then we have to
// clear the annotations on the new content (as it may have been set from some other // clear the annotations on the new content (as it may have been set from some other