|
|
/*
* This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2021 Jon Evans <jon@craftyjon.com> * Copyright The KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <thread>
#include <core/wx_stl_compat.h>
#include <symbol_async_loader.h>
#include <symbol_lib_table.h>
#include <progress_reporter.h>
SYMBOL_ASYNC_LOADER::SYMBOL_ASYNC_LOADER( const std::vector<wxString>& aNicknames, SYMBOL_LIB_TABLE* aTable, bool aOnlyPowerSymbols, std::unordered_map<wxString, std::vector<LIB_SYMBOL*>>* aOutput, PROGRESS_REPORTER* aReporter ) : m_nicknames( aNicknames ), m_table( aTable ), m_onlyPowerSymbols( aOnlyPowerSymbols ), m_output( aOutput ), m_reporter( aReporter ), m_nextLibrary( 0 ){ wxASSERT( m_table ); m_threadCount = std::max<size_t>( 1, std::thread::hardware_concurrency() );
m_returns.resize( m_threadCount );}
SYMBOL_ASYNC_LOADER::~SYMBOL_ASYNC_LOADER(){ Join();}
void SYMBOL_ASYNC_LOADER::Start(){ for( size_t ii = 0; ii < m_threadCount; ++ii ) m_returns[ii] = std::async( std::launch::async, &SYMBOL_ASYNC_LOADER::worker, this );}
bool SYMBOL_ASYNC_LOADER::Join(){ for( size_t ii = 0; ii < m_threadCount; ++ii ) { if( !m_returns[ii].valid() ) continue;
m_returns[ii].wait();
const std::vector<LOADED_PAIR>& ret = m_returns[ii].get();
if( m_output && !ret.empty() ) { for( const LOADED_PAIR& pair : ret ) { // Don't show libraries that had no power symbols
if( m_onlyPowerSymbols && pair.second.empty() ) continue;
// *Do* show empty libraries in the normal case
m_output->insert( pair ); } } }
return true;}
bool SYMBOL_ASYNC_LOADER::Done(){ return m_nextLibrary.load() >= m_nicknames.size();}
std::vector<SYMBOL_ASYNC_LOADER::LOADED_PAIR> SYMBOL_ASYNC_LOADER::worker(){ std::vector<LOADED_PAIR> ret;
bool onlyPower = m_onlyPowerSymbols;
for( size_t libraryIndex = m_nextLibrary++; libraryIndex < m_nicknames.size(); libraryIndex = m_nextLibrary++ ) { const wxString& nickname = m_nicknames[libraryIndex];
if( m_reporter ) m_reporter->AdvancePhase( wxString::Format( _( "Loading library %s..." ), nickname ) );
if( m_reporter && m_reporter->IsCancelled() ) break;
LOADED_PAIR pair( nickname, {} );
try { m_table->LoadSymbolLib( pair.second, nickname, onlyPower ); ret.emplace_back( std::move( pair ) ); } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error loading symbol library %s.\n\n%s\n" ), nickname, ioe.What() );
std::lock_guard<std::mutex> lock( m_errorMutex ); m_errors += msg; } catch( std::exception& e ) { wxString msg = wxString::Format( _( "Error loading symbol library %s.\n\n%s\n" ), nickname, e.what() );
std::lock_guard<std::mutex> lock( m_errorMutex ); m_errors += msg; } }
return ret;}
|