LCOV - code coverage report
Current view: top level - eq/fabric - layout.ipp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 113 152 74.3 %
Date: 2014-06-18 Functions: 31 50 62.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2009-2013, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                    2012, Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include "layout.h"
      20             : 
      21             : #include "commands.h"
      22             : #include "elementVisitor.h"
      23             : #include "leafVisitor.h"
      24             : #include "log.h"
      25             : #include "nameFinder.h"
      26             : #include "observer.h"
      27             : #include "paths.h"
      28             : 
      29             : #include <co/dataIStream.h>
      30             : #include <co/dataOStream.h>
      31             : #include <co/objectICommand.h>
      32             : 
      33             : #include <lunchbox/stdExt.h>
      34             : 
      35             : namespace eq
      36             : {
      37             : namespace fabric
      38             : {
      39             : template< class C, class L, class V >
      40         443 : Layout< C, L, V >::Layout( C* config )
      41         443 :         : _config( config )
      42             : {
      43         443 :     LBASSERT( config );
      44         443 :     static_cast< L* >( this )->_config->_addLayout( static_cast< L* >( this ));
      45         443 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      46         443 : }
      47             : 
      48             : template< class C, class L, class V >
      49         442 : Layout< C, L, V >::~Layout()
      50             : {
      51         442 :     LBLOG( LOG_INIT ) << "Delete " << lunchbox::className( this ) << std::endl;
      52        1297 :     while( !_views.empty( ))
      53             :     {
      54         413 :         V* view = _views.back();
      55         413 :         LBCHECK( _removeChild( view ));
      56         413 :         release( view );
      57             :     }
      58             : 
      59         442 :     _config->_removeLayout( static_cast< L* >( this ));
      60         884 : }
      61             : 
      62             : template< class C, class L, class V >
      63         126 : void Layout< C, L, V >::attach( const uint128_t& id,
      64             :                                 const uint32_t instanceID )
      65             : {
      66         126 :     Object::attach( id, instanceID );
      67             : 
      68         126 :     co::CommandQueue* queue = _config->getMainThreadQueue();
      69         126 :     LBASSERT( queue );
      70             : 
      71         126 :     registerCommand( CMD_LAYOUT_NEW_VIEW,
      72             :                      CmdFunc( this, &Layout< C, L, V >::_cmdNewView ), queue );
      73         126 :     registerCommand( CMD_LAYOUT_NEW_VIEW_REPLY,
      74             :                      CmdFunc( this, &Layout< C, L, V >::_cmdNewViewReply ), 0 );
      75         126 : }
      76             : 
      77             : template< class C, class L, class V >
      78       73487 : uint128_t Layout< C, L, V >::commit( const uint32_t incarnation )
      79             : {
      80             :     // Always traverse views: view proxy objects may be dirty
      81       73487 :     commitChildren< V >( _views, CMD_LAYOUT_NEW_VIEW, incarnation );
      82       73487 :     return Object::commit( incarnation );
      83             : }
      84             : 
      85             : template< class C, class L, class V >
      86         275 : void Layout< C, L, V >::serialize( co::DataOStream& os,
      87             :                                    const uint64_t dirtyBits )
      88             : {
      89         275 :     Object::serialize( os, dirtyBits );
      90             : 
      91         275 :     if( dirtyBits & DIRTY_VIEWS && isMaster( ))
      92         219 :         os.serializeChildren( _views );
      93         275 : }
      94             : 
      95             : template< class C, class L, class V >
      96         196 : void Layout< C, L, V >::deserialize( co::DataIStream& is,
      97             :                                      const uint64_t dirtyBits )
      98             : {
      99         196 :     Object::deserialize( is, dirtyBits );
     100             : 
     101         196 :     if( dirtyBits & DIRTY_VIEWS )
     102             :     {
     103         196 :         if( isMaster( ))
     104          56 :             syncChildren( _views );
     105             :         else
     106             :         {
     107         140 :             Views result;
     108         140 :             is.deserializeChildren( this, _views, result );
     109         140 :             _views.swap( result );
     110             :         }
     111             :     }
     112         196 : }
     113             : 
     114             : template< class C, class L, class V >
     115        1355 : void Layout< C, L, V >::setDirty( const uint64_t dirtyBits )
     116             : {
     117        1355 :     Object::setDirty( dirtyBits );
     118        1355 :     _config->setDirty( C::DIRTY_LAYOUTS );
     119        1355 : }
     120             : 
     121             : template< class C, class L, class V >
     122         126 : void Layout< C, L, V >::notifyDetach()
     123             : {
     124         126 :     Object::notifyDetach();
     125         126 :     releaseChildren< L, V >( _views );
     126         126 : }
     127             : 
     128             : template< class C, class L, class V >
     129          63 : void Layout< C, L, V >::create( V** view )
     130             : {
     131          63 :     *view = getConfig()->getServer()->getNodeFactory()->createView(
     132             :         static_cast< L* >( this ));
     133          63 : }
     134             : 
     135             : template< class C, class L, class V >
     136         476 : void Layout< C, L, V >::release( V* view )
     137             : {
     138         476 :     getConfig()->getServer()->getNodeFactory()->releaseView( view );
     139         476 : }
     140             : 
     141             : namespace
     142             : {
     143             : template< class L, class V >
     144       14880 : VisitorResult _accept( L* layout, V& visitor )
     145             : {
     146       14880 :     VisitorResult result = visitor.visitPre( layout );
     147       14880 :     if( result != TRAVERSE_CONTINUE )
     148        1084 :         return result;
     149             : 
     150       13796 :     const typename L::Views& views = layout->getViews();
     151       85908 :     for( typename L::Views::const_iterator i = views.begin();
     152       57272 :          i != views.end(); ++i )
     153             :     {
     154       14840 :         switch( (*i)->accept( visitor ))
     155             :         {
     156             :             case TRAVERSE_TERMINATE:
     157           0 :                 return TRAVERSE_TERMINATE;
     158             : 
     159             :             case TRAVERSE_PRUNE:
     160           0 :                 result = TRAVERSE_PRUNE;
     161           0 :                 break;
     162             : 
     163             :             case TRAVERSE_CONTINUE:
     164             :             default:
     165       14840 :                 break;
     166             :         }
     167             :     }
     168             : 
     169       13796 :     switch( visitor.visitPost( layout ))
     170             :     {
     171             :         case TRAVERSE_TERMINATE:
     172           0 :             return TRAVERSE_TERMINATE;
     173             : 
     174             :         case TRAVERSE_PRUNE:
     175           0 :             return TRAVERSE_PRUNE;
     176             : 
     177             :         case TRAVERSE_CONTINUE:
     178             :         default:
     179       13796 :             break;
     180             :     }
     181             : 
     182       13796 :     return result;
     183             : }
     184             : }
     185             : 
     186             : template< class C, class L, class V >
     187       14880 : VisitorResult Layout< C, L, V >::accept( Visitor& visitor )
     188             : {
     189       14880 :     return _accept( static_cast< L* >( this ), visitor );
     190             : }
     191             : 
     192             : template< class C, class L, class V >
     193           0 : VisitorResult Layout< C, L, V >::accept( Visitor& visitor ) const
     194             : {
     195           0 :     return _accept( static_cast< const L* >( this ), visitor );
     196             : }
     197             : 
     198             : template< class C, class L, class V >
     199         477 : void Layout< C, L, V >::_addChild( V* view )
     200             : {
     201         477 :     LBASSERT( view );
     202         477 :     LBASSERT( view->getLayout() == this );
     203         477 :     _views.push_back( view );
     204         477 :     setDirty( DIRTY_VIEWS );
     205         477 : }
     206             : 
     207             : template< class C, class L, class V >
     208         952 : bool Layout< C, L, V >::_removeChild( V* view )
     209             : {
     210         952 :     typename Views::iterator i = lunchbox::find( _views, view );
     211         952 :     if( i == _views.end( ))
     212         476 :         return false;
     213             : 
     214         476 :     LBASSERT( view->getLayout() == this );
     215         476 :     _views.erase( i );
     216         476 :     setDirty( DIRTY_VIEWS );
     217         476 :     if( !isMaster( ))
     218         476 :         postRemove( view );
     219         476 :     return true;
     220             : }
     221             : 
     222             : template< class C, class L, class V >
     223           0 : template< class O > void Layout< C, L, V >::_removeObserver( const O* observer )
     224             : {
     225           0 :     for( typename Views::const_iterator i = _views.begin();
     226           0 :          i != _views.end(); ++i )
     227             :     {
     228           0 :         V* view = *i;
     229           0 :         if( view->getObserver() == observer )
     230             :         {
     231           0 :             LBINFO << "Removing " << lunchbox::disableHeader << *observer
     232           0 :                    << " used by " << *view << std::endl
     233           0 :                    << lunchbox::enableHeader;
     234           0 :             view->setObserver( 0 );
     235             :         }
     236             :     }
     237           0 : }
     238             : 
     239             : template< class C, class L, class V >
     240           7 : bool Layout< C, L, V >::isActive() const
     241             : {
     242           7 :     const typename C::Canvases& canvases = _config->getCanvases();
     243          39 :     for( typename C::Canvases::const_iterator i = canvases.begin();
     244          26 :          i != canvases.end(); ++i )
     245             :     {
     246           7 :         if( (*i)->getActiveLayout() == this )
     247           1 :             return true;
     248             :     }
     249           6 :     return false;
     250             : }
     251             : 
     252             : template< class C, class L, class V >
     253        1410 : V* Layout< C, L, V >::getView( const ViewPath& path )
     254             : {
     255        1410 :     LBASSERTINFO( _views.size() > path.viewIndex,
     256             :                   _views.size() << " <= " << path.viewIndex << " " << this );
     257             : 
     258        1410 :     if( _views.size() <= path.viewIndex )
     259           0 :         return 0;
     260             : 
     261        1410 :     return _views[ path.viewIndex ];
     262             : }
     263             : 
     264             : template< class C, class L, class V >
     265         562 : LayoutPath Layout< C, L, V >::getPath() const
     266             : {
     267         562 :     LBASSERT( _config );
     268         562 :     const std::vector< L* >& layouts = _config->getLayouts();
     269             :     typename std::vector< L* >::const_iterator i = std::find( layouts.begin(),
     270             :                                                               layouts.end(),
     271         562 :                                                               this );
     272         562 :     LBASSERT( i != layouts.end( ));
     273             : 
     274         562 :     LayoutPath path;
     275         562 :     path.layoutIndex = std::distance( layouts.begin(), i );
     276         562 :     return path;
     277             : }
     278             : 
     279             : template< class C, class L, class V >
     280           0 : V* Layout< C, L, V >::findView( const std::string& name )
     281             : {
     282           0 :     NameFinder< V, Visitor > finder( name );
     283           0 :     accept( finder );
     284           0 :     return finder.getResult();
     285             : }
     286             : 
     287             : //----------------------------------------------------------------------
     288             : // ICommand handlers
     289             : //----------------------------------------------------------------------
     290             : template< class C, class L, class V > bool
     291           0 : Layout< C, L, V >::_cmdNewView( co::ICommand& cmd )
     292             : {
     293           0 :     co::ObjectICommand command( cmd );
     294             : 
     295           0 :     V* view = 0;
     296           0 :     create( &view );
     297           0 :     LBASSERT( view );
     298             : 
     299           0 :     getLocalNode()->registerObject( view );
     300           0 :     view->setAutoObsolete( _config->getLatency() + 1 );
     301           0 :     LBASSERT( view->isAttached() );
     302             : 
     303           0 :     send( command.getRemoteNode(), CMD_LAYOUT_NEW_VIEW_REPLY )
     304           0 :             << command.read< uint32_t >() << view->getID();
     305             : 
     306           0 :     return true;
     307             : }
     308             : 
     309             : template< class C, class L, class V > bool
     310           0 : Layout< C, L, V >::_cmdNewViewReply( co::ICommand& cmd )
     311             : {
     312           0 :     co::ObjectICommand command( cmd );
     313           0 :     const uint32_t requestID = command.read< uint32_t >();
     314           0 :     const uint128_t& result = command.read< uint128_t >();
     315             : 
     316           0 :     getLocalNode()->serveRequest( requestID, result );
     317             : 
     318           0 :     return true;
     319             : }
     320             : 
     321             : template< class C, class L, class V >
     322         282 : std::ostream& operator << ( std::ostream& os, const Layout< C, L, V >& layout )
     323             : {
     324         282 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "layout"
     325             :        << std::endl;
     326         282 :     os << "{" << std::endl << lunchbox::indent;
     327             : 
     328         282 :     const std::string& name = layout.getName();
     329         282 :     if( !name.empty( ))
     330         196 :         os << "name     \"" << name << "\"" << std::endl;
     331             : 
     332         282 :     const std::vector< V* >& views = layout.getViews();
     333        1743 :     for( typename std::vector< V* >::const_iterator i = views.begin();
     334        1162 :          i != views.end(); ++i )
     335             :     {
     336         299 :         os << **i;
     337             :     }
     338         282 :     os << lunchbox::exdent << "}" << std::endl << lunchbox::enableHeader
     339             :        << lunchbox::enableFlush;
     340         282 :     return os;
     341             : }
     342             : 
     343             : }
     344             : }

Generated by: LCOV version 1.10