KiCad PCB EDA Suite
FOOTPRINT_LIST_IMPL Class Reference

#include <footprint_info_impl.h>

Inheritance diagram for FOOTPRINT_LIST_IMPL:
FOOTPRINT_LIST

Public Member Functions

 FOOTPRINT_LIST_IMPL ()
 
virtual ~FOOTPRINT_LIST_IMPL ()
 
virtual bool ReadFootprintFiles (FP_LIB_TABLE *aTable, const wxString *aNickname=NULL) 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...
 
FOOTPRINT_INFOGetModuleInfo (const wxString &aFootprintName)
 Get info for a module by name. More...
 
FOOTPRINT_INFOGetItem (unsigned aIdx)
 Get info for a module by index. More...
 
void AddItem (FOOTPRINT_INFO *aItem)
 Add aItem to list. More...
 
unsigned GetErrorCount () const
 
std::unique_ptr< IO_ERRORPopError ()
 
void DisplayErrors (wxTopLevelWindow *aCaller=NULL)
 
FP_LIB_TABLEGetTable () const
 

Static Public Member Functions

static std::unique_ptr< FOOTPRINT_LISTGetInstance (KIWAY &aKiway)
 Factory function to return a new FOOTPRINT_LIST via Kiway. More...
 

Protected Types

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

Protected Member Functions

virtual void StartWorkers (FP_LIB_TABLE *aTable, wxString const *aNickname, FOOTPRINT_ASYNC_LOADER *aLoader, unsigned aNThreads) override
 Launch worker threads to load footprints. More...
 
virtual bool JoinWorkers () override
 Join worker threads. More...
 
virtual size_t CountFinished () override
 Return the number of libraries finished (successfully or otherwise). More...
 
void loader_job ()
 Function loader_job loads 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...
 
MUTEX m_list_lock
 

Private Member Functions

bool CatchErrors (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
 
std::atomic_bool m_first_to_finish
 

Detailed Description

Definition at line 58 of file footprint_info_impl.h.

Member Typedef Documentation

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

Definition at line 177 of file footprint_info.h.

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

Definition at line 176 of file footprint_info.h.

Constructor & Destructor Documentation

FOOTPRINT_LIST_IMPL::FOOTPRINT_LIST_IMPL ( )

Definition at line 247 of file footprint_info_impl.cpp.

247  : m_loader( nullptr )
248 {
249 }
FOOTPRINT_ASYNC_LOADER * m_loader
FOOTPRINT_LIST_IMPL::~FOOTPRINT_LIST_IMPL ( )
virtual

Definition at line 252 of file footprint_info_impl.cpp.

References m_threads.

253 {
254  for( auto& i : m_threads )
255  i.join();
256 }
std::vector< std::thread > m_threads

Member Function Documentation

void FOOTPRINT_LIST::AddItem ( FOOTPRINT_INFO aItem)
inherited

Add aItem to list.

Parameters
aItem= item to add
bool FOOTPRINT_LIST_IMPL::CatchErrors ( 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 69 of file footprint_info_impl.cpp.

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

Referenced by loader_job().

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

Return the number of libraries finished (successfully or otherwise).

Implements FOOTPRINT_LIST.

Definition at line 241 of file footprint_info_impl.cpp.

References m_count_finished.

242 {
243  return m_count_finished.load();
244 }
std::atomic_size_t m_count_finished
void FOOTPRINT_LIST::DisplayErrors ( wxTopLevelWindow *  aCaller = NULL)
inherited

Definition at line 83 of file footprint_info.cpp.

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

Referenced by PCB_BASE_FRAME::SelectFootprint().

84 {
85  // @todo: go to a more HTML !<table>! ? centric output, possibly with
86  // recommendations for remedy of errors. Add numeric error codes
87  // to PARSE_ERROR, and switch on them for remedies, etc. Full
88  // access is provided to everything in every exception!
89 
90  HTML_MESSAGE_BOX dlg( aWindow, _( "Load Error" ) );
91 
92  dlg.MessageSet( _( "Errors were encountered loading footprints:" ) );
93 
94  wxString msg;
95 
96  while( auto error = PopError() )
97  {
98  wxString tmp = error->Problem();
99 
100  // Preserve new lines in error messages so queued errors don't run together.
101  tmp.Replace( "\n", "<BR>" );
102  msg += wxT( "<p>" ) + tmp + wxT( "</p>" );
103  }
104 
105  dlg.AddHTML_Text( msg );
106 
107  dlg.ShowModal();
108 }
Class HTML_MESSAGE_BOX.
std::unique_ptr< IO_ERROR > PopError()
unsigned FOOTPRINT_LIST::GetCount ( ) const
inlineinherited
Returns
the number of items stored in list

Definition at line 197 of file footprint_info.h.

Referenced by FOOTPRINT_FILTER::ITERATOR::dereference(), FOOTPRINT_FILTER::end(), and PCB_BASE_FRAME::SelectFootprint().

198  {
199  return m_list.size();
200  }
unsigned FOOTPRINT_LIST::GetErrorCount ( ) const
inlineinherited

Definition at line 231 of file footprint_info.h.

References SYNC_QUEUE< T >::size().

Referenced by PCB_BASE_FRAME::SelectFootprint().

232  {
233  return m_errors.size();
234  }
size_t size() const
Return the size of the queue.
Definition: sync_queue.h:94
ERRLIST m_errors
some can be PARSE_ERRORs also
std::unique_ptr< FOOTPRINT_LIST > FOOTPRINT_LIST::GetInstance ( KIWAY aKiway)
staticinherited

Factory function to return a new FOOTPRINT_LIST via Kiway.

NOT guaranteed to succeed; will return null if the kiface is not available.

Parameters
aKiway- active kiway instance

Definition at line 136 of file footprint_info.cpp.

References get_instance_from_id(), and KIFACE_NEW_FOOTPRINT_LIST.

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

137 {
139 }
Return a new instance of FOOTPRINT_LIST from pcbnew.
Definition: kiface_ids.h:39
static std::unique_ptr< FOOTPRINT_LIST > get_instance_from_id(KIWAY &aKiway, int aId)
FOOTPRINT_INFO& FOOTPRINT_LIST::GetItem ( unsigned  aIdx)
inlineinherited

Get info for a module by index.

Parameters
aIdx= index of the given item
Returns
the aIdx item in list

Definition at line 220 of file footprint_info.h.

Referenced by PCB_BASE_FRAME::SelectFootprint().

221  {
222  return *m_list[aIdx];
223  }
const FPILIST& FOOTPRINT_LIST::GetList ( ) const
inlineinherited

Was forced to add this by modview_frame.cpp.

Definition at line 203 of file footprint_info.h.

References FOOTPRINT_ASYNC_LOADER::m_list.

204  {
205  return m_list;
206  }
FOOTPRINT_INFO * FOOTPRINT_LIST::GetModuleInfo ( const wxString &  aFootprintName)
inherited

Get info for a module by name.

Parameters
aFootprintName= the footprint name inside the FOOTPRINT_INFO of interest.
Returns
FOOTPRINT_INF* - the item stored in list if found

Definition at line 53 of file footprint_info.cpp.

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

Referenced by DisplayCmpDoc().

54 {
55  if( aFootprintName.IsEmpty() )
56  return NULL;
57 
58  for( auto& fp : m_list )
59  {
60  LIB_ID fpid;
61 
62  wxCHECK_MSG( fpid.Parse( aFootprintName ) < 0, NULL,
64  wxT( "'%s' is not a valid LIB_ID." ), GetChars( aFootprintName ) ) );
65 
66  wxString libNickname = fpid.GetLibNickname();
67  wxString footprintName = fpid.GetLibItemName();
68 
69  if( libNickname == fp->GetNickname() && footprintName == fp->GetFootprintName() )
70  return &*fp;
71  }
72 
73  return NULL;
74 }
int Parse(const UTF8 &aId)
Function Parse.
Definition: lib_id.cpp:122
Class LIB_ID.
Definition: lib_id.h:56
const UTF8 & GetLibItemName() const
Function GetLibItemName.
Definition: lib_id.h:129
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
const UTF8 & GetLibNickname() const
Function GetLibNickname.
Definition: lib_id.h:108
FP_LIB_TABLE* FOOTPRINT_LIST::GetTable ( ) const
inlineinherited

Definition at line 258 of file footprint_info.h.

Referenced by FOOTPRINT_INFO_IMPL::load().

259  {
260  return m_lib_table;
261  }
FP_LIB_TABLE * m_lib_table
no ownership
bool FOOTPRINT_LIST_IMPL::JoinWorkers ( )
overrideprotectedvirtual

Join worker threads.

Part of the FOOTPRINT_ASYNC_LOADER implementation.

Implements FOOTPRINT_LIST.

Definition at line 165 of file footprint_info_impl.cpp.

References SYNC_QUEUE< T >::clear(), SYNC_QUEUE< T >::empty(), FP_LIB_TABLE::FootprintEnumerate(), FOOTPRINT_LIST::m_errors, FOOTPRINT_LIST::m_lib_table, FOOTPRINT_LIST::m_list, m_queue_in, m_queue_out, m_threads, SYNC_QUEUE< T >::move_push(), SYNC_QUEUE< T >::pop(), and THROW_IO_ERROR.

166 {
167  for( auto& i : m_threads )
168  i.join();
169 
170  m_threads.clear();
171  m_queue_in.clear();
172 
173  LOCALE_IO toggle_locale;
174 
175  // Parse the footprints in parallel. WARNING! This requires changing the locale, which is
176  // GLOBAL. It is only threadsafe to construct the LOCALE_IO before the threads are created,
177  // destroy it after they finish, and block the main (GUI) thread while they work. Any deviation
178  // from this will cause nasal demons.
179  //
180  // TODO: blast LOCALE_IO into the sun
181 
183  std::vector<std::thread> threads;
184 
185  for( size_t i = 0; i < std::thread::hardware_concurrency() + 1; ++i )
186  {
187  threads.push_back( std::thread( [this, &queue_parsed]() {
188  wxString nickname;
189 
190  while( this->m_queue_out.pop( nickname ) )
191  {
192  wxArrayString fpnames;
193 
194  try
195  {
196  this->m_lib_table->FootprintEnumerate( fpnames, nickname );
197  }
198  catch( const IO_ERROR& ioe )
199  {
200  m_errors.move_push( std::make_unique<IO_ERROR>( ioe ) );
201  }
202  catch( const std::exception& se )
203  {
204  // This is a round about way to do this, but who knows what THROW_IO_ERROR()
205  // may be tricked out to do someday, keep it in the game.
206  try
207  {
208  THROW_IO_ERROR( se.what() );
209  }
210  catch( const IO_ERROR& ioe )
211  {
212  m_errors.move_push( std::make_unique<IO_ERROR>( ioe ) );
213  }
214  }
215 
216  for( auto const& fpname : fpnames )
217  {
218  FOOTPRINT_INFO* fpinfo = new FOOTPRINT_INFO_IMPL( this, nickname, fpname );
219  queue_parsed.move_push( std::unique_ptr<FOOTPRINT_INFO>( fpinfo ) );
220  }
221  }
222  } ) );
223  }
224 
225  for( auto& thr : threads )
226  thr.join();
227 
228  std::unique_ptr<FOOTPRINT_INFO> fpi;
229 
230  while( queue_parsed.pop( fpi ) )
231  m_list.push_back( std::move( fpi ) );
232 
233  std::sort( m_list.begin(), m_list.end(),
234  []( std::unique_ptr<FOOTPRINT_INFO> const& lhs,
235  std::unique_ptr<FOOTPRINT_INFO> const& rhs ) -> bool { return *lhs < *rhs; } );
236 
237  return m_errors.empty();
238 }
SYNC_QUEUE< wxString > m_queue_out
bool pop(T &aReceiver)
Pop a value off the queue into the provided variable.
Definition: sync_queue.h:66
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:165
ERRLIST m_errors
some can be PARSE_ERRORs also
FP_LIB_TABLE * m_lib_table
no ownership
Synchronized, locking queue.
Definition: sync_queue.h:30
bool empty() const
Return true iff the queue is empty.
Definition: sync_queue.h:85
std::vector< std::thread > m_threads
void move_push(T &&aValue)
Move a value onto the queue.
Definition: sync_queue.h:54
SYNC_QUEUE< wxString > m_queue_in
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aNickname)
Return a list of footprint names contained within the library given by aNickname. ...
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:47
void clear()
Clear the queue.
Definition: sync_queue.h:103
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void FOOTPRINT_LIST_IMPL::loader_job ( )
protected

