LCOV - code coverage report
Current view: top level - eq/fabric - config.ipp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 369 475 77.7 %
Date: 2014-06-18 Functions: 81 294 27.6 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2013, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                    2010, Cedric Stalder <cedric Stalder@gmail.com>
       4             :  *               2011-2012, Daniel Nachbaur <danielnachbaur@gmail.com>
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify it under
       7             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       8             :  * by the Free Software Foundation.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      12             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      17             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             :  */
      19             : 
      20             : #include "config.h"
      21             : 
      22             : #include "paths.h"
      23             : 
      24             : #include "configVisitor.h"
      25             : 
      26             : #include <co/global.h>
      27             : #include <co/objectICommand.h>
      28             : 
      29             : #include "layout.ipp" // Layout::_removeObserver template impl
      30             : 
      31             : namespace eq
      32             : {
      33             : namespace fabric
      34             : {
      35             : 
      36             : #define MAKE_ATTR_STRING( attr ) ( std::string("EQ_CONFIG_") + #attr )
      37             : 
      38             : namespace
      39             : {
      40          42 : std::string _fAttributeStrings[] =
      41             : {
      42             :     MAKE_ATTR_STRING( FATTR_EYE_BASE ),
      43             :     MAKE_ATTR_STRING( FATTR_VERSION ),
      44          21 : };
      45          42 : std::string _iAttributeStrings[] =
      46             : {
      47             :     MAKE_ATTR_STRING( IATTR_ROBUSTNESS ),
      48          21 : };
      49             : }
      50             : 
      51             : template< class S, class C, class O, class L, class CV, class N, class V >
      52         235 : Config< S, C, O, L, CV, N, V >::Config( lunchbox::RefPtr< S > server )
      53             :         : Object()
      54         235 :         , _server( server )
      55             : {
      56         235 :     server->_addConfig( static_cast< C* >( this ));
      57         235 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      58         235 : }
      59             : 
      60             : template< class S, class C, class O, class L, class CV, class N, class V >
      61         224 : Config< S, C, O, L, CV, N, V >::~Config()
      62             : {
      63         224 :     LBLOG( LOG_INIT ) << "Delete " << lunchbox::className( this ) << std::endl;
      64         224 :     _appNodeID = 0;
      65             : 
      66         670 :     while( !_canvases.empty( ))
      67             :     {
      68         222 :         CV* canvas = _canvases.back();
      69         222 :         _removeCanvas( canvas );
      70         222 :         delete canvas;
      71             :     }
      72             : 
      73         827 :     while( !_layouts.empty( ))
      74             :     {
      75         379 :         L* layout = _layouts.back();
      76         379 :         _removeLayout( layout );
      77         379 :         delete layout;
      78             :     }
      79             : 
      80         664 :     while( !_observers.empty( ))
      81             :     {
      82         216 :         O* observer = _observers.back();
      83         216 :         _removeObserver( observer );
      84         216 :         delete observer;
      85             :     }
      86             : 
      87         885 :     while( !_nodes.empty( ))
      88             :     {
      89         437 :         N* node = _nodes.back();
      90         437 :         _removeNode( node );
      91         437 :         delete node;
      92             :     }
      93             : 
      94         224 :     _server->_removeConfig( static_cast< C* >( this ));
      95         224 :     _server = 0;
      96             : 
      97         448 : }
      98             : 
      99             : template< class S, class C, class O, class L, class CV, class N, class V >
     100          20 : void Config< S, C, O, L, CV, N, V >::attach( const uint128_t& id,
     101             :                                              const uint32_t instanceID )
     102             : {
     103          20 :     Object::attach( id, instanceID );
     104             : 
     105          20 :     co::CommandQueue* queue = _server->getMainThreadQueue();
     106          20 :     LBASSERT( queue );
     107             : 
     108          20 :     registerCommand( CMD_CONFIG_NEW_LAYOUT,
     109             :                 CmdFunc( this, &Config< S, C, O, L, CV, N, V >::_cmdNewLayout ),
     110             :                      queue );
     111          20 :     registerCommand( CMD_CONFIG_NEW_CANVAS,
     112             :                 CmdFunc( this, &Config< S, C, O, L, CV, N, V >::_cmdNewCanvas ),
     113             :                      queue);
     114          20 :     registerCommand( CMD_CONFIG_NEW_OBSERVER,
     115             :               CmdFunc( this, &Config< S, C, O, L, CV, N, V >::_cmdNewObserver ),
     116             :                      queue);
     117          20 :     registerCommand( CMD_CONFIG_NEW_ENTITY_REPLY,
     118             :            CmdFunc( this, &Config< S, C, O, L, CV, N, V >::_cmdNewEntityReply ),
     119             :                      0);
     120          20 : }
     121             : 
     122             : template< class C, class V >
     123        6957 : VisitorResult _acceptImpl( C* config, V& visitor )
     124             : {
     125        6957 :     VisitorResult result = visitor.visitPre( config );
     126        6957 :     if( result != TRAVERSE_CONTINUE )
     127         317 :         return result;
     128             : 
     129        6640 :     const typename C::Nodes& nodes = config->getNodes();
     130       47817 :     for( typename C::Nodes::const_iterator i = nodes.begin();
     131       31878 :          i != nodes.end(); ++i )
     132             :     {
     133       12227 :         switch( (*i)->accept( visitor ))
     134             :         {
     135             :             case TRAVERSE_TERMINATE:
     136        2928 :                 return TRAVERSE_TERMINATE;
     137             : 
     138             :             case TRAVERSE_PRUNE:
     139         251 :                 result = TRAVERSE_PRUNE;
     140         251 :                 break;
     141             : 
     142             :             case TRAVERSE_CONTINUE:
     143             :             default:
     144        9048 :                 break;
     145             :         }
     146             :     }
     147             : 
     148        3712 :     const typename C::Observers& observers = config->getObservers();
     149       20724 :     for( typename C::Observers::const_iterator i = observers.begin();
     150       13816 :          i != observers.end(); ++i )
     151             :     {
     152        3727 :         switch( (*i)->accept( visitor ))
     153             :         {
     154             :             case TRAVERSE_TERMINATE:
     155         531 :                 return TRAVERSE_TERMINATE;
     156             : 
     157             :             case TRAVERSE_PRUNE:
     158           0 :                 result = TRAVERSE_PRUNE;
     159           0 :                 break;
     160             : 
     161             :             case TRAVERSE_CONTINUE:
     162             :             default:
     163        3196 :                 break;
     164             :         }
     165             :     }
     166             : 
     167        3181 :     const typename C::Layouts& layouts = config->getLayouts();
     168       50931 :     for( typename C::Layouts::const_iterator i = layouts.begin();
     169       33954 :          i != layouts.end(); ++i )
     170             :     {
     171       14880 :         switch( (*i)->accept( visitor ))
     172             :         {
     173             :             case TRAVERSE_TERMINATE:
     174        1084 :                 return TRAVERSE_TERMINATE;
     175             : 
     176             :             case TRAVERSE_PRUNE:
     177           0 :                 result = TRAVERSE_PRUNE;
     178           0 :                 break;
     179             : 
     180             :             case TRAVERSE_CONTINUE:
     181             :             default:
     182       13796 :                 break;
     183             :         }
     184             :     }
     185             : 
     186        2097 :     const typename C::Canvases& canvases = config->getCanvases();
     187       11592 :     for( typename C::Canvases::const_iterator i = canvases.begin();
     188        7728 :          i != canvases.end(); ++i )
     189             :     {
     190        1783 :         switch( (*i)->accept( visitor ))
     191             :         {
     192             :             case TRAVERSE_TERMINATE:
     193          16 :                 return TRAVERSE_TERMINATE;
     194             : 
     195             :             case TRAVERSE_PRUNE:
     196           0 :                 result = TRAVERSE_PRUNE;
     197           0 :                 break;
     198             : 
     199             :             case TRAVERSE_CONTINUE:
     200             :             default:
     201        1767 :                 break;
     202             :         }
     203             :     }
     204             : 
     205        2081 :     switch( config->_acceptCompounds( visitor ))
     206             :     {
     207             :         case TRAVERSE_TERMINATE:
     208         213 :             return TRAVERSE_TERMINATE;
     209             : 
     210             :         case TRAVERSE_PRUNE:
     211         394 :             result = TRAVERSE_PRUNE;
     212         394 :             break;
     213             : 
     214             :         case TRAVERSE_CONTINUE:
     215             :         default:
     216        1474 :             break;
     217             :     }
     218             : 
     219        1868 :     switch( visitor.visitPost( config ))
     220             :     {
     221             :         case TRAVERSE_TERMINATE:
     222           0 :             return TRAVERSE_TERMINATE;
     223             : 
     224             :         case TRAVERSE_PRUNE:
     225           0 :             result = TRAVERSE_PRUNE;
     226           0 :             break;
     227             : 
     228             :         case TRAVERSE_CONTINUE:
     229             :         default:
     230        1868 :             break;
     231             :     }
     232             : 
     233        1868 :     return result;
     234             : }
     235             : 
     236             : template< class S, class C, class O, class L, class CV, class N, class V >
     237        4910 : VisitorResult Config< S, C, O, L, CV, N, V >::accept( V& visitor )
     238             : {
     239        4910 :     return _acceptImpl( static_cast< C* >( this ), visitor );
     240             : }
     241             : 
     242             : template< class S, class C, class O, class L, class CV, class N, class V >
     243        2047 : VisitorResult Config< S, C, O, L, CV, N, V >::accept( V& visitor ) const
     244             : {
     245        2047 :     return _acceptImpl( static_cast< const C* >( this ), visitor );
     246             : }
     247             : 
     248             : template< class S, class C, class O, class L, class CV, class N, class V >
     249       21745 : lunchbox::RefPtr< S > Config< S, C, O, L, CV, N, V >::getServer()
     250             : {
     251       21745 :     return _server;
     252             : }
     253             : 
     254             : template< class S, class C, class O, class L, class CV, class N, class V >
     255         122 : lunchbox::RefPtr< const S > Config< S, C, O, L, CV, N, V >::getServer() const
     256             : {
     257         122 :     return _server;
     258             : }
     259             : 
     260             : namespace
     261             : {
     262             : template< typename T, typename V > class IDFinder : public V
     263             : {
     264             : public:
     265         136 :     IDFinder( const uint128_t& id ) : _id( id ), _result( 0 ) {}
     266         136 :     virtual ~IDFinder(){}
     267             : 
     268         266 :     virtual VisitorResult visitPre( T* node ) { return visit( node ); }
     269         329 :     virtual VisitorResult visit( T* node )
     270             :         {
     271         329 :             if( node->getID() == _id )
     272             :             {
     273         126 :                 _result = node;
     274         126 :                 return TRAVERSE_TERMINATE;
     275             :             }
     276         203 :             return TRAVERSE_CONTINUE;
     277             :         }
     278             : 
     279         136 :     T* getResult() { return _result; }
     280             : 
     281             : private:
     282             :     const uint128_t _id;
     283             :     T*              _result;
     284             : };
     285             : }
     286             : 
     287             : 
     288             : template< class S, class C, class O, class L, class CV, class N, class V >
     289             : template< typename T >
     290         136 : void Config< S, C, O, L, CV, N, V >::find( const uint128_t& id, T** result )
     291             : {
     292         136 :     IDFinder< T, V > finder( id );
     293         136 :     static_cast< C* >( this )->accept( finder );
     294         136 :     *result = finder.getResult();
     295         136 : }
     296             : 
     297             : template< class S, class C, class O, class L, class CV, class N, class V >
     298             : template< typename T >
     299         577 : void Config< S, C, O, L, CV, N, V >::find( const std::string& name,
     300             :                                            const T** result ) const
     301             : {
     302         577 :     NameFinder< T, V > finder( name );
     303         577 :     static_cast< const C* >( this )->accept( finder );
     304         577 :     *result = finder.getResult();
     305         577 : }
     306             : 
     307             : template< class S, class C, class O, class L, class CV, class N, class V >
     308             : template< typename T >
     309           0 : T* Config< S, C, O, L, CV, N, V >::find( const uint128_t& id )
     310             : {
     311           0 :     IDFinder< T, V > finder( id );
     312           0 :     static_cast< C* >( this )->accept( finder );
     313           0 :     return finder.getResult();
     314             : }
     315             : 
     316             : template< class S, class C, class O, class L, class CV, class N, class V >
     317             : template< typename T >
     318           0 : const T* Config< S, C, O, L, CV, N, V >::find( const uint128_t& id ) const
     319             : {
     320           0 :     IDFinder< const T, V > finder( id );
     321           0 :     static_cast< const C* >( this )->accept( finder );
     322           0 :     return finder.getResult();
     323             : }
     324             : 
     325             : template< class S, class C, class O, class L, class CV, class N, class V >
     326             : template< typename T >
     327        1870 : T* Config< S, C, O, L, CV, N, V >::find( const std::string& name )
     328             : {
     329        1870 :     NameFinder< T, V > finder( name );
     330        1870 :     static_cast< C* >( this )->accept( finder );
     331        1870 :     return finder.getResult();
     332             : }
     333             : 
     334             : template< class S, class C, class O, class L, class CV, class N, class V >
     335             : template< typename T >
     336        1470 : const T* Config< S, C, O, L, CV, N, V >::find( const std::string& name ) const
     337             : {
     338        1470 :     NameFinder< const T, V > finder( name );
     339        1470 :     static_cast< const C* >( this )->accept( finder );
     340        1470 :     return finder.getResult();
     341             : }
     342             : 
     343             : 
     344             : template< class S, class C, class O, class L, class CV, class N, class V >
     345         153 : O* Config< S, C, O, L, CV, N, V >::getObserver( const ObserverPath& path )
     346             : {
     347         153 :     LBASSERTINFO( _observers.size() > path.observerIndex,
     348             :                   _observers.size() << " <= " << path.observerIndex );
     349             : 
     350         153 :     if( _observers.size() <= path.observerIndex )
     351           0 :         return 0;
     352             : 
     353         153 :     return _observers[ path.observerIndex ];
     354             : }
     355             : 
     356             : template< class S, class C, class O, class L, class CV, class N, class V >
     357         712 : const std::string& Config< S, C, O, L, CV, N, V >::getFAttributeString(
     358             :     const FAttribute attr )
     359             : {
     360         712 :     return _fAttributeStrings[ attr ];
     361             : }
     362             : 
     363             : template< class S, class C, class O, class L, class CV, class N, class V >
     364         360 : const std::string& Config< S, C, O, L, CV, N, V >::getIAttributeString(
     365             :     const IAttribute attr )
     366             : {
     367         360 :     return _iAttributeStrings[ attr ];
     368             : }
     369             : 
     370             : template< class S, class C, class O, class L, class CV, class N, class V >
     371           9 : uint32_t Config< S, C, O, L, CV, N, V >::getTimeout() const
     372             : {
     373           9 :     if( getIAttribute( IATTR_ROBUSTNESS ) == OFF )
     374           3 :         return LB_TIMEOUT_INDEFINITE;
     375           6 :     return co::Global::getIAttribute( co::Global::IATTR_TIMEOUT_DEFAULT );
     376             : }
     377             : 
     378             : template< class S, class C, class O, class L, class CV, class N, class V >
     379         863 : L* Config< S, C, O, L, CV, N, V >::getLayout( const LayoutPath& path )
     380             : {
     381         863 :     LBASSERTINFO( _layouts.size() > path.layoutIndex,
     382             :                   _layouts.size() << " <= " << path.layoutIndex );
     383             : 
     384         863 :     if( _layouts.size() <= path.layoutIndex )
     385           0 :         return 0;
     386             : 
     387         863 :     return _layouts[ path.layoutIndex ];
     388             : }
     389             : 
     390             : template< class S, class C, class O, class L, class CV, class N, class V >
     391        1001 : CV* Config< S, C, O, L, CV, N, V >::getCanvas( const CanvasPath& path )
     392             : {
     393        1001 :     LBASSERTINFO( _canvases.size() > path.canvasIndex,
     394             :                   _canvases.size() << " <= " << path.canvasIndex );
     395             : 
     396        1001 :     if( _canvases.size() <= path.canvasIndex )
     397           0 :         return 0;
     398             : 
     399        1001 :     return _canvases[ path.canvasIndex ];
     400             : }
     401             : 
     402             : template< class S, class C, class O, class L, class CV, class N, class V >
     403         227 : void Config< S, C, O, L, CV, N, V >::_addObserver( O* observer )
     404             : {
     405         227 :     LBASSERT( observer->getConfig() == this );
     406         227 :     _observers.push_back( observer );
     407         227 :     setDirty( DIRTY_OBSERVERS );
     408         227 : }
     409             : 
     410             : template< class S, class C, class O, class L, class CV, class N, class V >
     411         452 : bool Config< S, C, O, L, CV, N, V >::_removeObserver( O* observer )
     412             : {
     413             :     typename Observers::iterator i = std::find( _observers.begin(),
     414         452 :                                                 _observers.end(), observer );
     415         452 :     if( i == _observers.end( ))
     416         226 :         return false;
     417             : 
     418             :     // remove from views
     419         678 :     for( typename Layouts::const_iterator j = _layouts.begin();
     420         452 :          j != _layouts.end(); ++j )
     421             :     {
     422           0 :         (*j)->_removeObserver( observer );
     423             :     }
     424             : 
     425         226 :     LBASSERT( observer->getConfig() == this );
     426         226 :     _observers.erase( i );
     427         226 :     setDirty( DIRTY_OBSERVERS );
     428         226 :     if( !isMaster( ))
     429         226 :         postRemove( observer );
     430         226 :     return true;
     431             : }
     432             : 
     433             : template< class S, class C, class O, class L, class CV, class N, class V >
     434         443 : void Config< S, C, O, L, CV, N, V >::_addLayout( L* layout )
     435             : {
     436         443 :     LBASSERT( layout->getConfig() == this );
     437         443 :     _layouts.push_back( layout );
     438         443 :     setDirty( DIRTY_LAYOUTS );
     439         443 : }
     440             : 
     441             : template< class S, class C, class O, class L, class CV, class N, class V >
     442         884 : bool Config< S, C, O, L, CV, N, V >::_removeLayout( L* layout )
     443             : {
     444             :     typename Layouts::iterator i = std::find( _layouts.begin(),
     445         884 :                                               _layouts.end(), layout );
     446         884 :     if( i == _layouts.end( ))
     447         442 :         return false;
     448             : 
     449             :     // remove from canvases
     450        1326 :     for( typename Canvases::const_iterator j = _canvases.begin();
     451         884 :          j != _canvases.end(); ++j )
     452             :     {
     453           0 :         (*j)->removeLayout( layout );
     454             :     }
     455             : 
     456         442 :     LBASSERT( layout->getConfig() == this );
     457         442 :     _layouts.erase( i );
     458         442 :     setDirty( DIRTY_LAYOUTS );
     459         442 :     if( !isMaster( ))
     460         442 :         postRemove( layout );
     461         442 :     return true;
     462             : }
     463             : 
     464             : template< class S, class C, class O, class L, class CV, class N, class V >
     465         233 : void Config< S, C, O, L, CV, N, V >::_addCanvas( CV* canvas )
     466             : {
     467         233 :     LBASSERT( canvas->getConfig() == this );
     468         233 :     _canvases.push_back( canvas );
     469         233 :     setDirty( DIRTY_CANVASES );
     470         233 : }
     471             : 
     472             : template< class S, class C, class O, class L, class CV, class N, class V >
     473          10 : void Config< S, C, O, L, CV, N, V >::create( O** observer )
     474             : {
     475          10 :     *observer = getServer()->getNodeFactory()->createObserver(
     476             :         static_cast< C* >( this ));
     477          10 : }
     478             : 
     479             : template< class S, class C, class O, class L, class CV, class N, class V >
     480           0 : void Config< S, C, O, L, CV, N, V >::release( O* observer )
     481             : {
     482           0 :     getServer()->getNodeFactory()->releaseObserver( observer );
     483           0 : }
     484             : 
     485             : template< class S, class C, class O, class L, class CV, class N, class V >
     486          63 : void Config< S, C, O, L, CV, N, V >::create( L** layout )
     487             : {
     488          63 :     *layout = getServer()->getNodeFactory()->createLayout(
     489             :         static_cast< C* >( this ));
     490          63 : }
     491             : 
     492             : template< class S, class C, class O, class L, class CV, class N, class V >
     493           0 : void Config< S, C, O, L, CV, N, V >::release( L* layout )
     494             : {
     495           0 :     getServer()->getNodeFactory()->releaseLayout( layout );
     496           0 : }
     497             : 
     498             : template< class S, class C, class O, class L, class CV, class N, class V >
     499          10 : void Config< S, C, O, L, CV, N, V >::create( CV** canvas )
     500             : {
     501          10 :     *canvas = getServer()->getNodeFactory()->createCanvas(
     502             :         static_cast< C* >( this ));
     503          10 : }
     504             : 
     505             : template< class S, class C, class O, class L, class CV, class N, class V >
     506           0 : void Config< S, C, O, L, CV, N, V >::release( CV* canvas )
     507             : {
     508           0 :     getServer()->getNodeFactory()->releaseCanvas( canvas );
     509           0 : }
     510             : 
     511             : template< class S, class C, class O, class L, class CV, class N, class V >
     512           0 : void Config< S, C, O, L, CV, N, V >::create( N** node )
     513             : {
     514           0 :     *node = getServer()->getNodeFactory()->createNode(
     515             :         static_cast< C* >( this ));
     516           0 : }
     517             : 
     518             : template< class S, class C, class O, class L, class CV, class N, class V >
     519           0 : void Config< S, C, O, L, CV, N, V >::release( N* node )
     520             : {
     521           0 :      getServer()->getNodeFactory()->releaseNode( node );
     522           0 : }
     523             : 
     524             : template< class S, class C, class O, class L, class CV, class N, class V >
     525         464 : bool Config< S, C, O, L, CV, N, V >::_removeCanvas( CV* canvas )
     526             : {
     527             :     typename Canvases::iterator i = std::find( _canvases.begin(),
     528         464 :                                                _canvases.end(), canvas );
     529         464 :     if( i == _canvases.end( ))
     530         232 :         return false;
     531             : 
     532         232 :     LBASSERT( canvas->getConfig() == this );
     533         232 :     _canvases.erase( i );
     534         232 :     setDirty( DIRTY_CANVASES );
     535         232 :     if( !isMaster( ))
     536         232 :         postRemove( canvas );
     537         232 :     return true;
     538             : }
     539             : 
     540             : template< class S, class C, class O, class L, class CV, class N, class V >
     541          19 : void Config< S, C, O, L, CV, N, V >::setLatency( const uint32_t latency )
     542             : {
     543          19 :     if( _data.latency == latency )
     544          20 :         return;
     545             : 
     546          18 :     _data.latency = latency;
     547          18 :     setDirty( DIRTY_LATENCY );
     548             : }
     549             : 
     550             : template< class S, class C, class O, class L, class CV, class N, class V >
     551          12 : void Config< S, C, O, L, CV, N, V >::setAppNodeID( const co::NodeID& nodeID )
     552             : {
     553          12 :     if( _appNodeID == nodeID )
     554          12 :         return;
     555             : 
     556          12 :     _appNodeID = nodeID;
     557          12 :     setDirty( DIRTY_MEMBER );
     558             : }
     559             : 
     560             : template< class S, class C, class O, class L, class CV, class N, class V >
     561           6 : EventOCommand Config< S, C, O, L, CV, N, V >::sendError( co::NodePtr node,
     562             :     const uint32_t event, const uint128_t& originator, const uint32_t error )
     563             : {
     564          18 :     LBWARN << "Emit " << Error( error ) << " at "
     565          24 :            << lunchbox::backtrace( 2 /*cut boring stack frames*/ ) << std::endl;
     566           6 :     EventOCommand cmd( send( node, CMD_CONFIG_EVENT ));
     567           6 :     cmd << event << originator << error;
     568           6 :     return cmd;
     569             : }
     570             : 
     571             : template< class S, class C, class O, class L, class CV, class N, class V >
     572           2 : void Config< S, C, O, L, CV, N, V >::restore()
     573             : {
     574           2 :     Object::restore();
     575           2 :     if( _data.latency != _backup.latency )
     576             :     {
     577           0 :         _data = _backup;
     578           0 :         changeLatency( _data.latency );
     579             :     }
     580             :     else
     581           2 :         _data = _backup;
     582           2 :     setDirty( DIRTY_MEMBER | DIRTY_LATENCY );
     583           2 : }
     584             : 
     585             : template< class S, class C, class O, class L, class CV, class N, class V >
     586         476 : void Config< S, C, O, L, CV, N, V >::_addNode( N* node )
     587             : {
     588         476 :     LBASSERT( node->getConfig() == this );
     589         476 :     _nodes.push_back( node );
     590         476 : }
     591             : 
     592             : template< class S, class C, class O, class L, class CV, class N, class V >
     593         882 : bool Config< S, C, O, L, CV, N, V >::_removeNode( N* node )
     594             : {
     595             :     typename Nodes::iterator i = std::find( _nodes.begin(),
     596         882 :                                             _nodes.end(), node );
     597         882 :     if( i == _nodes.end( ))
     598         437 :         return false;
     599             : 
     600         445 :     LBASSERT( node->getConfig() == this );
     601         445 :     _nodes.erase( i );
     602         445 :     return true;
     603             : }
     604             : 
     605             : template< class S, class C, class O, class L, class CV, class N, class V >
     606          24 : N* Config< S, C, O, L, CV, N, V >::findAppNode()
     607             : {
     608          72 :     for( typename Nodes::const_iterator i = _nodes.begin();
     609          48 :          i != _nodes.end(); ++i )
     610             :     {
     611          24 :         N* node = *i;
     612          24 :         if( node->isApplicationNode( ))
     613          24 :             return node;
     614             :     }
     615           0 :     return 0;
     616             : }
     617             : 
     618             : template< class S, class C, class O, class L, class CV, class N, class V >
     619           0 : const N* Config< S, C, O, L, CV, N, V >::findAppNode() const
     620             : {
     621           0 :     for( typename Nodes::const_iterator i = _nodes.begin();
     622           0 :          i != _nodes.end(); ++i )
     623             :     {
     624           0 :         const N* node = *i;
     625           0 :         if( node->isApplicationNode( ))
     626           0 :             return node;
     627             :     }
     628           0 :     return 0;
     629             : }
     630             : 
     631             : template< class S, class C, class O, class L, class CV, class N, class V >
     632           8 : N* Config< S, C, O, L, CV, N, V >::_findNode( const uint128_t& id )
     633             : {
     634          24 :     for( typename Nodes::const_iterator i = _nodes.begin();
     635          16 :          i != _nodes.end(); ++i )
     636             :     {
     637           8 :         N* node = *i;
     638           8 :         if( node->getID() == id )
     639           8 :             return node;
     640             :     }
     641           0 :     return 0;
     642             : }
     643             : 
     644             : template< class S, class C, class O, class L, class CV, class N, class V >
     645        9200 : uint128_t Config< S, C, O, L, CV, N, V >::commit( const uint32_t incarnation )
     646             : {
     647        9200 :     if( Serializable::isDirty( DIRTY_NODES ))
     648          21 :         commitChildren< N >( _nodes, incarnation );
     649        9200 :     if( Serializable::isDirty( DIRTY_OBSERVERS ))
     650          18 :         commitChildren< O, C >( _observers, static_cast< C* >( this ),
     651          18 :                                 CMD_CONFIG_NEW_OBSERVER, incarnation );
     652             : 
     653             :     // Always traverse layouts and canvases: view/segment objects may be dirty
     654        9200 :     commitChildren< L, C >( _layouts, static_cast<C*>( this ),
     655        9200 :                             CMD_CONFIG_NEW_LAYOUT, incarnation );
     656        9200 :     commitChildren< CV, C >( _canvases, static_cast<C*>( this ),
     657        9200 :                             CMD_CONFIG_NEW_CANVAS, incarnation );
     658             : 
     659        9200 :     if( Serializable::isDirty( DIRTY_CANVASES ))
     660          19 :         commitChildren< CV, C >( _canvases, static_cast< C* >( this ),
     661          19 :                                  CMD_CONFIG_NEW_CANVAS, incarnation );
     662        9200 :     return Object::commit( incarnation );
     663             : }
     664             : 
     665             : template< class S, class C, class O, class L, class CV, class N, class V >
     666          69 : void Config< S, C, O, L, CV, N, V >::serialize( co::DataOStream& os,
     667             :                                                 const uint64_t dirtyBits )
     668             : {
     669          69 :     Object::serialize( os, dirtyBits );
     670             : 
     671          69 :     if( dirtyBits & Config::DIRTY_MEMBER )
     672          41 :         os << _appNodeID;
     673          69 :     if( dirtyBits & Config::DIRTY_ATTRIBUTES )
     674          41 :         os << co::Array< float >( _fAttributes, C::FATTR_ALL )
     675          82 :            << co::Array< int32_t >( _iAttributes, C::IATTR_ALL );
     676          69 :     if( isMaster( ) )
     677             :     {
     678          60 :         if( dirtyBits & Config::DIRTY_NODES )
     679          60 :             os.serializeChildren( _nodes );
     680          60 :         if( dirtyBits & Config::DIRTY_OBSERVERS )
     681          49 :             os.serializeChildren( _observers );
     682          60 :         if( dirtyBits & Config::DIRTY_LAYOUTS )
     683          57 :             os.serializeChildren( _layouts );
     684          60 :         if( dirtyBits & Config::DIRTY_CANVASES )
     685          50 :             os.serializeChildren( _canvases );
     686             :     }
     687          69 :     if( dirtyBits & Config::DIRTY_LATENCY )
     688          41 :         os << _data.latency;
     689          69 : }
     690             : 
     691             : template< class S, class C, class O, class L, class CV, class N, class V >
     692          38 : void Config< S, C, O, L, CV, N, V >::deserialize( co::DataIStream& is,
     693             :                                                   const uint64_t dirtyBits )
     694             : {
     695          38 :     Object::deserialize( is, dirtyBits );
     696             : 
     697          38 :     if( dirtyBits & Config::DIRTY_MEMBER )
     698          10 :         is >> _appNodeID;
     699          38 :     if( dirtyBits & Config::DIRTY_ATTRIBUTES )
     700          10 :         is >> co::Array< float >( _fAttributes, C::FATTR_ALL )
     701          20 :            >> co::Array< int32_t >( _iAttributes, C::IATTR_ALL );
     702          38 :     if( isMaster( ))
     703             :     {
     704           9 :         if( dirtyBits & Config::DIRTY_NODES )
     705           0 :             syncChildren( _nodes );
     706           9 :         if( dirtyBits & Config::DIRTY_OBSERVERS )
     707           8 :             syncChildren( _observers );
     708           9 :         if( dirtyBits & Config::DIRTY_LAYOUTS )
     709           9 :             syncChildren( _layouts );
     710           9 :         if( dirtyBits & Config::DIRTY_CANVASES )
     711           8 :             syncChildren( _canvases );
     712             :     }
     713             :     else
     714             :     {
     715          29 :         if( dirtyBits & Config::DIRTY_NODES )
     716             :         {
     717          29 :             if( mapNodeObjects( ))
     718             :             {
     719           0 :                 typename C::Nodes result;
     720           0 :                 is.deserializeChildren( this, _nodes, result );
     721           0 :                 _nodes.swap( result );
     722           0 :                 LBASSERT( _nodes.size() == result.size( ));
     723             :             }
     724             :             else // consume unused ObjectVersions
     725             :             {
     726          29 :                 co::ObjectVersions childIDs;
     727          29 :                 is >> childIDs;
     728             :             }
     729             :         }
     730             : 
     731          29 :         if( mapViewObjects( )) // depends on _config._appNodeID !
     732             :         {
     733          29 :             if( dirtyBits & Config::DIRTY_OBSERVERS )
     734             :             {
     735          18 :                 typename C::Observers result;
     736          18 :                 is.deserializeChildren( this, _observers, result );
     737          18 :                 _observers.swap( result );
     738          18 :                 LBASSERT( _observers.size() == result.size( ));
     739             :             }
     740          29 :             if( dirtyBits & Config::DIRTY_LAYOUTS )
     741             :             {
     742          26 :                 typename C::Layouts result;
     743          26 :                 is.deserializeChildren( this, _layouts, result );
     744          26 :                 _layouts.swap( result );
     745          26 :                 LBASSERT( _layouts.size() == result.size( ));
     746             :             }
     747          29 :             if( dirtyBits & Config::DIRTY_CANVASES )
     748             :             {
     749          19 :                 typename C::Canvases result;
     750          19 :                 is.deserializeChildren( this, _canvases, result );
     751          19 :                 _canvases.swap( result );
     752          19 :                 LBASSERT( _canvases.size() == result.size( ));
     753             :             }
     754             :         }
     755             :         else // consume unused ObjectVersions
     756             :         {
     757           0 :             co::ObjectVersions childIDs;
     758           0 :             if( dirtyBits & Config::DIRTY_OBSERVERS )
     759           0 :                 is >> childIDs;
     760           0 :             if( dirtyBits & Config::DIRTY_LAYOUTS )
     761           0 :                 is >> childIDs;
     762           0 :             if( dirtyBits & Config::DIRTY_CANVASES )
     763           0 :                 is >> childIDs;
     764             :         }
     765             :     }
     766             : 
     767          38 :     if( dirtyBits & Config::DIRTY_LATENCY )
     768             :     {
     769          10 :         uint32_t latency = 0;
     770          10 :         is >> latency;
     771          10 :         if( _data.latency != latency )
     772             :         {
     773           0 :             _data.latency = latency;
     774           0 :             changeLatency( latency );
     775             :         }
     776             :     }
     777          38 : }
     778             : 
     779             : template< class S, class C, class O, class L, class CV, class N, class V >
     780          20 : void Config< S, C, O, L, CV, N, V >::notifyDetach()
     781             : {
     782          20 :     Object::notifyDetach();
     783          20 :     if( isMaster( ))
     784          30 :         return;
     785             : 
     786          10 :     typename S::NodeFactory* nodeFactory = getServer()->getNodeFactory();
     787             : 
     788          10 :     co::LocalNodePtr localNode = getLocalNode();
     789          20 :     while( !_nodes.empty( ))
     790             :     {
     791           0 :         LBASSERT( mapNodeObjects( ));
     792           0 :         N* node = _nodes.back();
     793           0 :         localNode->unmapObject( node );
     794           0 :         _removeNode( node );
     795           0 :         nodeFactory->releaseNode( node );
     796             :     }
     797             : 
     798          30 :     while( !_canvases.empty( ))
     799             :     {
     800          10 :         LBASSERT( mapViewObjects( ));
     801          10 :         CV* canvas = _canvases.back();
     802          10 :         localNode->unmapObject( canvas );
     803          10 :         _removeCanvas( canvas );
     804          10 :         nodeFactory->releaseCanvas( canvas );
     805             :     }
     806             : 
     807          83 :     while( !_layouts.empty( ))
     808             :     {
     809          63 :         LBASSERT( mapViewObjects( ));
     810          63 :         L* layout = _layouts.back();
     811          63 :         localNode->unmapObject( layout );
     812          63 :         _removeLayout( layout );
     813          63 :         nodeFactory->releaseLayout( layout );
     814             :     }
     815             : 
     816          30 :     while( !_observers.empty( ))
     817             :     {
     818          10 :         LBASSERT( mapViewObjects( ));
     819          10 :         O* observer = _observers.back();
     820          10 :         localNode->unmapObject( observer );
     821          10 :         _removeObserver( observer );
     822          10 :         nodeFactory->releaseObserver( observer );
     823          10 :     }
     824             : }
     825             : 
     826             : //----------------------------------------------------------------------
     827             : // ICommand handlers
     828             : //----------------------------------------------------------------------
     829             : template< class S, class C, class O, class L, class CV, class N, class V >
     830           0 : bool Config< S, C, O, L, CV, N, V >::_cmdNewLayout( co::ICommand& cmd )
     831             : {
     832           0 :     co::ObjectICommand command( cmd );
     833             : 
     834           0 :     L* layout = 0;
     835           0 :     create( &layout );
     836           0 :     LBASSERT( layout );
     837             : 
     838           0 :     getLocalNode()->registerObject( layout );
     839           0 :     layout->setAutoObsolete( _data.latency + 1 );
     840           0 :     LBASSERT( layout->isAttached() );
     841             : 
     842           0 :     send( command.getRemoteNode(), CMD_CONFIG_NEW_ENTITY_REPLY )
     843           0 :             << command.read< uint32_t >() << layout->getID();
     844           0 :     return true;
     845             : }
     846             : 
     847             : template< class S, class C, class O, class L, class CV, class N, class V >
     848           0 : bool Config< S, C, O, L, CV, N, V >::_cmdNewCanvas( co::ICommand& cmd )
     849             : {
     850           0 :     co::ObjectICommand command( cmd );
     851             : 
     852           0 :     CV* canvas = 0;
     853           0 :     create( &canvas );
     854           0 :     LBASSERT( canvas );
     855             : 
     856           0 :     getLocalNode()->registerObject( canvas );
     857           0 :     canvas->setAutoObsolete( _data.latency + 1 );
     858           0 :     LBASSERT( canvas->isAttached() );
     859             : 
     860           0 :     send( command.getRemoteNode(), CMD_CONFIG_NEW_ENTITY_REPLY )
     861           0 :             << command.read< uint32_t >() << canvas->getID();
     862           0 :     return true;
     863             : }
     864             : 
     865             : template< class S, class C, class O, class L, class CV, class N, class V >
     866           0 : bool Config< S, C, O, L, CV, N, V >::_cmdNewObserver( co::ICommand& cmd )
     867             : {
     868           0 :     co::ObjectICommand command( cmd );
     869             : 
     870           0 :     O* observer = 0;
     871           0 :     create( &observer );
     872           0 :     LBASSERT( observer );
     873             : 
     874           0 :     getLocalNode()->registerObject( observer );
     875           0 :     observer->setAutoObsolete( _data.latency + 1 );
     876           0 :     LBASSERT( observer->isAttached() );
     877             : 
     878           0 :     send( command.getRemoteNode(), CMD_CONFIG_NEW_ENTITY_REPLY )
     879           0 :             << command.read< uint32_t >() << observer->getID();
     880           0 :     return true;
     881             : }
     882             : 
     883             : template< class S, class C, class O, class L, class CV, class N, class V >
     884           0 : bool Config< S, C, O, L, CV, N, V >::_cmdNewEntityReply( co::ICommand& cmd )
     885             : {
     886           0 :     co::ObjectICommand command( cmd );
     887             : 
     888           0 :     const uint32_t requestID = command.read< uint32_t >();
     889           0 :     const uint128_t& result = command.read< uint128_t >();
     890             : 
     891           0 :     getLocalNode()->serveRequest( requestID, result );
     892             : 
     893           0 :     return true;
     894             : }
     895             : 
     896             : template< class S, class C, class O, class L, class CV, class N, class V >
     897         120 : std::ostream& operator << ( std::ostream& os,
     898             :                             const Config< S, C, O, L, CV, N, V >& config )
     899             : {
     900         120 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "config "
     901             :        << std::endl;
     902         120 :     os << "{" << std::endl << lunchbox::indent;
     903             : 
     904         120 :     if( !config.getName().empty( ))
     905         120 :         os << "name    \"" << config.getName() << '"' << std::endl;
     906             : 
     907         120 :     if( config.getLatency() != 1 )
     908           9 :         os << "latency " << config.getLatency() << std::endl;
     909         120 :     os << std::endl;
     910             : 
     911         240 :     os << "attributes" << std::endl << "{" << std::endl << lunchbox::indent
     912         120 :        << "robustness "
     913         240 :        << IAttribute( config.getIAttribute( C::IATTR_ROBUSTNESS )) << std::endl
     914         240 :        << "eye_base   " << config.getFAttribute( C::FATTR_EYE_BASE )
     915         120 :        << std::endl
     916         120 :        << lunchbox::exdent << "}" << std::endl;
     917             : 
     918         120 :     const typename C::Nodes& nodes = config.getNodes();
     919        1077 :     for( typename C::Nodes::const_iterator i = nodes.begin();
     920         718 :          i != nodes.end(); ++i )
     921             :     {
     922         239 :         os << **i;
     923             :     }
     924         120 :     os << std::endl;
     925             : 
     926         120 :     const typename C::Observers& observers = config.getObservers();
     927         723 :     for( typename C::Observers::const_iterator i = observers.begin();
     928         482 :          i !=observers.end(); ++i )
     929             :     {
     930         121 :         os << **i;
     931             :     }
     932         120 :     const typename C::Layouts& layouts = config.getLayouts();
     933        1206 :     for( typename C::Layouts::const_iterator i = layouts.begin();
     934         804 :          i !=layouts.end(); ++i )
     935             :     {
     936         282 :         os << **i;
     937             :     }
     938         120 :     const typename C::Canvases& canvases = config.getCanvases();
     939         732 :     for( typename C::Canvases::const_iterator i = canvases.begin();
     940         488 :          i != canvases.end(); ++i )
     941             :     {
     942         124 :         os << **i;
     943             :     }
     944             : 
     945         120 :     config.output( os );
     946             : 
     947         120 :     os << lunchbox::exdent << "}" << std::endl << lunchbox::enableHeader
     948             :        << lunchbox::enableFlush;
     949             : 
     950         120 :     return os;
     951             : }
     952             : 
     953             : }
     954             : }

Generated by: LCOV version 1.10