NGSPICE as a singleton
One cannot call ngSpice_Init() twice without unloading the dll. When calling ngSpice_Init, we pass a pointer to a NGSPICE instance and thus it cannot be changed. When any of the callback function is called with a stale pointer everything crashes.
This commit is contained in:
parent
bcfce68daa
commit
2a6b8f153b
|
@ -45,7 +45,6 @@ NGSPICE::~NGSPICE()
|
||||||
|
|
||||||
void NGSPICE::Init()
|
void NGSPICE::Init()
|
||||||
{
|
{
|
||||||
init();
|
|
||||||
Command( "reset" );
|
Command( "reset" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,19 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
|
||||||
if( m_schematicFrame == NULL )
|
if( m_schematicFrame == NULL )
|
||||||
throw std::runtime_error( "There is no schematic window" );
|
throw std::runtime_error( "There is no schematic window" );
|
||||||
|
|
||||||
|
m_simulator = SPICE_SIMULATOR::CreateInstance( "ngspice" );
|
||||||
|
|
||||||
|
if( !m_simulator )
|
||||||
|
{
|
||||||
|
throw std::runtime_error( "Could not create simulator instance" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_simulator->Init();
|
||||||
|
|
||||||
|
m_reporter = new SIM_THREAD_REPORTER( this );
|
||||||
|
m_simulator->SetReporter( m_reporter );
|
||||||
|
|
||||||
updateNetlistExporter();
|
updateNetlistExporter();
|
||||||
|
|
||||||
Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SIM_PLOT_FRAME::onClose ), NULL, this );
|
Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SIM_PLOT_FRAME::onClose ), NULL, this );
|
||||||
|
@ -145,12 +158,13 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
|
||||||
|
|
||||||
m_toolBar->Realize();
|
m_toolBar->Realize();
|
||||||
m_plotNotebook->SetPageText( 0, _( "Welcome!" ) );
|
m_plotNotebook->SetPageText( 0, _( "Welcome!" ) );
|
||||||
m_simulator.reset( SPICE_SIMULATOR::CreateInstance( "ngspice" ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SIM_PLOT_FRAME::~SIM_PLOT_FRAME()
|
SIM_PLOT_FRAME::~SIM_PLOT_FRAME()
|
||||||
{
|
{
|
||||||
|
delete m_simulator;
|
||||||
|
delete m_reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,12 +173,6 @@ void SIM_PLOT_FRAME::StartSimulation()
|
||||||
STRING_FORMATTER formatter;
|
STRING_FORMATTER formatter;
|
||||||
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
||||||
|
|
||||||
if( !m_simulator )
|
|
||||||
{
|
|
||||||
DisplayError( this, wxT( "Could not create simulator instance" ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_simConsole->Clear();
|
m_simConsole->Clear();
|
||||||
updateNetlistExporter();
|
updateNetlistExporter();
|
||||||
|
|
||||||
|
@ -183,8 +191,6 @@ void SIM_PLOT_FRAME::StartSimulation()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_simulator->SetReporter( new SIM_THREAD_REPORTER( this ) );
|
|
||||||
m_simulator->Init();
|
|
||||||
m_simulator->LoadNetlist( formatter.GetString() );
|
m_simulator->LoadNetlist( formatter.GetString() );
|
||||||
updateTuners();
|
updateTuners();
|
||||||
applyTuners();
|
applyTuners();
|
||||||
|
@ -194,8 +200,7 @@ void SIM_PLOT_FRAME::StartSimulation()
|
||||||
|
|
||||||
void SIM_PLOT_FRAME::StopSimulation()
|
void SIM_PLOT_FRAME::StopSimulation()
|
||||||
{
|
{
|
||||||
if( m_simulator )
|
m_simulator->Stop();
|
||||||
m_simulator->Stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -367,9 +372,6 @@ void SIM_PLOT_FRAME::updateNetlistExporter()
|
||||||
|
|
||||||
bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL* aPanel )
|
bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL* aPanel )
|
||||||
{
|
{
|
||||||
if( !m_simulator )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SIM_TYPE simType = m_exporter->GetSimType();
|
SIM_TYPE simType = m_exporter->GetSimType();
|
||||||
wxString spiceVector = m_exporter->GetSpiceVector( aDescriptor.GetName(),
|
wxString spiceVector = m_exporter->GetSpiceVector( aDescriptor.GetName(),
|
||||||
aDescriptor.GetType(), aDescriptor.GetParam() );
|
aDescriptor.GetType(), aDescriptor.GetParam() );
|
||||||
|
@ -494,6 +496,7 @@ void SIM_PLOT_FRAME::applyTuners()
|
||||||
/// @todo no ngspice hardcoding
|
/// @todo no ngspice hardcoding
|
||||||
std::string command( "alter @" + tuner->GetSpiceName()
|
std::string command( "alter @" + tuner->GetSpiceName()
|
||||||
+ "=" + tuner->GetValue().ToSpiceString() );
|
+ "=" + tuner->GetValue().ToSpiceString() );
|
||||||
|
|
||||||
m_simulator->Command( command );
|
m_simulator->Command( command );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1015,9 +1018,6 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
|
||||||
|
|
||||||
void SIM_PLOT_FRAME::onSimUpdate( wxCommandEvent& aEvent )
|
void SIM_PLOT_FRAME::onSimUpdate( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
if( !m_simulator )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( IsSimulationRunning() )
|
if( IsSimulationRunning() )
|
||||||
StopSimulation();
|
StopSimulation();
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ class SCH_COMPONENT;
|
||||||
class SPICE_SIMULATOR;
|
class SPICE_SIMULATOR;
|
||||||
class NETLIST_EXPORTER_PSPICE_SIM;
|
class NETLIST_EXPORTER_PSPICE_SIM;
|
||||||
class SIM_PLOT_PANEL;
|
class SIM_PLOT_PANEL;
|
||||||
|
class SIM_THREAD_REPORTER;
|
||||||
class TUNER_SLIDER;
|
class TUNER_SLIDER;
|
||||||
|
|
||||||
///> Trace descriptor class
|
///> Trace descriptor class
|
||||||
|
@ -271,7 +272,8 @@ private:
|
||||||
|
|
||||||
SCH_EDIT_FRAME* m_schematicFrame;
|
SCH_EDIT_FRAME* m_schematicFrame;
|
||||||
std::unique_ptr<NETLIST_EXPORTER_PSPICE_SIM> m_exporter;
|
std::unique_ptr<NETLIST_EXPORTER_PSPICE_SIM> m_exporter;
|
||||||
std::unique_ptr<SPICE_SIMULATOR> m_simulator;
|
SPICE_SIMULATOR* m_simulator;
|
||||||
|
SIM_THREAD_REPORTER* m_reporter;
|
||||||
|
|
||||||
typedef std::map<wxString, TRACE_DESC> TRACE_MAP;
|
typedef std::map<wxString, TRACE_DESC> TRACE_MAP;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,12 @@ SPICE_SIMULATOR* SPICE_SIMULATOR::CreateInstance( const std::string& )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new NGSPICE;
|
static NGSPICE* ngspiceInstance = nullptr;
|
||||||
|
|
||||||
|
if( !ngspiceInstance )
|
||||||
|
ngspiceInstance = new NGSPICE;
|
||||||
|
|
||||||
|
return ngspiceInstance;
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue