Add project name to symbol instance data.

This improves the readability of the schematic file format and creates
an opportunity to remove orphaned instance data by project name rather
than cryptic UUIDs.
This commit is contained in:
Wayne Stambaugh 2022-09-29 12:26:14 -04:00
parent 7984e114db
commit 4b276b339a
7 changed files with 98 additions and 43 deletions

View File

@ -2641,13 +2641,12 @@ SCH_SYMBOL* SCH_SEXPR_PARSER::parseSchematicSymbol()
token = NextTok(); token = NextTok();
if( token != T_path ) if( token != T_project )
Expecting( "path" ); Expecting( "project" );
SYMBOL_INSTANCE_REFERENCE instance;
NeedSYMBOL(); NeedSYMBOL();
instance.m_Path = KIID_PATH( FromUTF8() );
wxString projectName = FromUTF8();
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
@ -2656,36 +2655,54 @@ SCH_SYMBOL* SCH_SEXPR_PARSER::parseSchematicSymbol()
token = NextTok(); token = NextTok();
switch( token ) if( token != T_path )
Expecting( "path" );
SYMBOL_INSTANCE_REFERENCE instance;
instance.m_ProjectName = projectName;
NeedSYMBOL();
instance.m_Path = KIID_PATH( FromUTF8() );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
case T_reference: if( token != T_LEFT )
NeedSYMBOL(); Expecting( T_LEFT );
instance.m_Reference = FromUTF8();
NeedRIGHT();
break;
case T_unit: token = NextTok();
instance.m_Unit = parseInt( "symbol unit" );
NeedRIGHT();
break;
case T_value: switch( token )
NeedSYMBOL(); {
instance.m_Value = FromUTF8(); case T_reference:
NeedRIGHT(); NeedSYMBOL();
break; instance.m_Reference = FromUTF8();
NeedRIGHT();
break;
case T_footprint: case T_unit:
NeedSYMBOL(); instance.m_Unit = parseInt( "symbol unit" );
instance.m_Footprint = FromUTF8(); NeedRIGHT();
NeedRIGHT(); break;
break;
default: case T_value:
Expecting( "reference, unit, value or footprint" ); NeedSYMBOL();
instance.m_Value = FromUTF8();
NeedRIGHT();
break;
case T_footprint:
NeedSYMBOL();
instance.m_Footprint = FromUTF8();
NeedRIGHT();
break;
default:
Expecting( "reference, unit, value or footprint" );
}
symbol->AddHierarchicalReference( instance );
} }
symbol->AddHierarchicalReference( instance );
} }
} }

View File

@ -811,18 +811,40 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
m_out->Print( aNestLevel + 1, "(instances\n" ); m_out->Print( aNestLevel + 1, "(instances\n" );
for( const SYMBOL_INSTANCE_REFERENCE& instance : aSymbol->GetInstanceReferences() ) // Sort symbol instance data to minimize file churn.
{ std::vector< SYMBOL_INSTANCE_REFERENCE > sortedInstances( aSymbol->GetInstanceReferences() );
wxString path = instance.m_Path.AsString(); std::sort( sortedInstances.begin(), sortedInstances.end(), SortSymbolInstancesByProjectUuid );
m_out->Print( aNestLevel + 2, "(path %s\n", KIID lastProjectUuid;
for( size_t i = 0; i < sortedInstances.size(); i++ )
{
if( lastProjectUuid != sortedInstances[i].m_Path[0] )
{
wxString projectName;
if( sortedInstances[i].m_Path[0] == m_schematic->RootScreen()->GetUuid() )
projectName = m_schematic->Prj().GetProjectName();
else
projectName = sortedInstances[i].m_ProjectName;
lastProjectUuid = sortedInstances[i].m_Path[0];
m_out->Print( aNestLevel + 2, "(project %s\n", m_out->Quotew( projectName ).c_str() );
}
wxString path = sortedInstances[i].m_Path.AsString();
m_out->Print( aNestLevel + 3, "(path %s\n",
m_out->Quotew( path ).c_str() ); m_out->Quotew( path ).c_str() );
m_out->Print( aNestLevel + 3, "(reference %s) (unit %d) (value %s) (footprint %s)\n", m_out->Print( aNestLevel + 4, "(reference %s) (unit %d) (value %s) (footprint %s)\n",
m_out->Quotew( instance.m_Reference ).c_str(), m_out->Quotew( sortedInstances[i].m_Reference ).c_str(),
instance.m_Unit, sortedInstances[i].m_Unit,
m_out->Quotew( instance.m_Value ).c_str(), m_out->Quotew( sortedInstances[i].m_Value ).c_str(),
m_out->Quotew( instance.m_Footprint ).c_str() ); m_out->Quotew( sortedInstances[i].m_Footprint ).c_str() );
m_out->Print( aNestLevel + 2, ")\n" ); m_out->Print( aNestLevel + 3, ")\n" );
if( i + 1 == sortedInstances.size() || lastProjectUuid != sortedInstances[i+1].m_Path[0] )
m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project`.
} }
m_out->Print( aNestLevel + 1, ")\n" ); // Closes `instances`. m_out->Print( aNestLevel + 1, ")\n" ); // Closes `instances`.

View File

@ -5,7 +5,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2020 CERN * Copyright (C) 2020 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Wayne Stambaugh <stambaughw@gmail.com> * @author Wayne Stambaugh <stambaughw@gmail.com>
* *

View File

@ -91,6 +91,15 @@ public:
}; };
bool SortSymbolInstancesByProjectUuid( const SYMBOL_INSTANCE_REFERENCE& aLhs,
const SYMBOL_INSTANCE_REFERENCE& aRhs )
{
wxCHECK2( !aLhs.m_Path.empty() && !aRhs.m_Path.empty(), false );
return aLhs.m_Path[0] < aRhs.m_Path[0];
}
namespace std namespace std
{ {
size_t hash<SCH_SHEET_PATH>::operator()( const SCH_SHEET_PATH& path ) const size_t hash<SCH_SHEET_PATH>::operator()( const SCH_SHEET_PATH& path ) const

View File

@ -51,9 +51,16 @@ struct SYMBOL_INSTANCE_REFERENCE
// Things that can be back-annotated: // Things that can be back-annotated:
wxString m_Value; wxString m_Value;
wxString m_Footprint; wxString m_Footprint;
// The project name associated with this instance.
wxString m_ProjectName;
}; };
extern bool SortSymbolInstancesByProjectUuid( const SYMBOL_INSTANCE_REFERENCE& aLhs,
const SYMBOL_INSTANCE_REFERENCE& aRhs );
/** /**
* A simple container for sheet instance information. * A simple container for sheet instance information.
*/ */

View File

@ -103,6 +103,7 @@ power
power_in power_in
power_out power_out
private private
project
property property
property_del property_del
pts pts

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -238,8 +238,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
"lastest file version will resolve this issue.\n\n" "lastest file version will resolve this issue.\n\n"
"Do you wish to continue?" ); "Do you wish to continue?" );
wxMessageDialog msgDlg7( this, msg, _( "Continue Load Schematic" ), wxMessageDialog msgDlg7( this, msg, _( "Continue Load Schematic" ),
wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER | wxICON_QUESTION );
wxCENTER | wxICON_QUESTION );
msgDlg7.SetOKCancelLabels( okButtonLabel, cancelButtonLabel ); msgDlg7.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
if( msgDlg7.ShowModal() == wxID_CANCEL ) if( msgDlg7.ShowModal() == wxID_CANCEL )