Function loader_job loads footprints from m_queue_in.

Definition at line 99 of file footprint_info_impl.cpp.

References CatchErrors(), FOOTPRINT_ASYNC_LOADER::m_completion_cb, m_count_finished, m_first_to_finish, FOOTPRINT_LIST::m_lib_table, m_loader, m_queue_in, m_queue_out, SYNC_QUEUE< T >::pop(), FP_LIB_TABLE::PrefetchLib(), and SYNC_QUEUE< T >::push().

Referenced by StartWorkers().

100 {
101  wxString nickname;
102 
103  while( m_queue_in.pop( nickname ) )
104  {
105  CatchErrors( [this, &nickname]() {
106  m_lib_table->PrefetchLib( nickname );
107  m_queue_out.push( nickname );
108  } );
109 
110  m_count_finished.fetch_add( 1 );
111  }
112 
113  if( !m_first_to_finish.exchange( true ) )
114  {
115  // yay, we're first to finish!
117  {
119  }
120  }
121 }
void push(T const &aValue)
Push a value onto the queue.
Definition: sync_queue.h:45
SYNC_QUEUE< wxString > m_queue_out
bool pop(T &aReceiver)
Pop a value off the queue into the provided variable.
Definition: sync_queue.h:66
FP_LIB_TABLE * m_lib_table
no ownership
SYNC_QUEUE< wxString > m_queue_in
void PrefetchLib(const wxString &aNickname)
Function PrefetchLib If possible, prefetches the specified library (e.g.
std::atomic_size_t m_count_finished
FOOTPRINT_ASYNC_LOADER * m_loader
std::atomic_bool m_first_to_finish
std::function< void()> m_completion_cb
bool CatchErrors(std::function< void()> aFunc)
Call aFunc, pushing any IO_ERRORs and std::exceptions it throws onto m_errors.
std::unique_ptr<IO_ERROR> FOOTPRINT_LIST::PopError ( )
inlineinherited

Definition at line 236 of file footprint_info.h.

References SYNC_QUEUE< T >::pop().

Referenced by FOOTPRINT_LIST::DisplayErrors().

237  {
238  std::unique_ptr<IO_ERROR> error;
239 
240  m_errors.pop( error );
241  return error;
242  }
bool pop(T &aReceiver)
Pop a value off the queue into the provided variable.
Definition: sync_queue.h:66
ERRLIST m_errors
some can be PARSE_ERRORs also
bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles ( FP_LIB_TABLE aTable,
const wxString *  aNickname = NULL 
)
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.
Returns
bool - 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 124 of file footprint_info_impl.cpp.

References FOOTPRINT_ASYNC_LOADER::Join(), FOOTPRINT_ASYNC_LOADER::SetList(), and FOOTPRINT_ASYNC_LOADER::Start().

Referenced by PCB_BASE_FRAME::SelectFootprint().

125 {
126  FOOTPRINT_ASYNC_LOADER loader;
127 
128  loader.SetList( this );
129  loader.Start( aTable, aNickname );
130  return loader.Join();
131 }
This class can be used to populate a FOOTPRINT_LIST asynchronously.
void Start(FP_LIB_TABLE *aTable, wxString const *aNickname=nullptr, unsigned aNThreads=DEFAULT_THREADS)
Launch the worker threads.
bool Join()
Wait until the worker threads are finished, and then perform any required single-threaded finishing o...
void SetList(FOOTPRINT_LIST *aList)
Assign a FOOTPRINT_LIST to the loader.
void FOOTPRINT_LIST_IMPL::StartWorkers ( FP_LIB_TABLE aTable,
wxString const *  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 134 of file footprint_info_impl.cpp.

References SYNC_QUEUE< T >::clear(), LIB_TABLE::GetLogicalLibs(), loader_job(), m_count_finished, FOOTPRINT_LIST::m_errors, m_first_to_finish, 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().

136 {
137  m_loader = aLoader;
138  m_lib_table = aTable;
139 
140  // Clear data before reading files
141  m_first_to_finish.store( false );
142  m_count_finished.store( 0 );
143  m_errors.clear();
144  m_list.clear();
145  m_threads.clear();
146  m_queue_in.clear();
147  m_queue_out.clear();
148 
149  if( aNickname )
150  m_queue_in.push( *aNickname );
151  else
152  {
153  for( auto const& nickname : aTable->GetLogicalLibs() )
154  m_queue_in.push( nickname );
155  }
156 
158 
159  for( unsigned i = 0; i < aNThreads; ++i )
160  {
161  m_threads.push_back( std::thread( &FOOTPRINT_LIST_IMPL::loader_job, this ) );
162  }
163 }
void push(T const &aValue)
Push a value onto the queue.
Definition: sync_queue.h:45
SYNC_QUEUE< wxString > m_queue_out
size_t size() const
Return the size of the queue.
Definition: sync_queue.h:94
ERRLIST m_errors
some can be PARSE_ERRORs also
void loader_job()
Function loader_job loads 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
std::atomic_bool m_first_to_finish
void clear()
Clear the queue.
Definition: sync_queue.h:103
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE...

Member Data Documentation

std::atomic_size_t FOOTPRINT_LIST_IMPL::m_count_finished
private

Definition at line 64 of file footprint_info_impl.h.

Referenced by CountFinished(), loader_job(), and StartWorkers().

ERRLIST FOOTPRINT_LIST::m_errors
protectedinherited

some can be PARSE_ERRORs also

Definition at line 180 of file footprint_info.h.

Referenced by CatchErrors(), JoinWorkers(), and StartWorkers().

std::atomic_bool FOOTPRINT_LIST_IMPL::m_first_to_finish
private

Definition at line 65 of file footprint_info_impl.h.

Referenced by loader_job(), and StartWorkers().

FP_LIB_TABLE* FOOTPRINT_LIST::m_lib_table
protectedinherited

no ownership

Definition at line 174 of file footprint_info.h.

Referenced by JoinWorkers(), loader_job(), and StartWorkers().

FPILIST FOOTPRINT_LIST::m_list
protectedinherited

Definition at line 179 of file footprint_info.h.

Referenced by FOOTPRINT_LIST::GetModuleInfo(), JoinWorkers(), and StartWorkers().

MUTEX FOOTPRINT_LIST::m_list_lock
protectedinherited

Definition at line 182 of file footprint_info.h.

FOOTPRINT_ASYNC_LOADER* FOOTPRINT_LIST_IMPL::m_loader
private

Definition at line 60 of file footprint_info_impl.h.

Referenced by loader_job(), and StartWorkers().

SYNC_QUEUE<wxString> FOOTPRINT_LIST_IMPL::m_queue_in
private

Definition at line 62 of file footprint_info_impl.h.

Referenced by JoinWorkers(), loader_job(), and StartWorkers().

SYNC_QUEUE<wxString> FOOTPRINT_LIST_IMPL::m_queue_out
private

Definition at line 63 of file footprint_info_impl.h.

Referenced by JoinWorkers(), loader_job(), and StartWorkers().

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

Definition at line 61 of file footprint_info_impl.h.

Referenced by JoinWorkers(), StartWorkers(), and ~FOOTPRINT_LIST_IMPL().


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