30#include <magic_enum.hpp>
34using namespace std::chrono_literals;
69 wxArrayString namesAS;
74 long long timestamp =
plugin->GetLibraryTimestamp( aUri );
78 std::lock_guard pluginGuard(
pluginMutex( nickname ) );
81 plugin->FootprintEnumerate( namesAS, aUri,
false, &options );
83 std::vector<std::unique_ptr<FOOTPRINT>> footprints;
84 footprints.reserve( namesAS.size() );
89 const bool pluginCaches =
plugin->CachesEnumeratedFootprints();
91 for(
const wxString& footprintName : namesAS )
95 const FOOTPRINT* cached =
plugin->GetEnumeratedFootprint( aUri, footprintName, &options );
113 footprints.emplace_back( footprint );
118 nickname, footprintName, e.
What() );
130 plugin->ClearCachedFootprints( aUri );
169 std::vector<FOOTPRINT*> footprints;
177 footprints.reserve( it->second.size() );
179 for(
const auto& fp : it->second )
180 footprints.push_back( fp.get() );
190 wxArrayString namesAS;
191 std::vector<wxString> names;
193 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
200 std::lock_guard pluginGuard(
pluginMutex( aNickname ) );
213 for(
const wxString&
name : namesAS )
214 names.emplace_back(
name );
226 wxCHECK(
HasLibrary( *aNickname,
true ), hash );
228 if( std::optional<const LIB_DATA*> r =
fetchIfLoaded( *aNickname ); r.has_value() )
233 + wxHashTable::MakeKey( *aNickname );
239 if( std::optional<const LIB_DATA*> r =
fetchIfLoaded( nickname ); r.has_value() )
241 wxCHECK2( ( *r )->plugin->IsPCB_IO(),
continue );
244 + wxHashTable::MakeKey( nickname );
254 std::optional<LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname );
266 long long currentTimestamp =
plugin->GetLibraryTimestamp( uri );
275 wxLogTrace(
traceLibraries,
"FP: %s changed on disk, re-enumerating", aNickname );
311 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
316 std::lock_guard pluginGuard(
pluginMutex( aNickname ) );
336 for(
const auto& fp : libIt->second )
338 if( fp->GetFPID().GetLibItemName() ==
UTF8( aName ) )
347 copy->SetParent(
nullptr );
356 if( std::optional<const LIB_DATA*> lib =
fetchIfLoaded( aNickname ) )
360 std::lock_guard pluginGuard(
pluginMutex( aNickname ) );
362 if( std::unique_ptr<FOOTPRINT> footprint =
365 LIB_ID id = footprint->GetFPID();
367 footprint->SetFPID(
id );
368 footprint->SetParent(
nullptr );
369 footprint->SetParentGroup(
nullptr );
370 footprint->ClearAllNets();
371 return footprint.release();
376 wxLogTrace(
traceLibraries,
"LoadFootprint: error loading %s:%s: %s", aNickname, aName, ioe.
What() );
381 wxLogTrace(
traceLibraries,
"LoadFootprint: requested library %s not loaded", aNickname );
393 if( nickname.size() )
415 if( std::optional<const LIB_DATA*> lib =
fetchIfLoaded( aNickname ) )
418 std::lock_guard pluginGuard(
pluginMutex( aNickname ) );
426 std::unique_ptr<FOOTPRINT> existing =
434 wxLogTrace(
traceLibraries,
"SaveFootprint: error checking for existing footprint %s: %s",
463 auto& footprints = it->second;
464 std::erase_if( footprints,
465 [&fpName](
const std::unique_ptr<FOOTPRINT>& fp )
467 return fp->GetFPID().GetLibItemName().wx_str() == fpName;
481 it->second.emplace_back( clone );
489 wxLogTrace(
traceLibraries,
"SaveFootprint: requested library %s not loaded", aNickname );
497 if( std::optional<const LIB_DATA*> lib =
fetchIfLoaded( aNickname ) )
499 std::lock_guard pluginGuard(
pluginMutex( aNickname ) );
507 wxLogTrace(
traceLibraries,
"DeleteFootprint: error deleting %s:%s: %s", aNickname,
508 aFootprintName, e.
What() );
518 auto& footprints = it->second;
519 std::erase_if( footprints,
520 [&aFootprintName](
const std::unique_ptr<FOOTPRINT>& fp )
522 return fp->GetFPID().GetLibItemName().wx_str() == aFootprintName;
529 wxLogTrace(
traceLibraries,
"DeleteFootprint: requested library %s not loaded", aNickname );
538 if( std::optional<const LIB_DATA*> lib =
fetchIfLoaded( aLib ) )
540 std::lock_guard pluginGuard(
pluginMutex( aLib ) );
542 return ( *lib )->plugin->IsLibraryWritable(
getUri( ( *lib )->row ) );
556 wxFileName fileName(
m_manager.GetFullURI( row,
true ) );
558 if( fileName.FileExists() )
561 msg = wxString::Format(
_(
"Nested table '%s' not found." ), row->
URI() );
568 wxString msg = wxString::Format(
_(
"Unknown library type %s " ), row->
Type() );
576 magic_enum::enum_name( row->
Scope() ) );
virtual void SetParentGroup(EDA_GROUP *aGroup)
virtual void SetParent(EDA_ITEM *aParent)
virtual bool IsPCB_IO() const
Work-around for lack of dynamic_cast across compile units on Mac.
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()
virtual const wxString Problem() const
what was the problem?
virtual const wxString Where() const
where did the Problem() occur?
A wrapper for static data that should not be destroyed at program exit.
void resetProjectCache()
Aborts pending loads and resets every project-scope cache entry in place (plugin and row cleared,...
void evictOwnedGlobalEntries()
Erases this adapter's own entries (LIB_DATA::global_owner == this) from the process-wide globalLibs()...
LIBRARY_MANAGER_ADAPTER(LIBRARY_MANAGER &aManager)
Constructs a type-specific adapter into the library manager.
wxString getUri(const LIBRARY_TABLE_ROW *aRow) const
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::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
static std::recursive_mutex & pluginMutex(const wxString &aNickname)
Serializes access to a library's shared plugin instance so its single mutable cache is not raced by c...
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)
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 & URI() 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 PCB_IO 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 std::unique_ptr< 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 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 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.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
#define IGNORE_PARENT_GROUP
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
Never destroyed while holding the map's mutex; a plugin's worker thread may be blocked on it.
const LIBRARY_TABLE_ROW * row
The overall status of a loaded or loading library.
std::optional< LIBRARY_ERROR > error
wxString result
Test unit parsing edge cases and error handling.
wxLogTrace helper definitions.