Add threaded library load to symbol editor
This commit is contained in:
parent
cc9787e47a
commit
82a4cacb4f
|
@ -22,21 +22,21 @@
|
||||||
|
|
||||||
#include <symbol_async_loader.h>
|
#include <symbol_async_loader.h>
|
||||||
#include <symbol_lib_table.h>
|
#include <symbol_lib_table.h>
|
||||||
#include <symbol_tree_model_adapter.h>
|
|
||||||
#include <widgets/progress_reporter.h>
|
#include <widgets/progress_reporter.h>
|
||||||
|
|
||||||
|
|
||||||
SYMBOL_ASYNC_LOADER::SYMBOL_ASYNC_LOADER( const std::vector<wxString>& aNicknames,
|
SYMBOL_ASYNC_LOADER::SYMBOL_ASYNC_LOADER( const std::vector<wxString>& aNicknames,
|
||||||
SYMBOL_TREE_MODEL_ADAPTER* aAdapter,
|
SYMBOL_LIB_TABLE* aTable, bool aOnlyPowerSymbols,
|
||||||
std::unordered_map<wxString, std::vector<LIB_PART*>>& aOutput,
|
std::unordered_map<wxString, std::vector<LIB_PART*>>* aOutput,
|
||||||
PROGRESS_REPORTER* aReporter ) :
|
PROGRESS_REPORTER* aReporter ) :
|
||||||
m_nicknames( aNicknames ),
|
m_nicknames( aNicknames ),
|
||||||
m_adapter( aAdapter ),
|
m_table( aTable ),
|
||||||
|
m_onlyPowerSymbols( aOnlyPowerSymbols ),
|
||||||
m_output( aOutput ),
|
m_output( aOutput ),
|
||||||
m_reporter( aReporter )
|
m_reporter( aReporter )
|
||||||
{
|
{
|
||||||
m_onlyPowerSymbols = ( m_adapter->GetFilter() == LIB_TREE_MODEL_ADAPTER::CMP_FILTER_POWER );
|
wxASSERT( m_table );
|
||||||
m_threadCount = std::max<size_t>( 1, std::thread::hardware_concurrency() - 1 );
|
m_threadCount = std::max<size_t>( 1, std::thread::hardware_concurrency() - 1 );
|
||||||
|
|
||||||
m_canceled.store( false );
|
m_canceled.store( false );
|
||||||
m_nextLibrary.store( 0 );
|
m_nextLibrary.store( 0 );
|
||||||
|
@ -69,10 +69,10 @@ bool SYMBOL_ASYNC_LOADER::Join()
|
||||||
|
|
||||||
const std::vector<LOADED_PAIR>& ret = m_returns[ii].get();
|
const std::vector<LOADED_PAIR>& ret = m_returns[ii].get();
|
||||||
|
|
||||||
if( !ret.empty() )
|
if( m_output && !ret.empty() )
|
||||||
{
|
{
|
||||||
for( const LOADED_PAIR& pair : ret )
|
for( const LOADED_PAIR& pair : ret )
|
||||||
m_output[pair.first] = pair.second;
|
m_output->insert( pair );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ std::vector<SYMBOL_ASYNC_LOADER::LOADED_PAIR> SYMBOL_ASYNC_LOADER::worker()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_adapter->m_libs->LoadSymbolLib( pair.second, nickname, onlyPower );
|
m_table->LoadSymbolLib( pair.second, nickname, onlyPower );
|
||||||
ret.emplace_back( std::move( pair ) );
|
ret.emplace_back( std::move( pair ) );
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& ioe )
|
catch( const IO_ERROR& ioe )
|
||||||
|
|
|
@ -24,12 +24,14 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <symbol_tree_model_adapter.h>
|
#include <wx/string.h>
|
||||||
|
|
||||||
class LIB_PART;
|
class LIB_PART;
|
||||||
class PROGRESS_REPORTER;
|
class PROGRESS_REPORTER;
|
||||||
|
class SYMBOL_LIB_TABLE;
|
||||||
|
|
||||||
|
|
||||||
class SYMBOL_ASYNC_LOADER
|
class SYMBOL_ASYNC_LOADER
|
||||||
|
@ -38,13 +40,14 @@ public:
|
||||||
/**
|
/**
|
||||||
* Constructs a loader for symbol libraries
|
* Constructs a loader for symbol libraries
|
||||||
* @param aNicknames is a list of library nicknames to load
|
* @param aNicknames is a list of library nicknames to load
|
||||||
* @param aAdapter is a pointer to the parent symbol tree model adapter
|
* @param aTable is a pointer to the symbol library table to load libraries for
|
||||||
|
* @param aOnlyPowerSymbols, if true, will only return power symbols in the output map
|
||||||
* @param aOutput will be filled with the loaded parts
|
* @param aOutput will be filled with the loaded parts
|
||||||
* @param aReporter will be used to repord progress, of not null
|
* @param aReporter will be used to repord progress, of not null
|
||||||
*/
|
*/
|
||||||
SYMBOL_ASYNC_LOADER( const std::vector<wxString>& aNicknames,
|
SYMBOL_ASYNC_LOADER( const std::vector<wxString>& aNicknames,
|
||||||
SYMBOL_TREE_MODEL_ADAPTER* aAdapter,
|
SYMBOL_LIB_TABLE* aTable, bool aOnlyPowerSymbols = false,
|
||||||
std::unordered_map<wxString, std::vector<LIB_PART*>>& aOutput,
|
std::unordered_map<wxString, std::vector<LIB_PART*>>* aOutput = nullptr,
|
||||||
PROGRESS_REPORTER* aReporter = nullptr );
|
PROGRESS_REPORTER* aReporter = nullptr );
|
||||||
|
|
||||||
~SYMBOL_ASYNC_LOADER();
|
~SYMBOL_ASYNC_LOADER();
|
||||||
|
@ -80,14 +83,14 @@ private:
|
||||||
///< list of libraries to load
|
///< list of libraries to load
|
||||||
std::vector<wxString> m_nicknames;
|
std::vector<wxString> m_nicknames;
|
||||||
|
|
||||||
///< Handle to the adapter that owns this loader
|
///< Handle to the symbol library table being loaded into
|
||||||
SYMBOL_TREE_MODEL_ADAPTER* m_adapter;
|
SYMBOL_LIB_TABLE* m_table;
|
||||||
|
|
||||||
///< True if we are loading only power symbols
|
///< True if we are loading only power symbols
|
||||||
bool m_onlyPowerSymbols;
|
bool m_onlyPowerSymbols;
|
||||||
|
|
||||||
///< Handle to map that will be filled with the loaded parts per library
|
///< Handle to map that will be filled with the loaded parts per library
|
||||||
std::unordered_map<wxString, std::vector<LIB_PART*>>& m_output;
|
std::unordered_map<wxString, std::vector<LIB_PART*>>* m_output;
|
||||||
|
|
||||||
///< Progress reporter (may be null)
|
///< Progress reporter (may be null)
|
||||||
PROGRESS_REPORTER* m_reporter;
|
PROGRESS_REPORTER* m_reporter;
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
#include <widgets/app_progress_dialog.h>
|
#include <widgets/app_progress_dialog.h>
|
||||||
#include <widgets/infobar.h>
|
#include <widgets/infobar.h>
|
||||||
#include <widgets/lib_tree.h>
|
#include <widgets/lib_tree.h>
|
||||||
|
#include <widgets/progress_reporter.h>
|
||||||
#include <widgets/symbol_tree_pane.h>
|
#include <widgets/symbol_tree_pane.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
#include <panel_sym_lib_table.h>
|
#include <panel_sym_lib_table.h>
|
||||||
|
@ -140,7 +141,13 @@ SYMBOL_EDIT_FRAME::SYMBOL_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
setupUIConditions();
|
setupUIConditions();
|
||||||
|
|
||||||
m_libMgr = new SYMBOL_LIBRARY_MANAGER( *this );
|
m_libMgr = new SYMBOL_LIBRARY_MANAGER( *this );
|
||||||
SyncLibraries( true );
|
|
||||||
|
// Preload libraries before using SyncLibraries the first time, as the preload is threaded
|
||||||
|
WX_PROGRESS_REPORTER reporter( this, _( "Loading Symbol Libraries" ),
|
||||||
|
m_libMgr->GetLibraryCount(), true );
|
||||||
|
m_libMgr->Preload( reporter );
|
||||||
|
|
||||||
|
SyncLibraries( false );
|
||||||
m_treePane = new SYMBOL_TREE_PANE( this, m_libMgr );
|
m_treePane = new SYMBOL_TREE_PANE( this, m_libMgr );
|
||||||
|
|
||||||
ReCreateMenuBar();
|
ReCreateMenuBar();
|
||||||
|
|
|
@ -33,7 +33,10 @@
|
||||||
#include <sch_io_mgr.h>
|
#include <sch_io_mgr.h>
|
||||||
#include <sch_plugins/legacy/sch_legacy_plugin.h>
|
#include <sch_plugins/legacy/sch_legacy_plugin.h>
|
||||||
#include <symbol_lib_table.h>
|
#include <symbol_lib_table.h>
|
||||||
|
#include <symbol_async_loader.h>
|
||||||
|
#include <widgets/progress_reporter.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <locale_io.h>
|
||||||
|
|
||||||
|
|
||||||
SYMBOL_LIBRARY_MANAGER::SYMBOL_LIBRARY_MANAGER( SYMBOL_EDIT_FRAME& aFrame ) :
|
SYMBOL_LIBRARY_MANAGER::SYMBOL_LIBRARY_MANAGER( SYMBOL_EDIT_FRAME& aFrame ) :
|
||||||
|
@ -58,6 +61,40 @@ void SYMBOL_LIBRARY_MANAGER::Sync( const wxString& aForceRefresh,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SYMBOL_LIBRARY_MANAGER::Preload( PROGRESS_REPORTER& aReporter )
|
||||||
|
{
|
||||||
|
const int progressIntervalMillis = 60;
|
||||||
|
|
||||||
|
SYMBOL_ASYNC_LOADER loader( symTable()->GetLogicalLibs(), symTable(), false, nullptr,
|
||||||
|
&aReporter );
|
||||||
|
|
||||||
|
LOCALE_IO toggle;
|
||||||
|
|
||||||
|
loader.Start();
|
||||||
|
|
||||||
|
while( !loader.Done() )
|
||||||
|
{
|
||||||
|
aReporter.KeepRefreshing();
|
||||||
|
|
||||||
|
wxMilliSleep( progressIntervalMillis );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aReporter.IsCancelled() )
|
||||||
|
{
|
||||||
|
loader.Abort();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loader.Join();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !loader.GetErrors().IsEmpty() )
|
||||||
|
{
|
||||||
|
wxLogError( loader.GetErrors() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SYMBOL_LIBRARY_MANAGER::HasModifications() const
|
bool SYMBOL_LIBRARY_MANAGER::HasModifications() const
|
||||||
{
|
{
|
||||||
for( const auto& lib : m_libs )
|
for( const auto& lib : m_libs )
|
||||||
|
@ -638,6 +675,12 @@ bool SYMBOL_LIBRARY_MANAGER:: HasDerivedSymbols( const wxString& aSymbolName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t SYMBOL_LIBRARY_MANAGER::GetLibraryCount() const
|
||||||
|
{
|
||||||
|
return symTable()->GetLogicalLibs().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString SYMBOL_LIBRARY_MANAGER::getLibraryName( const wxString& aFilePath )
|
wxString SYMBOL_LIBRARY_MANAGER::getLibraryName( const wxString& aFilePath )
|
||||||
{
|
{
|
||||||
wxFileName fn( aFilePath );
|
wxFileName fn( aFilePath );
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
class LIB_PART;
|
class LIB_PART;
|
||||||
class PART_LIB;
|
class PART_LIB;
|
||||||
|
class PROGRESS_REPORTER;
|
||||||
class SCH_PLUGIN;
|
class SCH_PLUGIN;
|
||||||
class SYMBOL_EDIT_FRAME;
|
class SYMBOL_EDIT_FRAME;
|
||||||
class SYMBOL_LIB_TABLE;
|
class SYMBOL_LIB_TABLE;
|
||||||
|
@ -108,6 +109,13 @@ public:
|
||||||
void Sync( const wxString& aForceRefresh,
|
void Sync( const wxString& aForceRefresh,
|
||||||
std::function<void( int, int, const wxString& )> aProgressCallback );
|
std::function<void( int, int, const wxString& )> aProgressCallback );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preloads all symbol libraries in the symbol library table using SYMBOL_ASYNC_LOADER.
|
||||||
|
* Call before the first call to Sync() to get better performance.
|
||||||
|
* @param aReporter is used to report progress of the load
|
||||||
|
*/
|
||||||
|
void Preload( PROGRESS_REPORTER& aReporter );
|
||||||
|
|
||||||
int GetHash() const;
|
int GetHash() const;
|
||||||
|
|
||||||
bool HasModifications() const;
|
bool HasModifications() const;
|
||||||
|
@ -292,6 +300,8 @@ public:
|
||||||
*/
|
*/
|
||||||
bool HasDerivedSymbols( const wxString& aSymbolName, const wxString& aLibraryName );
|
bool HasDerivedSymbols( const wxString& aSymbolName, const wxString& aLibraryName );
|
||||||
|
|
||||||
|
size_t GetLibraryCount() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///< Extract library name basing on the file name.
|
///< Extract library name basing on the file name.
|
||||||
static wxString getLibraryName( const wxString& aFilePath );
|
static wxString getLibraryName( const wxString& aFilePath );
|
||||||
|
|
|
@ -71,7 +71,9 @@ void SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
|
||||||
|
|
||||||
std::unordered_map<wxString, std::vector<LIB_PART*>> loadedSymbols;
|
std::unordered_map<wxString, std::vector<LIB_PART*>> loadedSymbols;
|
||||||
|
|
||||||
SYMBOL_ASYNC_LOADER loader( aNicknames, this, loadedSymbols, prg.get() );
|
SYMBOL_ASYNC_LOADER loader( aNicknames, m_libs,
|
||||||
|
GetFilter() == LIB_TREE_MODEL_ADAPTER::CMP_FILTER_POWER,
|
||||||
|
&loadedSymbols, prg.get() );
|
||||||
|
|
||||||
LOCALE_IO toggle;
|
LOCALE_IO toggle;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue