More performance optimizations for symbol libraries

1) don't call UI-level LIB_PIN routines when reading library --
not only are they a performance hit, they set the modified flag
too
2) limit progress dialog updating to 15 times a second (this
had crept back up to 31% of the time spent loading libraries)

Fixes: lp:1734773
* https://bugs.launchpad.net/kicad/+bug/1734773
This commit is contained in:
Jeff Young 2018-01-29 00:51:07 +00:00 committed by Wayne Stambaugh
parent b43dc7954c
commit 99ad5cf394
4 changed files with 52 additions and 35 deletions

View File

@ -32,6 +32,8 @@ CMP_TREE_MODEL_ADAPTER_BASE::WIDTH_CACHE CMP_TREE_MODEL_ADAPTER_BASE::m_width_ca
bool CMP_TREE_MODEL_ADAPTER_BASE::m_show_progress = true;
#define PROGRESS_INTERVAL_MILLIS 66
static const int kDataViewIndent = 20;
@ -111,6 +113,7 @@ void CMP_TREE_MODEL_ADAPTER_BASE::AddLibrariesWithProgress(
const std::vector<wxString>& aNicknames, wxWindow* aParent )
{
wxProgressDialog* prg = nullptr;
wxLongLong nextUpdate = wxGetUTCTimeMillis() + (PROGRESS_INTERVAL_MILLIS / 2);
if( m_show_progress )
prg = new wxProgressDialog( _( "Loading Symbol Libraries" ),
@ -122,10 +125,14 @@ void CMP_TREE_MODEL_ADAPTER_BASE::AddLibrariesWithProgress(
for( const auto& nickname : aNicknames )
{
if( prg )
prg->Update( ii++, wxString::Format( _( "Loading library \"%s\"" ), nickname ) );
if( prg && wxGetUTCTimeMillis() > nextUpdate )
{
prg->Update( ii, wxString::Format( _( "Loading library \"%s\"" ), nickname ) );
nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS;
}
AddLibrary( nickname );
ii++;
}
if( prg )

View File

@ -54,11 +54,11 @@ bool LIB_MANAGER_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
}
#define PROGRESS_INTERVAL_MILLIS 50
#define PROGRESS_INTERVAL_MILLIS 66
void LIB_MANAGER_ADAPTER::Sync( bool aForce, std::function<void(int, int, const wxString&)> aProgressCallback )
{
wxLongLong nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS;
wxLongLong nextUpdate = wxGetUTCTimeMillis() + (PROGRESS_INTERVAL_MILLIS / 2);
int libMgrHash = m_libMgr->GetHash();
@ -75,7 +75,7 @@ void LIB_MANAGER_ADAPTER::Sync( bool aForce, std::function<void(int, int, const
if( wxGetUTCTimeMillis() > nextUpdate )
{
aProgressCallback( i++, max, name );
aProgressCallback( i, max, name );
nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS;
}
@ -90,6 +90,7 @@ void LIB_MANAGER_ADAPTER::Sync( bool aForce, std::function<void(int, int, const
}
++it;
++i;
}
// Look for new libraries

View File

@ -67,6 +67,11 @@ enum LibPinDrawFlags {
class LIB_PIN : public LIB_ITEM
{
// Unlike most of the other LIB_ITEMs, the SetXXX() routines on LIB_PINs are at the UI
// level, performing additional pin checking, multi-pin editing, and setting the modified
// flag. So the LEGACY_PLUGIN_CACHE needs direct access to the member variables.
friend class SCH_LEGACY_PLUGIN_CACHE;
wxPoint m_position; ///< Position of the pin.
int m_length; ///< Length of the pin.
int m_orientation; ///< Pin orientation (Up, Down, Left, Right)

View File

@ -3136,20 +3136,24 @@ LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr< LIB_PART >& aPart,
parseUnquotedString( name, aReader, line, &line );
parseUnquotedString( number, aReader, line, &line );
pin->SetName( name, false );
pin->SetNumber( number );
// Unlike most of the other LIB_ITEMs, the SetXXX() routines on LIB_PINs are at the UI
// level, performing additional pin checking, multi-pin editing, and setting the modified
// flag. So we must set the member fields directly.
pin->m_name = name;
pin->m_number = number;
wxPoint pos;
pos.x = parseInt( aReader, line, &line );
pos.y = parseInt( aReader, line, &line );
pin->SetPosition( pos );
pin->SetLength( parseInt( aReader, line, &line ), false );
pin->SetOrientation( parseChar( aReader, line, &line ), false );
pin->SetNumberTextSize( parseInt( aReader, line, &line ), false );
pin->SetNameTextSize( parseInt( aReader, line, &line ), false );
pin->SetUnit( parseInt( aReader, line, &line ) );
pin->SetConvert( parseInt( aReader, line, &line ) );
pin->m_position = pos;
pin->m_length = parseInt( aReader, line, &line );
pin->m_orientation = parseChar( aReader, line, &line );
pin->m_numTextSize = parseInt( aReader, line, &line );
pin->m_nameTextSize = parseInt( aReader, line, &line );
pin->m_Unit = parseInt( aReader, line, &line );
pin->m_Convert = parseInt( aReader, line, &line );
char type = parseChar( aReader, line, &line );
@ -3161,47 +3165,47 @@ LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr< LIB_PART >& aPart,
switch( type )
{
case 'I':
pin->SetType( PIN_INPUT, false );
pin->m_type = PIN_INPUT;
break;
case 'O':
pin->SetType( PIN_OUTPUT, false );
pin->m_type = PIN_OUTPUT;
break;
case 'B':
pin->SetType( PIN_BIDI, false );
pin->m_type = PIN_BIDI;
break;
case 'T':
pin->SetType( PIN_TRISTATE, false );
pin->m_type = PIN_TRISTATE;
break;
case 'P':
pin->SetType( PIN_PASSIVE, false );
pin->m_type = PIN_PASSIVE;
break;
case 'U':
pin->SetType( PIN_UNSPECIFIED, false );
pin->m_type = PIN_UNSPECIFIED;
break;
case 'W':
pin->SetType( PIN_POWER_IN, false );
pin->m_type = PIN_POWER_IN;
break;
case 'w':
pin->SetType( PIN_POWER_OUT, false );
pin->m_type = PIN_POWER_OUT;
break;
case 'C':
pin->SetType( PIN_OPENCOLLECTOR, false );
pin->m_type = PIN_OPENCOLLECTOR;
break;
case 'E':
pin->SetType( PIN_OPENEMITTER, false );
pin->m_type = PIN_OPENEMITTER;
break;
case 'N':
pin->SetType( PIN_NC, false );
pin->m_type = PIN_NC;
break;
default:
@ -3230,7 +3234,7 @@ LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr< LIB_PART >& aPart,
break;
case 'N':
pin->SetVisible( false );
pin->m_attributes |= PIN_INVISIBLE;
break;
case 'I':
@ -3265,39 +3269,39 @@ LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr< LIB_PART >& aPart,
switch( flags )
{
case 0:
pin->SetShape( PINSHAPE_LINE );
pin->m_shape = PINSHAPE_LINE;
break;
case INVERTED:
pin->SetShape( PINSHAPE_INVERTED );
pin->m_shape = PINSHAPE_INVERTED;
break;
case CLOCK:
pin->SetShape( PINSHAPE_CLOCK );
pin->m_shape = PINSHAPE_CLOCK;
break;
case INVERTED | CLOCK:
pin->SetShape( PINSHAPE_INVERTED_CLOCK );
pin->m_shape = PINSHAPE_INVERTED_CLOCK;
break;
case LOWLEVEL_IN:
pin->SetShape( PINSHAPE_INPUT_LOW );
pin->m_shape = PINSHAPE_INPUT_LOW;
break;
case LOWLEVEL_IN | CLOCK:
pin->SetShape( PINSHAPE_CLOCK_LOW );
pin->m_shape = PINSHAPE_CLOCK_LOW;
break;
case LOWLEVEL_OUT:
pin->SetShape( PINSHAPE_OUTPUT_LOW );
pin->m_shape = PINSHAPE_OUTPUT_LOW;
break;
case FALLING_EDGE:
pin->SetShape( PINSHAPE_FALLING_EDGE_CLOCK );
pin->m_shape = PINSHAPE_FALLING_EDGE_CLOCK;
break;
case NONLOGIC:
pin->SetShape( PINSHAPE_NONLOGIC );
pin->m_shape = PINSHAPE_NONLOGIC;
break;
default: