diff --git a/eeschema/dialogs/dialog_sim_model.cpp b/eeschema/dialogs/dialog_sim_model.cpp index e7c73e037c..cf39288ace 100644 --- a/eeschema/dialogs/dialog_sim_model.cpp +++ b/eeschema/dialogs/dialog_sim_model.cpp @@ -46,10 +46,10 @@ DIALOG_SIM_MODEL::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, : DIALOG_SIM_MODEL_BASE( aParent ), m_symbol( aSymbol ), m_fields( aFields ), - m_builtinModelMgr( Prj() ), - m_curModelType( SIM_MODEL::TYPE::NONE ), - m_library( std::make_shared() ), + m_libraryModelsMgr( Prj() ), + m_builtinModelsMgr( Prj() ), m_prevModel( nullptr ), + m_curModelType( SIM_MODEL::TYPE::NONE ), m_scintillaTricks( nullptr ), m_wasCodePreviewUpdated( true ), m_firstCategory( nullptr ), @@ -143,7 +143,6 @@ bool DIALOG_SIM_MODEL::TransferDataToWindow() wxCommandEvent dummyEvent; int pinCount = m_sortedSymbolPins.size(); - std::string ref = SIM_MODEL::GetFieldValue( &m_fields, SIM_MODEL::REFERENCE_FIELD ); std::string libraryFilename = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::LIBRARY_FIELD ); if( libraryFilename != "" ) @@ -159,7 +158,7 @@ bool DIALOG_SIM_MODEL::TransferDataToWindow() if( isIbisLoaded() && ( m_modelNameCombobox->GetSelection() >= 0 ) ) { SIM_MODEL_KIBIS* kibismodel = dynamic_cast( - m_libraryModels.at( m_modelNameCombobox->GetSelection() ).get() ); + &m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get() ); if( kibismodel ) { @@ -172,9 +171,9 @@ bool DIALOG_SIM_MODEL::TransferDataToWindow() if( strs.first == SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY_KIBIS::PIN_FIELD ) ) { - kibismodel->ChangePin( - *( std::dynamic_pointer_cast( m_library ) ), - strs.first ); + auto kibisLibrary = static_cast( library() ); + + kibismodel->ChangePin( *kibisLibrary, strs.first ); m_ibisPinCombobox->SetSelection( static_cast( i ) ); break; } @@ -214,9 +213,9 @@ bool DIALOG_SIM_MODEL::TransferDataToWindow() try { if( m_useInstanceModelRadioButton->GetValue() && type == m_curModelType ) - m_builtinModelMgr.CreateModel( m_fields, m_sortedSymbolPins.size() ); + m_builtinModelsMgr.CreateModel( m_fields, pinCount ); else - m_builtinModelMgr.CreateModel( type, m_sortedSymbolPins.size() ); + m_builtinModelsMgr.CreateModel( type, pinCount ); } catch( const IO_ERROR& e ) { @@ -256,9 +255,9 @@ bool DIALOG_SIM_MODEL::TransferDataFromWindow() std::string path; - if( m_useLibraryModelRadioButton->GetValue() || isIbisLoaded() ) + if( ( library() && m_useLibraryModelRadioButton->GetValue() ) || isIbisLoaded() ) { - path = m_library->GetFilePath(); + path = library()->GetFilePath(); wxFileName fn( path ); if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( ".." ) ) @@ -270,7 +269,7 @@ bool DIALOG_SIM_MODEL::TransferDataFromWindow() if( isIbisLoaded() ) { SIM_MODEL_KIBIS* kibismodel = dynamic_cast( - m_libraryModels.at( m_modelNameCombobox->GetSelection() ).get() ); + &m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get() ); if( kibismodel ) { @@ -584,51 +583,21 @@ void DIALOG_SIM_MODEL::removeOrphanedPinAssignments() template -void DIALOG_SIM_MODEL::loadLibrary( const wxString& aFilePath ) +void DIALOG_SIM_MODEL::loadLibrary( const wxString& aLibraryPath ) { - const wxString absolutePath = Prj().AbsolutePath( aFilePath ); - - if( absolutePath.EndsWith( ".ibs" ) ) - m_library = std::make_shared(); - else - m_library = std::make_shared(); + m_libraryModelsMgr.Clear(); + m_libraryModelsMgr.CreateLibrary( std::string( aLibraryPath.ToUTF8() ) ); try { - m_library->ReadFile( std::string( absolutePath.ToUTF8() ) ); - } - catch( const IO_ERROR& e ) - { - DisplayErrorMessage( this, wxString::Format( _( "Failed reading model library '%s'." ), - absolutePath ), - e.What() ); - return; - } + std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD ); - m_tclibraryPathName->ChangeValue( aFilePath ); - - m_libraryModels.clear(); - - try - { - for( auto& [baseModelName, baseModel] : m_library->GetModels() ) + for( auto& [baseModelName, baseModel] : library()->GetModels() ) { - wxString expectedModelName = - SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD ); - - // Only the current model is initialized from fields. Others have default - // initialization. - if( baseModelName == expectedModelName ) - { - //TODO: it's not cur model. - - m_libraryModels.push_back( - SIM_MODEL::Create( baseModel, m_sortedSymbolPins.size(), m_fields ) ); - } + if( baseModelName == modelName ) + m_libraryModelsMgr.CreateModel( baseModel, m_sortedSymbolPins.size(), m_fields ); else - { - m_libraryModels.push_back( SIM_MODEL::Create( baseModel, m_sortedSymbolPins.size() ) ); - } + m_libraryModelsMgr.CreateModel( baseModel, m_sortedSymbolPins.size() ); } } catch( const IO_ERROR& e ) @@ -638,7 +607,7 @@ void DIALOG_SIM_MODEL::loadLibrary( const wxString& aFilePath ) wxArrayString modelNames; - for( auto& [modelName, model] : m_library->GetModels() ) + for( auto& [modelName, model] : library()->GetModels() ) modelNames.Add( modelName ); auto validator = dynamic_cast( m_modelNameCombobox->GetValidator() ); @@ -646,6 +615,7 @@ void DIALOG_SIM_MODEL::loadLibrary( const wxString& aFilePath ) if( validator ) validator->SetIncludes( modelNames ); + m_tclibraryPathName->ChangeValue( aLibraryPath ); m_modelNameCombobox->Set( modelNames ); m_useLibraryModelRadioButton->SetValue( true ); @@ -843,10 +813,20 @@ SIM_MODEL& DIALOG_SIM_MODEL::curModel() const if( m_useLibraryModelRadioButton->GetValue() && m_modelNameCombobox->GetSelection() != wxNOT_FOUND ) { - return *m_libraryModels.at( m_modelNameCombobox->GetSelection() ); + return m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get(); } else - return m_builtinModelMgr.GetModels().at( static_cast( m_curModelType ) ); + return m_builtinModelsMgr.GetModels().at( static_cast( m_curModelType ) ); +} + + +template +const SIM_LIBRARY* DIALOG_SIM_MODEL::library() const +{ + if( m_libraryModelsMgr.GetLibraries().size() == 1 ) + return &m_libraryModelsMgr.GetLibraries().begin()->second.get(); + + return nullptr; } @@ -1000,24 +980,19 @@ void DIALOG_SIM_MODEL::onIbisPinCombobox( wxCommandEvent& aEvent ) { wxArrayString modelLabels; - SIM_MODEL_KIBIS* modelkibis = dynamic_cast( &curModel() ); + SIM_MODEL_KIBIS& kibisModel = static_cast( curModel() ); - if( !modelkibis ) - { - wxFAIL; - return; - } - - std::vector> strs = modelkibis->GetIbisPins(); + std::vector> strs = kibisModel.GetIbisPins(); std::string pinNumber = strs.at( m_ibisPinCombobox->GetSelection() ).first; - modelkibis->ChangePin( *std::dynamic_pointer_cast( m_library ), - pinNumber ); + const SIM_LIBRARY_KIBIS* kibisLibrary = dynamic_cast( library() ); - modelkibis->m_enableDiff = dynamic_cast( m_library.get() ) - ->isPinDiff( modelkibis->GetComponentName(), pinNumber ); + kibisModel.ChangePin( *kibisLibrary, pinNumber ); - for( wxString modelName : modelkibis->GetIbisModels() ) + kibisModel.m_enableDiff = static_cast( library() ) + ->isPinDiff( kibisModel.GetComponentName(), pinNumber ); + + for( wxString modelName : kibisModel.GetIbisModels() ) modelLabels.Add( modelName ); m_ibisModelCombobox->Set( modelLabels ); @@ -1096,11 +1071,13 @@ void DIALOG_SIM_MODEL::onTypeChoice( wxCommandEvent& aEvent ) || type == SIM_MODEL::TYPE::KIBIS_DRIVER_RECT || type == SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS ) ) { - SIM_MODEL_KIBIS* kibismodel = dynamic_cast( - m_libraryModels.at( m_modelNameCombobox->GetSelection() ).get() ); + SIM_MODEL_KIBIS& kibisModel = static_cast( + m_libraryModelsMgr.GetModels().at( m_modelNameCombobox->GetSelection() ).get() ); - m_libraryModels.at( m_modelNameCombobox->GetSelection() ) = - std::make_unique( type, *kibismodel, m_fields ); + m_libraryModelsMgr.SetModel( m_modelNameCombobox->GetSelection(), + std::make_unique( type, + kibisModel, + m_fields ) ); } m_curModelType = type; diff --git a/eeschema/dialogs/dialog_sim_model.h b/eeschema/dialogs/dialog_sim_model.h index 25d4d91443..b09a711161 100644 --- a/eeschema/dialogs/dialog_sim_model.h +++ b/eeschema/dialogs/dialog_sim_model.h @@ -99,7 +99,7 @@ private: void removeOrphanedPinAssignments(); - void loadLibrary( const wxString& aFilePath ); + void loadLibrary( const wxString& aLibraryPath ); void addParamPropertyIfRelevant( int aParamIndex ); wxPGProperty* newParamProperty( int aParamIndex ) const; @@ -107,6 +107,7 @@ private: int findSymbolPinRow( const wxString& aSymbolPinNumber ) const; SIM_MODEL& curModel() const; + const SIM_LIBRARY* library() const; wxString getSymbolPinString( int aSymbolPinNumber ) const; wxString getModelPinString( int aModelPinIndex ) const; @@ -133,21 +134,20 @@ private: void onParamGridSetFocus( wxFocusEvent& aEvent ); void onParamGridSelectionChange( wxPropertyGridEvent& aEvent ); - bool isIbisLoaded() { return dynamic_cast( m_library.get() ); } + bool isIbisLoaded() { return dynamic_cast( library() ); } private: SCH_SYMBOL& m_symbol; std::vector& m_fields; - SIM_LIB_MGR m_builtinModelMgr; + SIM_LIB_MGR m_libraryModelsMgr; + SIM_LIB_MGR m_builtinModelsMgr; + const SIM_MODEL* m_prevModel; + std::vector m_sortedSymbolPins; std::map m_curModelTypeOfDeviceType; SIM_MODEL::TYPE m_curModelType; - std::shared_ptr m_library; - std::vector> m_libraryModels; - const SIM_MODEL* m_prevModel; - MODEL_NAME_VALIDATOR m_modelNameValidator; SCINTILLA_TRICKS* m_scintillaTricks; bool m_wasCodePreviewUpdated; diff --git a/eeschema/sim/kibis/kibis.cpp b/eeschema/sim/kibis/kibis.cpp index a39b798459..a97f76ec94 100644 --- a/eeschema/sim/kibis/kibis.cpp +++ b/eeschema/sim/kibis/kibis.cpp @@ -1529,4 +1529,4 @@ std::vector> KIBIS_WAVEFORM_PRBS::GenerateBitSequence() } while ( ++bits < m_bits ); return bitSequence; -} \ No newline at end of file +} diff --git a/eeschema/sim/sim_lib_mgr.cpp b/eeschema/sim/sim_lib_mgr.cpp index 75b2b77fa2..39a4a64388 100644 --- a/eeschema/sim/sim_lib_mgr.cpp +++ b/eeschema/sim/sim_lib_mgr.cpp @@ -35,9 +35,18 @@ SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT& aPrj ) : m_project( aPrj ) } +void SIM_LIB_MGR::Clear() +{ + m_libraries.clear(); + m_models.clear(); +} + + SIM_LIBRARY& SIM_LIB_MGR::CreateLibrary( const std::string& aLibraryPath ) { - auto it = m_libraries.try_emplace( aLibraryPath, SIM_LIBRARY::Create( aLibraryPath ) ).first; + std::string absolutePath = std::string( m_project.AbsolutePath( aLibraryPath ).ToUTF8() ); + + auto it = m_libraries.try_emplace( aLibraryPath, SIM_LIBRARY::Create( absolutePath ) ).first; return *it->second; } @@ -56,66 +65,94 @@ SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPin } +template +SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount, + const std::vector& aFields ) +{ + m_models.push_back( SIM_MODEL::Create( aBaseModel, aSymbolPinCount, aFields ) ); + return *m_models.back(); +} + +template SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount, + const std::vector& aFields ); +template SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount, + const std::vector& aFields ); + + SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol ) { return CreateModel( aSymbol.GetFields(), static_cast( aSymbol.GetLibPins().size() ) ); } +template +SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector& aFields, int aSymbolPinCount ) +{ + std::string libraryPath = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::LIBRARY_FIELD ); + std::string baseModelName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::NAME_FIELD ); + + if( libraryPath != "" ) + return CreateModel( libraryPath, baseModelName, aFields, aSymbolPinCount ); + else + { + m_models.push_back( SIM_MODEL::Create( aSymbolPinCount, aFields ) ); + return { baseModelName, *m_models.back() }; + } +} template SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector& aFields, int aSymbolPinCount ); template SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector& aFields, int aSymbolPinCount ); + template -SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector& aFields, int aSymbolPinCount ) +SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::string& aLibraryPath, + const std::string& aBaseModelName, + const std::vector& aFields, + int aSymbolPinCount ) { - std::string libraryPath = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::LIBRARY_FIELD ); - std::string baseModelName; + std::string absolutePath = std::string( m_project.AbsolutePath( aLibraryPath ).ToUTF8() ); + SIM_LIBRARY* library = nullptr; - if( libraryPath != "" ) + try { - std::string absolutePath = std::string( m_project.AbsolutePath( libraryPath ).ToUTF8() ); - SIM_LIBRARY* library = nullptr; - - try - { - auto it = m_libraries.try_emplace( libraryPath, - SIM_LIBRARY::Create( absolutePath ) ).first; - library = &*it->second; - } - catch( const IO_ERROR& e ) - { - THROW_IO_ERROR( - wxString::Format( _( "Error loading simulation model library '%s': %s" ), - absolutePath, - e.What() ) ); - } - - baseModelName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::NAME_FIELD ); - - if( baseModelName == "" ) - { - THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model: no '%s' field" ), - SIM_LIBRARY::NAME_FIELD ) ); - } - - SIM_MODEL* baseModel = library->FindModel( baseModelName ); - - if( !baseModel ) - { - THROW_IO_ERROR( - wxString::Format( _( "Error loading simulation model: could not find base model '%s' in library '%s'" ), - baseModelName, - absolutePath ) ); - } - - m_models.push_back( SIM_MODEL::Create( *baseModel, aSymbolPinCount, aFields ) ); + auto it = m_libraries.try_emplace( aLibraryPath, + SIM_LIBRARY::Create( absolutePath ) ).first; + library = &*it->second; + } + catch( const IO_ERROR& e ) + { + THROW_IO_ERROR( + wxString::Format( _( "Error loading simulation model library '%s': %s" ), + absolutePath, + e.What() ) ); } - else - m_models.push_back( SIM_MODEL::Create( aSymbolPinCount, aFields ) ); - return { baseModelName, *m_models.back() }; + if( aBaseModelName == "" ) + { + THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model: no '%s' field" ), + SIM_LIBRARY::NAME_FIELD ) ); + } + + SIM_MODEL* baseModel = library->FindModel( aBaseModelName ); + + if( !baseModel ) + { + THROW_IO_ERROR( + wxString::Format( _( "Error loading simulation model: could not find base model '%s' in library '%s'" ), + aBaseModelName, + absolutePath ) ); + } + + m_models.push_back( SIM_MODEL::Create( *baseModel, aSymbolPinCount, aFields ) ); + + return { aBaseModelName, *m_models.back() }; +} + + +void SIM_LIB_MGR::SetModel( int aIndex, std::unique_ptr aModel ) +{ + m_models.at( aIndex ) = std::move( aModel ); } diff --git a/eeschema/sim/sim_lib_mgr.h b/eeschema/sim/sim_lib_mgr.h index 273b6e30ed..e8008ca9b2 100644 --- a/eeschema/sim/sim_lib_mgr.h +++ b/eeschema/sim/sim_lib_mgr.h @@ -43,17 +43,32 @@ public: SIM_LIB_MGR( const PROJECT& aPrj ); virtual ~SIM_LIB_MGR() = default; + void Clear(); + SIM_LIBRARY& CreateLibrary( const std::string& aLibraryPath ); SIM_MODEL& CreateModel( SIM_MODEL::TYPE aType, int aSymbolPinCount ); + SIM_MODEL& CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount ); + template + SIM_MODEL& CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount, + const std::vector& aFields ); + // TODO: The argument can be made const. SIM_LIBRARY::MODEL CreateModel( SCH_SYMBOL& aSymbol ); template SIM_LIBRARY::MODEL CreateModel( const std::vector& aFields, int aSymbolPinCount ); + template + SIM_LIBRARY::MODEL CreateModel( const std::string& aLibraryPath, + const std::string& aBaseModelName, + const std::vector& aFields, + int aSymbolPinCount ); + + void SetModel( int aIndex, std::unique_ptr aModel ); + std::map> GetLibraries() const; std::vector> GetModels() const; diff --git a/eeschema/sim/sim_library_kibis.cpp b/eeschema/sim/sim_library_kibis.cpp index 8ad1c7d5f3..d285875112 100644 --- a/eeschema/sim/sim_library_kibis.cpp +++ b/eeschema/sim/sim_library_kibis.cpp @@ -79,7 +79,7 @@ bool SIM_LIBRARY_KIBIS::InitModel( SIM_MODEL_KIBIS& aModel, wxString aCompName ) } -bool SIM_LIBRARY_KIBIS::isPinDiff( const std::string& aComp, const std::string& aPinNumber ) +bool SIM_LIBRARY_KIBIS::isPinDiff( const std::string& aComp, const std::string& aPinNumber ) const { for( std::pair aInfo : m_diffPins ) { diff --git a/eeschema/sim/sim_library_kibis.h b/eeschema/sim/sim_library_kibis.h index dd248a9671..76207ca2a8 100644 --- a/eeschema/sim/sim_library_kibis.h +++ b/eeschema/sim/sim_library_kibis.h @@ -44,10 +44,10 @@ public: void WriteFile( const std::string& aFilePath ) override{}; bool InitModel( SIM_MODEL_KIBIS& aModel, wxString aCompName ); - bool isPinDiff( const std::string& aComp, const std::string& aPinNumber ); + bool isPinDiff( const std::string& aComp, const std::string& aPinNumber ) const; protected: - KIBIS m_kibis; + mutable KIBIS m_kibis; std::vector> m_diffPins; }; diff --git a/eeschema/sim/sim_model_kibis.cpp b/eeschema/sim/sim_model_kibis.cpp index 41738ccf68..5994269eb8 100644 --- a/eeschema/sim/sim_model_kibis.cpp +++ b/eeschema/sim/sim_model_kibis.cpp @@ -313,7 +313,7 @@ void SIM_MODEL_KIBIS::CreatePins( unsigned aSymbolPinCount ) } -bool SIM_MODEL_KIBIS::ChangePin( SIM_LIBRARY_KIBIS& aLib, std::string aPinNumber ) +bool SIM_MODEL_KIBIS::ChangePin( const SIM_LIBRARY_KIBIS& aLib, std::string aPinNumber ) { KIBIS_COMPONENT* kcomp = aLib.m_kibis.GetComponent( std::string( GetComponentName() ) ); @@ -516,4 +516,4 @@ void SIM_MODEL_KIBIS::ReadDataLibFields( unsigned aSymbolPinCount, const std::ve SwitchSingleEndedDiff( diffMode ); SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields ); -} \ No newline at end of file +} diff --git a/eeschema/sim/sim_model_kibis.h b/eeschema/sim/sim_model_kibis.h index f1ddd861c1..8874b40492 100644 --- a/eeschema/sim/sim_model_kibis.h +++ b/eeschema/sim/sim_model_kibis.h @@ -88,7 +88,7 @@ public: /** @brief update the list of available models based on the pin number. * */ - bool ChangePin( SIM_LIBRARY_KIBIS& aLib, std::string aPinNumber ); + bool ChangePin( const SIM_LIBRARY_KIBIS& aLib, std::string aPinNumber ); void SetBaseModel( const SIM_MODEL& aBaseModel ) override;