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#include <tl/expected.hpp>
27
28#include <kicommon.h>
30#include <io/io_base.h>
31
32
34{
35 LIBRARY_ERROR( const wxString& aMessage ) :
36 message( aMessage )
37 {};
38
39 wxString message;
40};
41
42
43template<typename ResultType>
44using LIBRARY_RESULT = tl::expected<ResultType, LIBRARY_ERROR>;
45
46class LIBRARY_MANAGER;
47class PROJECT;
48
49
58
61{
63 std::optional<LIBRARY_ERROR> error;
64};
65
66
69{
70 std::unique_ptr<IO_BASE> plugin;
71 const LIBRARY_TABLE_ROW* row = nullptr;
72 std::mutex mutex;
74
76 std::vector<wxString> available_fields_cache;
77};
78
79
85{
86public:
95
97
98 LIBRARY_MANAGER& Manager() const;
99
101 virtual LIBRARY_TABLE_TYPE Type() const = 0;
102
104 LIBRARY_TABLE* GlobalTable() const;
105
107 std::optional<LIBRARY_TABLE*> ProjectTable() const;
108
109 std::optional<wxString> FindLibraryByURI( const wxString& aURI ) const;
110
112 std::vector<wxString> GetLibraryNames() const;
113
120 bool HasLibrary( const wxString& aNickname, bool aCheckEnabled = false ) const;
121
123 bool DeleteLibrary( const wxString& aNickname );
124
125 std::optional<wxString> GetLibraryDescription( const wxString& aNickname ) const;
126
128 std::vector<LIBRARY_TABLE_ROW*> Rows( LIBRARY_TABLE_SCOPE aScope = LIBRARY_TABLE_SCOPE::BOTH,
129 bool aIncludeInvalid = false ) const;
130
132 std::optional<LIBRARY_TABLE_ROW*> GetRow( const wxString& aNickname,
134
136 std::optional<LIBRARY_TABLE_ROW*> FindRowByURI( const wxString& aUri,
138
140 virtual void ProjectChanged();
141
143 void GlobalTablesChanged( std::initializer_list<LIBRARY_TABLE_TYPE> aChangedTables = {} );
144
146 virtual void AsyncLoad() = 0;
147
149 std::optional<float> AsyncLoadProgress() const;
150
151 void BlockUntilLoaded();
152
153 bool IsLibraryLoaded( const wxString& aNickname );
154
156 virtual bool IsWritable( const wxString& aNickname ) const { return false; }
157
158 virtual bool SupportsConfigurationDialog( const wxString& aNickname ) const { return false; }
159
160 virtual void ShowConfigurationDialog( const wxString& aNickname, wxWindow* aParent ) const {};
161
162protected:
163 virtual std::map<wxString, LIB_DATA>& globalLibs() = 0;
164 virtual std::map<wxString, LIB_DATA>& globalLibs() const = 0;
165 virtual std::mutex& globalLibsMutex() = 0;
166
167 static wxString getUri( const LIBRARY_TABLE_ROW* aRow );
168
169 std::optional<const LIB_DATA*> fetchIfLoaded( const wxString& aNickname ) const;
170
171 std::optional<LIB_DATA*> fetchIfLoaded( const wxString& aNickname );
172
174 LIBRARY_RESULT<LIB_DATA*> loadIfNeeded( const wxString& aNickname );
175
177 void abortLoad();
178
181
183
184 // The actual library content is held in an associated IO plugin
185 // TODO(JE) should this be an expected<LIB_ROW> so we can store the
186 // error result if a lib can't be loaded instead of retrying the load every time
187 // content is requested?
188 std::map<wxString, LIB_DATA> m_libraries;
189
191
192 std::atomic_bool m_abort;
193 std::vector<std::future<void>> m_futures;
194
195 std::atomic<size_t> m_loadCount;
197};
198
199
201{
202public:
204
206
209
210 static wxString DefaultGlobalTablePath( LIBRARY_TABLE_TYPE aType );
211
212 static bool IsTableValid( const wxString& aPath );
213
215 static bool GlobalTablesValid();
216
218 static std::vector<LIBRARY_TABLE_TYPE> InvalidGlobalTables();
219
220 static bool CreateGlobalTable( LIBRARY_TABLE_TYPE aType, bool aPopulateDefaultLibraries );
221
223 void LoadGlobalTables( std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad = {} );
224
226 void ProjectChanged();
227
228 void RegisterAdapter( LIBRARY_TABLE_TYPE aType,
229 std::unique_ptr<LIBRARY_MANAGER_ADAPTER>&& aAdapter );
230
231 std::optional<LIBRARY_MANAGER_ADAPTER*> Adapter( LIBRARY_TABLE_TYPE aType ) const;
232
241 std::optional<LIBRARY_TABLE*> Table( LIBRARY_TABLE_TYPE aType,
242 LIBRARY_TABLE_SCOPE aScope );
243
251 std::vector<LIBRARY_TABLE_ROW*> Rows( LIBRARY_TABLE_TYPE aType,
253 bool aIncludeInvalid = false ) const;
254
262 std::optional<LIBRARY_TABLE_ROW*> GetRow( LIBRARY_TABLE_TYPE aType,
263 const wxString &aNickname,
264 LIBRARY_TABLE_SCOPE aScope =
266
267 std::optional<LIBRARY_TABLE_ROW*> FindRowByURI( LIBRARY_TABLE_TYPE aType,
268 const wxString &aUri,
269 LIBRARY_TABLE_SCOPE aScope =
271
272 void LoadProjectTables( const wxString& aProjectPath );
273
274 LIBRARY_RESULT<void> Save( LIBRARY_TABLE* aTable ) const;
275
285 std::optional<wxString> GetFullURI( LIBRARY_TABLE_TYPE aType, const wxString& aNickname,
286 bool aSubstituted = false ) const;
287
288 static wxString GetFullURI( const LIBRARY_TABLE_ROW* aRow, bool aSubstituted = false );
289
290 static wxString ExpandURI( const wxString& aShortURI, const PROJECT& aProject );
291
292 static bool UrisAreEquivalent( const wxString& aURI1, const wxString& aURI2 );
293
294private:
295 void loadTables( const wxString& aTablePath, LIBRARY_TABLE_SCOPE aScope,
296 std::vector<LIBRARY_TABLE_TYPE> aTablesToLoad = {} );
297
298 void loadNestedTables( LIBRARY_TABLE& aTable );
299
300 static wxString tableFileName( LIBRARY_TABLE_TYPE aType );
301
302 void createEmptyTable( LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope );
303
304 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>> m_tables;
305
307 std::map<wxString, std::unique_ptr<LIBRARY_TABLE>> m_childTables;
308
309 // TODO: support multiple projects
310 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>> m_projectTables;
311
312 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_MANAGER_ADAPTER>> m_adapters;
313};
314
315#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 bool IsWritable(const wxString &aNickname) const
Return true if the given nickname exists and is not a read-only library.
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.
std::optional< wxString > FindLibraryByURI(const wxString &aURI) const
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
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)
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.
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
tl::expected< ResultType, LIBRARY_ERROR > LIBRARY_RESULT
LOAD_STATUS
Status of a library load managed by a library adapter.
LIBRARY_TABLE_TYPE
LIBRARY_TABLE_SCOPE
LIBRARY_ERROR(const wxString &aMessage)
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