00001
00002
00003
00004
00005 #include "config.h"
00006
00007 #include "client.h"
00008 #include "configEvent.h"
00009 #include "configStatistics.h"
00010 #include "frame.h"
00011 #include "frameData.h"
00012 #include "global.h"
00013 #include "log.h"
00014 #include "node.h"
00015 #include "nodeFactory.h"
00016 #include "packets.h"
00017 #include "server.h"
00018 #include "view.h"
00019
00020 #include <eq/net/command.h>
00021 #include <eq/net/global.h>
00022
00023 using namespace eq::base;
00024 using namespace std;
00025
00026 namespace eq
00027 {
00028 typedef net::CommandFunc<Config> ConfigFunc;
00029
00030 Config::Config( base::RefPtr< Server > server )
00031 : net::Session()
00032 , _lastEvent( 0 )
00033 , _latency( 0 )
00034 , _currentFrame( 0 )
00035 , _unlockedFrame( 0 )
00036 , _finishedFrame( 0 )
00037 , _running( false )
00038 {
00039 net::CommandQueue* queue = server->getNodeThreadQueue();
00040
00041 registerCommand( CMD_CONFIG_CREATE_NODE,
00042 ConfigFunc( this, &Config::_cmdCreateNode ), queue );
00043 registerCommand( CMD_CONFIG_DESTROY_NODE,
00044 ConfigFunc( this, &Config::_cmdDestroyNode ), queue );
00045 registerCommand( CMD_CONFIG_START_INIT_REPLY,
00046 ConfigFunc( this, &Config::_cmdStartInitReply ), queue );
00047 registerCommand( CMD_CONFIG_FINISH_INIT_REPLY,
00048 ConfigFunc( this, &Config::_cmdFinishInitReply ), queue );
00049 registerCommand( CMD_CONFIG_EXIT_REPLY,
00050 ConfigFunc( this, &Config::_cmdExitReply ), queue );
00051 registerCommand( CMD_CONFIG_START_FRAME_REPLY,
00052 ConfigFunc( this, &Config::_cmdStartFrameReply ), 0 );
00053 registerCommand( CMD_CONFIG_FRAME_FINISH,
00054 ConfigFunc( this, &Config::_cmdFrameFinish ), 0 );
00055 registerCommand( CMD_CONFIG_EVENT,
00056 ConfigFunc( this, &Config::_cmdUnknown ), &_eventQueue );
00057 #ifdef EQ_TRANSMISSION_API
00058 registerCommand( CMD_CONFIG_DATA,
00059 ConfigFunc( this, &Config::_cmdData ), queue );
00060 #endif
00061 registerCommand( CMD_CONFIG_START_CLOCK,
00062 ConfigFunc( this, &Config::_cmdStartClock ), 0 );
00063 }
00064
00065 Config::~Config()
00066 {
00067 EQINFO << "Delete config @" << (void*)this << endl;
00068
00069 for( ViewVector::const_iterator i = _views.begin(); i != _views.end(); ++i )
00070 delete *i;
00071 _views.clear();
00072
00073 while( tryNextEvent( )) ;
00074 _eventQueue.release( _lastEvent );
00075 _eventQueue.flush();
00076 _lastEvent = 0;
00077
00078 _appNodeID = net::NodeID::ZERO;
00079 _appNode = 0;
00080 }
00081
00082 ConfigVisitor::Result Config::accept( ConfigVisitor* visitor )
00083 {
00084 NodeVisitor::Result result = visitor->visitPre( this );
00085 if( result != NodeVisitor::TRAVERSE_CONTINUE )
00086 return result;
00087
00088 for( NodeVector::const_iterator i = _nodes.begin();
00089 i != _nodes.end(); ++i )
00090 {
00091 Node* node = *i;
00092 switch( node->accept( visitor ))
00093 {
00094 case NodeVisitor::TRAVERSE_TERMINATE:
00095 return NodeVisitor::TRAVERSE_TERMINATE;
00096
00097 case NodeVisitor::TRAVERSE_PRUNE:
00098 result = NodeVisitor::TRAVERSE_PRUNE;
00099 break;
00100
00101 case NodeVisitor::TRAVERSE_CONTINUE:
00102 default:
00103 break;
00104 }
00105 }
00106
00107 switch( visitor->visitPost( this ))
00108 {
00109 case NodeVisitor::TRAVERSE_TERMINATE:
00110 return NodeVisitor::TRAVERSE_TERMINATE;
00111
00112 case NodeVisitor::TRAVERSE_PRUNE:
00113 return NodeVisitor::TRAVERSE_PRUNE;
00114 break;
00115
00116 case NodeVisitor::TRAVERSE_CONTINUE:
00117 default:
00118 break;
00119 }
00120
00121 return result;
00122 }
00123
00124 ServerPtr Config::getServer()
00125 {
00126 net::NodePtr node = net::Session::getServer();
00127 EQASSERT( dynamic_cast< Server* >( node.get( )));
00128 return RefPtr_static_cast< net::Node, Server >( node );
00129 }
00130
00131 ClientPtr Config::getClient()
00132 {
00133 return getServer()->getClient();
00134 }
00135
00136 void Config::_addNode( Node* node )
00137 {
00138 EQASSERT( node->getConfig() == this );
00139 _nodes.push_back( node );
00140 }
00141
00142 void Config::_removeNode( Node* node )
00143 {
00144 vector<Node*>::iterator i = find( _nodes.begin(), _nodes.end(), node );
00145 EQASSERT( i != _nodes.end( ));
00146 _nodes.erase( i );
00147 }
00148
00149 Node* Config::_findNode( const uint32_t id )
00150 {
00151 for( vector<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end();
00152 ++i )
00153 {
00154 Node* node = *i;
00155 if( node->getID() == id )
00156 return node;
00157 }
00158 return 0;
00159 }
00160
00161 bool Config::_startInit( const uint32_t initID )
00162 {
00163 EQASSERT( !_running );
00164 _currentFrame = 0;
00165 _unlockedFrame = 0;
00166 _finishedFrame = 0;
00167
00168 ConfigStartInitPacket packet;
00169 packet.requestID = _requestHandler.registerRequest();
00170 packet.initID = initID;
00171
00172 send( packet );
00173
00174 RefPtr< Client > client = getClient();
00175 while( !_requestHandler.isServed( packet.requestID ))
00176 client->processCommand();
00177
00178 bool ret = false;
00179 _requestHandler.waitRequest( packet.requestID, ret );
00180 return ret;
00181 }
00182
00183 bool Config::_finishInit()
00184 {
00185 EQASSERT( !_running );
00186 registerObject( &_headMatrix );
00187
00188 ConfigFinishInitPacket packet;
00189 packet.requestID = _requestHandler.registerRequest();
00190 packet.headMatrixID = _headMatrix.getID();
00191
00192 send( packet );
00193
00194 RefPtr< Client > client = getClient();
00195 while( !_requestHandler.isServed( packet.requestID ))
00196 client->processCommand();
00197
00198 _requestHandler.waitRequest( packet.requestID, _running );
00199
00200 if( !_running )
00201 deregisterObject( &_headMatrix );
00202
00203 handleEvents();
00204 return _running;
00205 }
00206
00207 bool Config::exit()
00208 {
00209 finishAllFrames();
00210 _running = false;
00211
00212 ConfigExitPacket packet;
00213 packet.requestID = _requestHandler.registerRequest();
00214 send( packet );
00215
00216 RefPtr< Client > client = getClient();
00217 while( !_requestHandler.isServed( packet.requestID ))
00218 client->processCommand();
00219
00220 bool ret = false;
00221 _requestHandler.waitRequest( packet.requestID, ret );
00222
00223 deregisterObject( &_headMatrix );
00224
00225 while( tryNextEvent( )) ;
00226 _eventQueue.release( _lastEvent );
00227 _eventQueue.flush();
00228 _lastEvent = 0;
00229
00230 _appNode = 0;
00231 _appNodeID = net::NodeID::ZERO;
00232 return ret;
00233 }
00234
00235 uint32_t Config::startFrame( const uint32_t frameID )
00236 {
00237 ConfigStatistics stat( Statistic::CONFIG_START_FRAME, this );
00238
00239
00240 for( ViewVector::const_iterator i = _views.begin(); i != _views.end(); ++i )
00241 {
00242 View* view = *i;
00243 if( view->isDirty( ))
00244 view->commit();
00245 }
00246
00247
00248 ConfigStartFramePacket packet;
00249 packet.requestID = _requestHandler.registerRequest();
00250 packet.frameID = frameID;
00251
00252 const uint32_t frameNumber = _currentFrame + 1;
00253 send( packet );
00254
00255 _requestHandler.waitRequest( packet.requestID );
00256 EQASSERT( frameNumber == _currentFrame );
00257 EQLOG( LOG_ANY ) << "---- Started Frame ---- " << frameNumber << endl;
00258
00259 stat.event.data.statistic.frameNumber = frameNumber;
00260 return frameNumber;
00261 }
00262
00263 uint32_t Config::finishFrame()
00264 {
00265 ConfigStatistics stat( Statistic::CONFIG_FINISH_FRAME, this );
00266
00267 RefPtr< Client > client = getClient();
00268 const uint32_t frameToFinish = (_currentFrame >= _latency) ?
00269 _currentFrame - _latency : 0;
00270 {
00271 ConfigStatistics waitStat( Statistic::CONFIG_WAIT_FINISH_FRAME, this );
00272
00273 while( _unlockedFrame < _currentFrame ||
00274 _finishedFrame < frameToFinish )
00275 {
00276 client->processCommand();
00277 EQVERB << "local " << _unlockedFrame << '/' << _currentFrame
00278 << " global " << _finishedFrame.get() << '/' << frameToFinish
00279 << endl;
00280 }
00281
00282
00283
00284 waitStat.event.data.statistic.frameNumber = frameToFinish;
00285 waitStat.event.data.statistic.endTime = getTime();
00286 handleEvent( &waitStat.event );
00287 waitStat.ignore = true;
00288 }
00289
00290 handleEvents();
00291
00292
00293 stat.event.data.statistic.frameNumber = frameToFinish;
00294 stat.event.data.statistic.endTime = getTime();
00295 handleEvent( &stat.event );
00296 stat.ignore = true;
00297
00298 _updateStatistics( frameToFinish );
00299
00300 EQLOG( LOG_ANY ) << "---- Finished Frame --- " << frameToFinish << " ("
00301 << _currentFrame << ')' << endl;
00302 return frameToFinish;
00303 }
00304
00305 uint32_t Config::finishAllFrames()
00306 {
00307 if( _finishedFrame == _currentFrame )
00308 return _currentFrame;
00309
00310 EQLOG( LOG_ANY ) << "-- Finish All Frames --" << endl;
00311 ConfigFinishAllFramesPacket packet;
00312 send( packet );
00313
00314 RefPtr< Client > client = getClient();
00315 while( _finishedFrame < _currentFrame )
00316 client->processCommand();
00317
00318 handleEvents();
00319 EQLOG( LOG_ANY ) << "-- Finished All Frames --" << endl;
00320 return _currentFrame;
00321 }
00322
00323 void Config::sendEvent( ConfigEvent& event )
00324 {
00325 EQASSERT( _appNodeID );
00326
00327 if( !_appNode )
00328 {
00329 net::NodePtr localNode = getLocalNode();
00330 net::NodePtr server = net::Session::getServer();
00331 _appNode = localNode->connect( _appNodeID, server );
00332 }
00333 EQASSERT( _appNode );
00334
00335 event.sessionID = getID();
00336 EQLOG( LOG_EVENTS ) << "send event " << &event << endl;
00337 _appNode->send( event );
00338 }
00339
00340 const ConfigEvent* Config::nextEvent()
00341 {
00342 _eventQueue.release( _lastEvent );
00343 _lastEvent = _eventQueue.pop();
00344 return _lastEvent->getPacket<ConfigEvent>();
00345 }
00346
00347 const ConfigEvent* Config::tryNextEvent()
00348 {
00349 net::Command* command = _eventQueue.tryPop();
00350 if( !command )
00351 return 0;
00352
00353 _eventQueue.release( _lastEvent );
00354 _lastEvent = command;
00355 return command->getPacket<ConfigEvent>();
00356 }
00357
00358 void Config::handleEvents()
00359 {
00360 for( const ConfigEvent* event = tryNextEvent(); event;
00361 event = tryNextEvent( ))
00362 {
00363 if( !handleEvent( event ))
00364 EQVERB << "Unhandled " << event << endl;
00365 }
00366 }
00367
00368 bool Config::handleEvent( const ConfigEvent* event )
00369 {
00370 switch( event->data.type )
00371 {
00372 case Event::WINDOW_CLOSE:
00373 _running = false;
00374 return true;
00375
00376 case Event::KEY_PRESS:
00377 if( event->data.keyPress.key == KC_ESCAPE )
00378 {
00379 _running = false;
00380 return true;
00381 }
00382 break;
00383
00384 case Event::POINTER_BUTTON_PRESS:
00385 if( event->data.pointerButtonPress.buttons ==
00386 ( PTR_BUTTON1 | PTR_BUTTON2 | PTR_BUTTON3 ))
00387 {
00388 _running = false;
00389 return true;
00390 }
00391 break;
00392
00393 case Event::STATISTIC:
00394 {
00395 EQLOG( LOG_STATS ) << event->data << endl;
00396
00397 const uint32_t originator = event->data.originator;
00398 EQASSERT( originator != EQ_ID_INVALID );
00399 if( originator == EQ_ID_INVALID )
00400 return true;
00401
00402 const Statistic& statistic = event->data.statistic;
00403 const uint32_t frame = statistic.frameNumber;
00404
00405 if( frame == 0 )
00406 return true;
00407
00408 ScopedMutex< SpinLock > mutex( _statisticsMutex );
00409
00410 for( deque< FrameStatistics >::iterator i = _statistics.begin();
00411 i != _statistics.end(); ++i )
00412 {
00413 FrameStatistics& frameStats = *i;
00414 if( frameStats.first == frame )
00415 {
00416 SortedStatistics& sortedStats = frameStats.second;
00417 Statistics& statistics = sortedStats[ originator ];
00418 statistics.push_back( statistic );
00419 return true;
00420 }
00421 }
00422
00423 _statistics.push_back( FrameStatistics( ));
00424 FrameStatistics& frameStats = _statistics.back();
00425 frameStats.first = frame;
00426
00427 SortedStatistics& sortedStats = frameStats.second;
00428 Statistics& statistics = sortedStats[ originator ];
00429 statistics.push_back( statistic );
00430
00431 return true;
00432 }
00433
00434 case Event::VIEW_RESIZE:
00435 handleViewResize( event->data.originator,
00436 vmml::Vector2i( event->data.resize.w,
00437 event->data.resize.h ));
00438 return true;
00439 }
00440
00441 return false;
00442 }
00443
00444 void Config::handleViewResize( const uint32_t viewID,
00445 const vmml::Vector2i& newSize )
00446 {
00447 net::IDHash< BaseView >::const_iterator i = _baseViews.find( viewID );
00448
00449 if( i == _baseViews.end( ))
00450 {
00451
00452 for( ViewVector::const_iterator j = _views.begin();
00453 j != _views.end(); ++j )
00454 {
00455 View* view = *j;
00456 if( view->getID() != viewID )
00457 continue;
00458
00459
00460 BaseView& baseView = _baseViews[ viewID ];
00461 baseView.view = view;
00462 baseView.base = *view;
00463 baseView.size = newSize;
00464 return;
00465 }
00466
00467 EQWARN << "View " << viewID << " not found" << endl;
00468 EQUNREACHABLE;
00469 return;
00470 }
00471
00472 const BaseView& baseView = i->second;
00473 View* view = baseView.view;
00474 const vmml::Vector2i& baseSize = baseView.size;
00475
00476 switch( view->getCurrentType( ))
00477 {
00478 case View::TYPE_WALL:
00479 {
00480 const float newAR = static_cast< float >( newSize.x ) /
00481 static_cast< float >( newSize.y );
00482 const float initAR = static_cast< float >( baseSize.x ) /
00483 static_cast< float >( baseSize.y );
00484 const float ratio = newAR / initAR;
00485
00486 Wall wall( baseView.base.getWall( ));
00487 wall.resizeHorizontal( ratio );
00488 view->setWall( wall );
00489 break;
00490 }
00491
00492 case View::TYPE_PROJECTION:
00493 {
00494 const float newAR = static_cast< float >( newSize.x ) /
00495 static_cast< float >( newSize.y );
00496 const float initAR = static_cast< float >( baseSize.x ) /
00497 static_cast< float >( baseSize.y );
00498 const float ratio = newAR / initAR;
00499
00500 eq::Projection projection( baseView.base.getProjection( ));
00501 projection.resizeHorizontal( ratio );
00502 view->setProjection( projection );
00503 break;
00504 }
00505
00506 case eq::View::TYPE_NONE:
00507 EQUNREACHABLE;
00508 break;
00509 default:
00510 EQUNIMPLEMENTED;
00511 break;
00512 }
00513 }
00514
00515 void Config::_updateStatistics( const uint32_t finishedFrame )
00516 {
00517
00518 _statisticsMutex.set();
00519 while( !_statistics.empty() &&
00520 finishedFrame - _statistics.front().first > _latency+1 )
00521
00522 _statistics.pop_front();
00523 _statisticsMutex.unset();
00524 }
00525
00526 void Config::getStatistics( std::vector< FrameStatistics >& statistics )
00527 {
00528 _statisticsMutex.set();
00529
00530 for( std::deque< FrameStatistics >::const_iterator i = _statistics.begin();
00531 i != _statistics.end(); ++i )
00532 {
00533 if( (*i).first <= _finishedFrame.get( ))
00534 statistics.push_back( *i );
00535 }
00536
00537 _statisticsMutex.unset();
00538 }
00539
00540 void Config::setWindowSystem( const WindowSystem windowSystem )
00541 {
00542
00543 static SpinLock _lock;
00544 ScopedMutex< SpinLock > mutex( _lock );
00545
00546 if( _eventQueue.getWindowSystem() == WINDOW_SYSTEM_NONE )
00547 {
00548 _eventQueue.setWindowSystem( windowSystem );
00549 EQINFO << "Client message pump set up for " << windowSystem << endl;
00550 }
00551 else if( _eventQueue.getWindowSystem() != windowSystem )
00552 EQWARN << "Can't switch to window system " << windowSystem
00553 << ", already using " << _eventQueue.getWindowSystem()
00554 << endl;
00555
00556 RefPtr< Client > client = getClient();
00557 client->setWindowSystem( windowSystem );
00558 }
00559
00560
00561 void Config::setHeadMatrix( const vmml::Matrix4f& matrix )
00562 {
00563 _headMatrix = matrix;
00564 _headMatrix.commit();
00565 }
00566
00567 #ifdef EQ_TRANSMISSION_API
00568 void Config::broadcastData( const void* data, uint64_t size )
00569 {
00570 if( _clientNodeIDs.empty( ))
00571 return;
00572
00573 if( !_connectClientNodes( ))
00574 return;
00575
00576 ConfigDataPacket packet;
00577 packet.sessionID = getID();
00578 packet.dataSize = size;
00579
00580 for( vector< net::NodePtr >::iterator i = _clientNodes.begin();
00581 i != _clientNodes.end(); ++i )
00582 {
00583 (*i)->send( packet, data, size );
00584 }
00585 }
00586
00587 bool Config::_connectClientNodes()
00588 {
00589 if( !_clientNodes.empty( ))
00590 return true;
00591
00592 net::NodePtr localNode = getLocalNode();
00593 net::NodePtr server = getServer();
00594
00595 for( vector< net::NodeID >::const_iterator i = _clientNodeIDs.begin();
00596 i < _clientNodeIDs.end(); ++i )
00597 {
00598 const net::NodeID& id = *i;
00599 net::NodePtr node = localNode->connect( id, server );
00600
00601 if( !node.isValid( ))
00602 {
00603 EQERROR << "Can't connect node with ID " << id << endl;
00604 _clientNodes.clear();
00605 return false;
00606 }
00607
00608 _clientNodes.push_back( node );
00609 }
00610 return true;
00611 }
00612 #endif // EQ_TRANSMISSION_API
00613
00614 void Config::freezeLoadBalancing( const bool onOff )
00615 {
00616 ConfigFreezeLoadBalancingPacket packet;
00617 packet.freeze = onOff;
00618 send( packet );
00619 }
00620
00621 void Config::Distributor::applyInstanceData( net::DataIStream& is )
00622 {
00623 is >> _config->_latency;
00624
00625 for( ViewVector::const_iterator i = _config->_views.begin();
00626 i != _config->_views.end(); ++i )
00627 {
00628 _config->deregisterObject( *i );
00629 delete *i;
00630 }
00631 _config->_views.clear();
00632
00633 View* view = new View( is );
00634 for( ; view->getCurrentType() != View::TYPE_NONE; view = new View( is ))
00635 {
00636 _config->registerObject( view );
00637 _config->_views.push_back( view );
00638 }
00639 delete view;
00640 }
00641
00642 void Config::_initAppNode( const uint32_t distributorID )
00643 {
00644 Config::Distributor distributor( this );
00645 EQCHECK( mapObject( &distributor, distributorID ));
00646 unmapObject( &distributor );
00647
00648 vector< uint32_t > viewIDs;
00649 for( ViewVector::const_iterator i = _views.begin(); i != _views.end(); ++i )
00650 viewIDs.push_back( (*i)->getID( ));
00651
00652 ConfigMapViewsPacket packet;
00653 packet.nViews = _views.size();
00654
00655 send( packet, viewIDs );
00656 }
00657
00658 void Config::_exitAppNode()
00659 {
00660 for( ViewVector::const_iterator i = _views.begin(); i != _views.end(); ++i )
00661 {
00662 View* view = *i;
00663 EQASSERT( view->getID() != EQ_ID_INVALID );
00664 EQASSERT( view->isMaster( ));
00665
00666 deregisterObject( view );
00667 delete view;
00668 }
00669 _views.clear();
00670 }
00671
00672
00673
00674
00675 net::CommandResult Config::_cmdCreateNode( net::Command& command )
00676 {
00677 const ConfigCreateNodePacket* packet =
00678 command.getPacket<ConfigCreateNodePacket>();
00679 EQINFO << "Handle create node " << packet << endl;
00680 EQASSERT( packet->nodeID != EQ_ID_INVALID );
00681
00682 Node* node = Global::getNodeFactory()->createNode( this );
00683 attachObject( node, packet->nodeID );
00684
00685 ConfigCreateNodeReplyPacket reply( packet );
00686 send( command.getNode(), reply );
00687
00688 return net::COMMAND_HANDLED;
00689 }
00690
00691 net::CommandResult Config::_cmdDestroyNode( net::Command& command )
00692 {
00693 const ConfigDestroyNodePacket* packet =
00694 command.getPacket<ConfigDestroyNodePacket>();
00695 EQINFO << "Handle destroy node " << packet << endl;
00696
00697 Node* node = _findNode( packet->nodeID );
00698 if( !node )
00699 return net::COMMAND_HANDLED;
00700
00701 detachObject( node );
00702 delete node;
00703
00704 return net::COMMAND_HANDLED;
00705 }
00706
00707 net::CommandResult Config::_cmdStartInitReply( net::Command& command )
00708 {
00709 const ConfigStartInitReplyPacket* packet =
00710 command.getPacket<ConfigStartInitReplyPacket>();
00711 EQINFO << "handle start init reply " << packet << endl;
00712
00713 if( !packet->result )
00714 _error = packet->error;
00715
00716 _requestHandler.serveRequest( packet->requestID, (void*)(packet->result) );
00717 return net::COMMAND_HANDLED;
00718 }
00719
00720 net::CommandResult Config::_cmdFinishInitReply( net::Command& command )
00721 {
00722 const ConfigFinishInitReplyPacket* packet =
00723 command.getPacket<ConfigFinishInitReplyPacket>();
00724 EQINFO << "handle finish init reply " << packet << endl;
00725
00726 if( !packet->result )
00727 {
00728 _error = packet->error;
00729 #ifdef EQ_TRANSMISSION_API
00730 _clientNodeIDs.clear();
00731 _clientNodes.clear();
00732 #endif
00733 }
00734
00735 _requestHandler.serveRequest( packet->requestID, (void*)(packet->result) );
00736 return net::COMMAND_HANDLED;
00737 }
00738
00739 net::CommandResult Config::_cmdExitReply( net::Command& command )
00740 {
00741 const ConfigExitReplyPacket* packet =
00742 command.getPacket<ConfigExitReplyPacket>();
00743 EQINFO << "handle exit reply " << packet << endl;
00744
00745 _baseViews.clear();
00746
00747 #ifdef EQ_TRANSMISSION_API
00748 _clientNodeIDs.clear();
00749 _clientNodes.clear();
00750 #endif
00751
00752 _requestHandler.serveRequest( packet->requestID, (void*)(packet->result) );
00753 return net::COMMAND_HANDLED;
00754 }
00755
00756 net::CommandResult Config::_cmdStartFrameReply( net::Command& command )
00757 {
00758 const ConfigStartFrameReplyPacket* packet =
00759 command.getPacket<ConfigStartFrameReplyPacket>();
00760 EQVERB << "handle frame start reply " << packet << endl;
00761
00762 #if 0 // enable when list of client nodes is dynamic
00763 _clientNodeIDs.clear();
00764 _clientNodes.clear();
00765
00766 for( uint32_t i=0; i<packet->nNodeIDs; ++i )
00767 {
00768 _clientNodeIDs.push_back( packet->nodeIDs[i] );
00769 _clientNodeIDs[i].convertToHost();
00770 }
00771 #endif
00772
00773 _currentFrame = packet->frameNumber;
00774 if( _nodes.empty( ))
00775 releaseFrameLocal( packet->frameNumber );
00776
00777 _requestHandler.serveRequest( packet->requestID );
00778 return net::COMMAND_HANDLED;
00779 }
00780
00781 net::CommandResult Config::_cmdFrameFinish( net::Command& command )
00782 {
00783 const ConfigFrameFinishPacket* packet =
00784 command.getPacket<ConfigFrameFinishPacket>();
00785 EQLOG( LOG_TASKS ) << "frame finish " << packet << endl;
00786
00787 _finishedFrame = packet->frameNumber;
00788
00789 if( _unlockedFrame < _finishedFrame.get( ))
00790 {
00791 EQWARN << "Finished frame was not locally unlocked, enforcing unlock"
00792 << endl;
00793 _unlockedFrame = _finishedFrame.get();
00794 }
00795
00796 getNodeThreadQueue()->wakeup();
00797 return net::COMMAND_HANDLED;
00798 }
00799
00800 #ifdef EQ_TRANSMISSION_API
00801 net::CommandResult Config::_cmdData( net::Command& command )
00802 {
00803 EQVERB << "received data " << command.getPacket<ConfigDataPacket>()
00804 << endl;
00805
00806
00807
00808
00809
00810 EQASSERTINFO( _nodes.size() == 1,
00811 "More than one config node instantiated locally" );
00812
00813 _nodes[0]->_dataQueue.push( command );
00814 return net::COMMAND_HANDLED;
00815 }
00816 #endif
00817
00818 net::CommandResult Config::_cmdStartClock( net::Command& command )
00819 {
00820 _clock.reset();
00821
00822 EQVERB << "start global clock" << endl;
00823 return net::COMMAND_HANDLED;
00824 }
00825
00826 }