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 )
sheetList.push_back( m_frame->GetCurrentSheet() );
else
sheetList.BuildSheetList( &m_frame->Schematic().Root() );
sheetList = m_frame->Schematic().GetSheets();
for( SCH_SHEET_PATH& sheet : sheetList )
{

View File

@ -270,6 +270,9 @@ bool DIALOG_SCH_SHEET_PROPS::TransferDataFromWindow()
{
if( !onSheetFilenameChanged( newRelativeFilename ) )
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();

View File

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

View File

@ -101,7 +101,7 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef,
SCH_SHEET_LIST sheetList;
if( aPlotAll )
sheetList.BuildSheetList( &m_parent->Schematic().Root() );
sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
else
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;
if( aPlotAll )
sheetList.BuildSheetList( &m_parent->Schematic().Root() );
sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
else
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;
if( aPlotAll )
sheetList.BuildSheetList( &m_parent->Schematic().Root() );
sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
else
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;
if( aPrintAll )
sheetList.BuildSheetList( &m_parent->Schematic().Root() );
sheetList.BuildSheetList( &m_parent->Schematic().Root(), true );
else
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( 1, "(symbol_instances\n" );
SCH_SHEET_LIST sheetPaths( aSheet );
SCH_SHEET_LIST sheetPaths( aSheet, true );
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 )
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." ) );
@ -421,25 +421,35 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
if( m_currentSheetPath.LastScreen() )
{
wxString parentFileName = aSheet->GetFileName();
std::vector<SCH_ITEM*> childSheets;
m_currentSheetPath.LastScreen()->GetSheets( &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(
sheet->GetFileName(), aSheet->GetFileName() ) )
BuildSheetList( sheet );
if( aCheckIntegrity )
{
if( !m_currentSheetPath.TestForRecursion( sheet->GetFileName(), parentFileName ) )
BuildSheetList( sheet, true );
else
badSheets.push_back( sheet );
}
else
badSheets.push_back( sheet );
{
BuildSheetList( sheet, false );
}
}
}
for( auto sheet : badSheets )
if( aCheckIntegrity )
{
m_currentSheetPath.LastScreen()->Remove( sheet );
m_currentSheetPath.LastScreen()->SetModify();
for( SCH_SHEET* sheet : badSheets )
{
m_currentSheetPath.LastScreen()->Remove( sheet );
m_currentSheetPath.LastScreen()->SetModify();
}
}
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.
*/
SCH_SHEET_LIST( SCH_SHEET* aSheet = NULL );
SCH_SHEET_LIST( SCH_SHEET* aSheet = nullptr, bool aCheckIntegrity = false );
~SCH_SHEET_LIST() {}
@ -431,7 +431,7 @@ public:
* indicating that g_RootSheet should be used.
* @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 );

View File

@ -1503,11 +1503,14 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
bool doClearAnnotation;
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(
sheet, &m_frame->GetCurrentSheet(), &doClearAnnotation );
// Keep track of existing sheet paths. EditSheet() can modify this list.
// 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
// clear the annotations on the new content (as it may have been set from some other