bool Config::_cmdUpdate( co::ICommand& cmd ) { co::ObjectICommand command( cmd ); LBVERB << "handle config update " << command << std::endl; const uint32_t versionID = command.read< uint32_t >(); const uint32_t finishID = command.read< uint32_t >(); sync(); commit(); co::NodePtr node = command.getRemoteNode(); if( !_needsFinish ) { send( node, fabric::CMD_CONFIG_UPDATE_VERSION ) << getVersion() << versionID << finishID << LB_UNDEFINED_UINT32; return true; } co::LocalNodePtr localNode = getLocalNode(); lunchbox::Request< void > request = localNode->registerRequest< void >(); send( node, fabric::CMD_CONFIG_UPDATE_VERSION ) << getVersion() << versionID << finishID << request; _flushAllFrames(); _finishedFrame.waitEQ( _currentFrame ); // wait for render clients idle request.wait(); // wait for app sync _needsFinish = false; const bool canFail = (getIAttribute( IATTR_ROBUSTNESS ) != OFF); const bool result = _updateRunning( canFail ); if( !result && !canFail ) { LBWARN << "Config update failed, exiting config" << std::endl; exit(); } const uint128_t version = commit(); send( command.getRemoteNode(), fabric::CMD_CONFIG_UPDATE_REPLY ) << version << command.read< uint32_t >() << result; return true; }
//--------------------------------------------------------------------------- // init //--------------------------------------------------------------------------- bool Config::_init( const uint128_t& initID ) { LBASSERT( _state == STATE_STOPPED ); _state = STATE_INITIALIZING; _currentFrame = 0; _finishedFrame = 0; _initID = initID; for( auto compound : _compounds ) compound->init(); for( auto observer : getObservers( )) observer->init(); for( auto canvas : getCanvases( )) canvas->init(); const auto& layouts = getLayouts(); for( auto layout : layouts ) for( auto view : layout->getViews( )) view->init(); // any of the above entities might have been updated commit(); if( !_updateRunning( false )) return false; // Needed to set up active state for first LB update for( CompoundsCIter i = _compounds.begin(); i != _compounds.end(); ++i ) (*i)->update( 0 ); // Update equalizer properties in views UpdateEqualizersVisitor updater; accept( updater ); _needsFinish = false; _state = STATE_RUNNING; return true; }
//--------------------------------------------------------------------------- // exit //--------------------------------------------------------------------------- bool Config::exit() { if( _state != STATE_RUNNING ) LBWARN << "Exiting non-initialized config" << std::endl; LBASSERT( _state == STATE_RUNNING || _state == STATE_INITIALIZING ); _state = STATE_EXITING; const Canvases& canvases = getCanvases(); for( Canvases::const_iterator i = canvases.begin(); i != canvases.end(); ++i ) { Canvas* canvas = *i; canvas->exit(); } for( Compounds::const_iterator i = _compounds.begin(); i != _compounds.end(); ++i ) { Compound* compound = *i; compound->exit(); } const bool success = _updateRunning( true ); // send exit event to app, needed if this is called from init() EventOCommand cmd( send( findApplicationNetNode(), fabric::CMD_CONFIG_EVENT )); Event event; event.serial = getSerial(); event.time = getServer()->getTime(); event.originator = getID(); cmd << EVENT_EXIT << event; _needsFinish = false; _state = STATE_STOPPED; return success; }
//--------------------------------------------------------------------------- // exit //--------------------------------------------------------------------------- bool Config::exit() { if( _state != STATE_RUNNING ) LBWARN << "Exiting non-initialized config" << std::endl; LBASSERT( _state == STATE_RUNNING || _state == STATE_INITIALIZING ); _state = STATE_EXITING; const Canvases& canvases = getCanvases(); for( Canvases::const_iterator i = canvases.begin(); i != canvases.end(); ++i ) { Canvas* canvas = *i; canvas->exit(); } for( Compounds::const_iterator i = _compounds.begin(); i != _compounds.end(); ++i ) { Compound* compound = *i; compound->exit(); } const bool success = _updateRunning( true ); // TODO: is this needed? sender of CMD_CONFIG_EXIT is the appNode itself // which sets the running state to false anyway. Besides, this event is // not handled by the appNode because it is already in exiting procedure // and does not call handleEvents anymore // eile: May be needed for reliability? send( findApplicationNetNode(), fabric::CMD_CONFIG_EVENT ) << Event::EXIT; _needsFinish = false; _state = STATE_STOPPED; return success; }