KiCad PCB EDA Suite
Loading...
Searching...
No Matches
library_manager.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 * @author Jon Evans <[email protected]>
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef LIBRARY_MANAGER_H
22#define LIBRARY_MANAGER_H
23
24#include <future>
25#include <memory>
26
27#include <kicommon.h>
29#include <io/io_base.h>
30
31
32class LIBRARY_MANAGER;
33class PROJECT;
34
35
44
47{
49 std::optional<LIBRARY_ERROR> error;
50};
51
52
55{
56 std::unique_ptr<IO_BASE> plugin;
57 const LIBRARY_TABLE_ROW* row = nullptr;
58 std::mutex mutex;
60
62 std::vector<wxString> available_fields_cache;
63};
64
65
71{
72public:
81
83
84 LIBRARY_MANAGER& Manager() const;
85
87 virtual LIBRARY_TABLE_TYPE Type() const = 0;
88
91
93 std::optional<LIBRARY_TABLE*> ProjectTable() const;
94
95 std::optional<wxString> FindLibraryByURI( const wxString& aURI ) const;
96
98 std::vector<wxString> GetLibraryNames() const;
99
106 bool HasLibrary( const wxString& aNickname, bool aCheckEnabled = false ) const;
107
109 bool DeleteLibrary( const wxString& aNickname );
110
111 std::optional<wxString> GetLibraryDescription( const wxString& aNickname ) const;
112
114 std::vector<LIBRARY_TABLE_ROW*> Rows( LIBRARY_TABLE_SCOPE aScope = LIBRARY_TABLE_SCOPE::BOTH,
115 bool aIncludeInvalid = false ) const;
116
118 std::optional<LIBRARY_TABLE_ROW*> GetRow( const wxString& aNickname,
120
122 std::optional<LIBRARY_TABLE_ROW*> FindRowByURI( const wxString& aUri,
124
126 virtual void ProjectChanged();
127
129 void GlobalTablesChanged( std::initializer_list<LIBRARY_TABLE_TYPE> aChangedTables = {} );
130
131 void CheckTableRow( LIBRARY_TABLE_ROW& aRow );
132
134 virtual void AsyncLoad() = 0;
135
136 virtual std::optional<LIB_STATUS> LoadOne( LIB_DATA* aLib ) = 0;
137
139 std::optional<float> AsyncLoadProgress() const;
140
141 void BlockUntilLoaded();
142
143 bool IsLibraryLoaded( const wxString& aNickname );
144
146 virtual std::optional<LIB_STATUS> GetLibraryStatus( const wxString& aNickname ) const = 0;
147
149 std::vector<std::pair<wxString, LIB_STATUS>> GetLibraryStatuses() const;
150
152 wxString GetLibraryLoadErrors() const;
153
154 void ReloadLibraryEntry( const wxString& aNickname,
156
158 virtual bool IsWritable( const wxString& aNickname ) const;
159
161 bool CreateLibrary( const wxString& aNickname );
162
163 virtual bool SupportsConfigurationDialog( const wxString& aNickname ) const { return false; }
164
165 virtual void ShowConfigurationDialog( const wxString& aNickname, wxWindow* aParent ) const {};
166
167 virtual std::optional<LIBRARY_ERROR> LibraryError( const wxString& aNickname ) const;
168
169protected:
170 virtual std::map<wxString, LIB_DATA>& globalLibs() = 0;
171 virtual std::map<wxString, LIB_DATA>& globalLibs() const = 0;
172 virtual std::mutex& globalLibsMutex() = 0;
173
174 static wxString getUri( const LIBRARY_TABLE_ROW* aRow );
175
176 std::optional<const LIB_DATA*> fetchIfLoaded( const wxString& aNickname ) const;
177
178 std::optional<LIB_DATA*> fetchIfLoaded( const wxString& aNickname );
179
181 LIBRARY_RESULT<LIB_DATA*> loadIfNeeded( const wxString& aNickname );
182
183 LIBRARY_RESULT<LIB_DATA*> loadFromScope( const wxString& aNickname,
184 LIBRARY_TABLE_SCOPE aScope,
185 std::map<wxString, LIB_DATA>& aTarget,
186 std::mutex& aMutex );
187
189 void abortLoad();
190
193
194 virtual IO_BASE* plugin( const LIB_DATA* aRow ) = 0;
195
197
198 // The actual library content is held in an associated IO plugin
199 // TODO(JE) should this be an expected<LIB_ROW> so we can store the
200 // error result if a lib can't be loaded instead of retrying the load every time
201 // content is requested?
202 std::map<wxString, LIB_DATA> m_libraries;
203
205
206 std::atomic_bool m_abort;
207 std::vector<std::future<void>> m_futures;
208
209 std::atomic<size_t> m_loadCount;
211};
212
213
215{
216public:
218
220
223
224 static wxString DefaultGlobalTablePath( LIBRARY_TABLE_TYPE aType );
225
226 static bool IsTableValid( const wxString& aPath );
227
229 static bool GlobalTablesValid();
230
232 static std::vector<LIBRARY_TABLE_TYPE> InvalidGlobalTables();
233
234 static bool CreateGlobalTable( LIBRARY_TABLE_TYPE aType, bool aPopulateDefaultLibraries );
235
237 void LoadGlobalTables( std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad = {} );
238
240 void LoadProjectTables( std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad = {} );
241
242 void ReloadTables( LIBRARY_TABLE_SCOPE aScope, std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad = {} );
243
245 void ProjectChanged();
246
247 void RegisterAdapter( LIBRARY_TABLE_TYPE aType,
248 std::unique_ptr<LIBRARY_MANAGER_ADAPTER>&& aAdapter );
249
250 bool RemoveAdapter( LIBRARY_TABLE_TYPE aType, LIBRARY_MANAGER_ADAPTER* aAdapter );
251
252 std::optional<LIBRARY_MANAGER_ADAPTER*> Adapter( LIBRARY_TABLE_TYPE aType ) const;
253
262 std::optional<LIBRARY_TABLE*> Table( LIBRARY_TABLE_TYPE aType,
263 LIBRARY_TABLE_SCOPE aScope );
264
272 std::vector<LIBRARY_TABLE_ROW*> Rows( LIBRARY_TABLE_TYPE aType,
274 bool aIncludeInvalid = false ) const;
275
283 std::optional<LIBRARY_TABLE_ROW*> GetRow( LIBRARY_TABLE_TYPE aType, const wxString &aNickname,
285
286 std::optional<LIBRARY_TABLE_ROW*> FindRowByURI( LIBRARY_TABLE_TYPE aType, const wxString &aUri,
288
289 void ReloadLibraryEntry( LIBRARY_TABLE_TYPE aType, const wxString& aNickname,
291
292 void LoadProjectTables( const wxString& aProjectPath,
293 std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad = {} );
294
304 std::optional<wxString> GetFullURI( LIBRARY_TABLE_TYPE aType, const wxString& aNickname,
305 bool aSubstituted = false ) const;
306
307 static wxString GetFullURI( const LIBRARY_TABLE_ROW* aRow, bool aSubstituted = false );
308
309 static wxString ExpandURI( const wxString& aShortURI, const PROJECT& aProject );
310
311 static bool UrisAreEquivalent( const wxString& aURI1, const wxString& aURI2 );
312
313private:
314 void loadTables( const wxString& aTablePath, LIBRARY_TABLE_SCOPE aScope,
315 std::vector<LIBRARY_TABLE_TYPE> aTablesToLoad = {} );
316
317 void loadNestedTables( LIBRARY_TABLE& aTable );
318
319 static wxString tableFileName( LIBRARY_TABLE_TYPE aType );
320
321 void createEmptyTable( LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope );
322
323 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>> m_tables;
324
326 std::map<wxString, std::unique_ptr<LIBRARY_TABLE>> m_childTables;
327
328 // TODO: support multiple projects
329 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>> m_projectTables;
330
331 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_MANAGER_ADAPTER>> m_adapters;
332
333 mutable std::mutex m_adaptersMutex;
334};
335
336#endif //LIBRARY_MANAGER_H
std::optional< float > AsyncLoadProgress() const
Returns async load progress between 0.0 and 1.0, or nullopt if load is not in progress.
virtual std::optional< LIB_STATUS > LoadOne(LIB_DATA *aLib)=0
void ReloadLibraryEntry(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH)
std::optional< LIBRARY_TABLE * > ProjectTable() const
Retrieves the project library table for this adapter type, or nullopt if one doesn't exist.
LIBRARY_TABLE * GlobalTable() const
Retrieves the global library table for this adapter type.
LIBRARY_MANAGER_ADAPTER(LIBRARY_MANAGER &aManager)
Constructs a type-specific adapter into the library manager.
bool IsLibraryLoaded(const wxString &aNickname)
std::vector< LIBRARY_TABLE_ROW * > Rows(LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH, bool aIncludeInvalid=false) const
Like LIBRARY_MANAGER::Rows but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::optional< LIBRARY_TABLE_ROW * > FindRowByURI(const wxString &aUri, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::FindRowByURI but filtered to the LIBRARY_TABLE_TYPE of this adapter.
virtual std::map< wxString, LIB_DATA > & globalLibs()=0
virtual std::mutex & globalLibsMutex()=0
virtual LIBRARY_TABLE_TYPE Type() const =0
The type of library table this adapter works with.
bool DeleteLibrary(const wxString &aNickname)
Deletes the given library from disk if it exists; returns true if deleted.
LIBRARY_RESULT< LIB_DATA * > loadIfNeeded(const wxString &aNickname)
Fetches a loaded library, triggering a load of that library if it isn't loaded yet.
wxString GetLibraryLoadErrors() const
Returns all library load errors as newline-separated strings for display.
std::optional< wxString > FindLibraryByURI(const wxString &aURI) const
virtual std::optional< LIB_STATUS > GetLibraryStatus(const wxString &aNickname) const =0
Returns the status of a loaded library, or nullopt if the library hasn't been loaded (yet)
LIBRARY_MANAGER & Manager() const
virtual void AsyncLoad()=0
Loads all available libraries for this adapter type in the background.
void abortLoad()
Aborts any async load in progress; blocks until fully done aborting.
std::optional< wxString > GetLibraryDescription(const wxString &aNickname) const
virtual LIBRARY_RESULT< IO_BASE * > createPlugin(const LIBRARY_TABLE_ROW *row)=0
Creates a concrete plugin for the given row.
void GlobalTablesChanged(std::initializer_list< LIBRARY_TABLE_TYPE > aChangedTables={})
Notify the adapter that the global library tables have changed.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library tables.
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
virtual void ShowConfigurationDialog(const wxString &aNickname, wxWindow *aParent) const
std::map< wxString, LIB_DATA > m_libraries
virtual IO_BASE * plugin(const LIB_DATA *aRow)=0
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
virtual bool SupportsConfigurationDialog(const wxString &aNickname) const
static wxString getUri(const LIBRARY_TABLE_ROW *aRow)
LIBRARY_RESULT< LIB_DATA * > loadFromScope(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope, std::map< wxString, LIB_DATA > &aTarget, std::mutex &aMutex)
bool CreateLibrary(const wxString &aNickname)
Creates the library (i.e. saves to disk) for the given row if it exists.
virtual bool IsWritable(const wxString &aNickname) const
Return true if the given nickname exists and is not a read-only library.
std::vector< std::pair< wxString, LIB_STATUS > > GetLibraryStatuses() const
Returns a list of all library nicknames and their status (even if they failed to load)
virtual std::map< wxString, LIB_DATA > & globalLibs() const =0
std::atomic< size_t > m_loadCount
LIBRARY_MANAGER & m_manager
std::optional< const LIB_DATA * > fetchIfLoaded(const wxString &aNickname) const
std::map< wxString, std::unique_ptr< LIBRARY_TABLE > > m_childTables
Map of full URI to table object for tables that are referenced by global or project tables.
std::mutex m_adaptersMutex
static wxString DefaultGlobalTablePath(LIBRARY_TABLE_TYPE aType)
static std::vector< LIBRARY_TABLE_TYPE > InvalidGlobalTables()
static bool GlobalTablesValid()
std::map< LIBRARY_TABLE_TYPE, std::unique_ptr< LIBRARY_TABLE > > m_projectTables
LIBRARY_MANAGER(const LIBRARY_MANAGER &)=delete
static bool CreateGlobalTable(LIBRARY_TABLE_TYPE aType, bool aPopulateDefaultLibraries)
void LoadGlobalTables(std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
(Re)loads the global library tables in the given list, or all tables if no list is given
std::map< LIBRARY_TABLE_TYPE, std::unique_ptr< LIBRARY_TABLE > > m_tables
LIBRARY_MANAGER & operator=(const LIBRARY_MANAGER &)=delete
static bool IsTableValid(const wxString &aPath)
std::map< LIBRARY_TABLE_TYPE, std::unique_ptr< LIBRARY_MANAGER_ADAPTER > > m_adapters
Container for project specific data.
Definition project.h:65
void ProjectChanged() override
#define KICOMMON_API
Definition kicommon.h:28
LOAD_STATUS
Status of a library load managed by a library adapter.
tl::expected< ResultType, LIBRARY_ERROR > LIBRARY_RESULT
LIBRARY_TABLE_TYPE
LIBRARY_TABLE_SCOPE
Storage for an actual loaded library (including library content owned by the plugin)
std::vector< wxString > available_fields_cache
LIB_STATUS status
std::unique_ptr< IO_BASE > plugin
std::mutex mutex
const LIBRARY_TABLE_ROW * row
The overall status of a loaded or loading library.
std::optional< LIBRARY_ERROR > error
LOAD_STATUS load_status