29#include <magic_enum.hpp>
56 [](
const std::future<void>& aFuture ) {
return aFuture.valid(); } );
60 wxLogTrace(
traceLibraries,
"FP: Cannot AsyncLoad, futures from a previous call remain!" );
71 wxLogTrace(
traceLibraries,
"FP: AsyncLoad: no libraries left to load; exiting" );
78 [](
const wxString& aLib, std::map<wxString, LIB_DATA>& aMap, std::mutex& aMutex )
80 std::lock_guard lock( aMutex );
82 if( aMap.contains( aLib ) )
95 wxString nickname = row->Nickname();
112 [
this, nickname, scope]()
117 LIBRARY_RESULT<LIB_DATA*> result = loadIfNeeded( nickname );
119 if( result.has_value() )
121 LIB_DATA* lib = *result;
122 wxArrayString dummyList;
123 std::lock_guard lock ( lib->mutex );
124 lib->status.load_status = LOAD_STATUS::LOADING;
126 std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
130 pcbplugin( lib )->FootprintEnumerate( dummyList, getUri( lib->row ), false, &options );
131 wxLogTrace( traceLibraries,
"FP: %s: library enumerated %zu items", nickname, dummyList.size() );
132 lib->status.load_status = LOAD_STATUS::LOADED;
136 lib->status.load_status = LOAD_STATUS::LOAD_ERROR;
137 lib->status.error = LIBRARY_ERROR( { e.What() } );
138 wxLogTrace( traceLibraries,
"FP: %s: plugin threw exception: %s", nickname, e.What() );
145 case LIBRARY_TABLE_SCOPE::GLOBAL:
147 std::lock_guard lock( GlobalLibraryMutex );
149 GlobalLibraries[nickname].status = LIB_STATUS( {
150 .load_status = LOAD_STATUS::LOAD_ERROR,
151 .error = result.error()
157 case LIBRARY_TABLE_SCOPE::PROJECT:
159 wxLogTrace( traceLibraries,
"FP: project library error: %s: %s", nickname, result.error().message );
160 std::lock_guard lock( m_libraries_mutex );
162 m_libraries[nickname].status = LIB_STATUS( {
163 .load_status = LOAD_STATUS::LOAD_ERROR,
164 .error = result.error()
171 wxFAIL_MSG(
"Unexpected library table scope" );
176 }, BS::pr::lowest ) );
179 wxLogTrace(
traceLibraries,
"FP: Started async load of %zu libraries", m_loadTotal );
188 std::lock_guard lock ( lib->
mutex );
195 wxArrayString dummyList;
197 wxLogTrace(
traceLibraries,
"Sym: %s: library enumerated %zu items", aNickname, dummyList.size() );
204 wxLogTrace(
traceLibraries,
"Sym: %s: plugin threw exception: %s", aNickname, e.
What() );
229 std::vector<FOOTPRINT*> footprints;
231 std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname );
239 wxArrayString namesAS;
247 wxLogTrace(
traceLibraries,
"FP: Exception enumerating library %s: %s",
251 for(
const wxString& footprintName : namesAS )
261 wxLogTrace(
traceLibraries,
"Sym: Exception enumerating library %s: %s",
266 wxCHECK2( footprint,
continue );
271 footprints.emplace_back( footprint );
281 wxArrayString namesAS;
282 std::vector<wxString> names;
284 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
295 wxLogTrace(
traceLibraries,
"FP: Exception enumerating library %s: %s",
300 for(
const wxString&
name : namesAS )
301 names.emplace_back(
name );
313 wxCHECK(
HasLibrary( *aNickname,
true ), hash );
315 if( std::optional<const LIB_DATA*> r =
fetchIfLoaded( *aNickname ); r.has_value() )
320 wxHashTable::MakeKey( *aNickname );
326 if( std::optional<const LIB_DATA*> r =
fetchIfLoaded( nickname ); r.has_value() )
329 wxCHECK2(
plugin,
continue );
331 wxHashTable::MakeKey( nickname );
341 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
355 if( std::optional<const LIB_DATA*> lib =
fetchIfLoaded( aNickname ) )
359 LIB_ID id = footprint->GetFPID();
361 footprint->SetFPID(
id );
367 wxLogTrace(
traceLibraries,
"LoadFootprint: requested library %s not loaded", aNickname );
379 if( nickname.size() )
401 if( std::optional<const LIB_DATA*> lib =
fetchIfLoaded( aNickname ) )
416 wxLogTrace(
traceLibraries,
"SaveFootprint: error checking for existing footprint %s: %s",
437 wxLogTrace(
traceLibraries,
"SaveFootprint: requested library %s not loaded", aNickname );
444 if( std::optional<const LIB_DATA*> lib =
fetchIfLoaded( aNickname ) )
452 wxLogTrace(
traceLibraries,
"DeleteFootprint: error deleting %s:%s: %s", aNickname,
453 aFootprintName, e.
What() );
458 wxLogTrace(
traceLibraries,
"DeleteFootprint: requested library %s not loaded", aNickname );
498 wxString msg = wxString::Format(
_(
"Unknown library type %s " ), row->
Type() );
515 wxCHECK( aRow->
plugin && ret,
nullptr );
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
LIBRARY_MANAGER_ADAPTER(LIBRARY_MANAGER &aManager)
Constructs a type-specific adapter into the library manager.
LIBRARY_RESULT< LIB_DATA * > loadIfNeeded(const wxString &aNickname)
Fetches a loaded library, triggering a load of that library if it isn't loaded yet.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library tables.
std::map< wxString, LIB_DATA > m_libraries
std::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
std::vector< std::future< void > > m_futures
static wxString getUri(const LIBRARY_TABLE_ROW *aRow)
std::mutex m_libraries_mutex
std::atomic< size_t > m_loadCount
LIBRARY_MANAGER & m_manager
std::optional< const LIB_DATA * > fetchIfLoaded(const wxString &aNickname) const
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
LIBRARY_TABLE_SCOPE Scope() const
std::map< std::string, UTF8 > GetOptionsMap() const
const wxString & Type() const
const wxString & Nickname() const
A logical library item identifier and consists of various portions much like a URI.
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
static PCB_FILE_T EnumFromStr(const wxString &aFileType)
Return the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
@ PCB_FILE_UNKNOWN
0 is not a legal menu id on Mac
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
A base class that BOARD loading and saving plugins should derive from.
virtual void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr)
Return a list of footprint names contained within the library at aLibraryPath.
virtual bool FootprintExists(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr)
Check for the existence of a footprint.
virtual void FootprintDelete(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr)
Delete aFootprintName from the library at aLibraryPath.
virtual FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr)
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
virtual void FootprintSave(const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const std::map< std::string, UTF8 > *aProperties=nullptr)
Write aFootprint to an existing library located at aLibraryPath.
Functions related to environment variables, including help functions.
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
tl::expected< ResultType, LIBRARY_ERROR > LIBRARY_RESULT
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Construct a versioned environment variable based on this KiCad major version.
Storage for an actual loaded library (including library content owned by the plugin)
std::unique_ptr< IO_BASE > plugin
const LIBRARY_TABLE_ROW * row
std::optional< LIBRARY_ERROR > error
wxString result
Test unit parsing edge cases and error handling.
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
wxLogTrace helper definitions.