lib/client/config.cpp

00001 
00002 /* Copyright (c) 2005-2009, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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( )) /* flush all pending events */ ;
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( )) /* flush all pending events */ ;
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     // Request new frame
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         // local draw sync
00438         if( needsLocalSync )
00439             while( _unlockedFrame < _currentFrame )
00440                 client->processCommand();
00441 
00442         // local node  finish (frame-latency) sync
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         // global sync
00453         _finishedFrame.waitGE( frameToFinish );
00454 
00455         // handle directly, it would not be processed in time using the normal
00456         // event flow
00457         waitStat.event.data.statistic.frameNumber = frameToFinish;
00458         waitStat.event.data.statistic.endTime     = getTime();
00459         handleEvent( &waitStat.event );
00460         waitStat.ignore = true; // don't send again
00461     }
00462 
00463     handleEvents();
00464     
00465     // handle directly - see above
00466     stat.event.data.statistic.frameNumber = frameToFinish;
00467     stat.event.data.statistic.endTime     = getTime();
00468     handleEvent( &stat.event );
00469     stat.ignore = true; // don't send again
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 ||      // Not a frame-related stat event or
00584                 statistic.type == Statistic::NONE ) // No event-type set
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     // keep statistics for latency+2 frames
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     // called from pipe threads - but only during init
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 ); // data was retrieved, unmap
00752 }
00753 
00754 //---------------------------------------------------------------------------
00755 // command handlers
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 }
Generated on Mon Aug 10 18:58:32 2009 for Equalizer 0.9 by  doxygen 1.5.8