37using namespace std::placeholders;
60 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
63 embeddedFilesStack.push_back( embeddedFiles );
65 wxString resolvedPath =
resolver.ResolvePath( aLibraryPath, wxEmptyString,
66 std::move( embeddedFilesStack ) );
69 if( !resolvedPath.IsEmpty() )
71 wxFileName fn( resolvedPath );
74 return fn.GetFullPath();
82 expandedPath.Replace(
'\\',
'/' );
84 wxFileName fn( expandedPath );
86 if( fn.IsAbsolute() && fn.Exists() )
87 return fn.GetFullPath();
89 wxFileName projectFn(
m_project ?
m_project->AbsolutePath( expandedPath ) : expandedPath );
91 if( projectFn.Exists() )
92 return projectFn.GetFullPath();
95 wxFileName spiceLibFn( expandedPath );
98 wxGetEnv( wxT(
"SPICE_LIB_DIR" ), &spiceLibDir );
100 if( !spiceLibDir.IsEmpty() && spiceLibFn.MakeAbsolute( spiceLibDir ) && spiceLibFn.Exists() )
101 return spiceLibFn.GetFullPath();
103 if( spiceLibDir.IsEmpty() || spiceLibFn.GetFullPath() == projectFn.GetFullPath() )
105 aReporter.
Report( wxString::Format(
_(
"Simulation model library not found at '%s'" ),
106 projectFn.GetFullPath() ) );
110 aReporter.
Report( wxString::Format(
_(
"Simulation model library not found at '%s' or '%s'" ),
111 projectFn.GetFullPath(),
112 spiceLibFn.GetFullPath() ) );
120 const wxString& aRelativeLib,
123 wxFileName testPath( aLibPath );
124 wxString fullPath( aLibPath );
126 if( !testPath.IsAbsolute() && !aRelativeLib.empty() )
128 wxString relLib( aRelativeLib );
132 wxFileName fn( relLib );
134 testPath.MakeAbsolute( fn.GetPath(
true ) );
135 fullPath = testPath.GetFullPath();
138 wxFileName fn( fullPath );
156 if( !wxFileName::Exists(
path ) )
158 aReporter.
Report( wxString::Format(
_(
"Simulation model library not found at '%s'" ),
164 [&](
const wxString& libPath,
const wxString& relativeLib ) -> wxString
183 std::span<const wxString> aPins,
REPORTER& aReporter )
191 const std::vector<SCH_FIELD>& aFields,
bool aResolve,
int aDepth,
200 int aDepth,
const wxString& aVariantName,
201 const wxString& aMergedSimPins )
210 input.
fields.emplace_back( field.GetName(), aSymbol.
GetRef( aSheetPath ) );
212 else if( field.GetId() ==
FIELD_T::VALUE || field.GetName().StartsWith( wxS(
"Sim." ) ) )
214 const wxString value = !aMergedSimPins.IsEmpty() && field.GetName() ==
SIM_PINS_FIELD
216 : field.GetShownText( aSheetPath,
FOR_NETNAME, aVariantName, aDepth );
217 input.
fields.emplace_back( field.GetName(), value );
225 [](
const wxString& lhs,
const wxString& rhs ) { return StrNumCmp( lhs, rhs, true ) < 0; } );
231 bool aResolve,
int aDepth,
const wxString& aVariantName,
232 REPORTER& aReporter,
const wxString& aMergedSimPins )
235 aResolve, aReporter );
242 std::vector<SCH_FIELD> fields;
244 for(
const auto& [
name, value] : aInput.
fields )
247 fields.back().SetText( value );
250 auto getOrCreateField =
257 return &fields.back();
262 wxString modelParams;
264 bool storeInValue =
false;
272 if( !modelType.IsEmpty() )
283 model.model.SetIsStoredInValue( storeInValue );
290 bool aResolve,
int aDepth,
291 std::span<const wxString> aPins,
294 return createModel( aFields, aResolve, aDepth, aPins, aReporter, aResolve );
299 std::span<const wxString> aPins,
REPORTER& aReporter,
300 bool aAllowRawFallback )
305 if( libraryPath !=
"" )
307 return CreateModel( libraryPath, baseModelName, aFields, aResolve, aDepth, aPins, aReporter );
312 return { baseModelName, *
m_models.back() };
318 const std::string& aBaseModelName,
319 const std::vector<SCH_FIELD>& aFields,
320 bool aResolve,
int aDepth,
321 std::span<const wxString> aPins,
327 std::string modelName;
335 [&](
const wxString& libPath,
const wxString& relativeLib ) -> wxString
343 if( aBaseModelName ==
"" )
345 msg.Printf(
_(
"Error loading simulation model: no '%s' field" ),
350 modelName =
_(
"unknown" ).ToStdString();
354 baseModel =
library->FindModel( aBaseModelName );
355 modelName = aBaseModelName;
359 msg.Printf(
_(
"Error loading simulation model: could not find base model '%s' "
370 return { modelName, *
m_models.back() };
376 m_models.at( aIndex ) = std::move( aModel );
382 std::map<wxString, std::reference_wrapper<const SIM_LIBRARY>> libraries;
393 std::vector<std::reference_wrapper<SIM_MODEL>> models;
396 models.emplace_back( *
model );
Provide an extensible class to resolve 3D model paths.
Container for project specific data.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
virtual bool HasMessageOfSeverity(int aSeverityMask) const
Returns true if the reporter has one or more messages matching the specified severity mask.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
std::vector< SCH_PIN * > GetAllLibPins() const
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
wxString GetPrefix() const
static std::unique_ptr< SIM_LIBRARY > Create(const wxString &aFilePath, bool aForceFullParse, REPORTER &aReporter, const std::function< wxString(const wxString &, const wxString &)> &aResolver)
Read library from a source file (e.g.
static constexpr auto LIBRARY_FIELD
static constexpr auto NAME_FIELD
void SetModel(int aIndex, std::unique_ptr< SIM_MODEL > aModel)
SIM_LIBRARY::MODEL createModel(const std::vector< SCH_FIELD > &aFields, bool aResolve, int aDepth, std::span< const wxString > aPins, REPORTER &aReporter, bool aAllowRawFallback)
wxString ResolveLibraryPath(const wxString &aLibraryPath, REPORTER &aReporter)
const PROJECT * m_project
std::vector< EMBEDDED_FILES * > m_embeddedFilesStack
SIM_LIB_MGR(const PROJECT *aPrj)
std::vector< std::unique_ptr< SIM_MODEL > > m_models
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, std::span< const wxString > aPins, REPORTER &aReporter)
std::map< wxString, std::reference_wrapper< const SIM_LIBRARY > > GetLibraries() const
wxString ResolveEmbeddedLibraryPath(const wxString &aLibPath, const wxString &aRelativeLib, REPORTER &aReporter)
std::vector< std::reference_wrapper< SIM_MODEL > > GetModels() const
static SIM_MODEL_INPUT CaptureModelInput(const SCH_SHEET_PATH *aSheetPath, const SCH_SYMBOL &aSymbol, int aDepth, const wxString &aVariantName, const wxString &aMergedSimPins=wxEmptyString)
Resolve instance fields once; editors use the field-based overloads for unresolved input.
void SetLibrary(const wxString &aLibraryPath, REPORTER &aReporter)
std::map< wxString, std::unique_ptr< SIM_LIBRARY > > m_libraries
static std::unique_ptr< SIM_MODEL > Create(TYPE aType, std::span< const wxString > aPins, REPORTER &aReporter)
static bool InferSimModel(const wxString &aPrefix, std::span< const wxString > aPins, std::vector< SCH_FIELD > *aFields, bool aResolve, int aDepth, SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString *aDeviceType, wxString *aModelType, wxString *aModelParams, wxString *aPinMap)
aPins follows lexical symbol-pin number order, including duplicate numbers.
static std::vector< wxString > PinNumbers(std::span< const SCH_PIN *const > aPins)
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
static FILENAME_RESOLVER * resolver
wxString GetFieldValue(const std::vector< SCH_FIELD > *aFields, FIELD_T aFieldType)
const SCH_FIELD * FindField(const std::vector< SCH_FIELD > &aFields, FIELD_T aFieldId)
#define SIM_DEVICE_SUBTYPE_FIELD
@ USER
The field ID hasn't been set yet; field is invalid.
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".