33#include <magic_enum.hpp>
57 wxCHECK( aRow->
plugin && ret,
nullptr );
71 wxString::Format(
_(
"Unknown library type %s " ), row->
Type() );
87 [](
const std::future<void>& aFuture ) {
return aFuture.valid(); } );
91 wxLogTrace(
traceLibraries,
"DB: Cannot AsyncLoad, futures from a previous call remain!" );
102 wxLogTrace(
traceLibraries,
"DB: AsyncLoad: no libraries left to load; exiting" );
113 [](
const wxString& aLib, std::map<wxString, LIB_DATA>& aMap, std::mutex& aMutex )
115 std::lock_guard lock( aMutex );
117 if( aMap.contains( aLib ) )
128 std::set<wxString> libNamesCurrentlyValid;
133 const wxString& nickname = row->Nickname();
135 libNamesCurrentlyValid.insert( nickname );
151 [
this, nickname, scope]()
156 LIBRARY_RESULT<LIB_DATA*> result = loadIfNeeded( nickname );
158 if( result.has_value() )
160 LIB_DATA* lib = *result;
161 wxArrayString dummyList;
162 std::lock_guard lock ( lib->mutex );
163 lib->status.load_status = LOAD_STATUS::LOADING;
165 std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
169 plugin( lib )->DesignBlockEnumerate( dummyList, getUri( lib->row ), false, &options );
170 wxLogTrace( traceLibraries,
"DB: %s: library enumerated %zu items", nickname, dummyList.size() );
171 lib->status.load_status = LOAD_STATUS::LOADED;
175 lib->status.load_status = LOAD_STATUS::LOAD_ERROR;
176 lib->status.error = LIBRARY_ERROR( { e.What() } );
177 wxLogTrace( traceLibraries,
"DB: %s: plugin threw exception: %s", nickname, e.What() );
184 case LIBRARY_TABLE_SCOPE::GLOBAL:
186 std::lock_guard lock( GlobalLibraryMutex );
188 GlobalLibraries[nickname].status = LIB_STATUS( {
189 .load_status = LOAD_STATUS::LOAD_ERROR,
190 .error = result.error()
196 case LIBRARY_TABLE_SCOPE::PROJECT:
198 wxLogTrace( traceLibraries,
"DB: project library error: %s: %s", nickname, result.error().message );
199 std::lock_guard lock( m_libraries_mutex );
201 m_libraries[nickname].status = LIB_STATUS( {
202 .load_status = LOAD_STATUS::LOAD_ERROR,
203 .error = result.error()
210 wxFAIL_MSG(
"Unexpected library table scope" );
220 std::lock_guard lock( GlobalLibraryMutex );
221 std::erase_if( GlobalLibraries, [&](
const auto& pair )
223 return libNamesCurrentlyValid.contains( pair.first );
228 std::lock_guard lock( m_libraries_mutex );
229 std::erase_if( m_libraries, [&](
const auto& pair )
231 return libNamesCurrentlyValid.contains( pair.first );
235 if( m_loadTotal > 0 )
236 wxLogTrace(
traceLibraries,
"DB: Started async load of %zu libraries", m_loadTotal );
242 std::vector<DESIGN_BLOCK*> blocks;
244 std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname );
251 wxArrayString blockNames;
259 wxLogTrace(
traceLibraries,
"DB: Exception enumerating library %s: %s",
263 for(
const wxString& blockName : blockNames )
267 blocks.emplace_back(
plugin( lib )->DesignBlockLoad(
getUri( lib->
row ), blockName,
false, &options ) );
271 wxLogTrace(
traceLibraries,
"DB: Exception enumerating design block %s: %s", blockName, e.
What() );
282 wxArrayString namesAS;
283 std::vector<wxString> names;
285 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
293 for(
const wxString&
name : namesAS )
294 names.emplace_back(
name );
301 const wxString& aDesignBlockName,
bool aKeepUUID )
303 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
319 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
332 const wxString& aDesignBlockName )
334 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
349 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
365 const wxString& aDesignBlockName )
367 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
378 if( std::optional<const LIB_DATA*> maybeLib =
fetchIfLoaded( aNickname ) )
394 if( nickname.size() )
@ DESIGN_BLOCK_FILE_UNKNOWN
0 is not a legal menu id on Mac
static DESIGN_BLOCK_FILE_T EnumFromStr(const wxString &aFileType)
static DESIGN_BLOCK_IO * FindPlugin(DESIGN_BLOCK_FILE_T aFileType)
bool DesignBlockExists(const wxString &aLibraryPath, const wxString &aDesignBlockName, const std::map< std::string, UTF8 > *aProperties=nullptr)
void DesignBlockDelete(const wxString &aLibraryPath, const wxString &aDesignBlockName, const std::map< std::string, UTF8 > *aProperties=nullptr)
DESIGN_BLOCK * DesignBlockLoad(const wxString &aLibraryPath, const wxString &aDesignBlockName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr)
void DesignBlockSave(const wxString &aLibraryPath, const DESIGN_BLOCK *aDesignBlock, const std::map< std::string, UTF8 > *aProperties=nullptr)
const DESIGN_BLOCK * GetEnumeratedDesignBlock(const wxString &aLibraryPath, const wxString &aDesignBlockName, const std::map< std::string, UTF8 > *aProperties=nullptr)
void DesignBlockEnumerate(wxArrayString &aDesignBlockNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr)
bool IsLibraryWritable(const wxString &aLibraryPath) override
Return true if the library at aLibraryPath is writable.
std::vector< wxString > GetDesignBlockNames(const wxString &aNickname)
SAVE_T
The set of return values from DesignBlockSave() below.
static DESIGN_BLOCK_IO * plugin(const LIB_DATA *aRow)
Helper to cast the ABC plugin in the LIB_DATA* to a concrete plugin.
std::vector< DESIGN_BLOCK * > GetDesignBlocks(const wxString &aNickname)
std::optional< LIBRARY_ERROR > LibraryError(const wxString &aNickname) const
void DeleteDesignBlock(const wxString &aNickname, const wxString &aDesignBlockName)
Delete the aDesignBlockName from the library given by aNickname.
static wxString GlobalPathEnvVariableName()
LIBRARY_RESULT< IO_BASE * > createPlugin(const LIBRARY_TABLE_ROW *row) override
Creates a concrete plugin for the given row.
void AsyncLoad() override
Loads all available libraries for this adapter type in the background.
DESIGN_BLOCK * LoadDesignBlock(const wxString &aNickname, const wxString &aDesignBlockName, bool aKeepUUID=false)
Load a design block having aDesignBlockName from the library given by aNickname.
static std::mutex GlobalLibraryMutex
DESIGN_BLOCK * DesignBlockLoadWithOptionalNickname(const LIB_ID &aDesignBlockId, bool aKeepUUID=false)
Load a design block having aDesignBlockId with possibly an empty nickname.
SAVE_T SaveDesignBlock(const wxString &aNickname, const DESIGN_BLOCK *aDesignBlock, bool aOverwrite=true)
Write aDesignBlock to an existing library given by aNickname.
static std::map< wxString, LIB_DATA > GlobalLibraries
DESIGN_BLOCK_LIBRARY_ADAPTER(LIBRARY_MANAGER &aManager)
bool IsDesignBlockLibWritable(const wxString &aNickname)
Return true if the library given by aNickname is writable.
const DESIGN_BLOCK * GetEnumeratedDesignBlock(const wxString &aNickname, const wxString &aDesignBlockName)
A version of #DesignBlockLoad() for use after #DesignBlockEnumerate() for more efficient cache manage...
bool DesignBlockExists(const wxString &aNickname, const wxString &aDesignBlockName)
Indicates whether or not the given design block already exists in the given library.
const LIB_ID & GetLibId() const
wxString GetName() const override
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.
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::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.
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
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool< 0 > thread_pool
wxLogTrace helper definitions.