KiCad PCB EDA Suite
FOOTPRINT_LIST_IMPL Class Reference

#include <footprint_info_impl.h>

Inheritance diagram for FOOTPRINT_LIST_IMPL:
FOOTPRINT_LIST

Public Types

typedef std::vector< std::unique_ptr< FOOTPRINT_INFO > > FPILIST
 
typedef SYNC_QUEUE< std::unique_ptr< IO_ERROR > > ERRLIST
 

Public Member Functions

 FOOTPRINT_LIST_IMPL ()
 
virtual ~FOOTPRINT_LIST_IMPL ()
 
void WriteCacheToFile (const wxString &aFilePath) override
 
void ReadCacheFromFile (const wxString &aFilePath) override
 
bool ReadFootprintFiles (FP_LIB_TABLE *aTable, const wxString *aNickname=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr) override
 Read all the footprints provided by the combination of aTable and aNickname. More...
 
unsigned GetCount () const
 
const FPILISTGetList () const
 Was forced to add this by modview_frame.cpp. More...
 
void Clear ()
 
FOOTPRINT_INFOGetFootprintInfo (const wxString &aFootprintName)
 Get info for a footprint by id. More...
 
FOOTPRINT_INFOGetFootprintInfo (const wxString &aLibNickname, const wxString &aFootprintName)
 Get info for a footprint by libNickname/footprintName. More...
 
FOOTPRINT_INFOGetItem (unsigned aIdx) const
 Get info for a footprint by index. More...
 
unsigned GetErrorCount () const
 
std::unique_ptr< IO_ERRORPopError ()
 
void DisplayErrors (wxTopLevelWindow *aCaller=nullptr)
 
FP_LIB_TABLEGetTable () const
 

Static Public Member Functions

static FOOTPRINT_LISTGetInstance (KIWAY &aKiway)
 Factory function to return a FOOTPRINT_LIST via Kiway. More...
 

Protected Member Functions

void startWorkers (FP_LIB_TABLE *aTable, const wxString *aNickname, FOOTPRINT_ASYNC_LOADER *aLoader, unsigned aNThreads) override
 Launch worker threads to load footprints. More...
 
bool joinWorkers () override
 Join worker threads. More...
 
void stopWorkers () override
 Stop worker threads. More...
 
void loader_job ()
 Load footprints from m_queue_in. More...
 

Protected Attributes

FP_LIB_TABLEm_lib_table
 no ownership More...
 
FPILIST m_list
 
ERRLIST m_errors
 some can be PARSE_ERRORs also More...
 

Private Member Functions

bool CatchErrors (const std::function< void()> &aFunc)
 Call aFunc, pushing any IO_ERRORs and std::exceptions it throws onto m_errors. More...
 

Private Attributes

FOOTPRINT_ASYNC_LOADERm_loader
 
std::vector< std::thread > m_threads
 
SYNC_QUEUE< wxString > m_queue_in
 
SYNC_QUEUE< wxString > m_queue_out
 
std::atomic_size_t m_count_finished
 
long long m_list_timestamp
 
PROGRESS_REPORTERm_progress_reporter
 
std::atomic_bool m_cancelled
 
std::mutex m_join
 

Detailed Description

Definition at line 84 of file footprint_info_impl.h.

Member Typedef Documentation

◆ ERRLIST

typedef SYNC_QUEUE<std::unique_ptr<IO_ERROR> > FOOTPRINT_LIST::ERRLIST
inherited

Definition at line 170 of file footprint_info.h.

◆ FPILIST

typedef std::vector<std::unique_ptr<FOOTPRINT_INFO> > FOOTPRINT_LIST::FPILIST
inherited

Definition at line 169 of file footprint_info.h.

Constructor & Destructor Documentation

◆ FOOTPRINT_LIST_IMPL()

FOOTPRINT_LIST_IMPL::FOOTPRINT_LIST_IMPL ( )

Definition at line 331 of file footprint_info_impl.cpp.

331  :
332  m_loader( nullptr ),
333  m_count_finished( 0 ),
334  m_list_timestamp( 0 ),
335  m_progress_reporter( nullptr ),
336  m_cancelled( false )
337 {
338 }
std::atomic_bool m_cancelled
PROGRESS_REPORTER * m_progress_reporter
std::atomic_size_t m_count_finished
FOOTPRINT_ASYNC_LOADER * m_loader

◆ ~FOOTPRINT_LIST_IMPL()

FOOTPRINT_LIST_IMPL::~FOOTPRINT_LIST_IMPL ( )
virtual

Definition at line 341 of file footprint_info_impl.cpp.

342 {
343  stopWorkers();
344 }
void stopWorkers() override
Stop worker threads.

References stopWorkers().

Member Function Documentation

◆ CatchErrors()

bool FOOTPRINT_LIST_IMPL::CatchErrors ( const std::function< void()> &  aFunc)
private

Call aFunc, pushing any IO_ERRORs and std::exceptions it throws onto m_errors.

Returns
true if no error occurred.

Definition at line 67 of file footprint_info_impl.cpp.

68 {
69  try
70  {
71  aFunc();
72  }
73  catch( const IO_ERROR& ioe )
74  {
75  m_errors.move_push( std::make_unique<IO_ERROR>( ioe ) );
76  return false;
77  }
78  catch( const std::exception& se )
79  {
80  // This is a round about way to do this, but who knows what THROW_IO_ERROR()
81  // may be tricked out to do someday, keep it in the game.
82  try
83  {
84  THROW_IO_ERROR( se.what() );
85  }
86  catch( const IO_ERROR& ioe )
87  {
88  m_errors.move_push( std::make_unique<IO_ERROR>( ioe ) );
89  }
90 
91  return false;
92  }
93 
94  return true;
95 }
ERRLIST m_errors
some can be PARSE_ERRORs also
void move_push(T &&aValue)
Move a value onto the queue.
Definition: sync_queue.h:50
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References FOOTPRINT_LIST::m_errors, SYNC_QUEUE< T >::move_push(), and THROW_IO_ERROR.

Referenced by loader_job().

◆ Clear()

void FOOTPRINT_LIST::Clear ( )
inlineinherited
Returns
Clears the footprint info cache

Definition at line 200 of file footprint_info.h.

201  {
202  m_list.clear();
203  }

Referenced by PCB_EDIT_FRAME::OpenProjectFiles().

◆ DisplayErrors()

void FOOTPRINT_LIST::DisplayErrors ( wxTopLevelWindow *  aCaller = nullptr)
inherited

Definition at line 93 of file footprint_info.cpp.

94 {
95  // @todo: go to a more HTML !<table>! ? centric output, possibly with recommendations
96  // for remedy of errors. Add numeric error codes to PARSE_ERROR, and switch on them for
97  // remedies, etc. Full access is provided to everything in every exception!
98 
99  HTML_MESSAGE_BOX dlg( aWindow, _( "Load Error" ) );
100 
101  dlg.MessageSet( _( "Errors were encountered loading footprints:" ) );
102 
103  wxString msg;
104 
105  while( std::unique_ptr<IO_ERROR> error = PopError() )
106  {
107  wxString tmp = error->Problem();
108 
109  // Preserve new lines in error messages so queued errors don't run together.
110  tmp.Replace( "\n", "<BR>" );
111  msg += wxT( "<p>" ) + tmp + wxT( "</p>" );
112  }
113 
114  dlg.AddHTML_Text( msg );
115 
116  dlg.ShowModal();
117 }
#define _(s)
std::unique_ptr< IO_ERROR > PopError()

References _, HTML_MESSAGE_BOX::AddHTML_Text(), HTML_MESSAGE_BOX::MessageSet(), and FOOTPRINT_LIST::PopError().

Referenced by FOOTPRINT_EDIT_FRAME::initLibraryTree(), CVPCB_MAINFRAME::LoadFootprintFiles(), and PCB_BASE_FRAME::SelectFootprintFromLibTree().

◆ GetCount()

unsigned FOOTPRINT_LIST::GetCount ( ) const
inlineinherited

◆ GetErrorCount()

unsigned FOOTPRINT_LIST::GetErrorCount ( ) const
inlineinherited

Definition at line 227 of file footprint_info.h.

228  {
229  return m_errors.size();
230  }
ERRLIST m_errors
some can be PARSE_ERRORs also
size_t size() const
Return the size of the queue.
Definition: sync_queue.h:91

Referenced by FOOTPRINT_EDIT_FRAME::initLibraryTree(), CVPCB_MAINFRAME::LoadFootprintFiles(), and PCB_BASE_FRAME::SelectFootprintFromLibTree().

◆ GetFootprintInfo() [1/2]

FOOTPRINT_INFO * FOOTPRINT_LIST::GetFootprintInfo ( const wxString &  aFootprintName)
inherited

Get info for a footprint by id.

Definition at line 58 of file footprint_info.cpp.

59 {
60  if( aFootprintName.IsEmpty() )
61  return nullptr;
62 
63  LIB_ID fpid;
64 
65  wxCHECK_MSG( fpid.Parse( aFootprintName ) < 0, nullptr,
66  wxString::Format( wxT( "'%s' is not a valid LIB_ID." ), aFootprintName ) );
67 
68  return GetFootprintInfo( fpid.GetLibNickname(), fpid.GetLibItemName() );
69 }
const UTF8 & GetLibItemName() const
Definition: lib_id.h:104
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:90
FOOTPRINT_INFO * GetFootprintInfo(const wxString &aFootprintName)
Get info for a footprint by id.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:49

References Format(), LIB_ID::GetLibItemName(), LIB_ID::GetLibNickname(), and LIB_ID::Parse().

Referenced by CVPCB_MAINFRAME::AutomaticFootprintMatching(), CVPCB_MAINFRAME::DisplayStatus(), DISPLAY_FOOTPRINTS_FRAME::InitDisplay(), and PCB_BASE_FRAME::SelectFootprintFromLibTree().

◆ GetFootprintInfo() [2/2]

FOOTPRINT_INFO * FOOTPRINT_LIST::GetFootprintInfo ( const wxString &  aLibNickname,
const wxString &  aFootprintName 
)
inherited

Get info for a footprint by libNickname/footprintName.

Definition at line 42 of file footprint_info.cpp.

44 {
45  if( aFootprintName.IsEmpty() )
46  return nullptr;
47 
48  for( std::unique_ptr<FOOTPRINT_INFO>& fp : m_list )
49  {
50  if( aLibNickname == fp->GetLibNickname() && aFootprintName == fp->GetFootprintName() )
51  return fp.get();
52  }
53 
54  return nullptr;
55 }

References FOOTPRINT_LIST::m_list.

◆ GetInstance()

FOOTPRINT_LIST * FOOTPRINT_LIST::GetInstance ( KIWAY aKiway)
staticinherited

Factory function to return a FOOTPRINT_LIST via Kiway.

This is not guaranteed to succeed and will return null if the kiface is not available.

Parameters
aKiwayactive kiway instance.

Definition at line 143 of file footprint_info.cpp.

144 {
145  FOOTPRINT_LIST* footprintInfo = get_instance_from_id( aKiway, KIFACE_FOOTPRINT_LIST );
146 
147  if( !footprintInfo )
148  return nullptr;
149 
150  if( !footprintInfo->GetCount() )
151  footprintInfo->ReadCacheFromFile( aKiway.Prj().GetProjectPath() + "fp-info-cache" );
152 
153  return footprintInfo;
154 }
static FOOTPRINT_LIST * get_instance_from_id(KIWAY &aKiway, int aId)
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition: kiway.cpp:190
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:122
unsigned GetCount() const
Holds a list of FOOTPRINT_INFO objects, along with a list of IO_ERRORs or PARSE_ERRORs that were thro...
virtual void ReadCacheFromFile(const wxString &aFilePath)
Return a pointer to the global instance of FOOTPRINT_LIST from pcbnew.
Definition: kiface_ids.h:39

References get_instance_from_id(), FOOTPRINT_LIST::GetCount(), PROJECT::GetProjectPath(), KIFACE_FOOTPRINT_LIST, KIWAY::Prj(), and FOOTPRINT_LIST::ReadCacheFromFile().

Referenced by DIALOG_CHOOSE_SYMBOL::ConstructRightPanel(), CVPCB_MAINFRAME::CVPCB_MAINFRAME(), FOOTPRINT_SELECT_WIDGET::Load(), and FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList().

◆ GetItem()

FOOTPRINT_INFO& FOOTPRINT_LIST::GetItem ( unsigned  aIdx) const
inlineinherited

Get info for a footprint by index.

Parameters
aIdxindex of the given item.
Returns
the aIdx item in list.

Definition at line 222 of file footprint_info.h.

223  {
224  return *m_list[aIdx];
225  }

Referenced by FOOTPRINT_FILTER::ITERATOR::increment().

◆ GetList()

const FPILIST& FOOTPRINT_LIST::GetList ( ) const
inlineinherited

Was forced to add this by modview_frame.cpp.

Definition at line 192 of file footprint_info.h.

193  {
194  return m_list;
195  }

Referenced by FP_TREE_MODEL_ADAPTER::getFootprints().

◆ GetTable()

FP_LIB_TABLE* FOOTPRINT_LIST::GetTable ( ) const
inlineinherited

Definition at line 257 of file footprint_info.h.

258  {
259  return m_lib_table;
260  }
FP_LIB_TABLE * m_lib_table
no ownership

Referenced by FOOTPRINT_INFO_IMPL::load().

◆ joinWorkers()

bool FOOTPRINT_LIST_IMPL::joinWorkers ( )
overrideprotectedvirtual

Join worker threads.

Part of the FOOTPRINT_ASYNC_LOADER implementation.

Implements FOOTPRINT_LIST.

Definition at line 231 of file footprint_info_impl.cpp.

232 {
233  {
234  std::lock_guard<std::mutex> lock1( m_join );
235 
236  for( auto& i : m_threads )
237  i.join();
238 
239  m_threads.clear();
240  m_queue_in.clear();
241  m_count_finished.store( 0 );
242  }
243 
244  size_t total_count = m_queue_out.size();
245 
246  LOCALE_IO toggle_locale;
247 
248  // Parse the footprints in parallel. WARNING! This requires changing the locale, which is
249  // GLOBAL. It is only thread safe to construct the LOCALE_IO before the threads are created,
250  // destroy it after they finish, and block the main (GUI) thread while they work. Any deviation
251  // from this will cause nasal demons.
252  //
253  // TODO: blast LOCALE_IO into the sun
254 
256  std::vector<std::thread> threads;
257 
258  for( size_t ii = 0; ii < std::thread::hardware_concurrency() + 1; ++ii )
259  {
260  threads.emplace_back( [this, &queue_parsed]() {
261  wxString nickname;
262 
263  while( m_queue_out.pop( nickname ) && !m_cancelled )
264  {
265  wxArrayString fpnames;
266 
267  try
268  {
269  m_lib_table->FootprintEnumerate( fpnames, nickname, false );
270  }
271  catch( const IO_ERROR& ioe )
272  {
273  m_errors.move_push( std::make_unique<IO_ERROR>( ioe ) );
274  }
275  catch( const std::exception& se )
276  {
277  // This is a round about way to do this, but who knows what THROW_IO_ERROR()
278  // may be tricked out to do someday, keep it in the game.
279  try
280  {
281  THROW_IO_ERROR( se.what() );
282  }
283  catch( const IO_ERROR& ioe )
284  {
285  m_errors.move_push( std::make_unique<IO_ERROR>( ioe ) );
286  }
287  }
288 
289  for( unsigned jj = 0; jj < fpnames.size() && !m_cancelled; ++jj )
290  {
291  wxString fpname = fpnames[jj];
292  FOOTPRINT_INFO* fpinfo = new FOOTPRINT_INFO_IMPL( this, nickname, fpname );
293  queue_parsed.move_push( std::unique_ptr<FOOTPRINT_INFO>( fpinfo ) );
294  }
295 
296  if( m_progress_reporter )
298 
299  m_count_finished.fetch_add( 1 );
300  }
301  } );
302  }
303 
304  while( !m_cancelled && (size_t)m_count_finished.load() < total_count )
305  {
307  m_cancelled = true;
308 
309  wxMilliSleep( 30 );
310  }
311 
312  for( auto& thr : threads )
313  thr.join();
314 
315  std::unique_ptr<FOOTPRINT_INFO> fpi;
316 
317  while( queue_parsed.pop( fpi ) )
318  m_list.push_back( std::move( fpi ) );
319 
320  std::sort( m_list.begin(), m_list.end(),
321  []( std::unique_ptr<FOOTPRINT_INFO> const& lhs,
322  std::unique_ptr<FOOTPRINT_INFO> const& rhs ) -> bool
323  {
324  return *lhs < *rhs;
325  } );
326 
327  return m_errors.empty();
328 }
SYNC_QUEUE< wxString > m_queue_out
bool pop(T &aReceiver)
Pop a value if the queue into the provided variable.
Definition: sync_queue.h:63
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
std::atomic_bool m_cancelled
ERRLIST m_errors
some can be PARSE_ERRORs also
FP_LIB_TABLE * m_lib_table
no ownership
Synchronized, locking queue.
Definition: sync_queue.h:31
std::vector< std::thread > m_threads
void move_push(T &&aValue)
Move a value onto the queue.
Definition: sync_queue.h:50
virtual void AdvanceProgress()=0
Increment the progress bar length (inside the current virtual zone).
SYNC_QUEUE< wxString > m_queue_in
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aNickname, bool aBestEfforts)
Return a list of footprint names contained within the library given by aNickname.
PROGRESS_REPORTER * m_progress_reporter
bool empty() const
Return true if the queue is empty.
Definition: sync_queue.h:82
std::atomic_size_t m_count_finished
size_t size() const
Return the size of the queue.
Definition: sync_queue.h:91
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
void clear()
Clear the queue.
Definition: sync_queue.h:100
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References PROGRESS_REPORTER::AdvanceProgress(), SYNC_QUEUE< T >::clear(), SYNC_QUEUE< T >::empty(), FP_LIB_TABLE::FootprintEnumerate(), PROGRESS_REPORTER::KeepRefreshing(), m_cancelled, m_count_finished, FOOTPRINT_LIST::m_errors, m_join, FOOTPRINT_LIST::m_lib_table, FOOTPRINT_LIST::m_list, m_progress_reporter, m_queue_in, m_queue_out, m_threads, SYNC_QUEUE< T >::move_push(), SYNC_QUEUE< T >::pop(), SYNC_QUEUE< T >::size(), and THROW_IO_ERROR.

