Refactor saving sheet and symbol instances in SCH_SEXPR_PLUGIN::Format

Avoid code duplication by moving all common code to a new function
SCH_SEXPR_PLUGIN::saveInstances

Also fixes a bug that was resulting in footprint and value information
not being saved for subsheets that were root sheets in a different
project.
This commit is contained in:
Roberto Fernandez Bautista 2021-04-12 20:08:02 +01:00
parent 2c75911669
commit 91fd28c4be
6 changed files with 101 additions and 65 deletions

View File

@ -240,6 +240,26 @@ int SCH_REFERENCE_LIST::GetLastReference( int aIndex, int aMinValue ) const
}
std::vector<SYMBOL_INSTANCE_REFERENCE> SCH_REFERENCE_LIST::GetSymbolInstances() const
{
std::vector<SYMBOL_INSTANCE_REFERENCE> retval;
for( const SCH_REFERENCE& ref : flatList )
{
SYMBOL_INSTANCE_REFERENCE instance;
instance.m_Path = ref.GetPath();
instance.m_Reference = ref.GetRef();
instance.m_Unit = ref.GetUnit();
instance.m_Value = ref.GetValue();
instance.m_Footprint = ref.GetFootprint();
retval.push_back( instance );
}
return retval;
}
int SCH_REFERENCE_LIST::CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue )
{
int expectedId = aFirstValue;

View File

@ -696,81 +696,21 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet )
{
SCH_SHEET_LIST sheetPaths( aSheet, true );
m_out->Print( 0, "\n" );
m_out->Print( 1, "(sheet_instances\n" );
SCH_REFERENCE_LIST symbolInstances;
for( const SCH_SHEET_PATH& sheetPath : sheetPaths )
{
SCH_SHEET* sheet = sheetPath.Last();
sheetPath.GetSymbols( symbolInstances, true, true );
wxCHECK2( sheet, continue );
symbolInstances.SortByReferenceOnly();
m_out->Print( 2, "(path %s (page %s))\n",
m_out->Quotew( sheetPath.PathAsString() ).c_str(),
m_out->Quotew( sheet->GetPageNumber( sheetPath ) ).c_str() );
}
m_out->Print( 1, ")\n" ); // Close sheet instances token.
m_out->Print( 0, "\n" );
m_out->Print( 1, "(symbol_instances\n" );
for( const SCH_SHEET_PATH& sheetPath : sheetPaths )
{
SCH_REFERENCE_LIST instances;
sheetPath.GetSymbols( instances, true, true );
instances.SortByReferenceOnly();
for( size_t i = 0; i < instances.GetCount(); i++ )
{
m_out->Print( 2, "(path %s\n",
m_out->Quotew( instances[i].GetPath() ).c_str() );
m_out->Print( 3, "(reference %s) (unit %d) (value %s) (footprint %s)\n",
m_out->Quotew( instances[i].GetRef() ).c_str(),
instances[i].GetUnit(),
m_out->Quotew( instances[i].GetValue() ).c_str(),
m_out->Quotew( instances[i].GetFootprint() ).c_str() );
m_out->Print( 2, ")\n" );
}
}
m_out->Print( 1, ")\n" ); // Close symbol instances token.
saveInstances( sheetPaths.GetSheetInstances(), symbolInstances.GetSymbolInstances(), 1 );
}
else
{
// Schematic files (SCH_SCREEN objects) can be shared so we have to save and restore
// symbol and sheet instance data even if the file being saved is not the root sheet
// because it is possible that the file is the root sheet of another project.
if( screen->m_sheetInstances.size() )
{
m_out->Print( 0, "\n" );
m_out->Print( 1, "(sheet_instances\n" );
for( const SCH_SHEET_INSTANCE& instance : screen->m_sheetInstances )
{
m_out->Print( 2, "(path %s (page %s))\n",
m_out->Quotew( instance.m_Path.AsString() ).c_str(),
m_out->Quotew( instance.m_PageNumber ).c_str() );
}
m_out->Print( 1, ")\n" ); // Close sheet instances token.
}
if( screen->m_symbolInstances.size() )
{
m_out->Print( 0, "\n" );
m_out->Print( 1, "(symbol_instances\n" );
for( const SYMBOL_INSTANCE_REFERENCE& instance : screen->m_symbolInstances )
{
m_out->Print( 2, "(path %s (reference %s) (unit %d))\n",
m_out->Quotew( instance.m_Path.AsString() ).c_str(),
m_out->Quotew( instance.m_Reference ).c_str(),
instance.m_Unit );
}
m_out->Print( 1, ")\n" ); // Close instances token.
}
saveInstances( screen->m_sheetInstances, screen->m_symbolInstances, 1 );
}
m_out->Print( 0, ")\n" );
@ -1319,6 +1259,52 @@ void SCH_SEXPR_PLUGIN::saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias, int aNes
}
void SCH_SEXPR_PLUGIN::saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheets,
const std::vector<SYMBOL_INSTANCE_REFERENCE>& aSymbols,
int aNestLevel )
{
if( aSheets.size() )
{
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel, "(sheet_instances\n" );
for( const SCH_SHEET_INSTANCE& instance : aSheets )
{
wxString path = instance.m_Path.AsString();
if( path.IsEmpty() )
path = wxT( "/" ); // Root path
m_out->Print( aNestLevel + 1, "(path %s (page %s))\n",
m_out->Quotew( path ).c_str(),
m_out->Quotew( instance.m_PageNumber ).c_str() );
}
m_out->Print( aNestLevel, ")\n" ); // Close sheet instances token.
}
if( aSymbols.size() )
{
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel, "(symbol_instances\n" );
for( const SYMBOL_INSTANCE_REFERENCE& instance : aSymbols )
{
m_out->Print( aNestLevel + 1, "(path %s\n",
m_out->Quotew( instance.m_Path.AsString() ).c_str() );
m_out->Print( aNestLevel + 2, "(reference %s) (unit %d) (value %s) (footprint %s)\n",
m_out->Quotew( instance.m_Reference ).c_str(),
instance.m_Unit,
m_out->Quotew( instance.m_Value ).c_str(),
m_out->Quotew( instance.m_Footprint ).c_str() );
m_out->Print( aNestLevel + 1, ")\n" );
}
m_out->Print( aNestLevel, ")\n" ); // Close symbol instances token.
}
}
int SCH_SEXPR_PLUGIN_CACHE::m_modHash = 1; // starts at 1 and goes up

View File

@ -32,6 +32,8 @@ class KIWAY;
class LINE_READER;
class SCH_SCREEN;
class SCH_SHEET;
struct SCH_SHEET_INSTANCE;
class SCH_SHEET_PATH;
class SCH_BITMAP;
class SCH_JUNCTION;
class SCH_NO_CONNECT;
@ -40,6 +42,7 @@ class SCH_BUS_ENTRY_BASE;
class SCH_TEXT;
class SCH_COMPONENT;
class SCH_FIELD;
struct SYMBOL_INSTANCE_REFERENCE;
class PROPERTIES;
class EE_SELECTION;
class SCH_SEXPR_PLUGIN_CACHE;
@ -141,6 +144,8 @@ private:
void saveLine( SCH_LINE* aLine, int aNestLevel );
void saveText( SCH_TEXT* aText, int aNestLevel );
void saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias, int aNestLevel );
void saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheets,
const std::vector<SYMBOL_INSTANCE_REFERENCE>& aSymbols, int aNestLevel );
void cacheLib( const wxString& aLibraryFileName, const PROPERTIES* aProperties );
bool isBuffering( const PROPERTIES* aProperties );

View File

@ -428,6 +428,8 @@ public:
*/
int GetLastReference( int aIndex, int aMinValue ) const;
std::vector<SYMBOL_INSTANCE_REFERENCE> GetSymbolInstances() const;
#if defined(DEBUG)
void Show( const char* aPrefix = "" )
{

View File

@ -883,6 +883,27 @@ std::vector<KIID_PATH> SCH_SHEET_LIST::GetPaths() const
}
std::vector<SCH_SHEET_INSTANCE> SCH_SHEET_LIST::GetSheetInstances() const
{
std::vector<SCH_SHEET_INSTANCE> retval;
for( const SCH_SHEET_PATH& path : *this )
{
SCH_SHEET_INSTANCE instance;
const SCH_SHEET* sheet = path.Last();
wxCHECK2( sheet, continue );
instance.m_Path = path.PathWithoutRootUuid();
instance.m_PageNumber = sheet->GetPageNumber( path );
retval.push_back( instance );
}
return retval;
}
bool SCH_SHEET_LIST::AllSheetPageNumbersEmpty() const
{
for( const SCH_SHEET_PATH& instance : *this )

View File

@ -509,6 +509,8 @@ public:
std::vector<KIID_PATH> GetPaths() const;
std::vector<SCH_SHEET_INSTANCE> GetSheetInstances() const;
/**
* Check all of the sheet instance for empty page numbers.
*