00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "config.h"
00019
00020 #include "canvas.h"
00021 #include "client.h"
00022 #include "configDeserializer.h"
00023 #include "configEvent.h"
00024 #include "configStatistics.h"
00025 #include "frame.h"
00026 #include "frameData.h"
00027 #include "global.h"
00028 #include "layout.h"
00029 #include "log.h"
00030 #include "node.h"
00031 #include "nodeFactory.h"
00032 #include "packets.h"
00033 #include "server.h"
00034 #include "task.h"
00035 #include "view.h"
00036
00037 #include <eq/net/command.h>
00038 #include <eq/net/global.h>
00039
00040 #include "configCommitVisitor.h"
00041
00042 using namespace eq::base;
00043 using namespace std;
00044
00045 namespace eq
00046 {
00048 typedef net::CommandFunc<Config> ConfigFunc;
00051 Config::Config( ServerPtr server )
00052 : net::Session()
00053 , _eyeBase( 0.f )
00054 , _lastEvent( 0 )
00055 , _latency( 0 )
00056 , _currentFrame( 0 )
00057 , _unlockedFrame( 0 )
00058 , _finishedFrame( 0 )
00059 , _running( false )
00060 {
00061 base::Log::setClock( &_clock );
00062 }
00063
00064 Config::~Config()
00065 {
00066 EQINFO << "Delete config @" << (void*)this << endl;
00067 EQASSERT( _observers.empty( ));
00068 EQASSERT( _layouts.empty( ));
00069 EQASSERT( _canvases.empty( ));
00070
00071 while( tryNextEvent( )) ;
00072 if( _lastEvent )
00073 _lastEvent->release();
00074 _eventQueue.flush();
00075 _lastEvent = 0;
00076
00077 _appNodeID = net::NodeID::ZERO;
00078 _appNode = 0;
00079 base::Log::setClock( 0 );
00080 }
00081
00082 void Config::notifyMapped( net::NodePtr node )
00083 {
00084 net::Session::notifyMapped( node );
00085
00086 ServerPtr server = getServer();
00087 net::CommandQueue* queue = server->getNodeThreadQueue();
00088
00089 registerCommand( CMD_CONFIG_CREATE_NODE,
00090 ConfigFunc( this, &Config::_cmdCreateNode ), queue );
00091 registerCommand( CMD_CONFIG_DESTROY_NODE,
00092 ConfigFunc( this, &Config::_cmdDestroyNode ), queue );
00093 registerCommand( CMD_CONFIG_INIT_REPLY,
00094 ConfigFunc( this, &Config::_cmdInitReply ), queue );
00095 registerCommand( CMD_CONFIG_EXIT_REPLY,
00096 ConfigFunc( this, &Config::_cmdExitReply ), queue );
00097 registerCommand( CMD_CONFIG_RELEASE_FRAME_LOCAL,
00098 ConfigFunc( this, &Config::_cmdReleaseFrameLocal ), queue);
00099 registerCommand( CMD_CONFIG_FRAME_FINISH,
00100 ConfigFunc( this, &Config::_cmdFrameFinish ), 0 );
00101 registerCommand( CMD_CONFIG_EVENT,
00102 ConfigFunc( this, &Config::_cmdUnknown ), &_eventQueue );
00103 registerCommand( CMD_CONFIG_SYNC_CLOCK,
00104 ConfigFunc( this, &Config::_cmdSyncClock ), 0 );
00105 registerCommand( CMD_CONFIG_UNMAP, ConfigFunc( this, &Config::_cmdUnmap ),
00106 queue );
00107 }
00108
00109 CommandQueue* Config::getNodeThreadQueue()
00110 {
00111 return getClient()->getNodeThreadQueue();
00112 }
00113
00114 namespace
00115 {
00116 template< typename P, typename T > class IDFinder : public P
00117 {
00118 public:
00119 IDFinder( const uint32_t id ) : _id( id ), _result( 0 ) {}
00120 virtual ~IDFinder(){}
00121
00122 virtual VisitorResult visitPre( T* node ) { return visit( node ); }
00123 virtual VisitorResult visit( T* node )
00124 {
00125 if( node->getID() == _id )
00126 {
00127 _result = node;
00128 return TRAVERSE_TERMINATE;
00129 }
00130 return TRAVERSE_CONTINUE;
00131 }
00132
00133 T* getResult() { return _result; }
00134
00135 private:
00136 const uint32_t _id;
00137 T* _result;
00138 };
00139
00140 typedef IDFinder< ConfigVisitor, Observer > ObserverIDFinder;
00141 typedef IDFinder< ConfigVisitor, Layout > LayoutIDFinder;
00142 typedef IDFinder< ConfigVisitor, View > ViewIDFinder;
00143 }
00144
00145 Observer* Config::findObserver( const uint32_t id )
00146 {
00147 ObserverIDFinder finder( id );
00148 accept( finder );
00149 return finder.getResult();
00150 }
00151
00152 Layout* Config::findLayout( const uint32_t id )
00153 {
00154 LayoutIDFinder finder( id );
00155 accept( finder );
00156 return finder.getResult();
00157 }
00158
00159 View* Config::findView( const uint32_t id )
00160 {
00161 ViewIDFinder finder( id );
00162 accept( finder );
00163 return finder.getResult();
00164 }
00165
00166 namespace
00167 {
00168 template< class C, class V >
00169 VisitorResult _accept( C* config, V& visitor )
00170 {
00171 VisitorResult result = visitor.visitPre( config );
00172 if( result != TRAVERSE_CONTINUE )
00173 return result;
00174
00175 const NodeVector& nodes = config->getNodes();
00176 for( NodeVector::const_iterator i = nodes.begin(); i != nodes.end(); ++i )
00177 {
00178 switch( (*i)->accept( visitor ))
00179 {
00180 case TRAVERSE_TERMINATE:
00181 return TRAVERSE_TERMINATE;
00182
00183 case TRAVERSE_PRUNE:
00184 result = TRAVERSE_PRUNE;
00185 break;
00186
00187 case TRAVERSE_CONTINUE:
00188 default:
00189 break;
00190 }
00191 }
00192
00193 const ObserverVector& observers = config->getObservers();
00194 for( ObserverVector::const_iterator i = observers.begin();
00195 i != observers.end(); ++i )
00196 {
00197 switch( (*i)->accept( visitor ))
00198 {
00199 case TRAVERSE_TERMINATE:
00200 return TRAVERSE_TERMINATE;
00201
00202 case TRAVERSE_PRUNE:
00203 result = TRAVERSE_PRUNE;
00204 break;
00205
00206 case TRAVERSE_CONTINUE:
00207 default:
00208 break;
00209 }
00210 }
00211
00212 const LayoutVector& layouts = config->getLayouts();
00213 for( LayoutVector::const_iterator i = layouts.begin();
00214 i != layouts.end(); ++i )
00215 {
00216 switch( (*i)->accept( visitor ))
00217 {
00218 case TRAVERSE_TERMINATE:
00219 return TRAVERSE_TERMINATE;
00220
00221 case TRAVERSE_PRUNE:
00222 result = TRAVERSE_PRUNE;
00223 break;
00224
00225 case TRAVERSE_CONTINUE:
00226 default:
00227 break;
00228 }
00229 }
00230
00231 const CanvasVector& canvases = config->getCanvases();
00232 for( CanvasVector::const_iterator i = canvases.begin();
00233 i != canvases.end(); ++i )
00234 {
00235 switch( (*i)->accept( visitor ))
00236 {
00237 case TRAVERSE_TERMINATE:
00238 return TRAVERSE_TERMINATE;
00239
00240 case TRAVERSE_PRUNE:
00241 result = TRAVERSE_PRUNE;
00242 break;
00243
00244 case TRAVERSE_CONTINUE:
00245 default:
00246 break;
00247 }
00248 }
00249
00250 switch( visitor.visitPost( config ))
00251 {
00252 case TRAVERSE_TERMINATE:
00253 return TRAVERSE_TERMINATE;
00254
00255 case TRAVERSE_PRUNE:
00256 result = TRAVERSE_PRUNE;
00257 break;
00258
00259 case TRAVERSE_CONTINUE:
00260 default:
00261 break;
00262 }
00263
00264 return result;
00265 }
00266 }
00267
00268 VisitorResult Config::accept( ConfigVisitor& visitor )
00269 {
00270 return _accept( this, visitor );
00271 }
00272
00273 ServerPtr Config::getServer()
00274 {
00275 net::NodePtr node = net::Session::getServer();
00276 EQASSERT( dynamic_cast< Server* >( node.get( )));
00277 ServerPtr server = static_cast< Server* >( node.get( ));
00278 return server;
00279 }
00280
00281 ClientPtr Config::getClient()
00282 {
00283 return getServer()->getClient();
00284 }
00285
00286 void Config::_addNode( Node* node )
00287 {
00288 EQASSERT( node->getConfig() == this );
00289 _nodes.push_back( node );
00290 }
00291
00292 void Config::_removeNode( Node* node )
00293 {
00294 vector<Node*>::iterator i = find( _nodes.begin(), _nodes.end(), node );
00295 EQASSERT( i != _nodes.end( ));
00296 _nodes.erase( i );
00297 }
00298
00299 Node* Config::_findNode( const uint32_t id )
00300 {
00301 for( vector<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end();
00302 ++i )
00303 {
00304 Node* node = *i;
00305 if( node->getID() == id )
00306 return node;
00307 }
00308 return 0;
00309 }
00310
00311 void Config::_addObserver( Observer* observer )
00312 {
00313 observer->_config = this;
00314 _observers.push_back( observer );
00315 }
00316
00317 void Config::_removeObserver( Observer* observer )
00318 {
00319 ObserverVector::iterator i = find( _observers.begin(), _observers.end(),
00320 observer );
00321 EQASSERT( i != _observers.end( ));
00322 _observers.erase( i );
00323 }
00324
00325 void Config::_addLayout( Layout* layout )
00326 {
00327 layout->_config = this;
00328 _layouts.push_back( layout );
00329 }
00330
00331 void Config::_removeLayout( Layout* layout )
00332 {
00333 LayoutVector::iterator i = find( _layouts.begin(), _layouts.end(), layout );
00334 EQASSERT( i != _layouts.end( ));
00335 _layouts.erase( i );
00336 }
00337
00338 void Config::_addCanvas( Canvas* canvas )
00339 {
00340 canvas->_config = this;
00341 _canvases.push_back( canvas );
00342 }
00343
00344 void Config::_removeCanvas( Canvas* canvas )
00345 {
00346 CanvasVector::iterator i = find( _canvases.begin(), _canvases.end(),
00347 canvas );
00348 EQASSERT( i != _canvases.end( ));
00349 _canvases.erase( i );
00350 }
00351
00352 bool Config::init( const uint32_t initID )
00353 {
00354 EQASSERT( !_running );
00355 _currentFrame = 0;
00356 _unlockedFrame = 0;
00357 _finishedFrame = 0;
00358
00359 ConfigInitPacket packet;
00360 packet.requestID = _requestHandler.registerRequest();
00361 packet.initID = initID;
00362
00363 send( packet );
00364
00365 RefPtr< Client > client = getClient();
00366 while( !_requestHandler.isServed( packet.requestID ))
00367 client->processCommand();
00368
00369 _requestHandler.waitRequest( packet.requestID, _running );
00370
00371 handleEvents();
00372 return _running;
00373 }
00374
00375 bool Config::exit()
00376 {
00377 finishAllFrames();
00378
00379 ConfigExitPacket packet;
00380 packet.requestID = _requestHandler.registerRequest();
00381 send( packet );
00382
00383 RefPtr< Client > client = getClient();
00384 while( !_requestHandler.isServed( packet.requestID ))
00385 client->processCommand();
00386
00387 bool ret = false;
00388 _requestHandler.waitRequest( packet.requestID, ret );
00389
00390 while( tryNextEvent( )) ;
00391 if( _lastEvent )
00392 _lastEvent->release();
00393 _eventQueue.flush();
00394 _lastEvent = 0;
00395 _running = false;
00396
00397 _appNode = 0;
00398 _appNodeID = net::NodeID::ZERO;
00399 return ret;
00400 }
00401
00402 uint32_t Config::startFrame( const uint32_t frameID )
00403 {
00404 ConfigStatistics stat( Statistic::CONFIG_START_FRAME, this );
00405
00406 ConfigCommitVisitor committer;
00407 accept( committer );
00408 const std::vector< net::ObjectVersion >& changes = committer.getChanges();
00409
00410 if( committer.needsFinish( ))
00411 finishAllFrames();
00412
00413
00414 ConfigStartFramePacket packet;
00415 packet.frameID = frameID;
00416 packet.nChanges = changes.size();
00417
00418 send( packet, changes );
00419 ++_currentFrame;
00420
00421 EQLOG( LOG_ANY ) << "---- Started Frame ---- " << _currentFrame << endl;
00422 stat.event.data.statistic.frameNumber = _currentFrame;
00423 return _currentFrame;
00424 }
00425
00426 uint32_t Config::finishFrame()
00427 {
00428 ConfigStatistics stat( Statistic::CONFIG_FINISH_FRAME, this );
00429
00430 RefPtr< Client > client = getClient();
00431 const uint32_t frameToFinish = (_currentFrame >= _latency) ?
00432 _currentFrame - _latency : 0;
00433 const bool needsLocalSync = _needsLocalSync();
00434 {
00435 ConfigStatistics waitStat( Statistic::CONFIG_WAIT_FINISH_FRAME, this );
00436
00437
00438 if( needsLocalSync )
00439 while( _unlockedFrame < _currentFrame )
00440 client->processCommand();
00441
00442
00443 if( !_nodes.empty( ))
00444 {
00445 EQASSERT( _nodes.size() == 1 );
00446 const Node* node = _nodes.front();
00447
00448 while( node->getFinishedFrame() < frameToFinish )
00449 client->processCommand();
00450 }
00451
00452
00453 _finishedFrame.waitGE( frameToFinish );
00454
00455
00456
00457 waitStat.event.data.statistic.frameNumber = frameToFinish;
00458 waitStat.event.data.statistic.endTime = getTime();
00459 handleEvent( &waitStat.event );
00460 waitStat.ignore = true;
00461 }
00462
00463 handleEvents();
00464
00465
00466 stat.event.data.statistic.frameNumber = frameToFinish;
00467 stat.event.data.statistic.endTime = getTime();
00468 handleEvent( &stat.event );
00469 stat.ignore = true;
00470
00471 _updateStatistics( frameToFinish );
00472
00473 EQLOG( LOG_ANY ) << "---- Finished Frame --- " << frameToFinish << " ("
00474 << _currentFrame << ')' << endl;
00475 return frameToFinish;
00476 }
00477
00478 uint32_t Config::finishAllFrames()
00479 {
00480 if( _finishedFrame == _currentFrame )
00481 return _currentFrame;
00482
00483 EQLOG( LOG_ANY ) << "-- Finish All Frames --" << endl;
00484 ConfigFinishAllFramesPacket packet;
00485 send( packet );
00486
00487 RefPtr< Client > client = getClient();
00488 while( _finishedFrame < _currentFrame )
00489 client->processCommand();
00490
00491 handleEvents();
00492 EQLOG( LOG_ANY ) << "-- Finished All Frames --" << endl;
00493 return _currentFrame;
00494 }
00495
00496 void Config::sendEvent( ConfigEvent& event )
00497 {
00498 EQASSERT( event.data.type != Event::STATISTIC ||
00499 event.data.statistic.type != Statistic::NONE );
00500 EQASSERT( _appNodeID );
00501
00502 if( !_appNode )
00503 {
00504 net::NodePtr localNode = getLocalNode();
00505 _appNode = localNode->connect( _appNodeID );
00506 }
00507 EQASSERT( _appNode );
00508
00509 event.sessionID = getID();
00510 EQLOG( LOG_EVENTS ) << "send event " << &event << endl;
00511 _appNode->send( event );
00512 }
00513
00514 const ConfigEvent* Config::nextEvent()
00515 {
00516 if( _lastEvent )
00517 _lastEvent->release();
00518 _lastEvent = _eventQueue.pop();
00519 return _lastEvent->getPacket<ConfigEvent>();
00520 }
00521
00522 const ConfigEvent* Config::tryNextEvent()
00523 {
00524 net::Command* command = _eventQueue.tryPop();
00525 if( !command )
00526 return 0;
00527
00528 if( _lastEvent )
00529 _lastEvent->release();
00530 _lastEvent = command;
00531 return command->getPacket<ConfigEvent>();
00532 }
00533
00534 void Config::handleEvents()
00535 {
00536 for( const ConfigEvent* event = tryNextEvent(); event;
00537 event = tryNextEvent( ))
00538 {
00539 if( !handleEvent( event ))
00540 EQVERB << "Unhandled " << event << endl;
00541 }
00542 }
00543
00544 bool Config::handleEvent( const ConfigEvent* event )
00545 {
00546 switch( event->data.type )
00547 {
00548 case Event::EXIT:
00549 case Event::WINDOW_CLOSE:
00550 _running = false;
00551 return true;
00552
00553 case Event::KEY_PRESS:
00554 if( event->data.keyPress.key == KC_ESCAPE )
00555 {
00556 _running = false;
00557 return true;
00558 }
00559 break;
00560
00561 case Event::POINTER_BUTTON_PRESS:
00562 if( event->data.pointerButtonPress.buttons ==
00563 ( PTR_BUTTON1 | PTR_BUTTON2 | PTR_BUTTON3 ))
00564 {
00565 _running = false;
00566 return true;
00567 }
00568 break;
00569
00570 case Event::STATISTIC:
00571 {
00572 EQLOG( LOG_STATS ) << event->data << endl;
00573
00574 const uint32_t originator = event->data.originator;
00575 EQASSERT( originator != EQ_ID_INVALID );
00576 if( originator == EQ_ID_INVALID )
00577 return false;
00578
00579 const Statistic& statistic = event->data.statistic;
00580 const uint32_t frame = statistic.frameNumber;
00581 EQASSERT( statistic.type != Statistic::NONE )
00582
00583 if( frame == 0 ||
00584 statistic.type == Statistic::NONE )
00585 {
00586 return false;
00587 }
00588
00589 ScopedMutex mutex( _statisticsMutex );
00590
00591 for( deque< FrameStatistics >::iterator i = _statistics.begin();
00592 i != _statistics.end(); ++i )
00593 {
00594 FrameStatistics& frameStats = *i;
00595 if( frameStats.first == frame )
00596 {
00597 SortedStatistics& sortedStats = frameStats.second;
00598 Statistics& statistics = sortedStats[ originator ];
00599 statistics.push_back( statistic );
00600 return false;
00601 }
00602 }
00603
00604 _statistics.push_back( FrameStatistics( ));
00605 FrameStatistics& frameStats = _statistics.back();
00606 frameStats.first = frame;
00607
00608 SortedStatistics& sortedStats = frameStats.second;
00609 Statistics& statistics = sortedStats[ originator ];
00610 statistics.push_back( statistic );
00611
00612 return false;
00613 }
00614
00615 case Event::VIEW_RESIZE:
00616 {
00617 View* view = findView( event->data.originator );
00618 EQASSERT( view );
00619 if( view )
00620 return view->handleEvent( event->data );
00621 break;
00622 }
00623 }
00624
00625 return false;
00626 }
00627
00628 bool Config::_needsLocalSync() const
00629 {
00630 if( _nodes.empty( ))
00631 return false;
00632
00633 EQASSERT( _nodes.size() == 1 );
00634 const Node* node = _nodes.front();
00635 switch( node->getIAttribute( Node::IATTR_THREAD_MODEL ))
00636 {
00637 case ASYNC:
00638 return false;
00639 break;
00640
00641 case DRAW_SYNC:
00642 if( !(node->getTasks() & TASK_DRAW) )
00643 return false;
00644 break;
00645
00646 case LOCAL_SYNC:
00647 if( node->getTasks() == TASK_NONE )
00648 return false;
00649 break;
00650
00651 default:
00652 EQUNIMPLEMENTED;
00653 }
00654
00655 return true;
00656 }
00657
00658 void Config::_updateStatistics( const uint32_t finishedFrame )
00659 {
00660
00661 _statisticsMutex.set();
00662 while( !_statistics.empty() &&
00663 finishedFrame - _statistics.front().first > _latency+1 )
00664
00665 _statistics.pop_front();
00666 _statisticsMutex.unset();
00667 }
00668
00669 void Config::getStatistics( std::vector< FrameStatistics >& statistics )
00670 {
00671 _statisticsMutex.set();
00672
00673 for( std::deque< FrameStatistics >::const_iterator i = _statistics.begin();
00674 i != _statistics.end(); ++i )
00675 {
00676 if( (*i).first <= _finishedFrame.get( ))
00677 statistics.push_back( *i );
00678 }
00679
00680 _statisticsMutex.unset();
00681 }
00682
00683 void Config::setWindowSystem( const WindowSystem windowSystem )
00684 {
00685
00686 static Lock _lock;
00687 ScopedMutex mutex( _lock );
00688
00689 if( _eventQueue.getWindowSystem() == WINDOW_SYSTEM_NONE )
00690 {
00691 _eventQueue.setWindowSystem( windowSystem );
00692 EQINFO << "Client event message pump set up for " << windowSystem
00693 << endl;
00694 }
00695 else if( _eventQueue.getWindowSystem() != windowSystem )
00696 EQWARN << "Can't switch to window system " << windowSystem
00697 << ", already using " << _eventQueue.getWindowSystem()
00698 << endl;
00699
00700 RefPtr< Client > client = getClient();
00701 client->setWindowSystem( windowSystem );
00702 }
00703
00704 #ifdef EQ_USE_DEPRECATED
00705 void Config::setHeadMatrix( const eq::Matrix4f& matrix )
00706 {
00707 for( ObserverVector::const_iterator i = _observers.begin();
00708 i != _observers.end(); ++i )
00709 {
00710 (*i)->setHeadMatrix( matrix );
00711 }
00712 }
00713
00714 const eq::Matrix4f& Config::getHeadMatrix() const
00715 {
00716 if( _observers.empty( ))
00717 return eq::Matrix4f::IDENTITY;
00718
00719 return _observers[0]->getHeadMatrix();
00720 }
00721
00722 void Config::setEyeBase( const float eyeBase )
00723 {
00724 for( ObserverVector::const_iterator i = _observers.begin();
00725 i != _observers.end(); ++i )
00726 {
00727 (*i)->setEyeBase( eyeBase );
00728 }
00729 }
00730
00731 float Config::getEyeBase() const
00732 {
00733 if( _observers.empty( ))
00734 return _eyeBase;
00735
00736 return _observers[0]->getEyeBase();
00737 }
00738 #endif
00739
00740 void Config::freezeLoadBalancing( const bool onOff )
00741 {
00742 ConfigFreezeLoadBalancingPacket packet;
00743 packet.freeze = onOff;
00744 send( packet );
00745 }
00746
00747 void Config::_initAppNode( const uint32_t distributorID )
00748 {
00749 ConfigDeserializer distributor( this );
00750 EQCHECK( mapObject( &distributor, distributorID ));
00751 unmapObject( &distributor );
00752 }
00753
00754
00755
00756
00757 net::CommandResult Config::_cmdCreateNode( net::Command& command )
00758 {
00759 const ConfigCreateNodePacket* packet =
00760 command.getPacket<ConfigCreateNodePacket>();
00761 EQINFO << "Handle create node " << packet << endl;
00762 EQASSERT( packet->nodeID != EQ_ID_INVALID );
00763
00764 Node* node = Global::getNodeFactory()->createNode( this );
00765 attachObject( node, packet->nodeID, EQ_ID_INVALID );
00766
00767 return net::COMMAND_HANDLED;
00768 }
00769
00770 net::CommandResult Config::_cmdDestroyNode( net::Command& command )
00771 {
00772 const ConfigDestroyNodePacket* packet =
00773 command.getPacket<ConfigDestroyNodePacket>();
00774 EQINFO << "Handle destroy node " << packet << endl;
00775
00776 Node* node = _findNode( packet->nodeID );
00777 if( !node )
00778 return net::COMMAND_HANDLED;
00779
00780 detachObject( node );
00781 Global::getNodeFactory()->releaseNode( node );
00782
00783 return net::COMMAND_HANDLED;
00784 }
00785
00786 net::CommandResult Config::_cmdInitReply( net::Command& command )
00787 {
00788 const ConfigInitReplyPacket* packet =
00789 command.getPacket<ConfigInitReplyPacket>();
00790 EQINFO << "handle init reply " << packet << endl;
00791
00792 if( !packet->result )
00793 _error = packet->error;
00794
00795 _requestHandler.serveRequest( packet->requestID, (void*)(packet->result) );
00796 return net::COMMAND_HANDLED;
00797 }
00798
00799 net::CommandResult Config::_cmdExitReply( net::Command& command )
00800 {
00801 const ConfigExitReplyPacket* packet =
00802 command.getPacket<ConfigExitReplyPacket>();
00803 EQINFO << "handle exit reply " << packet << endl;
00804
00805 _requestHandler.serveRequest( packet->requestID, (void*)(packet->result) );
00806 return net::COMMAND_HANDLED;
00807 }
00808
00809 net::CommandResult Config::_cmdReleaseFrameLocal( net::Command& command )
00810 {
00811 const ConfigReleaseFrameLocalPacket* packet =
00812 command.getPacket< ConfigReleaseFrameLocalPacket >();
00813
00814 releaseFrameLocal( packet->frameNumber );
00815 return net::COMMAND_HANDLED;
00816 }
00817
00818 net::CommandResult Config::_cmdFrameFinish( net::Command& command )
00819 {
00820 const ConfigFrameFinishPacket* packet =
00821 command.getPacket<ConfigFrameFinishPacket>();
00822 EQLOG( LOG_TASKS ) << "frame finish " << packet << endl;
00823
00824 _finishedFrame = packet->frameNumber;
00825
00826 if( _unlockedFrame < _finishedFrame.get( ))
00827 {
00828 EQWARN << "Finished frame " << _unlockedFrame
00829 << " was not locally unlocked, enforcing unlock" << endl;
00830 _unlockedFrame = _finishedFrame.get();
00831 }
00832
00833 getNodeThreadQueue()->wakeup();
00834 return net::COMMAND_HANDLED;
00835 }
00836
00837 net::CommandResult Config::_cmdSyncClock( net::Command& command )
00838 {
00839 const ConfigSyncClockPacket* packet =
00840 command.getPacket< ConfigSyncClockPacket >();
00841
00842 EQVERB << "sync global clock to " << packet->time << ", drift "
00843 << packet->time - _clock.getTime64() << std::endl;
00844
00845 _clock.set( packet->time );
00846 return net::COMMAND_HANDLED;
00847 }
00848
00849 net::CommandResult Config::_cmdUnmap( net::Command& command )
00850 {
00851 const ConfigUnmapPacket* packet = command.getPacket< ConfigUnmapPacket >();
00852 EQVERB << "Handle unmap " << packet << endl;
00853
00854 NodeFactory* nodeFactory = Global::getNodeFactory();
00855
00856 for( CanvasVector::const_iterator i = _canvases.begin();
00857 i != _canvases.end(); ++i )
00858 {
00859 Canvas* canvas = *i;
00860 canvas->deregister();
00861 canvas->_config = 0;
00862 nodeFactory->releaseCanvas( canvas );
00863 }
00864 _canvases.clear();
00865
00866 for( LayoutVector::const_iterator i = _layouts.begin();
00867 i != _layouts.end(); ++i )
00868 {
00869 Layout* layout = *i;
00870 layout->deregister();
00871 layout->_config = 0;
00872 nodeFactory->releaseLayout( layout );
00873 }
00874 _layouts.clear();
00875
00876 for( ObserverVector::const_iterator i = _observers.begin();
00877 i != _observers.end(); ++i )
00878 {
00879 Observer* observer = *i;
00880 observer->deregister();
00881 observer->_config = 0;
00882 nodeFactory->releaseObserver( observer );
00883 }
00884 _observers.clear();
00885
00886 ConfigUnmapReplyPacket reply( packet );
00887 send( command.getNode(), reply );
00888
00889 return net::COMMAND_HANDLED;
00890 }
00891
00892 }