◆ loader_job()

void FOOTPRINT_LIST_IMPL::loader_job ( )
protected

Load footprints from m_queue_in.

Definition at line 98 of file footprint_info_impl.cpp.

99 {
100  wxString nickname;
101 
102  while( m_queue_in.pop( nickname ) && !m_cancelled )
103  {
104  CatchErrors( [this, &nickname]()
105  {
106  m_lib_table->PrefetchLib( nickname );
107  m_queue_out.push( nickname );
108  } );
109 
110  m_count_finished.fetch_add( 1 );
111 
112  if( m_progress_reporter )
114  }
115 }
void push(T const &aValue)
Push a value onto the queue.
Definition: sync_queue.h:41
SYNC_QUEUE< wxString > m_queue_out
bool pop(T &aReceiver)
Pop a value if the queue into the provided variable.
Definition: sync_queue.h:63
std::atomic_bool m_cancelled
FP_LIB_TABLE * m_lib_table
no ownership
virtual void AdvanceProgress()=0
Increment the progress bar length (inside the current virtual zone).
SYNC_QUEUE< wxString > m_queue_in
PROGRESS_REPORTER * m_progress_reporter
void PrefetchLib(const wxString &aNickname)
If possible, prefetches the specified library (e.g.
std::atomic_size_t m_count_finished
bool CatchErrors(const std::function< void()> &aFunc)
Call aFunc, pushing any IO_ERRORs and std::exceptions it throws onto m_errors.

References PROGRESS_REPORTER::AdvanceProgress(), CatchErrors(), m_cancelled, m_count_finished, FOOTPRINT_LIST::m_lib_table, m_progress_reporter, m_queue_in, m_queue_out, SYNC_QUEUE< T >::pop(), FP_LIB_TABLE::PrefetchLib(), and SYNC_QUEUE< T >::push().

Referenced by startWorkers().

◆ PopError()

std::unique_ptr<IO_ERROR> FOOTPRINT_LIST::PopError ( )
inlineinherited

Definition at line 232 of file footprint_info.h.

233  {
234  std::unique_ptr<IO_ERROR> error;
235 
236  m_errors.pop( error );
237  return error;
238  }
bool pop(T &aReceiver)
Pop a value if the queue into the provided variable.
Definition: sync_queue.h:63
ERRLIST m_errors
some can be PARSE_ERRORs also

Referenced by FOOTPRINT_LIST::DisplayErrors().

◆ ReadCacheFromFile()

void FOOTPRINT_LIST_IMPL::ReadCacheFromFile ( const wxString &  aFilePath)
overridevirtual

Reimplemented from FOOTPRINT_LIST.

Definition at line 383 of file footprint_info_impl.cpp.

384 {
385  wxTextFile cacheFile( aFilePath );
386 
387  m_list_timestamp = 0;
388  m_list.clear();
389 
390  try
391  {
392  if( cacheFile.Exists() && cacheFile.Open() )
393  {
394  cacheFile.GetFirstLine().ToLongLong( &m_list_timestamp );
395 
396  while( cacheFile.GetCurrentLine() + 6 < cacheFile.GetLineCount() )
397  {
398  wxString libNickname = cacheFile.GetNextLine();
399  wxString name = cacheFile.GetNextLine();
400  wxString desc = UnescapeString( cacheFile.GetNextLine() );
401  wxString keywords = UnescapeString( cacheFile.GetNextLine() );
402  int orderNum = wxAtoi( cacheFile.GetNextLine() );
403  unsigned int padCount = (unsigned) wxAtoi( cacheFile.GetNextLine() );
404  unsigned int uniquePadCount = (unsigned) wxAtoi( cacheFile.GetNextLine() );
405 
406  FOOTPRINT_INFO_IMPL* fpinfo = new FOOTPRINT_INFO_IMPL( libNickname, name, desc,
407  keywords, orderNum,
408  padCount, uniquePadCount );
409 
410  m_list.emplace_back( std::unique_ptr<FOOTPRINT_INFO>( fpinfo ) );
411  }
412  }
413  }
414  catch( ... )
415  {
416  // whatever went wrong, invalidate the cache
417  m_list_timestamp = 0;
418  }
419 
420  // Sanity check: an empty list is very unlikely to be correct.
421  if( m_list.size() == 0 )
422  m_list_timestamp = 0;
423 
424  if( cacheFile.IsOpened() )
425  cacheFile.Close();
426 }
wxString UnescapeString(const wxString &aSource)
const char * name
Definition: DXF_plotter.cpp:56

References FOOTPRINT_LIST::m_list, m_list_timestamp, name, and UnescapeString().

Referenced by FOOTPRINT_EDIT_FRAME::initLibraryTree(), and PCB_EDIT_FRAME::OpenProjectFiles().

◆ ReadFootprintFiles()

bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles ( FP_LIB_TABLE aTable,
const wxString *  aNickname = nullptr,
PROGRESS_REPORTER aProgressReporter = nullptr 
)
overridevirtual

Read all the footprints provided by the combination of aTable and aNickname.

Parameters
aTabledefines all the libraries.
aNicknameis the library to read from, or if NULL means read all footprints from all known libraries in aTable.
aProgressReporteris an optional progress reporter. ReadFootprintFiles() will use 2 phases within the reporter.
Returns
true if it ran to completion, else false if it aborted after some number of errors. If true, it does not mean there were no errors, check GetErrorCount() for that, should be zero to indicate success.

Implements FOOTPRINT_LIST.

Definition at line 118 of file footprint_info_impl.cpp.

120 {
121  long long int generatedTimestamp = aTable->GenerateTimestamp( aNickname );
122 
123  if( generatedTimestamp == m_list_timestamp )
124  return true;
125 
126  m_progress_reporter = aProgressReporter;
127 
128  if( m_progress_reporter )
129  {
131  m_progress_reporter->Report( _( "Fetching footprint libraries..." ) );
132  }
133 
134  m_cancelled = false;
135 
136  FOOTPRINT_ASYNC_LOADER loader;
137 
138  loader.SetList( this );
139  loader.Start( aTable, aNickname );
140 
141  while( !m_cancelled && (int)m_count_finished.load() < m_loader->m_total_libs )
142  {
144  m_cancelled = true;
145 
146  wxMilliSleep( 20 );
147  }
148 
149  if( m_cancelled )
150  {
151  loader.Abort();
152  }
153  else
154  {
155  if( m_progress_reporter )
156  {
159  m_progress_reporter->Report( _( "Loading footprints..." ) );
160  }
161 
162  loader.Join();
163 
164  if( m_progress_reporter )
166  }
167 
168  if( m_cancelled )
169  m_list_timestamp = 0; // God knows what we got before we were canceled
170  else
171  m_list_timestamp = generatedTimestamp;
172 
173  return m_errors.empty();
174 }
virtual void SetMaxProgress(int aMaxProgress)=0
Fix the value that gives the 100 percent progress bar length (inside the current virtual zone).
SYNC_QUEUE< wxString > m_queue_out
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
std::atomic_bool m_cancelled
ERRLIST m_errors
some can be PARSE_ERRORs also
Object used to populate a FOOTPRINT_LIST asynchronously.
SYNC_QUEUE< wxString > m_queue_in
long long GenerateTimestamp(const wxString *aNickname)
Generate a hashed timestamp representing the last-mod-times of the library indicated by aNickname,...
PROGRESS_REPORTER * m_progress_reporter
virtual void AdvancePhase()=0
Use the next available virtual zone of the dialog progress bar.
bool empty() const
Return true if the queue is empty.
Definition: sync_queue.h:82
#define _(s)
std::atomic_size_t m_count_finished
bool Join()
Wait until the worker threads are finished, and then perform any required single-threaded finishing o...
FOOTPRINT_ASYNC_LOADER * m_loader
size_t size() const
Return the size of the queue.
Definition: sync_queue.h:91
void Start(FP_LIB_TABLE *aTable, const wxString *aNickname=nullptr, unsigned aNThreads=DEFAULT_THREADS)
Launch the worker threads.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
void SetList(FOOTPRINT_LIST *aList)
Assign a FOOTPRINT_LIST to the loader.
void Abort()
Safely stop the current process.

References _, FOOTPRINT_ASYNC_LOADER::Abort(), PROGRESS_REPORTER::AdvancePhase(), SYNC_QUEUE< T >::empty(), FP_LIB_TABLE::GenerateTimestamp(), FOOTPRINT_ASYNC_LOADER::Join(), PROGRESS_REPORTER::KeepRefreshing(), m_cancelled, m_count_finished, FOOTPRINT_LIST::m_errors, m_list_timestamp, m_loader, m_progress_reporter, m_queue_in, m_queue_out, FOOTPRINT_ASYNC_LOADER::m_total_libs, PROGRESS_REPORTER::Report(), FOOTPRINT_ASYNC_LOADER::SetList(), PROGRESS_REPORTER::SetMaxProgress(), SYNC_QUEUE< T >::size(), and FOOTPRINT_ASYNC_LOADER::Start().

Referenced by FOOTPRINT_EDIT_FRAME::initLibraryTree(), PCB_BASE_FRAME::SelectFootprintFromLibTree(), and FOOTPRINT_EDIT_FRAME::SyncLibraryTree().

◆ startWorkers()

void FOOTPRINT_LIST_IMPL::startWorkers ( FP_LIB_TABLE aTable,
const wxString *  aNickname,
FOOTPRINT_ASYNC_LOADER aLoader,
unsigned  aNThreads 
)
overrideprotectedvirtual

Launch worker threads to load footprints.

Part of the FOOTPRINT_ASYNC_LOADER implementation.

Implements FOOTPRINT_LIST.

Definition at line 177 of file footprint_info_impl.cpp.

179 {
180  m_loader = aLoader;
181  m_lib_table = aTable;
182 
183  // Clear data before reading files
184  m_count_finished.store( 0 );
185  m_errors.clear();
186  m_list.clear();
187  m_threads.clear();
188  m_queue_in.clear();
189  m_queue_out.clear();
190 
191  if( aNickname )
192  {
193  m_queue_in.push( *aNickname );
194  }
195  else
196  {
197  for( auto const& nickname : aTable->GetLogicalLibs() )
198  m_queue_in.push( nickname );
199  }
200 
202 
203  for( unsigned i = 0; i < aNThreads; ++i )
204  {
205  m_threads.emplace_back( &FOOTPRINT_LIST_IMPL::loader_job, this );
206  }
207 }
void push(T const &aValue)
Push a value onto the queue.
Definition: sync_queue.h:41
SYNC_QUEUE< wxString > m_queue_out
ERRLIST m_errors
some can be PARSE_ERRORs also
void loader_job()
Load footprints from m_queue_in.
FP_LIB_TABLE * m_lib_table
no ownership
std::vector< std::thread > m_threads
SYNC_QUEUE< wxString > m_queue_in
std::atomic_size_t m_count_finished
FOOTPRINT_ASYNC_LOADER * m_loader
size_t size() const
Return the size of the queue.
Definition: sync_queue.h:91
void clear()
Clear the queue.
Definition: sync_queue.h:100
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.

References SYNC_QUEUE< T >::clear(), LIB_TABLE::GetLogicalLibs(), loader_job(), m_count_finished, FOOTPRINT_LIST::m_errors, FOOTPRINT_LIST::m_lib_table, FOOTPRINT_LIST::m_list, m_loader, m_queue_in, m_queue_out, m_threads, FOOTPRINT_ASYNC_LOADER::m_total_libs, SYNC_QUEUE< T >::push(), and SYNC_QUEUE< T >::size().

◆ stopWorkers()

void FOOTPRINT_LIST_IMPL::stopWorkers ( )
overrideprotectedvirtual

Stop worker threads.

Part of the FOOTPRINT_ASYNC_LOADER implementation.

Implements FOOTPRINT_LIST.

Definition at line 210 of file footprint_info_impl.cpp.

211 {
212  std::lock_guard<std::mutex> lock1( m_join );
213 
214  // To safely stop our workers, we set the cancellation flag (they will each
215  // exit on their next safe loop location when this is set). Then we need to wait
216  // for all threads to finish as closing the implementation will free the queues
217  // that the threads write to.
218  for( auto& i : m_threads )
219  i.join();
220 
221  m_threads.clear();
222  m_queue_in.clear();
223  m_count_finished.store( 0 );
224 
225  // If we have canceled in the middle of a load, clear our timestamp to re-load next time
226  if( m_cancelled )
227  m_list_timestamp = 0;
228 }
std::atomic_bool m_cancelled
std::vector< std::thread > m_threads
SYNC_QUEUE< wxString > m_queue_in
std::atomic_size_t m_count_finished
void clear()
Clear the queue.
Definition: sync_queue.h:100

References SYNC_QUEUE< T >::clear(), m_cancelled, m_count_finished, m_join, m_list_timestamp, m_queue_in, and m_threads.

Referenced by ~FOOTPRINT_LIST_IMPL().

◆ WriteCacheToFile()

void FOOTPRINT_LIST_IMPL::WriteCacheToFile ( const wxString &  aFilePath)
overridevirtual

Reimplemented from FOOTPRINT_LIST.

Definition at line 347 of file footprint_info_impl.cpp.

348 {
349  wxFileName tmpFileName = wxFileName::CreateTempFileName( aFilePath );
350  wxFFileOutputStream outStream( tmpFileName.GetFullPath() );
351  wxTextOutputStream txtStream( outStream );
352 
353  if( !outStream.IsOk() )
354  {
355  return;
356  }
357 
358  txtStream << wxString::Format( "%lld", m_list_timestamp ) << endl;
359 
360  for( std::unique_ptr<FOOTPRINT_INFO>& fpinfo : m_list )
361  {
362  txtStream << fpinfo->GetLibNickname() << endl;
363  txtStream << fpinfo->GetName() << endl;
364  txtStream << EscapeString( fpinfo->GetDescription(), CTX_LINE ) << endl;
365  txtStream << EscapeString( fpinfo->GetKeywords(), CTX_LINE ) << endl;
366  txtStream << wxString::Format( "%d", fpinfo->GetOrderNum() ) << endl;
367  txtStream << wxString::Format( "%u", fpinfo->GetPadCount() ) << endl;
368  txtStream << wxString::Format( "%u", fpinfo->GetUniquePadCount() ) << endl;
369  }
370 
371  txtStream.Flush();
372  outStream.Close();
373 
374  if( !wxRenameFile( tmpFileName.GetFullPath(), aFilePath, true ) )
375  {
376  // cleanup in case rename failed
377  // its also not the end of the world since this is just a cache file
378  wxRemoveFile( tmpFileName.GetFullPath() );
379  }
380 }
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...

References CTX_LINE, EscapeString(), Format(), FOOTPRINT_LIST::m_list, and m_list_timestamp.

Referenced by PCB_BASE_EDIT_FRAME::doCloseWindow(), and FOOTPRINT_EDIT_FRAME::doCloseWindow().

Member Data Documentation

◆ m_cancelled

std::atomic_bool FOOTPRINT_LIST_IMPL::m_cancelled
private

Definition at line 123 of file footprint_info_impl.h.

Referenced by joinWorkers(), loader_job(), ReadFootprintFiles(), and stopWorkers().

◆ m_count_finished

std::atomic_size_t FOOTPRINT_LIST_IMPL::m_count_finished
private

◆ m_errors

ERRLIST FOOTPRINT_LIST::m_errors
protectedinherited

some can be PARSE_ERRORs also

Definition at line 296 of file footprint_info.h.

Referenced by CatchErrors(), joinWorkers(), ReadFootprintFiles(), and startWorkers().

◆ m_join

std::mutex FOOTPRINT_LIST_IMPL::m_join
private

Definition at line 124 of file footprint_info_impl.h.

Referenced by joinWorkers(), and stopWorkers().

◆ m_lib_table

FP_LIB_TABLE* FOOTPRINT_LIST::m_lib_table
protectedinherited

no ownership

Definition at line 293 of file footprint_info.h.

Referenced by joinWorkers(), loader_job(), and startWorkers().

◆ m_list

◆ m_list_timestamp

long long FOOTPRINT_LIST_IMPL::m_list_timestamp
private

◆ m_loader

FOOTPRINT_ASYNC_LOADER* FOOTPRINT_LIST_IMPL::m_loader
private

Definition at line 116 of file footprint_info_impl.h.

Referenced by ReadFootprintFiles(), and startWorkers().

◆ m_progress_reporter

PROGRESS_REPORTER* FOOTPRINT_LIST_IMPL::m_progress_reporter
private

Definition at line 122 of file footprint_info_impl.h.

Referenced by joinWorkers(), loader_job(), and ReadFootprintFiles().

◆ m_queue_in

SYNC_QUEUE<wxString> FOOTPRINT_LIST_IMPL::m_queue_in
private

◆ m_queue_out

SYNC_QUEUE<wxString> FOOTPRINT_LIST_IMPL::m_queue_out
private

Definition at line 119 of file footprint_info_impl.h.

Referenced by joinWorkers(), loader_job(), ReadFootprintFiles(), and startWorkers().

◆ m_threads

std::vector<std::thread> FOOTPRINT_LIST_IMPL::m_threads
private

Definition at line 117 of file footprint_info_impl.h.

Referenced by joinWorkers(), startWorkers(), and stopWorkers().


The documentation for this class was generated from the following files: