Fix for crash when AC simulation is relaunched

This commit is contained in:
Maciej Suminski 2016-08-11 14:41:50 +02:00
parent e5604fee1c
commit cf28e843ba
3 changed files with 97 additions and 17 deletions

View File

@ -304,8 +304,8 @@ bool SIM_PLOT_FRAME::updatePlot( const wxString& aSpiceName, const wxString& aNa
if( data_mag.empty() || data_phase.empty() ) if( data_mag.empty() || data_phase.empty() )
return false; return false;
aPanel->AddTrace( aSpiceName, aName + " (mag)", size, data_x.data(), data_mag.data(), 0 ); aPanel->AddTrace( aSpiceName, aName, size, data_x.data(), data_mag.data(), SPF_AC_MAG );
aPanel->AddTrace( aSpiceName, aName + " (phase)", size, data_x.data(), data_phase.data(), SPF_AC_PHASE ); aPanel->AddTrace( aSpiceName, aName, size, data_x.data(), data_phase.data(), SPF_AC_PHASE );
} }
break; break;
@ -429,7 +429,7 @@ void SIM_PLOT_FRAME::menuSaveCsv( wxCommandEvent& event )
timeWritten = true; timeWritten = true;
} }
out.Write( wxString::Format( "%s%c", t.first, SEPARATOR ) ); out.Write( wxString::Format( "%s%c", t.first.GetDescription(), SEPARATOR ) );
for( double v : trace->GetDataY() ) for( double v : trace->GetDataY() )
out.Write( wxString::Format( "%f%c", v, SEPARATOR ) ); out.Write( wxString::Format( "%f%c", v, SEPARATOR ) );
@ -612,7 +612,7 @@ void SIM_PLOT_FRAME::onCursorUpdate( wxCommandEvent& event )
if( CURSOR* cursor = trace.second->GetCursor() ) if( CURSOR* cursor = trace.second->GetCursor() )
{ {
const wxRealPoint coords = cursor->GetCoords(); const wxRealPoint coords = cursor->GetCoords();
long idx = m_cursors->InsertItem( SIGNAL_COL, trace.first ); long idx = m_cursors->InsertItem( SIGNAL_COL, trace.first.GetDescription() );
m_cursors->SetItem( idx, X_COL, wxString::Format( "%f", coords.x ) ); m_cursors->SetItem( idx, X_COL, wxString::Format( "%f", coords.x ) );
m_cursors->SetItem( idx, Y_COL, wxString::Format( "%f", coords.y ) ); m_cursors->SetItem( idx, Y_COL, wxString::Format( "%f", coords.y ) );
} }
@ -646,7 +646,7 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
if( SIM_PLOT_PANEL::IsPlottable( simType ) ) if( SIM_PLOT_PANEL::IsPlottable( simType ) )
{ {
for( const auto& trace : plotPanel->GetTraces() ) for( const auto& trace : plotPanel->GetTraces() )
updatePlot( trace.second->GetSpiceName(), trace.second->GetName(), plotPanel ); updatePlot( trace.second->GetSpiceName(), trace.first.GetName(), plotPanel );
plotPanel->UpdateAll(); plotPanel->UpdateAll();
} }

View File

@ -237,6 +237,44 @@ void CURSOR::Plot( wxDC& aDC, mpWindow& aWindow )
} }
TRACE_DESC::TRACE_DESC( const wxString& aDescription )
: m_name( aDescription )
{
for( const auto& desc : m_descMap )
{
if( m_name.EndsWith( desc.second ) )
{
m_type = desc.first;
m_name.Replace( desc.second, "" );
}
}
}
wxString TRACE_DESC::GetDescription() const
{
wxString res( m_name );
for( const auto& desc : m_descMap )
{
if( m_type == desc.first )
{
res += desc.second;
break;
}
}
return res;
}
const std::map<SIM_PLOT_FLAGS, wxString> TRACE_DESC::m_descMap =
{
{ SPF_AC_PHASE, wxT( " (phase)" ) },
{ SPF_AC_MAG, wxT( " (mag)" ) }
};
SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id, const wxPoint& pos, SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name ) const wxSize& size, long style, const wxString& name )
: mpWindow( parent, id, pos, size, style ), m_colorIdx( 0 ), : mpWindow( parent, id, pos, size, style ), m_colorIdx( 0 ),
@ -341,8 +379,15 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aName
{ {
TRACE* t = NULL; TRACE* t = NULL;
wxString name( aName );
if( aFlags == SPF_AC_MAG )
name += " (mag)";
else if( aFlags == SPF_AC_PHASE )
name += " (phase)";
// Find previous entry, if there is one // Find previous entry, if there is one
auto prev = m_traces.find( aName ); auto prev = m_traces.find( TRACE_DESC( aName, (SIM_PLOT_FLAGS) aFlags ) );
bool addedNewEntry = ( prev == m_traces.end() ); bool addedNewEntry = ( prev == m_traces.end() );
if( addedNewEntry ) if( addedNewEntry )
@ -351,18 +396,18 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aName
switch ( m_type ) switch ( m_type )
{ {
case ST_TRANSIENT: case ST_TRANSIENT:
t = new TRACE_TRANSIENT( aName, aSpiceName ); t = new TRACE_TRANSIENT( name, aSpiceName );
break; break;
case ST_AC: case ST_AC:
//printf("makeFreqResp!\n"); //printf("makeFreqResp!\n");
t = new TRACE_FREQ_RESPONSE( aName, aSpiceName ); t = new TRACE_FREQ_RESPONSE( name, aSpiceName );
break; break;
default: default:
assert(false); assert(false);
} }
t->SetPen( wxPen( generateColor(), 2, wxSOLID ) ); t->SetPen( wxPen( generateColor(), 2, wxSOLID ) );
m_traces[aName] = t; m_traces[TRACE_DESC( aName, (SIM_PLOT_FLAGS) aFlags )] = t;
// It is a trick to keep legend & coords always on the top // It is a trick to keep legend & coords always on the top
for( mpLayer* l : m_topLevel ) for( mpLayer* l : m_topLevel )
@ -409,7 +454,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aName
bool SIM_PLOT_PANEL::DeleteTrace( const wxString& aName ) bool SIM_PLOT_PANEL::DeleteTrace( const wxString& aName )
{ {
auto it = m_traces.find( aName ); auto it = m_traces.find( TRACE_DESC( aName ) );
if( it != m_traces.end() ) if( it != m_traces.end() )
{ {
@ -432,7 +477,7 @@ void SIM_PLOT_PANEL::DeleteAllTraces()
{ {
for( auto& t : m_traces ) for( auto& t : m_traces )
{ {
DeleteTrace( t.first ); DeleteTrace( t.first.GetDescription() );
} }
m_traces.clear(); m_traces.clear();

View File

@ -156,7 +156,42 @@ public:
}; };
enum SIM_PLOT_FLAGS { enum SIM_PLOT_FLAGS {
SPF_AC_PHASE = 0x1 SPF_AC_PHASE = 0x01,
SPF_AC_MAG = 0x02
};
class TRACE_DESC
{
public:
TRACE_DESC( const wxString& aName, SIM_PLOT_FLAGS aType )
: m_name( aName ), m_type( aType )
{
}
TRACE_DESC( const wxString& aDescription );
wxString GetDescription() const;
const wxString& GetName() const
{
return m_name;
}
SIM_PLOT_FLAGS GetType() const
{
return m_type;
}
bool operator<( const TRACE_DESC& aOther ) const
{
return ( m_name < aOther.m_name ) || ( m_name == aOther.m_name && m_type < aOther.m_type );
}
private:
wxString m_name;
SIM_PLOT_FLAGS m_type;
static const std::map<SIM_PLOT_FLAGS, wxString> m_descMap;
}; };
class SIM_PLOT_PANEL : public mpWindow class SIM_PLOT_PANEL : public mpWindow
@ -198,17 +233,17 @@ public:
bool IsShown( const wxString& aName ) const bool IsShown( const wxString& aName ) const
{ {
return ( m_traces.count( aName ) != 0 ); return m_traces.count( TRACE_DESC( aName ) ) > 0;
} }
const std::map<wxString, TRACE*>& GetTraces() const const std::map<TRACE_DESC, TRACE*>& GetTraces() const
{ {
return m_traces; return m_traces;
} }
TRACE* GetTrace( const wxString& aName ) const TRACE* GetTrace( const wxString& aName ) const
{ {
auto trace = m_traces.find( aName ); auto trace = m_traces.find( TRACE_DESC( aName ) );
return trace == m_traces.end() ? NULL : trace->second; return trace == m_traces.end() ? NULL : trace->second;
} }
@ -259,7 +294,7 @@ private:
unsigned int m_colorIdx; unsigned int m_colorIdx;
// Traces to be plotted // Traces to be plotted
std::map<wxString, TRACE*> m_traces; std::map<TRACE_DESC, TRACE*> m_traces;
mpScaleXBase* m_axis_x; mpScaleXBase* m_axis_x;
mpScaleY* m_axis_y1; mpScaleY* m_axis_y1;