SIM_MODEL code simplification.
1) Reduce API surface. 2) Prefer for(int) loops when what we're looking for is the index of the item to be found 3) Move "_" escape processing to SIM_MODEL_NGSPICE (which is the only model which uses the escape mechanism)
This commit is contained in:
parent
75053cfc57
commit
e7e3f3bced
|
@ -532,18 +532,13 @@ std::string SIM_MODEL::GetFieldValue( const std::vector<T>* aFields, const std::
|
|||
if( !aFields )
|
||||
return ""; // Should not happen, T=void specialization will be called instead.
|
||||
|
||||
auto it = std::find_if( aFields->begin(), aFields->end(),
|
||||
[aFieldName]( const T& field )
|
||||
for( const T& field : *aFields )
|
||||
{
|
||||
return field.GetName() == aFieldName;
|
||||
} );
|
||||
if( field.GetName() == aFieldName )
|
||||
return aResolve ? field.GetShownText().ToStdString() : field.GetText().ToStdString();
|
||||
}
|
||||
|
||||
if( it == aFields->end() )
|
||||
return "";
|
||||
else if( aResolve )
|
||||
return std::string( it->GetShownText().ToUTF8() );
|
||||
else
|
||||
return std::string( it->GetText().ToUTF8() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -660,39 +655,30 @@ void SIM_MODEL::SetPinSymbolPinNumber( int aPinIndex, const std::string& aSymbol
|
|||
void SIM_MODEL::SetPinSymbolPinNumber( const std::string& aPinName,
|
||||
const std::string& aSymbolPinNumber )
|
||||
{
|
||||
int aPinIndex = -1;
|
||||
|
||||
const std::vector<std::reference_wrapper<const PIN>> pins = GetPins();
|
||||
|
||||
for( int ii = 0; ii < (int) pins.size(); ++ii )
|
||||
{
|
||||
if( pins.at( ii ).get().name == aPinName )
|
||||
{
|
||||
aPinIndex = ii;
|
||||
break;
|
||||
SetPinSymbolPinNumber( ii, aSymbolPinNumber );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( aPinIndex < 0 )
|
||||
// If aPinName wasn't in fact a name, see if it's a raw (1-based) index. This is required
|
||||
// for legacy files which didn't use pin names.
|
||||
int aPinIndex = (int) strtol( aPinName.c_str(), nullptr, 10 );
|
||||
|
||||
if( aPinIndex < 1 )
|
||||
{
|
||||
// If aPinName wasn't in fact a name, see if it's a raw (1-based) index. This is
|
||||
// required for legacy files which didn't use pin names.
|
||||
aPinIndex = (int) strtol( aPinName.c_str(), nullptr, 10 );
|
||||
|
||||
// Convert to 0-based. (Note that this will also convert the error state to -1, which
|
||||
// means we don't have to check for it separately.)
|
||||
aPinIndex--;
|
||||
}
|
||||
|
||||
if( aPinIndex < 0 )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Could not find a pin named '%s' in "
|
||||
"simulation model of type '%s'" ),
|
||||
THROW_IO_ERROR( wxString::Format( _( "Could not find a pin named '%s' in simulation "
|
||||
"model of type '%s'" ),
|
||||
aPinName,
|
||||
GetTypeInfo().fieldValue ) );
|
||||
}
|
||||
|
||||
SetPinSymbolPinNumber( aPinIndex, aSymbolPinNumber );
|
||||
SetPinSymbolPinNumber( --aPinIndex /* convert to 0-based */, aSymbolPinNumber );
|
||||
}
|
||||
|
||||
|
||||
|
@ -705,34 +691,27 @@ const SIM_MODEL::PARAM& SIM_MODEL::GetParam( unsigned aParamIndex ) const
|
|||
}
|
||||
|
||||
|
||||
const SIM_MODEL::PARAM* SIM_MODEL::FindParam( const std::string& aParamName ) const
|
||||
int SIM_MODEL::doFindParam( const std::string& aParamName ) const
|
||||
{
|
||||
std::string lowerParamName = boost::to_lower_copy( aParamName );
|
||||
|
||||
std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
|
||||
|
||||
auto it = std::find_if( params.begin(), params.end(),
|
||||
[lowerParamName]( const PARAM& param )
|
||||
for( int ii = 0; ii < (int) params.size(); ++ii )
|
||||
{
|
||||
return param.info.name == lowerParamName;
|
||||
} );
|
||||
|
||||
// Also check for model params that had to be escaped due to collisions with instance
|
||||
// params.
|
||||
if( it == params.end() )
|
||||
{
|
||||
it = std::find_if( params.begin(), params.end(),
|
||||
[lowerParamName]( const PARAM& param )
|
||||
{
|
||||
return param.info.name == lowerParamName + "_";
|
||||
} );
|
||||
|
||||
if( params[ii].get().info.name == lowerParamName )
|
||||
return ii;
|
||||
}
|
||||
|
||||
if( it == params.end() )
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return &it->get();
|
||||
|
||||
const SIM_MODEL::PARAM* SIM_MODEL::FindParam( const std::string& aParamName ) const
|
||||
{
|
||||
int idx = doFindParam( aParamName );
|
||||
|
||||
return idx >= 0 ? &GetParam( idx ) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -776,48 +755,12 @@ void SIM_MODEL::SetParamValue( int aParamIndex, const std::string& aValue,
|
|||
}
|
||||
|
||||
|
||||
void SIM_MODEL::SetParamValue( const std::string& aParamName, const SIM_VALUE& aValue )
|
||||
{
|
||||
std::string lowerParamName = boost::to_lower_copy( aParamName );
|
||||
|
||||
std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
|
||||
|
||||
auto it = std::find_if( params.begin(), params.end(),
|
||||
[lowerParamName]( const PARAM& param )
|
||||
{
|
||||
return param.info.name == lowerParamName;
|
||||
} );
|
||||
|
||||
// Also check for model params that had to be escaped due to collisions with instance
|
||||
// params.
|
||||
if( it == params.end() )
|
||||
{
|
||||
it = std::find_if( params.begin(), params.end(),
|
||||
[lowerParamName]( const PARAM& param )
|
||||
{
|
||||
return param.info.name == lowerParamName + "_";
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
if( it == params.end() )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Could not find a parameter named '%s' in "
|
||||
"simulation model of type '%s'" ),
|
||||
aParamName,
|
||||
GetTypeInfo().fieldValue ) );
|
||||
}
|
||||
|
||||
SetParamValue( static_cast<int>( it - params.begin() ), aValue );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL::SetParamValue( const std::string& aParamName, const std::string& aValue,
|
||||
SIM_VALUE::NOTATION aNotation )
|
||||
{
|
||||
const PARAM* param = FindParam( aParamName );
|
||||
int idx = doFindParam( aParamName );
|
||||
|
||||
if( !param )
|
||||
if( idx < 0 )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Could not find a parameter named '%s' in "
|
||||
"simulation model of type '%s'" ),
|
||||
|
@ -825,8 +768,7 @@ void SIM_MODEL::SetParamValue( const std::string& aParamName, const std::string&
|
|||
GetTypeInfo().fieldValue ) );
|
||||
}
|
||||
|
||||
const SIM_VALUE& value = *FindParam( aParamName )->value;
|
||||
SetParamValue( aParamName, *SIM_VALUE::Create( value.GetType(), aValue, aNotation ) );
|
||||
SetParamValue( idx, aValue, aNotation );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -495,7 +495,6 @@ public:
|
|||
virtual void SetParamValue( int aParamIndex, const SIM_VALUE& aValue );
|
||||
void SetParamValue( int aParamIndex, const std::string& aValue,
|
||||
SIM_VALUE::NOTATION aNotation = SIM_VALUE::NOTATION::SI );
|
||||
void SetParamValue( const std::string& aParamName, const SIM_VALUE& aValue );
|
||||
void SetParamValue( const std::string& aParamName, const std::string& aValue,
|
||||
SIM_VALUE::NOTATION aNotation = SIM_VALUE::NOTATION::SI );
|
||||
|
||||
|
@ -537,6 +536,8 @@ protected:
|
|||
|
||||
virtual void CreatePins( const std::vector<LIB_PIN*>& aSymbolPins );
|
||||
|
||||
virtual int doFindParam( const std::string& aParamName ) const;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void doReadDataFields( const std::vector<T>* aFields, const std::vector<LIB_PIN*>& aPins );
|
||||
|
|
|
@ -81,8 +81,28 @@ SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType ) :
|
|||
}
|
||||
|
||||
|
||||
int SIM_MODEL_NGSPICE::doFindParam( const std::string& aParamName ) const
|
||||
{
|
||||
// Special case to allow escaped model parameters (suffixed with "_")
|
||||
|
||||
std::string lowerParamName = boost::to_lower_copy( aParamName );
|
||||
|
||||
std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
|
||||
|
||||
for( int ii = 0; ii < (int) params.size(); ++ii )
|
||||
{
|
||||
const PARAM& param = params[ii];
|
||||
|
||||
if( param.info.name == lowerParamName || param.info.name == lowerParamName + "_" )
|
||||
return ii;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const std::string& aParamName,
|
||||
const std::string& aParamValue,
|
||||
const std::string& aValue,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
||||
{
|
||||
std::string paramName = boost::to_lower_copy( aParamName );
|
||||
|
@ -99,67 +119,54 @@ void SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const std::string& aParamName,
|
|||
|
||||
std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
|
||||
|
||||
auto paramIt = std::find_if( params.begin(), params.end(),
|
||||
[lowerParamName]( const PARAM& param )
|
||||
for( int ii = 0; ii < (int) params.size(); ++ii )
|
||||
{
|
||||
return !param.info.isSpiceInstanceParam
|
||||
&& param.info.category != PARAM::CATEGORY::SUPERFLUOUS
|
||||
&& ( param.info.name == lowerParamName
|
||||
|| param.info.name == lowerParamName + "_" );
|
||||
} );
|
||||
const PARAM& param = params[ii];
|
||||
|
||||
if( paramIt != params.end() )
|
||||
if( !param.info.isSpiceInstanceParam
|
||||
&& param.info.category != PARAM::CATEGORY::SUPERFLUOUS
|
||||
&& ( param.info.name == lowerParamName || param.info.name == lowerParamName + "_" ) )
|
||||
{
|
||||
SIM_MODEL::SetParamValue( static_cast<int>( paramIt - params.begin() ), aParamValue, aNotation );
|
||||
const SIM_VALUE& value = *GetParam( ii ).value;
|
||||
SetParamValue( ii, *SIM_VALUE::Create( value.GetType(), aValue, aNotation ) );
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// One Spice param can have multiple names, we need to take this into account.
|
||||
|
||||
std::vector<PARAM::INFO> ngspiceParams = ModelInfo( getModelType() ).modelParams;
|
||||
// Now we search the base model parameters without excluding superfluous parameters (which
|
||||
// may be aliases to non-superfluous parameters).
|
||||
|
||||
auto ngspiceParamIt = std::find_if( ngspiceParams.begin(), ngspiceParams.end(),
|
||||
[lowerParamName]( const PARAM& param )
|
||||
for( const PARAM::INFO& ngspiceParamInfo : ModelInfo( getModelType() ).modelParams )
|
||||
{
|
||||
// Now we search without excluding Spice instance
|
||||
// parameters and superfluous parameters.
|
||||
return param.info.name == lowerParamName;
|
||||
} );
|
||||
if( ngspiceParamInfo.name == lowerParamName )
|
||||
{
|
||||
// Find an actual parameter with the same id. Even if the ngspiceParam was
|
||||
// superfluous, its alias target might not be.
|
||||
for( int ii = 0; ii < (int) params.size(); ++ii )
|
||||
{
|
||||
const PARAM& param = params[ii];
|
||||
|
||||
if( ngspiceParamIt == ngspiceParams.end() )
|
||||
if( param.info.id == ngspiceParamInfo.id
|
||||
&& param.info.category != PARAM::CATEGORY::SUPERFLUOUS )
|
||||
{
|
||||
if( canSilentlyIgnoreParam( paramName ) )
|
||||
const SIM_VALUE& value = *GetParam( ii ).value;
|
||||
SetParamValue( ii, *SIM_VALUE::Create( value.GetType(), aValue, aNotation ) );
|
||||
return;
|
||||
|
||||
THROW_IO_ERROR( wxString::Format( "Failed to set parameter '%s' to value '%s'",
|
||||
aParamName,
|
||||
aParamValue ) );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We obtain the id of the Ngspice param that is to be set. We use this id to address the
|
||||
// parameter to be set here because a superfluous parameter may be an alias: this will
|
||||
// dereference it.
|
||||
unsigned id = ngspiceParamIt->id;
|
||||
|
||||
// Find an actual parameter with the same id.
|
||||
paramIt = std::find_if( params.begin(), params.end(),
|
||||
[id]( const PARAM& param )
|
||||
{
|
||||
// Look for any non-superfluous parameter with the same id.
|
||||
return param.info.id == id
|
||||
&& param.info.category != PARAM::CATEGORY::SUPERFLUOUS;
|
||||
} );
|
||||
|
||||
if( paramIt == params.end() )
|
||||
if( !canSilentlyIgnoreParam( paramName ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( "Failed to set parameter '%s' to value '%s'",
|
||||
aParamName,
|
||||
aParamValue ) );
|
||||
aValue ) );
|
||||
}
|
||||
|
||||
SIM_MODEL::SetParamValue( static_cast<int>( paramIt - params.begin() ), aParamValue, aNotation );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
|
||||
SIM_MODEL_NGSPICE( TYPE aType );
|
||||
|
||||
void SetParamFromSpiceCode( const std::string& aParamName, const std::string& aParamValue,
|
||||
void SetParamFromSpiceCode( const std::string& aParamName, const std::string& aValue,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation ) override;
|
||||
|
||||
// Protected because it's accessed by QA tests.
|
||||
|
@ -104,6 +104,8 @@ protected:
|
|||
|
||||
static const MODEL_INFO& ModelInfo( MODEL_TYPE aType );
|
||||
|
||||
int doFindParam( const std::string& aParamName ) const override;
|
||||
|
||||
private:
|
||||
bool requiresSpiceModelLine() const override { return false; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue