bool Client::initLocal( const int argc, char** argv ) { if( _impl->name.empty() && argc > 0 && argv ) { const boost::filesystem::path prog = argv[0]; setName( prog.stem().string( )); } const auto options = _getProgramOptions(); arg::variables_map vm; try { Strings args; for( int i = 0; i < argc; ++i ) if( strcmp( argv[i], "--" ) != 0 ) args.push_back( argv[i] ); arg::store( arg::command_line_parser( args ) .options( options ).allow_unregistered().run(), vm ); arg::notify( vm ); } catch( const std::exception& e ) { LBERROR << "Error in argument parsing: " << e.what() << std::endl; return false; } const bool isClient = vm.count( "eq-client" ); std::string clientOpts; if( vm.count( "eq-layout" )) _impl->activeLayouts.push_back( vm["eq-layout"].as< std::string >( )); if( vm.count( "eq-gpufilter" )) _impl->gpuFilter = vm["eq-gpufilter"].as< std::string >(); if( vm.count( "eq-modelunit" )) _impl->modelUnit = vm["eq-modelunit"].as< float >(); LBVERB << "Launching " << getNodeID() << std::endl; if( !Super::initLocal( argc, argv )) return false; if( isClient ) { LBVERB << "Client node started from command line with option " << clientOpts << std::endl; if( !_setupClient( clientOpts )) { exitLocal(); return false; } _impl->running = true; clientLoop(); exitClient(); } _impl->initQt( argc, argv ); return true; }
void Client::releaseConfig(Config* config) { _impl->server->releaseConfig(config); if (!disconnectServer(_impl->server)) LBERROR << "Client::disconnectServer failed" << std::endl; _impl->server = 0; exitLocal(); LBASSERTINFO(getRefCount() == 1, "Client still referenced by " << getRefCount() - 1); }
void Client::exitClient() { _impl->queue.flush(); bool ret = exitLocal(); LBINFO << "Exit " << lunchbox::className( this ) << " process used " << getRefCount() << std::endl; if( !eq::exit( )) ret = false; ::exit( ret ? EXIT_SUCCESS : EXIT_FAILURE ); }
Client::Client(const int argc, char** argv, const bool isResident) : _impl(new Client::Impl(isResident)) { if (!initLocal(argc, argv)) LBTHROW(std::runtime_error("Can't init client")); _impl->server = new eq::Server; if (!connectServer(_impl->server)) { exitLocal(); LBTHROW(std::runtime_error("Can't open server")); } }
bool Application::exit() { bool retVal = true; if( _impl ) retVal = _impl->exit(); if( !exitLocal( )) retVal = false; if( !eq::exit( )) retVal = false; exitErrors(); delete _impl; _impl = 0; LBASSERTINFO( getRefCount() == 1, this->getRefCount( )); return retVal; }
int Client::run( const int argc, char** argv ) { // 0. Init local client if( !initLocal( argc, argv )) { LBERROR << "Can't init client" << std::endl; return EXIT_FAILURE; } // 1. connect to server eq::ServerPtr server = new eq::Server; if( !connectServer( server )) { LBERROR << "Can't open server" << std::endl; exitLocal(); return EXIT_FAILURE; } // 2. choose config eq::fabric::ConfigParams configParams; Config* config = static_cast< Config * >( server->chooseConfig( configParams )); if( !config ) { LBERROR << "No matching config on server" << std::endl; disconnectServer( server ); exitLocal(); return EXIT_FAILURE; } FrameData& frameData = config->getFrameData(); frameData.setup( _impl->_applicationParameters, _impl->_rendererParameters ); frameData.getVolumeSettings()->setURI( _impl->_applicationParameters.dataFileName); // 3. init config lunchbox::Clock clock; if( !config->init( argc, argv )) { server->releaseConfig( config ); disconnectServer( server ); exitLocal(); return EXIT_FAILURE; } LBLOG( LOG_STATS ) << "Config init took " << clock.getTimef() << " ms" << std::endl; // 4. run main loop uint32_t maxFrames = _impl->_applicationParameters.maxFrames; frameData.getCameraSettings()->setDefaultCameraPosition( _impl->_applicationParameters.cameraPosition ); frameData.getCameraSettings()->setDefaultCameraLookAt( _impl->_applicationParameters.cameraLookAt ); clock.reset(); while( config->isRunning() && maxFrames-- ) { if( !config->frame()) // If not valid, reset maxFrames maxFrames++; if( _impl->_idleFunc ) _impl->_idleFunc(); // order is important to latency while( !config->needRedraw( )) // wait for an event requiring redraw { if( hasCommands( )) // execute non-critical pending commands { processCommand(); config->handleEvents(); // non-blocking } else // no pending commands, block on user event { // Poll ZeroEq subscribers at least every 100 ms in handleEvents const eq::EventICommand& event = config->getNextEvent( 100 ); if( event.isValid( )) config->handleEvent( event ); config->handleEvents(); // non-blocking } } config->handleEvents(); // process all pending events } const uint32_t frame = config->finishAllFrames(); const float time = clock.getTimef(); LBLOG( LOG_STATS ) << "Rendering took " << time << " ms (" << frame << " frames @ " << ( frame / time * 1000.f) << " FPS)" << std::endl; // 5. exit config clock.reset(); config->exit(); LBLOG( LOG_STATS ) << "Exit took " << clock.getTimef() << " ms" <<std::endl; // 6. cleanup and exit server->releaseConfig( config ); if( !disconnectServer( server )) LBERROR << "Client::disconnectServer failed" << std::endl; server = 0; exitLocal(); return EXIT_SUCCESS; }