Symbol library load performance enhancements.
1) Edit Symbol gets similar fix as Place Symbol 2) progress dialog updating reduced to once every 50ms 3) SearchText gets lazy normalization 4) TypeNames get lazy translation 5) default fieldNames get translated a single time per language change These fixes reduce first-load-time of both Edit Symbol and Place Symbol by about 2/3, and second-load-time of Edit Symbol to near-instantaneous.
This commit is contained in:
parent
54ebd45749
commit
829c236437
|
@ -25,6 +25,7 @@
|
|||
#include <eda_pattern_match.h>
|
||||
#include <make_unique.h>
|
||||
#include <utility>
|
||||
#include <pgm_base.h>
|
||||
|
||||
|
||||
// Each node gets this lowest score initially, without any matches applied.
|
||||
|
@ -114,13 +115,24 @@ CMP_TREE_NODE::CMP_TREE_NODE()
|
|||
|
||||
CMP_TREE_NODE_UNIT::CMP_TREE_NODE_UNIT( CMP_TREE_NODE* aParent, int aUnit )
|
||||
{
|
||||
static void* locale = nullptr;
|
||||
static wxString namePrefix;
|
||||
|
||||
// Fetching translations can take a surprising amount of time when loading libraries,
|
||||
// so only do it when necessary.
|
||||
if( Pgm().GetLocale() != locale )
|
||||
{
|
||||
namePrefix = _( "Unit" );
|
||||
locale = Pgm().GetLocale();
|
||||
}
|
||||
|
||||
Parent = aParent;
|
||||
Type = UNIT;
|
||||
|
||||
Unit = aUnit;
|
||||
LibId = aParent->LibId;
|
||||
|
||||
Name = _( "Unit" ) + " " + LIB_PART::SubReference( aUnit, false );
|
||||
Name = namePrefix + " " + LIB_PART::SubReference( aUnit, false );
|
||||
Desc = wxEmptyString;
|
||||
MatchName = wxEmptyString;
|
||||
|
||||
|
@ -158,7 +170,7 @@ void CMP_TREE_NODE_LIB_ID::Update( LIB_ALIAS* aAlias )
|
|||
// Search text spaces out keywords and description to penalize description
|
||||
// matches - earlier matches are worth more.
|
||||
MatchName = aAlias->GetName().Lower();
|
||||
SearchText = (aAlias->GetKeyWords() + " " + Desc).Lower();
|
||||
SearchText = (aAlias->GetKeyWords() + " " + Desc);
|
||||
|
||||
// Extract default footprint text
|
||||
LIB_PART* part = aAlias->GetPart();
|
||||
|
@ -177,7 +189,7 @@ void CMP_TREE_NODE_LIB_ID::Update( LIB_ALIAS* aAlias )
|
|||
if( !footprint.IsEmpty() )
|
||||
{
|
||||
SearchText += " ";
|
||||
SearchText += footprint.Lower();
|
||||
SearchText += footprint;
|
||||
}
|
||||
|
||||
Children.clear();
|
||||
|
@ -195,6 +207,12 @@ void CMP_TREE_NODE_LIB_ID::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
|||
if( Score <= 0 )
|
||||
return; // Leaf nodes without scores are out of the game.
|
||||
|
||||
if( !SearchTextNormalized )
|
||||
{
|
||||
SearchText = SearchText.Lower();
|
||||
SearchTextNormalized = true;
|
||||
}
|
||||
|
||||
// Keywords and description we only count if the match string is at
|
||||
// least two characters long. That avoids spurious, low quality
|
||||
// matches. Most abbreviations are at three characters long.
|
||||
|
|
|
@ -100,6 +100,8 @@ public:
|
|||
wxString Desc; ///< Description to be displayed
|
||||
wxString MatchName; ///< Normalized name for matching
|
||||
wxString SearchText; ///< Descriptive text to search
|
||||
bool SearchTextNormalized; ///< Support for lazy normalization.
|
||||
|
||||
|
||||
LIB_ID LibId; ///< LIB_ID determined by the parent library nickname and alias name.
|
||||
int Unit; ///< Actual unit, or zero
|
||||
|
|
|
@ -92,7 +92,6 @@ LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent )
|
|||
m_Width = 0;
|
||||
m_Fill = NO_FILL;
|
||||
m_isFillable = true;
|
||||
m_typeName = _( "Arc" );
|
||||
m_editState = 0;
|
||||
m_lastEditState = 0;
|
||||
m_editCenterDistance = 0.0;
|
||||
|
|
|
@ -91,6 +91,11 @@ public:
|
|||
return wxT( "LIB_ARC" );
|
||||
}
|
||||
|
||||
wxString GetTypeName() override
|
||||
{
|
||||
return _( "Arc" );
|
||||
}
|
||||
|
||||
bool HitTest( const wxPoint& aPosition ) const override;
|
||||
|
||||
bool HitTest( const wxPoint& aPosition, int aThreshold, const TRANSFORM& aTransform ) const override;
|
||||
|
|
|
@ -47,7 +47,6 @@ LIB_BEZIER::LIB_BEZIER( LIB_PART* aParent ) :
|
|||
m_Fill = NO_FILL;
|
||||
m_Width = 0;
|
||||
m_isFillable = true;
|
||||
m_typeName = _( "Bezier" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,10 @@ public:
|
|||
return wxT( "LIB_BEZIER" );
|
||||
}
|
||||
|
||||
wxString GetTypeName() override
|
||||
{
|
||||
return _( "Bezier" );
|
||||
}
|
||||
|
||||
void AddPoint( const wxPoint& aPoint ) { m_BezierPoints.push_back( aPoint ); }
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ LIB_CIRCLE::LIB_CIRCLE( LIB_PART* aParent ) :
|
|||
m_Width = 0;
|
||||
m_Fill = NO_FILL;
|
||||
m_isFillable = true;
|
||||
m_typeName = _( "Circle" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -56,6 +56,10 @@ public:
|
|||
return wxT( "LIB_CIRCLE" );
|
||||
}
|
||||
|
||||
wxString GetTypeName() override
|
||||
{
|
||||
return _( "Circle" );
|
||||
}
|
||||
|
||||
bool HitTest( const wxPoint& aPosition ) const override;
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ LIB_ITEM::LIB_ITEM( KICAD_T aType,
|
|||
m_Convert = aConvert;
|
||||
m_Fill = aFillType;
|
||||
m_Parent = (EDA_ITEM*) aComponent;
|
||||
m_typeName = _( "Undefined" );
|
||||
m_isFillable = false;
|
||||
m_eraseLastDrawItem = false;
|
||||
}
|
||||
|
@ -62,7 +61,7 @@ void LIB_ITEM::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
|
|||
{
|
||||
wxString msg;
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Type" ), m_typeName, CYAN ) );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Type" ), GetTypeName(), CYAN ) );
|
||||
|
||||
if( m_Unit == 0 )
|
||||
msg = _( "All" );
|
||||
|
|
|
@ -128,8 +128,6 @@ protected:
|
|||
*/
|
||||
FILL_T m_Fill;
|
||||
|
||||
wxString m_typeName; ///< Name of object displayed in the message panel.
|
||||
|
||||
wxPoint m_initialPos; ///< Temporary position when moving an existing item.
|
||||
wxPoint m_initialCursorPos; ///< Initial cursor position at the beginning of a move.
|
||||
|
||||
|
@ -148,7 +146,11 @@ public:
|
|||
|
||||
virtual ~LIB_ITEM() { }
|
||||
|
||||
wxString GetTypeName() { return m_typeName; }
|
||||
/**
|
||||
* Provide a user-consumable name of the object type. Perform localization when
|
||||
* called so that run-time language selection works.
|
||||
*/
|
||||
virtual wxString GetTypeName() = 0;
|
||||
|
||||
/**
|
||||
* Begin an editing a component library draw item in \a aEditMode at \a aPosition.
|
||||
|
|
|
@ -84,8 +84,6 @@ void LIB_FIELD::Init( int id )
|
|||
SetTextWidth( GetDefaultTextSize() );
|
||||
SetTextHeight( GetDefaultTextSize() );
|
||||
|
||||
m_typeName = _( "Field" );
|
||||
|
||||
SetTextAngle( TEXT_ANGLE_HORIZ ); // constructor already did this.
|
||||
|
||||
m_rotate = false;
|
||||
|
|
|
@ -100,6 +100,11 @@ public:
|
|||
return wxT( "LIB_FIELD" );
|
||||
}
|
||||
|
||||
wxString GetTypeName() override
|
||||
{
|
||||
return _( "Field" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Object constructor initialization helper.
|
||||
*/
|
||||
|
|
|
@ -288,14 +288,15 @@ std::list<LIB_ALIAS*> LIB_MANAGER::GetAliases( const wxString& aLibrary ) const
|
|||
}
|
||||
else
|
||||
{
|
||||
wxArrayString symbols;
|
||||
std::vector<LIB_ALIAS*> aliases;
|
||||
|
||||
try {
|
||||
symTable()->EnumerateSymbolLib( aLibrary, symbols );
|
||||
try
|
||||
{
|
||||
symTable()->LoadSymbolLib( aliases, aLibrary );
|
||||
}
|
||||
catch( IO_ERROR& ) {}
|
||||
|
||||
for( const auto& symbol : symbols )
|
||||
ret.push_back( symTable()->LoadSymbol( aLibrary, symbol ) );
|
||||
} catch( IO_ERROR& e ) {}
|
||||
std::copy( aliases.begin(), aliases.end(), std::back_inserter( ret ) );
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -54,8 +54,12 @@ bool LIB_MANAGER_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
|
|||
}
|
||||
|
||||
|
||||
#define PROGRESS_INTERVAL_MILLIS 50
|
||||
|
||||
void LIB_MANAGER_ADAPTER::Sync( bool aForce, std::function<void(int, int, const wxString&)> aProgressCallback )
|
||||
{
|
||||
wxLongLong nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS;
|
||||
|
||||
int libMgrHash = m_libMgr->GetHash();
|
||||
|
||||
if( !aForce && m_lastSyncHash == libMgrHash )
|
||||
|
@ -68,7 +72,12 @@ void LIB_MANAGER_ADAPTER::Sync( bool aForce, std::function<void(int, int, const
|
|||
for( auto it = m_tree.Children.begin(); it != m_tree.Children.end(); /* iteration inside */ )
|
||||
{
|
||||
const wxString& name = it->get()->Name;
|
||||
aProgressCallback( i++, max, name );
|
||||
|
||||
if( wxGetUTCTimeMillis() > nextUpdate )
|
||||
{
|
||||
aProgressCallback( i++, max, name );
|
||||
nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS;
|
||||
}
|
||||
|
||||
if( !m_libMgr->LibraryExists( name ) )
|
||||
{
|
||||
|
@ -88,7 +97,12 @@ void LIB_MANAGER_ADAPTER::Sync( bool aForce, std::function<void(int, int, const
|
|||
{
|
||||
if( m_libHashes.count( libName ) == 0 )
|
||||
{
|
||||
aProgressCallback( i++, max, libName );
|
||||
if( wxGetUTCTimeMillis() > nextUpdate )
|
||||
{
|
||||
aProgressCallback( i++, max, libName );
|
||||
nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS;
|
||||
}
|
||||
|
||||
auto& lib_node = m_tree.AddLib( libName );
|
||||
updateLibrary( lib_node );
|
||||
m_tree.AssignIntrinsicRanks();
|
||||
|
|
|
@ -154,7 +154,6 @@ LIB_PIN::LIB_PIN( LIB_PART* aParent ) :
|
|||
m_numTextSize = LIB_EDIT_FRAME::GetPinNumDefaultSize();
|
||||
m_nameTextSize = LIB_EDIT_FRAME::GetPinNameDefaultSize();
|
||||
m_width = 0;
|
||||
m_typeName = _( "Pin" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -110,6 +110,11 @@ public:
|
|||
return wxT( "LIB_PIN" );
|
||||
}
|
||||
|
||||
wxString GetTypeName() override
|
||||
{
|
||||
return _( "Pin" );
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override;
|
||||
#endif
|
||||
|
|
|
@ -48,7 +48,6 @@ LIB_POLYLINE::LIB_POLYLINE( LIB_PART* aParent ) :
|
|||
m_Fill = NO_FILL;
|
||||
m_Width = 0;
|
||||
m_isFillable = true;
|
||||
m_typeName = _( "PolyLine" );
|
||||
m_ModifyIndex = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,10 @@ public:
|
|||
return wxT( "LIB_POLYLINE" );
|
||||
}
|
||||
|
||||
wxString GetTypeName() override
|
||||
{
|
||||
return _( "PolyLine" );
|
||||
}
|
||||
|
||||
void AddPoint( const wxPoint& aPoint );
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ LIB_RECTANGLE::LIB_RECTANGLE( LIB_PART* aParent ) :
|
|||
m_Width = 0;
|
||||
m_Fill = NO_FILL;
|
||||
m_isFillable = true;
|
||||
m_typeName = _( "Rectangle" );
|
||||
m_isHeightLocked = false;
|
||||
m_isWidthLocked = false;
|
||||
m_isStartPointSelected = false;
|
||||
|
|
|
@ -59,6 +59,11 @@ public:
|
|||
return wxT( "LIB_RECTANGLE" );
|
||||
}
|
||||
|
||||
wxString GetTypeName() override
|
||||
{
|
||||
return _( "Rectangle" );
|
||||
}
|
||||
|
||||
void SetEndPosition( const wxPoint& aPosition ) { m_End = aPosition; }
|
||||
|
||||
bool HitTest( const wxPoint& aPosition ) const override;
|
||||
|
|
|
@ -48,7 +48,6 @@ LIB_TEXT::LIB_TEXT( LIB_PART * aParent ) :
|
|||
EDA_TEXT()
|
||||
{
|
||||
SetTextSize( wxSize( 50, 50 ) );
|
||||
m_typeName = _( "Text" );
|
||||
m_rotate = false;
|
||||
m_updateText = false;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,11 @@ public:
|
|||
return wxT( "LIB_TEXT" );
|
||||
}
|
||||
|
||||
wxString GetTypeName() override
|
||||
{
|
||||
return _( "Text" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text item string to \a aText.
|
||||
*
|
||||
|
|
|
@ -26,33 +26,54 @@
|
|||
#include <dsnlexer.h>
|
||||
#include <fctsys.h>
|
||||
#include <macros.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
using namespace TFIELD_T;
|
||||
|
||||
|
||||
const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx )
|
||||
{
|
||||
static void* locale = nullptr;
|
||||
static wxString referenceDefault;
|
||||
static wxString valueDefault;
|
||||
static wxString footprintDefault;
|
||||
static wxString datasheetDefault;
|
||||
static wxString fieldDefault;
|
||||
|
||||
// Fetching translations can take a surprising amount of time when loading libraries,
|
||||
// so only do it when necessary.
|
||||
if( Pgm().GetLocale() != locale )
|
||||
{
|
||||
referenceDefault = _( "Reference" );
|
||||
valueDefault = _( "Value" );
|
||||
footprintDefault = _( "Footprint" );
|
||||
datasheetDefault = _( "Datasheet" );
|
||||
fieldDefault = _( "Field" );
|
||||
locale = Pgm().GetLocale();
|
||||
}
|
||||
|
||||
// Fixed values for the first few default fields used by EESCHEMA
|
||||
// (mandatory fields)
|
||||
switch( aFieldNdx )
|
||||
{
|
||||
case REFERENCE:
|
||||
return _( "Reference" ); // The component reference, R1, C1, etc.
|
||||
return referenceDefault; // The component reference, R1, C1, etc.
|
||||
|
||||
case VALUE:
|
||||
return _( "Value" ); // The component value + name
|
||||
return valueDefault; // The component value + name
|
||||
|
||||
case FOOTPRINT:
|
||||
return _( "Footprint" ); // The footprint for use with Pcbnew
|
||||
return footprintDefault; // The footprint for use with Pcbnew
|
||||
|
||||
case DATASHEET:
|
||||
return _( "Datasheet" ); // Link to a datasheet for component
|
||||
return datasheetDefault; // Link to a datasheet for component
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Other fields are use fields, give a default name:
|
||||
wxString fieldName = _( "Field" );
|
||||
wxString fieldName = fieldDefault;
|
||||
fieldName << aFieldNdx;
|
||||
return fieldName;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue