diff --git a/src/tools/pcb_reader/exportmgr.h b/src/tools/pcb_reader/exportmgr.h index 5d378e59..f4d7f931 100644 --- a/src/tools/pcb_reader/exportmgr.h +++ b/src/tools/pcb_reader/exportmgr.h @@ -18,6 +18,16 @@ public: waitForTasks(); } + void restart( bool cancel = false, unsigned int maxJobs = 0 ) + { + if( cancel ) + m_threadpool.cancel(); + + m_threadpool.complete(); + + m_threadpool.addWorkers( maxJobs ); + } + void exportZone(const ExportedZone& zone, ExportFileType exportFileTypes) { m_threadpool.queue( [zone, exportFileTypes]() diff --git a/src/tools/pcb_reader/main.cpp b/src/tools/pcb_reader/main.cpp index d4eab40b..8b44878e 100644 --- a/src/tools/pcb_reader/main.cpp +++ b/src/tools/pcb_reader/main.cpp @@ -156,16 +156,36 @@ int main( int argc, char* argv[] ) std::vector< std::string > argVec( argv + 1, argv + argc ); std::string zoneName = "r2t2"; - noObj = std::remove_if( argVec.begin(), argVec.end(), []( auto arg ) + noObj = std::find_if( argVec.begin(), argVec.end(), []( auto arg ) { return arg == "--no-obj"; } ) != argVec.end(); - bool dumpAllZones = std::remove_if( argVec.begin(), argVec.end(), []( auto arg ) + bool dumpAllZones = std::find_if( argVec.begin(), argVec.end(), []( auto arg ) { return arg == "--dump-all"; } ) != argVec.end(); - bool generateNavmesh = std::remove_if( argVec.begin(), argVec.end(), []( auto arg ) + bool generateNavmesh = std::find_if( argVec.begin(), argVec.end(), []( auto arg ) { return arg == "--navmesh"; } ) != argVec.end(); - bool splitByGroup = std::remove_if( argVec.begin(), argVec.end(), []( auto arg ) + bool splitByGroup = std::find_if( argVec.begin(), argVec.end(), []( auto arg ) { return arg == "--split-by-group"; }) != argVec.end(); - bool splitByZone = std::remove_if( argVec.begin(), argVec.end(), []( auto arg ) + bool splitByZone = std::find_if( argVec.begin(), argVec.end(), []( auto arg ) { return arg == "--split-by-zone"; }) != argVec.end(); + int nJobs = std::thread::hardware_concurrency(); + if( auto it = std::find_if( argVec.begin(), argVec.end(), []( auto arg ) + { return arg == "--jobs"; }); it != argVec.end() ) + { + + try + { + auto it2 = ( it + 1 ); + nJobs = std::stoi( *it2 ); + if( nJobs < 0 ) + throw std::runtime_error( "Number of jobs < 0\n" ); + } + catch( std::exception& e ) + { + std::cout << e.what() << "\n"; + std::cout << "Invalid number of jobs " << nJobs << "\n"; + std::cout << "--jobs \n"; + return -1; + } + } int exportFileType = 0; if( !noObj ) exportFileType |= ExportFileType::WavefrontObj; @@ -190,10 +210,10 @@ int main( int argc, char* argv[] ) } catch( std::exception& e ) { - printf( "Unable to initialise EXD!\n Usage: pcb_reader \"path/to/FINAL FANTASY XIV - A REALM REBORN/game/sqpack\" [--no-obj, --dump-all, --navmesh]\n" ); + printf( "Unable to initialise EXD!\n Usage: pcb_reader \"path/to/FINAL FANTASY XIV - A REALM REBORN/game/sqpack\" [--no-obj, --dump-all, --navmesh, --jobs #]\n" ); return -1; } - ExportMgr exportMgr; + ExportMgr exportMgr( nJobs ); zoneNameToPath( zoneName ); if( dumpAllZones ) @@ -496,12 +516,15 @@ int main( int argc, char* argv[] ) } } exportMgr.exportZone( exportedZone, static_cast< ExportFileType >( exportFileType ) ); - if( zoneCount++ % 3 == 0 ) - pCache->purge(); - printf( "Exported %s in %lu seconds \n", + printf( "Built export struct for %s in %lu seconds \n", zoneName.c_str(), std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - entryStartTime ).count() ); + if( zoneCount++ % nJobs == 0 ) + { + exportMgr.restart(); + pCache->purge(); + } } catch( std::exception& e ) {