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:
Maciej Suminski 2016-08-19 15:51:19 +02:00
parent bcfce68daa
commit 2a6b8f153b
4 changed files with 26 additions and 20 deletions

View File

@ -45,7 +45,6 @@ NGSPICE::~NGSPICE()
void NGSPICE::Init()
{
init();
Command( "reset" );
}

View File

@ -109,6 +109,19 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
if( m_schematicFrame == NULL )
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();
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_plotNotebook->SetPageText( 0, _( "Welcome!" ) );
m_simulator.reset( SPICE_SIMULATOR::CreateInstance( "ngspice" ) );
}
SIM_PLOT_FRAME::~SIM_PLOT_FRAME()
{
delete m_simulator;
delete m_reporter;
}
@ -159,12 +173,6 @@ void SIM_PLOT_FRAME::StartSimulation()
STRING_FORMATTER formatter;
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
if( !m_simulator )
{
DisplayError( this, wxT( "Could not create simulator instance" ) );
return;
}
m_simConsole->Clear();
updateNetlistExporter();
@ -183,8 +191,6 @@ void SIM_PLOT_FRAME::StartSimulation()
return;
}
m_simulator->SetReporter( new SIM_THREAD_REPORTER( this ) );
m_simulator->Init();
m_simulator->LoadNetlist( formatter.GetString() );
updateTuners();
applyTuners();
@ -194,7 +200,6 @@ void SIM_PLOT_FRAME::StartSimulation()
void SIM_PLOT_FRAME::StopSimulation()
{
if( m_simulator )
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 )
{
if( !m_simulator )
return false;
SIM_TYPE simType = m_exporter->GetSimType();
wxString spiceVector = m_exporter->GetSpiceVector( aDescriptor.GetName(),
aDescriptor.GetType(), aDescriptor.GetParam() );
@ -494,6 +496,7 @@ void SIM_PLOT_FRAME::applyTuners()
/// @todo no ngspice hardcoding
std::string command( "alter @" + tuner->GetSpiceName()
+ "=" + tuner->GetValue().ToSpiceString() );
m_simulator->Command( command );
}
}
@ -1015,9 +1018,6 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
void SIM_PLOT_FRAME::onSimUpdate( wxCommandEvent& aEvent )
{
if( !m_simulator )
return;
if( IsSimulationRunning() )
StopSimulation();

View File

@ -48,6 +48,7 @@ class SCH_COMPONENT;
class SPICE_SIMULATOR;
class NETLIST_EXPORTER_PSPICE_SIM;
class SIM_PLOT_PANEL;
class SIM_THREAD_REPORTER;
class TUNER_SLIDER;
///> Trace descriptor class
@ -271,7 +272,8 @@ private:
SCH_EDIT_FRAME* m_schematicFrame;
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;

View File

@ -30,7 +30,12 @@ SPICE_SIMULATOR* SPICE_SIMULATOR::CreateInstance( const std::string& )
{
try
{
return new NGSPICE;
static NGSPICE* ngspiceInstance = nullptr;
if( !ngspiceInstance )
ngspiceInstance = new NGSPICE;
return ngspiceInstance;
}
catch( std::exception& e )
{