Support for variable references in SPICE models.
Also fixes a couple of bugs where sheet instance data wasn't being handled correctly.
This commit is contained in:
parent
0b3ecdd968
commit
95ebfeeed1
|
@ -66,7 +66,7 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
|
||||||
|
|
||||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||||
{
|
{
|
||||||
m_models.push_back( SIM_MODEL::Create( type, m_sortedSymbolPins.size() ) );
|
m_models.push_back( SIM_MODEL::Create( type, m_sortedSymbolPins.size(), false ) );
|
||||||
|
|
||||||
SIM_MODEL::DEVICE_TYPE_ deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
|
SIM_MODEL::DEVICE_TYPE_ deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
|
||||||
{
|
{
|
||||||
wxCommandEvent dummyEvent;
|
wxCommandEvent dummyEvent;
|
||||||
|
|
||||||
int pinCount = m_sortedSymbolPins.size();
|
unsigned pinCount = m_sortedSymbolPins.size();
|
||||||
std::string ref = SIM_MODEL::GetFieldValue( &m_fields, SIM_MODEL::REFERENCE_FIELD );
|
std::string ref = SIM_MODEL::GetFieldValue( &m_fields, SIM_MODEL::REFERENCE_FIELD );
|
||||||
std::string libraryFilename = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::LIBRARY_FIELD );
|
std::string libraryFilename = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::LIBRARY_FIELD );
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_models.at( static_cast<int>( type ) ) = SIM_MODEL::Create( pinCount, m_fields );
|
m_models.at( static_cast<int>( type ) ) = SIM_MODEL::Create( pinCount, m_fields, false );
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
|
@ -638,6 +638,7 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned pinCount = m_sortedSymbolPins.size();
|
||||||
m_tclibraryPathName->ChangeValue( aFilePath );
|
m_tclibraryPathName->ChangeValue( aFilePath );
|
||||||
|
|
||||||
m_libraryModels.clear();
|
m_libraryModels.clear();
|
||||||
|
@ -655,12 +656,12 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
|
||||||
{
|
{
|
||||||
//TODO: it's not cur model.
|
//TODO: it's not cur model.
|
||||||
|
|
||||||
m_libraryModels.push_back(
|
m_libraryModels.push_back( SIM_MODEL::Create( baseModel, pinCount, m_fields,
|
||||||
SIM_MODEL::Create( baseModel, m_sortedSymbolPins.size(), m_fields ) );
|
false ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_libraryModels.push_back( SIM_MODEL::Create( baseModel, m_sortedSymbolPins.size() ) );
|
m_libraryModels.push_back( SIM_MODEL::Create( baseModel, pinCount, false ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -782,12 +783,12 @@ wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
|
||||||
|
|
||||||
case SIM_VALUE::TYPE_INT:
|
case SIM_VALUE::TYPE_INT:
|
||||||
prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library,
|
prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library,
|
||||||
curModelSharedPtr(), aParamIndex, SIM_VALUE::TYPE_INT );
|
curModelSharedPtr(), aParamIndex );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIM_VALUE::TYPE_FLOAT:
|
case SIM_VALUE::TYPE_FLOAT:
|
||||||
prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library,
|
prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library,
|
||||||
curModelSharedPtr(), aParamIndex, SIM_VALUE::TYPE_FLOAT );
|
curModelSharedPtr(), aParamIndex );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//case TYPE_COMPLEX:
|
//case TYPE_COMPLEX:
|
||||||
|
@ -797,14 +798,12 @@ wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
|
||||||
if( param.info.enumValues.empty() )
|
if( param.info.enumValues.empty() )
|
||||||
{
|
{
|
||||||
prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library,
|
prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library,
|
||||||
curModelSharedPtr(), aParamIndex,
|
curModelSharedPtr(), aParamIndex );
|
||||||
SIM_VALUE::TYPE_STRING );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prop = new SIM_ENUM_PROPERTY( paramDescription, param.info.name, m_library,
|
prop = new SIM_ENUM_PROPERTY( paramDescription, param.info.name, m_library,
|
||||||
curModelSharedPtr(), aParamIndex,
|
curModelSharedPtr(), aParamIndex );
|
||||||
SIM_VALUE::TYPE_STRING );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1145,7 +1144,7 @@ void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
|
||||||
|
|
||||||
m_libraryModels.at( m_modelNameCombobox->GetSelection() ) =
|
m_libraryModels.at( m_modelNameCombobox->GetSelection() ) =
|
||||||
std::shared_ptr<SIM_MODEL>( dynamic_cast<SIM_MODEL*>(
|
std::shared_ptr<SIM_MODEL>( dynamic_cast<SIM_MODEL*>(
|
||||||
new SIM_MODEL_KIBIS( type, *kibismodel, m_fields ) ) );
|
new SIM_MODEL_KIBIS( type, *kibismodel, m_fields, false ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_curModelType = type;
|
m_curModelType = type;
|
||||||
|
|
|
@ -210,11 +210,19 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||||
|
|
||||||
SPICE_ITEM spiceItem;
|
SPICE_ITEM spiceItem;
|
||||||
|
|
||||||
// This is a little bit dangerous as any value fetched from the fields will not
|
for( int i = 0; i < symbol->GetFieldCount(); ++i )
|
||||||
// be instance-data aware, and will just fetch the value of some random sheet
|
{
|
||||||
// (whatever sheet the user happens to be looking at). However, we currently only
|
spiceItem.fields.emplace_back( VECTOR2I(), i, symbol, symbol->GetFields()[ i ].GetName() );
|
||||||
// use it to fetch "Sim_*" fields, which have no instance data.
|
|
||||||
spiceItem.fields = &symbol->GetFields();
|
if( i == REFERENCE_FIELD )
|
||||||
|
spiceItem.fields.back().SetText( symbol->GetRef( &sheet ) );
|
||||||
|
else if( i == VALUE_FIELD )
|
||||||
|
spiceItem.fields.back().SetText( symbol->GetValue( &sheet, true ) );
|
||||||
|
else if( i == FOOTPRINT_FIELD )
|
||||||
|
spiceItem.fields.back().SetText( symbol->GetFootprint( &sheet, true ) );
|
||||||
|
else
|
||||||
|
spiceItem.fields.back().SetText( symbol->GetFields()[ i ].GetShownText( 0, false ) );
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -376,7 +384,7 @@ bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aS
|
||||||
|
|
||||||
void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
||||||
{
|
{
|
||||||
SIM_LIBRARY::MODEL libModel = m_libMgr.CreateModel( aSymbol );
|
SIM_LIBRARY::MODEL libModel = m_libMgr.CreateModel( &aSheet, aSymbol, true );
|
||||||
|
|
||||||
aItem.baseModelName = libModel.name;
|
aItem.baseModelName = libModel.name;
|
||||||
aItem.model = &libModel.model;
|
aItem.model = &libModel.model;
|
||||||
|
|
|
@ -210,7 +210,7 @@ wxString SCH_FIELD::GetShownText( int aDepth, bool aAllowExtraText ) const
|
||||||
PROJECT* project = nullptr;
|
PROJECT* project = nullptr;
|
||||||
wxString text = EDA_TEXT::GetShownText();
|
wxString text = EDA_TEXT::GetShownText();
|
||||||
|
|
||||||
if( IsNameShown() )
|
if( IsNameShown() && aAllowExtraText )
|
||||||
text = GetName() << wxS( ": " ) << text;
|
text = GetName() << wxS( ": " ) << text;
|
||||||
|
|
||||||
if( text == wxS( "~" ) ) // Legacy placeholder for empty string
|
if( text == wxS( "~" ) ) // Legacy placeholder for empty string
|
||||||
|
|
|
@ -35,12 +35,31 @@ SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT& aPrj ) : m_project( aPrj )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, SCH_SYMBOL& aSymbol,
|
||||||
|
bool aResolve )
|
||||||
{
|
{
|
||||||
std::vector<LIB_PIN*> pins = aSymbol.GetLibPins();
|
int pinCount = aSymbol.GetLibPins().size();
|
||||||
SCH_FIELD* libraryField = aSymbol.FindField( SIM_LIBRARY::LIBRARY_FIELD );
|
SCH_FIELD* libraryField = aSymbol.FindField( SIM_LIBRARY::LIBRARY_FIELD );
|
||||||
std::string baseModelName;
|
std::string baseModelName;
|
||||||
|
|
||||||
|
std::vector<SCH_FIELD> fields;
|
||||||
|
|
||||||
|
for( int i = 0; i < aSymbol.GetFieldCount(); ++i )
|
||||||
|
{
|
||||||
|
fields.emplace_back( VECTOR2I(), i, &aSymbol, aSymbol.GetFields()[ i ].GetName() );
|
||||||
|
|
||||||
|
if( i == REFERENCE_FIELD )
|
||||||
|
fields.back().SetText( aSymbol.GetRef( aSheetPath ) );
|
||||||
|
else if( i == VALUE_FIELD )
|
||||||
|
fields.back().SetText( aSymbol.GetValue( aSheetPath, aResolve ) );
|
||||||
|
else if( i == FOOTPRINT_FIELD )
|
||||||
|
fields.back().SetText( aSymbol.GetFootprint( aSheetPath, aResolve ) );
|
||||||
|
else if( aResolve )
|
||||||
|
fields.back().SetText( aSymbol.GetFields()[ i ].GetShownText( 0, false ) );
|
||||||
|
else
|
||||||
|
fields.back().SetText( aSymbol.GetFields()[ i ].GetText() );
|
||||||
|
}
|
||||||
|
|
||||||
if( libraryField )
|
if( libraryField )
|
||||||
{
|
{
|
||||||
wxString path = libraryField->GetShownText();
|
wxString path = libraryField->GetShownText();
|
||||||
|
@ -55,8 +74,7 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
THROW_IO_ERROR(
|
THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model library '%s': %s" ),
|
||||||
wxString::Format( _( "Error loading simulation model library '%s': %s" ),
|
|
||||||
absolutePath,
|
absolutePath,
|
||||||
e.What() ) );
|
e.What() ) );
|
||||||
}
|
}
|
||||||
|
@ -74,20 +92,17 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
||||||
|
|
||||||
if( !baseModel )
|
if( !baseModel )
|
||||||
{
|
{
|
||||||
THROW_IO_ERROR(
|
THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model: could not find "
|
||||||
wxString::Format( _( "Error loading simulation model: could not find base model '%s' in library '%s'" ),
|
"base model '%s' in library '%s'" ),
|
||||||
baseModelName,
|
baseModelName,
|
||||||
absolutePath ) );
|
absolutePath ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_models.push_back( SIM_MODEL::Create( *baseModel,
|
m_models.push_back( SIM_MODEL::Create( *baseModel, pinCount, fields, aResolve ) );
|
||||||
static_cast<int>( pins.size() ),
|
|
||||||
aSymbol.GetFields() ) );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_models.push_back( SIM_MODEL::Create( static_cast<int>( pins.size() ),
|
m_models.push_back( SIM_MODEL::Create( pinCount, fields, aResolve ) );
|
||||||
aSymbol.GetFields() ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { baseModelName, *m_models.back() };
|
return { baseModelName, *m_models.back() };
|
||||||
|
|
|
@ -44,7 +44,8 @@ public:
|
||||||
virtual ~SIM_LIB_MGR() = default;
|
virtual ~SIM_LIB_MGR() = default;
|
||||||
|
|
||||||
// TODO: The argument can be made const.
|
// TODO: The argument can be made const.
|
||||||
SIM_LIBRARY::MODEL CreateModel( SCH_SYMBOL& aSymbol );
|
SIM_LIBRARY::MODEL CreateModel( const SCH_SHEET_PATH* aSheetPath, SCH_SYMBOL& aSymbol,
|
||||||
|
bool aResolve );
|
||||||
|
|
||||||
SIM_LIBRARY& CreateLibrary( const std::string& aLibraryPath );
|
SIM_LIBRARY& CreateLibrary( const std::string& aLibraryPath );
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,8 @@
|
||||||
|
|
||||||
#include <sim/sim_library_kibis.h>
|
#include <sim/sim_library_kibis.h>
|
||||||
#include <sim/sim_model_kibis.h>
|
#include <sim/sim_model_kibis.h>
|
||||||
#include <sim/spice_grammar.h>
|
|
||||||
#include <ki_exception.h>
|
#include <ki_exception.h>
|
||||||
#include <locale_io.h>
|
#include <locale_io.h>
|
||||||
#include <pegtl.hpp>
|
|
||||||
#include <pegtl/contrib/parse_tree.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath, SIM_MODEL::TYPE aType )
|
void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath, SIM_MODEL::TYPE aType )
|
||||||
|
@ -45,7 +42,7 @@ void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath, SIM_MODEL::TYPE
|
||||||
|
|
||||||
for( KIBIS_COMPONENT& kcomp : m_kibis.m_components )
|
for( KIBIS_COMPONENT& kcomp : m_kibis.m_components )
|
||||||
{
|
{
|
||||||
m_models.push_back( SIM_MODEL::Create( aType, pinNumber ) );
|
m_models.push_back( SIM_MODEL::Create( aType, pinNumber, true ) );
|
||||||
m_modelNames.emplace_back( kcomp.m_name );
|
m_modelNames.emplace_back( kcomp.m_name );
|
||||||
|
|
||||||
SIM_MODEL_KIBIS* libcomp = dynamic_cast<SIM_MODEL_KIBIS*>( m_models.back().get() );
|
SIM_MODEL_KIBIS* libcomp = dynamic_cast<SIM_MODEL_KIBIS*>( m_models.back().get() );
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
|
|
||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
#include <boost/algorithm/string/trim.hpp>
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <pegtl.hpp>
|
#include <pegtl.hpp>
|
||||||
|
@ -566,9 +565,9 @@ void SIM_MODEL::WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, unsigned aSymbolPinCount )
|
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, unsigned aSymbolPinCount, bool aResolve )
|
||||||
{
|
{
|
||||||
std::unique_ptr<SIM_MODEL> model = Create( aType );
|
std::unique_ptr<SIM_MODEL> model = Create( aType, aResolve );
|
||||||
|
|
||||||
// Passing nullptr to ReadDataFields will make it act as if all fields were empty.
|
// Passing nullptr to ReadDataFields will make it act as if all fields were empty.
|
||||||
model->ReadDataFields( aSymbolPinCount, static_cast<const std::vector<void>*>( nullptr ) );
|
model->ReadDataFields( aSymbolPinCount, static_cast<const std::vector<void>*>( nullptr ) );
|
||||||
|
@ -576,10 +575,10 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, unsigned aSymbolPinCou
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
||||||
unsigned aSymbolPinCount )
|
bool aResolve )
|
||||||
{
|
{
|
||||||
std::unique_ptr<SIM_MODEL> model = Create( aBaseModel.GetType() );
|
std::unique_ptr<SIM_MODEL> model = Create( aBaseModel.GetType(), aResolve );
|
||||||
|
|
||||||
model->SetBaseModel( aBaseModel );
|
model->SetBaseModel( aBaseModel );
|
||||||
model->ReadDataFields( aSymbolPinCount, static_cast<const std::vector<void>*>( nullptr ) );
|
model->ReadDataFields( aSymbolPinCount, static_cast<const std::vector<void>*>( nullptr ) );
|
||||||
|
@ -589,7 +588,7 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
||||||
const std::vector<T>& aFields )
|
const std::vector<T>& aFields, bool aResolve )
|
||||||
{
|
{
|
||||||
TYPE type = ReadTypeFromFields( aFields, aSymbolPinCount );
|
TYPE type = ReadTypeFromFields( aFields, aSymbolPinCount );
|
||||||
|
|
||||||
|
@ -597,7 +596,7 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsig
|
||||||
if( type == TYPE::NONE )
|
if( type == TYPE::NONE )
|
||||||
type = aBaseModel.GetType();
|
type = aBaseModel.GetType();
|
||||||
|
|
||||||
std::unique_ptr<SIM_MODEL> model = Create( type );
|
std::unique_ptr<SIM_MODEL> model = Create( type, aResolve );
|
||||||
|
|
||||||
model->SetBaseModel( aBaseModel );
|
model->SetBaseModel( aBaseModel );
|
||||||
model->ReadDataFields( aSymbolPinCount, &aFields );
|
model->ReadDataFields( aSymbolPinCount, &aFields );
|
||||||
|
@ -606,32 +605,36 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsig
|
||||||
|
|
||||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||||
unsigned aSymbolPinCount,
|
unsigned aSymbolPinCount,
|
||||||
const std::vector<SCH_FIELD>& aFields );
|
const std::vector<SCH_FIELD>& aFields,
|
||||||
|
bool aResolve );
|
||||||
|
|
||||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||||
unsigned aSymbolPinCount,
|
unsigned aSymbolPinCount,
|
||||||
const std::vector<LIB_FIELD>& aFields );
|
const std::vector<LIB_FIELD>& aFields,
|
||||||
|
bool aResolve );
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
||||||
const std::vector<T>& aFields )
|
const std::vector<T>& aFields, bool aResolve )
|
||||||
{
|
{
|
||||||
TYPE type = ReadTypeFromFields( aFields, aSymbolPinCount );
|
TYPE type = ReadTypeFromFields( aFields, aSymbolPinCount );
|
||||||
|
|
||||||
if( type == TYPE::NONE )
|
if( type == TYPE::NONE )
|
||||||
THROW_IO_ERROR( wxString::Format( _( "Failed to read simulation model from fields." ) ) );
|
THROW_IO_ERROR( wxString::Format( _( "Failed to read simulation model from fields." ) ) );
|
||||||
|
|
||||||
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
|
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type, aResolve );
|
||||||
|
|
||||||
model->ReadDataFields( aSymbolPinCount, &aFields );
|
model->ReadDataFields( aSymbolPinCount, &aFields );
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
||||||
const std::vector<SCH_FIELD>& aFields );
|
const std::vector<SCH_FIELD>& aFields,
|
||||||
|
bool aResolve );
|
||||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
||||||
const std::vector<LIB_FIELD>& aFields );
|
const std::vector<LIB_FIELD>& aFields,
|
||||||
|
bool aResolve );
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -747,10 +750,17 @@ std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> SIM_MODEL::GetPins() c
|
||||||
|
|
||||||
const SIM_MODEL::PARAM& SIM_MODEL::GetParam( unsigned aParamIndex ) const
|
const SIM_MODEL::PARAM& SIM_MODEL::GetParam( unsigned aParamIndex ) const
|
||||||
{
|
{
|
||||||
if( m_baseModel && m_params.at( aParamIndex ).value->ToString() == "" )
|
const SIM_MODEL::PARAM& param = m_params.at( aParamIndex );
|
||||||
|
|
||||||
|
if( m_baseModel )
|
||||||
|
{
|
||||||
|
std::string value = param.resolved ? param.value->ToString() : param.source.ToStdString();
|
||||||
|
|
||||||
|
if( value.empty() )
|
||||||
return m_baseModel->GetParam( aParamIndex );
|
return m_baseModel->GetParam( aParamIndex );
|
||||||
else
|
}
|
||||||
return m_params.at( aParamIndex );
|
|
||||||
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -849,6 +859,33 @@ void SIM_MODEL::SetParamValue( const std::string& aParamName, const std::string&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SIM_MODEL::SetParamSource( const std::string& aParamName, const wxString& aSource )
|
||||||
|
{
|
||||||
|
for( PARAM& param : m_params )
|
||||||
|
{
|
||||||
|
if( param.info.name == boost::to_lower_copy( aParamName ) )
|
||||||
|
{
|
||||||
|
param.source = aSource;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
THROW_IO_ERROR( wxString::Format( _( "Could not find a parameter named '%s' in simulation model of type '%s'" ),
|
||||||
|
aParamName,
|
||||||
|
GetTypeInfo().fieldValue ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SIM_MODEL::SetParamSource( int aParamIndex, const wxString& aSource )
|
||||||
|
{
|
||||||
|
SIM_MODEL::PARAM& param = m_params.at( aParamIndex );
|
||||||
|
|
||||||
|
wxASSERT( !param.resolved );
|
||||||
|
|
||||||
|
param.source = aSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SIM_MODEL::HasOverrides() const
|
bool SIM_MODEL::HasOverrides() const
|
||||||
{
|
{
|
||||||
for( const PARAM& param : m_params )
|
for( const PARAM& param : m_params )
|
||||||
|
@ -885,7 +922,7 @@ bool SIM_MODEL::HasSpiceNonInstanceOverrides() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType )
|
std::unique_ptr<SIM_MODEL> SIM_MODEL::doCreate( TYPE aType )
|
||||||
{
|
{
|
||||||
switch( aType )
|
switch( aType )
|
||||||
{
|
{
|
||||||
|
@ -966,6 +1003,23 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, bool aResolve )
|
||||||
|
{
|
||||||
|
std::unique_ptr<SIM_MODEL> model = doCreate( aType );
|
||||||
|
|
||||||
|
if( !aResolve )
|
||||||
|
{
|
||||||
|
for( PARAM& param : model->m_params )
|
||||||
|
{
|
||||||
|
param.source = param.value->ToString();
|
||||||
|
param.resolved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SIM_MODEL::SIM_MODEL( TYPE aType ) :
|
SIM_MODEL::SIM_MODEL( TYPE aType ) :
|
||||||
SIM_MODEL( aType, std::make_unique<SPICE_GENERATOR>( *this ) )
|
SIM_MODEL( aType, std::make_unique<SPICE_GENERATOR>( *this ) )
|
||||||
{
|
{
|
||||||
|
@ -1052,11 +1106,12 @@ std::string SIM_MODEL::GenerateParamValuePair( const PARAM& aParam, bool& aIsFir
|
||||||
if( boost::ends_with( aParam.info.name, "_" ) )
|
if( boost::ends_with( aParam.info.name, "_" ) )
|
||||||
name = aParam.info.name.substr( 0, aParam.info.name.length() - 1);
|
name = aParam.info.name.substr( 0, aParam.info.name.length() - 1);
|
||||||
|
|
||||||
std::string value = aParam.value->ToString();
|
std::string value = aParam.resolved ? aParam.value->ToString() : aParam.source.ToStdString();
|
||||||
|
|
||||||
if( value.find( " " ) != std::string::npos )
|
if( value.find( " " ) != std::string::npos )
|
||||||
value = "\"" + value + "\"";
|
value = "\"" + value + "\"";
|
||||||
|
|
||||||
result.append( fmt::format( "{}={}", aParam.info.name, value ) );
|
result.append( fmt::format( "{}={}", name, value ) );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,7 +1152,9 @@ std::string SIM_MODEL::GenerateParamsField( const std::string& aPairSeparator )
|
||||||
|
|
||||||
for( const PARAM& param : m_params )
|
for( const PARAM& param : m_params )
|
||||||
{
|
{
|
||||||
if( param.value->ToString() == "" )
|
std::string value = param.resolved ? param.value->ToString() : param.source.ToStdString();
|
||||||
|
|
||||||
|
if( value.empty() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result.append( GenerateParamValuePair( param, isFirst ) );
|
result.append( GenerateParamValuePair( param, isFirst ) );
|
||||||
|
@ -1116,12 +1173,10 @@ void SIM_MODEL::ParseParamsField( const std::string& aParamsField )
|
||||||
{
|
{
|
||||||
// Using parse tree instead of actions because we don't care about performance that much,
|
// Using parse tree instead of actions because we don't care about performance that much,
|
||||||
// and having a tree greatly simplifies things.
|
// and having a tree greatly simplifies things.
|
||||||
root = tao::pegtl::parse_tree::parse<
|
root = tao::pegtl::parse_tree::parse< SIM_MODEL_PARSER::fieldParamValuePairsGrammar,
|
||||||
SIM_MODEL_PARSER::fieldParamValuePairsGrammar,
|
|
||||||
SIM_MODEL_PARSER::fieldParamValuePairsSelector,
|
SIM_MODEL_PARSER::fieldParamValuePairsSelector,
|
||||||
tao::pegtl::nothing,
|
tao::pegtl::nothing,
|
||||||
SIM_MODEL_PARSER::control>
|
SIM_MODEL_PARSER::control>( in );
|
||||||
( in );
|
|
||||||
}
|
}
|
||||||
catch( const tao::pegtl::parse_error& e )
|
catch( const tao::pegtl::parse_error& e )
|
||||||
{
|
{
|
||||||
|
@ -1133,7 +1188,9 @@ void SIM_MODEL::ParseParamsField( const std::string& aParamsField )
|
||||||
for( const auto& node : root->children )
|
for( const auto& node : root->children )
|
||||||
{
|
{
|
||||||
if( node->is_type<SIM_MODEL_PARSER::param>() )
|
if( node->is_type<SIM_MODEL_PARSER::param>() )
|
||||||
|
{
|
||||||
paramName = node->string();
|
paramName = node->string();
|
||||||
|
}
|
||||||
// TODO: Do something with number<SIM_VALUE::TYPE_INT, ...>.
|
// TODO: Do something with number<SIM_VALUE::TYPE_INT, ...>.
|
||||||
// It doesn't seem too useful?
|
// It doesn't seem too useful?
|
||||||
else if( node->is_type<SIM_MODEL_PARSER::quotedStringContent>()
|
else if( node->is_type<SIM_MODEL_PARSER::quotedStringContent>()
|
||||||
|
@ -1142,7 +1199,10 @@ void SIM_MODEL::ParseParamsField( const std::string& aParamsField )
|
||||||
wxASSERT( paramName != "" );
|
wxASSERT( paramName != "" );
|
||||||
// TODO: Shouldn't be named "...fromSpiceCode" here...
|
// TODO: Shouldn't be named "...fromSpiceCode" here...
|
||||||
|
|
||||||
|
if( FindParam( paramName )->resolved )
|
||||||
SetParamValue( paramName, node->string(), SIM_VALUE_GRAMMAR::NOTATION::SI );
|
SetParamValue( paramName, node->string(), SIM_VALUE_GRAMMAR::NOTATION::SI );
|
||||||
|
else
|
||||||
|
SetParamSource( paramName, node->string() );
|
||||||
}
|
}
|
||||||
else if( node->is_type<SIM_MODEL_PARSER::quotedString>() )
|
else if( node->is_type<SIM_MODEL_PARSER::quotedString>() )
|
||||||
{
|
{
|
||||||
|
@ -1151,7 +1211,10 @@ void SIM_MODEL::ParseParamsField( const std::string& aParamsField )
|
||||||
// Unescape quotes.
|
// Unescape quotes.
|
||||||
boost::replace_all( str, "\\\"", "\"" );
|
boost::replace_all( str, "\\\"", "\"" );
|
||||||
|
|
||||||
|
if( FindParam( paramName )->resolved )
|
||||||
SetParamValue( paramName, str, SIM_VALUE_GRAMMAR::NOTATION::SI );
|
SetParamValue( paramName, str, SIM_VALUE_GRAMMAR::NOTATION::SI );
|
||||||
|
else
|
||||||
|
SetParamSource( paramName, str );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1275,9 +1338,11 @@ void SIM_MODEL::InferredReadDataFields( unsigned aSymbolPinCount, const std::vec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( node->is_type<SIM_MODEL_PARSER::fieldParamValuePairs>() )
|
else if( node->is_type<SIM_MODEL_PARSER::fieldParamValuePairs>() )
|
||||||
|
{
|
||||||
ParseParamsField( node->string() );
|
ParseParamsField( node->string() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch( const tao::pegtl::parse_error& e )
|
catch( const tao::pegtl::parse_error& e )
|
||||||
{
|
{
|
||||||
THROW_IO_ERROR( e.what() );
|
THROW_IO_ERROR( e.what() );
|
||||||
|
|
|
@ -463,12 +463,15 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool resolved;
|
||||||
|
wxString source;
|
||||||
std::unique_ptr<SIM_VALUE> value;
|
std::unique_ptr<SIM_VALUE> value;
|
||||||
const INFO& info;
|
const INFO& info;
|
||||||
bool isOtherVariant = false; // Legacy.
|
bool isOtherVariant = false; // Legacy.
|
||||||
|
|
||||||
PARAM( const INFO& aInfo, bool aIsOtherVariant = false )
|
PARAM( const INFO& aInfo, bool aIsOtherVariant = false )
|
||||||
: value( SIM_VALUE::Create( aInfo.type ) ),
|
: resolved( true ),
|
||||||
|
value( SIM_VALUE::Create( aInfo.type ) ),
|
||||||
info( aInfo ),
|
info( aInfo ),
|
||||||
isOtherVariant( aIsOtherVariant )
|
isOtherVariant( aIsOtherVariant )
|
||||||
{}
|
{}
|
||||||
|
@ -492,17 +495,17 @@ public:
|
||||||
static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields );
|
static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields );
|
||||||
|
|
||||||
|
|
||||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, unsigned aSymbolPinCount );
|
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, unsigned aSymbolPinCount, bool aResolve );
|
||||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel,
|
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
||||||
unsigned aSymbolPinCount );
|
bool aResolve );
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
||||||
const std::vector<T>& aFields );
|
const std::vector<T>& aFields, bool aResolve );
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::unique_ptr<SIM_MODEL> Create( unsigned aSymbolPinCount,
|
static std::unique_ptr<SIM_MODEL> Create( unsigned aSymbolPinCount,
|
||||||
const std::vector<T>& aFields );
|
const std::vector<T>& aFields, bool aResolve );
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::string GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName );
|
static std::string GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName );
|
||||||
|
@ -599,6 +602,9 @@ public:
|
||||||
void SetParamValue( const std::string& aParamName, const std::string& aValue,
|
void SetParamValue( const std::string& aParamName, const std::string& aValue,
|
||||||
SIM_VALUE::NOTATION aNotation = SIM_VALUE::NOTATION::SI );
|
SIM_VALUE::NOTATION aNotation = SIM_VALUE::NOTATION::SI );
|
||||||
|
|
||||||
|
void SetParamSource( const std::string& aParamName, const wxString& aSource );
|
||||||
|
void SetParamSource( int aParamIndex, const wxString& aSource );
|
||||||
|
|
||||||
bool HasOverrides() const;
|
bool HasOverrides() const;
|
||||||
bool HasNonInstanceOverrides() const;
|
bool HasNonInstanceOverrides() const;
|
||||||
bool HasSpiceNonInstanceOverrides() const;
|
bool HasSpiceNonInstanceOverrides() const;
|
||||||
|
@ -613,7 +619,7 @@ public:
|
||||||
bool IsInferred() const { return m_isInferred; }
|
bool IsInferred() const { return m_isInferred; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType );
|
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, bool aResolve );
|
||||||
|
|
||||||
SIM_MODEL( TYPE aType );
|
SIM_MODEL( TYPE aType );
|
||||||
SIM_MODEL( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator );
|
SIM_MODEL( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator );
|
||||||
|
@ -638,6 +644,8 @@ protected:
|
||||||
const SIM_MODEL* m_baseModel;
|
const SIM_MODEL* m_baseModel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static std::unique_ptr<SIM_MODEL> doCreate( TYPE aType );
|
||||||
|
|
||||||
static TYPE readTypeFromSpiceStrings( const std::string& aTypeString,
|
static TYPE readTypeFromSpiceStrings( const std::string& aTypeString,
|
||||||
const std::string& aLevel = "",
|
const std::string& aLevel = "",
|
||||||
const std::string& aVersion = "",
|
const std::string& aVersion = "",
|
||||||
|
|
|
@ -61,11 +61,11 @@ std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const SPICE_ITEM&
|
||||||
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const std::string aCwd,
|
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const std::string aCwd,
|
||||||
const std::string aCacheDir ) const
|
const std::string aCacheDir ) const
|
||||||
{
|
{
|
||||||
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
|
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
|
||||||
std::string ibisCompName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::NAME_FIELD );
|
std::string ibisCompName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY::NAME_FIELD );
|
||||||
std::string ibisPinName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::PIN_FIELD );
|
std::string ibisPinName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::PIN_FIELD );
|
||||||
std::string ibisModelName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
|
std::string ibisModelName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
|
||||||
bool diffMode = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
bool diffMode = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
||||||
|
|
||||||
wxFileName libPath = wxFileName( wxString( ibisLibFilename ) );
|
wxFileName libPath = wxFileName( wxString( ibisLibFilename ) );
|
||||||
|
|
||||||
|
@ -267,7 +267,8 @@ void SIM_MODEL_KIBIS::SwitchSingleEndedDiff( bool aDiff )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource ) : SIM_MODEL_KIBIS( aType )
|
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource, bool aResolve ) :
|
||||||
|
SIM_MODEL_KIBIS( aType )
|
||||||
{
|
{
|
||||||
for( PARAM& param1 : m_params )
|
for( PARAM& param1 : m_params )
|
||||||
{
|
{
|
||||||
|
@ -278,6 +279,12 @@ SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource ) :
|
||||||
if( param1.info.name == param2.info.name )
|
if( param1.info.name == param2.info.name )
|
||||||
*( param1.value ) = *( param2.value );
|
*( param1.value ) = *( param2.value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !aResolve )
|
||||||
|
{
|
||||||
|
param1.source = param1.value->ToString();
|
||||||
|
param1.resolved = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_componentName = aSource.m_componentName;
|
m_componentName = aSource.m_componentName;
|
||||||
|
@ -287,15 +294,15 @@ SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource ) :
|
||||||
}
|
}
|
||||||
|
|
||||||
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource,
|
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource,
|
||||||
const std::vector<LIB_FIELD>& aFields ) :
|
const std::vector<LIB_FIELD>& aFields, bool aResolve ) :
|
||||||
SIM_MODEL_KIBIS( aType, aSource )
|
SIM_MODEL_KIBIS( aType, aSource, aResolve )
|
||||||
{
|
{
|
||||||
ReadDataFields( 2, &aFields );
|
ReadDataFields( 2, &aFields );
|
||||||
}
|
}
|
||||||
|
|
||||||
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource,
|
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource,
|
||||||
const std::vector<SCH_FIELD>& aFields ) :
|
const std::vector<SCH_FIELD>& aFields, bool aResolve ) :
|
||||||
SIM_MODEL_KIBIS( aType, aSource )
|
SIM_MODEL_KIBIS( aType, aSource, aResolve )
|
||||||
{
|
{
|
||||||
ReadDataFields( 2, &aFields );
|
ReadDataFields( 2, &aFields );
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,12 @@ public:
|
||||||
|
|
||||||
// @brief Special copy constructor
|
// @brief Special copy constructor
|
||||||
// creates a a model with aType, but tries to match parameters from aSource.
|
// creates a a model with aType, but tries to match parameters from aSource.
|
||||||
SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource );
|
SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource, bool aResolve );
|
||||||
|
|
||||||
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<LIB_FIELD>& aFields );
|
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<LIB_FIELD>& aFields,
|
||||||
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<SCH_FIELD>& aFields );
|
bool aResolve );
|
||||||
|
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<SCH_FIELD>& aFields,
|
||||||
|
bool aResolve );
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> GetIbisPins() const
|
std::vector<std::pair<std::string, std::string>> GetIbisPins() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,8 +56,8 @@ std::string SPICE_GENERATOR_SPICE::Preview( const SPICE_ITEM& aItem ) const
|
||||||
std::unique_ptr<SIM_MODEL_SPICE> SIM_MODEL_SPICE::Create( const SIM_LIBRARY_SPICE& aLibrary,
|
std::unique_ptr<SIM_MODEL_SPICE> SIM_MODEL_SPICE::Create( const SIM_LIBRARY_SPICE& aLibrary,
|
||||||
const std::string& aSpiceCode )
|
const std::string& aSpiceCode )
|
||||||
{
|
{
|
||||||
auto model = static_cast<SIM_MODEL_SPICE*>(
|
SIM_MODEL::TYPE modelType = SPICE_MODEL_PARSER::ReadType( aLibrary, aSpiceCode );
|
||||||
SIM_MODEL::Create( SPICE_MODEL_PARSER::ReadType( aLibrary, aSpiceCode ) ).release() );
|
auto model = static_cast<SIM_MODEL_SPICE*>( SIM_MODEL::Create( modelType, true ).release() );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -588,7 +588,8 @@ void SIM_PLOT_FRAME::UpdateTunerValue( SCH_SYMBOL* aSymbol, const wxString& aVal
|
||||||
if( item == aSymbol )
|
if( item == aSymbol )
|
||||||
{
|
{
|
||||||
SIM_LIB_MGR mgr( Prj() );
|
SIM_LIB_MGR mgr( Prj() );
|
||||||
SIM_MODEL& model = mgr.CreateModel( *aSymbol ).model;
|
SIM_MODEL& model = mgr.CreateModel( &m_schematicFrame->GetCurrentSheet(), *aSymbol,
|
||||||
|
true ).model;
|
||||||
|
|
||||||
const SIM_MODEL::PARAM* tunerParam = model.GetTunerParam();
|
const SIM_MODEL::PARAM* tunerParam = model.GetTunerParam();
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,7 @@
|
||||||
#include <sim/sim_property.h>
|
#include <sim/sim_property.h>
|
||||||
#include <sim/sim_value.h>
|
#include <sim/sim_value.h>
|
||||||
#include <ki_exception.h>
|
#include <ki_exception.h>
|
||||||
#include <confirm.h>
|
|
||||||
#include <wx/combo.h>
|
#include <wx/combo.h>
|
||||||
#include <wx/combobox.h>
|
|
||||||
#include <wx/notebook.h>
|
|
||||||
|
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE( SIM_VALIDATOR, wxValidator )
|
wxBEGIN_EVENT_TABLE( SIM_VALIDATOR, wxValidator )
|
||||||
|
@ -170,87 +167,12 @@ void SIM_VALIDATOR::onKeyDown( wxKeyEvent& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE( SIM_BOOL_VALIDATOR, SIM_VALIDATOR )
|
bool SIM_VALIDATOR::Validate( wxWindow* aParent )
|
||||||
wxEND_EVENT_TABLE()
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_BOOL_VALIDATOR::Validate( wxWindow* aParent )
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SIM_STRING_VALIDATOR::SIM_STRING_VALIDATOR( SIM_VALUE::TYPE aValueType,
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
|
||||||
: SIM_VALIDATOR(),
|
|
||||||
m_valueType( aValueType ),
|
|
||||||
m_notation( aNotation )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxObject* SIM_STRING_VALIDATOR::Clone() const
|
|
||||||
{
|
|
||||||
return new SIM_STRING_VALIDATOR( *this );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_STRING_VALIDATOR::Validate( wxWindow* aParent )
|
|
||||||
{
|
|
||||||
if( !m_validatorWindow->IsEnabled() )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
wxTextEntry* const textEntry = getTextEntry();
|
|
||||||
|
|
||||||
if( !textEntry )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return isValid( textEntry->GetValue() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_STRING_VALIDATOR::TransferToWindow()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_STRING_VALIDATOR::TransferFromWindow()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SIM_STRING_VALIDATOR::isValid( const wxString& aString )
|
|
||||||
{
|
|
||||||
return SIM_VALUE_GRAMMAR::IsValid( aString.ToStdString(), m_valueType, m_notation );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxTextEntry* SIM_STRING_VALIDATOR::getTextEntry()
|
|
||||||
{
|
|
||||||
if( !m_validatorWindow )
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// Taken from wxTextValidator.
|
|
||||||
|
|
||||||
if( wxDynamicCast( m_validatorWindow, wxTextCtrl ) )
|
|
||||||
return ( wxTextCtrl* ) m_validatorWindow;
|
|
||||||
|
|
||||||
if( wxDynamicCast( m_validatorWindow, wxComboBox ) )
|
|
||||||
return ( wxComboBox* ) m_validatorWindow;
|
|
||||||
|
|
||||||
if( wxDynamicCast( m_validatorWindow, wxComboCtrl ) )
|
|
||||||
return ( wxComboCtrl* ) m_validatorWindow;
|
|
||||||
|
|
||||||
wxFAIL_MSG(
|
|
||||||
"SIM_STRING_VALIDATOR can only be used with wxTextCtrl, wxComboBox, or wxComboCtrl"
|
|
||||||
);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SIM_PROPERTY::SIM_PROPERTY( std::shared_ptr<SIM_LIBRARY> aLibrary,
|
SIM_PROPERTY::SIM_PROPERTY( std::shared_ptr<SIM_LIBRARY> aLibrary,
|
||||||
std::shared_ptr<SIM_MODEL> aModel,
|
std::shared_ptr<SIM_MODEL> aModel,
|
||||||
int aParamIndex )
|
int aParamIndex )
|
||||||
|
@ -279,7 +201,7 @@ SIM_BOOL_PROPERTY::SIM_BOOL_PROPERTY( const wxString& aLabel, const wxString& aN
|
||||||
|
|
||||||
wxValidator* SIM_BOOL_PROPERTY::DoGetValidator() const
|
wxValidator* SIM_BOOL_PROPERTY::DoGetValidator() const
|
||||||
{
|
{
|
||||||
return new SIM_BOOL_VALIDATOR();
|
return new SIM_VALIDATOR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -302,21 +224,21 @@ void SIM_BOOL_PROPERTY::OnSetValue()
|
||||||
SIM_STRING_PROPERTY::SIM_STRING_PROPERTY( const wxString& aLabel, const wxString& aName,
|
SIM_STRING_PROPERTY::SIM_STRING_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||||
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
||||||
std::shared_ptr<SIM_MODEL> aModel,
|
std::shared_ptr<SIM_MODEL> aModel,
|
||||||
int aParamIndex,
|
int aParamIndex )
|
||||||
SIM_VALUE::TYPE aValueType,
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
|
||||||
: wxStringProperty( aLabel, aName ),
|
: wxStringProperty( aLabel, aName ),
|
||||||
SIM_PROPERTY( aLibrary, aModel, aParamIndex ),
|
SIM_PROPERTY( aLibrary, aModel, aParamIndex )
|
||||||
m_valueType( aValueType ),
|
|
||||||
m_notation( aNotation )
|
|
||||||
{
|
{
|
||||||
SetValueFromString( GetParam().value->ToString() );
|
const SIM_MODEL::PARAM& param = GetParam();
|
||||||
|
|
||||||
|
wxASSERT( !param.resolved );
|
||||||
|
|
||||||
|
SetValueFromString( param.source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxValidator* SIM_STRING_PROPERTY::DoGetValidator() const
|
wxValidator* SIM_STRING_PROPERTY::DoGetValidator() const
|
||||||
{
|
{
|
||||||
return new SIM_STRING_VALIDATOR( m_valueType, m_notation );
|
return new SIM_VALIDATOR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -329,6 +251,13 @@ bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aT
|
||||||
// TODO: Don't use string comparison.
|
// TODO: Don't use string comparison.
|
||||||
if( m_model->GetBaseModel() && ( aText == "" || aText == baseParamValue ) )
|
if( m_model->GetBaseModel() && ( aText == "" || aText == baseParamValue ) )
|
||||||
{
|
{
|
||||||
|
// TODO: do we want this magic of clearing overrides?
|
||||||
|
// Consider the case where someone uses a library model set to 220u and overrides it to
|
||||||
|
// 330u. Someone then modifies the library to use 330u. But that doesn't work either,
|
||||||
|
// so they modify the library again to 470u. If the overridden symbol was edited in the
|
||||||
|
// middle (to set some other parameter perhaps), it suddenly gets changed to 470u, which
|
||||||
|
// will be a surprise to the user.
|
||||||
|
// NOTE: other properties also contain this magic.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_model->SetParamValue( m_paramIndex, "" ); // Nullify.
|
m_model->SetParamValue( m_paramIndex, "" ); // Nullify.
|
||||||
|
@ -342,8 +271,8 @@ bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aT
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_model->SetParamValue( m_paramIndex, std::string( aText.ToUTF8() ) );
|
m_model->SetParamSource( m_paramIndex, aText );
|
||||||
aVariant = GetParam().value->ToString();
|
aVariant = aText;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -364,9 +293,7 @@ static wxArrayString convertStringsToWx( const std::vector<std::string>& aString
|
||||||
SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||||
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
||||||
std::shared_ptr<SIM_MODEL> aModel,
|
std::shared_ptr<SIM_MODEL> aModel,
|
||||||
int aParamIndex,
|
int aParamIndex )
|
||||||
SIM_VALUE::TYPE aValueType,
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
|
||||||
: wxEnumProperty( aLabel, aName,
|
: wxEnumProperty( aLabel, aName,
|
||||||
convertStringsToWx( aModel->GetParam( aParamIndex ).info.enumValues ) ),
|
convertStringsToWx( aModel->GetParam( aParamIndex ).info.enumValues ) ),
|
||||||
SIM_PROPERTY( aLibrary, aModel, aParamIndex )
|
SIM_PROPERTY( aLibrary, aModel, aParamIndex )
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include <wx/propgrid/props.h>
|
#include <wx/propgrid/props.h>
|
||||||
|
|
||||||
|
|
||||||
|
// This doesn't actually do any validation, but it's a convenient place to fix some navigation
|
||||||
|
// issues with wxPropertyGrid.
|
||||||
class SIM_VALIDATOR : public wxValidator
|
class SIM_VALIDATOR : public wxValidator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -40,41 +42,8 @@ private:
|
||||||
|
|
||||||
void onKeyDown( wxKeyEvent& aEvent );
|
void onKeyDown( wxKeyEvent& aEvent );
|
||||||
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SIM_STRING_VALIDATOR : public SIM_VALIDATOR
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SIM_STRING_VALIDATOR( SIM_VALUE::TYPE aValueType, SIM_VALUE_GRAMMAR::NOTATION aNotation );
|
|
||||||
SIM_STRING_VALIDATOR( const SIM_STRING_VALIDATOR& aValidator ) = default;
|
|
||||||
|
|
||||||
wxObject* Clone() const override;
|
|
||||||
|
|
||||||
bool Validate( wxWindow* aParent ) override;
|
|
||||||
bool TransferToWindow() override;
|
|
||||||
bool TransferFromWindow() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isValid( const wxString& aString );
|
|
||||||
|
|
||||||
wxTextEntry* getTextEntry();
|
|
||||||
|
|
||||||
SIM_VALUE::TYPE m_valueType;
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION m_notation;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SIM_BOOL_VALIDATOR : public SIM_VALIDATOR
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SIM_BOOL_VALIDATOR() : SIM_VALIDATOR() {}
|
|
||||||
SIM_BOOL_VALIDATOR( const SIM_BOOL_VALIDATOR& aValidator ) = default;
|
|
||||||
|
|
||||||
bool Validate( wxWindow* aParent ) override;
|
bool Validate( wxWindow* aParent ) override;
|
||||||
|
|
||||||
private:
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -117,18 +86,12 @@ public:
|
||||||
SIM_STRING_PROPERTY( const wxString& aLabel, const wxString& aName,
|
SIM_STRING_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||||
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
||||||
std::shared_ptr<SIM_MODEL> aModel,
|
std::shared_ptr<SIM_MODEL> aModel,
|
||||||
int aParamIndex,
|
int aParamIndex );
|
||||||
SIM_VALUE::TYPE aValueType = SIM_VALUE::TYPE_FLOAT,
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI );
|
|
||||||
|
|
||||||
wxValidator* DoGetValidator() const override;
|
wxValidator* DoGetValidator() const override;
|
||||||
|
|
||||||
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 )
|
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 )
|
||||||
const override;
|
const override;
|
||||||
|
|
||||||
protected:
|
|
||||||
SIM_VALUE::TYPE m_valueType;
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION m_notation;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,9 +101,7 @@ public:
|
||||||
SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
|
||||||
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
std::shared_ptr<SIM_LIBRARY> aLibrary,
|
||||||
std::shared_ptr<SIM_MODEL> aModel,
|
std::shared_ptr<SIM_MODEL> aModel,
|
||||||
int aParamIndex,
|
int aParamIndex );
|
||||||
SIM_VALUE::TYPE aValueType = SIM_VALUE::TYPE_FLOAT,
|
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI );
|
|
||||||
|
|
||||||
bool IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags = 0 ) const override;
|
bool IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags = 0 ) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct SPICE_ITEM
|
||||||
std::string baseModelName;
|
std::string baseModelName;
|
||||||
std::string modelName;
|
std::string modelName;
|
||||||
const SIM_MODEL* model = nullptr;
|
const SIM_MODEL* model = nullptr;
|
||||||
const std::vector<SCH_FIELD>* fields = nullptr;
|
std::vector<SCH_FIELD> fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -874,6 +874,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
||||||
EDA_ITEM* item = selTool->GetNode( aPosition );
|
EDA_ITEM* item = selTool->GetNode( aPosition );
|
||||||
|
SCH_SHEET_PATH& sheet = m_frame->GetCurrentSheet();
|
||||||
|
|
||||||
if( !item )
|
if( !item )
|
||||||
return false;
|
return false;
|
||||||
|
@ -887,10 +888,10 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
std::vector<LIB_PIN*> pins = symbol->GetLibPins();
|
std::vector<LIB_PIN*> pins = symbol->GetLibPins();
|
||||||
|
|
||||||
SIM_LIB_MGR mgr( m_frame->Prj() );
|
SIM_LIB_MGR mgr( m_frame->Prj() );
|
||||||
SIM_MODEL& model = mgr.CreateModel( *symbol ).model;
|
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, true ).model;
|
||||||
|
|
||||||
SPICE_ITEM spiceItem;
|
SPICE_ITEM spiceItem;
|
||||||
spiceItem.refName = std::string( symbol->GetRef( &m_frame->GetCurrentSheet() ).ToUTF8() );
|
spiceItem.refName = std::string( symbol->GetRef( &sheet ).ToUTF8() );
|
||||||
std::vector<std::string> currentNames =
|
std::vector<std::string> currentNames =
|
||||||
model.SpiceGenerator().CurrentNames( spiceItem );
|
model.SpiceGenerator().CurrentNames( spiceItem );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue