LCOV - code coverage report
Current view: top level - eq/fabric - layout.ipp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 110 152 72.4 %
Date: 2016-09-29 05:02:09 Functions: 28 75 37.3 %

          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         656 : Layout< C, L, V >::Layout( C* config )
      41         656 :         : _config( config )
      42             : {
      43         656 :     LBASSERT( config );
      44         656 :     static_cast< L* >( this )->_config->_addLayout( static_cast< L* >( this ));
      45         656 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      46         656 : }
      47             : 
      48             : template< class C, class L, class V >
      49         654 : Layout< C, L, V >::~Layout()
      50             : {
      51         654 :     LBLOG( LOG_INIT ) << "Delete " << lunchbox::className( this ) << std::endl;
      52        2028 :     while( !_views.empty( ))
      53             :     {
      54         720 :         V* view = _views.back();
      55         720 :         LBCHECK( _removeChild( view ));
      56         720 :         release( view );
      57             :     }
      58             : 
      59         654 :     _config->_removeLayout( static_cast< L* >( this ));
      60        1308 : }
      61             : 
      62             : template< class C, class L, class V >
      63           6 : void Layout< C, L, V >::attach( const uint128_t& id,
      64             :                                 const uint32_t instanceID )
      65             : {
      66           6 :     Object::attach( id, instanceID );
      67             : 
      68           6 :     co::CommandQueue* queue = _config->getMainThreadQueue();
      69           6 :     LBASSERT( queue );
      70             : 
      71           6 :     registerCommand( CMD_LAYOUT_NEW_VIEW,
      72             :                      CmdFunc( this, &Layout< C, L, V >::_cmdNewView ), queue );
      73           6 :     registerCommand( CMD_LAYOUT_NEW_VIEW_REPLY,
      74             :                      CmdFunc( this, &Layout< C, L, V >::_cmdNewViewReply ), 0 );
      75           6 : }
      76             : 
      77             : template< class C, class L, class V >
      78          14 : uint128_t Layout< C, L, V >::commit( const uint32_t incarnation )
      79             : {
      80             :     // Always traverse views: view proxy objects may be dirty
      81          14 :     commitChildren< V >( _views, CMD_LAYOUT_NEW_VIEW, incarnation );
      82          14 :     return Object::commit( incarnation );
      83             : }
      84             : 
      85             : template< class C, class L, class V >
      86          12 : void Layout< C, L, V >::serialize( co::DataOStream& os,
      87             :                                    const uint64_t dirtyBits )
      88             : {
      89          12 :     Object::serialize( os, dirtyBits );
      90             : 
      91          12 :     if( dirtyBits & DIRTY_VIEWS && isMaster( ))
      92          12 :         os.serializeChildren( _views );
      93          12 : }
      94             : 
      95             : template< class C, class L, class V >
      96           3 : void Layout< C, L, V >::deserialize( co::DataIStream& is,
      97             :                                      const uint64_t dirtyBits )
      98             : {
      99           3 :     Object::deserialize( is, dirtyBits );
     100             : 
     101           3 :     if( dirtyBits & DIRTY_VIEWS )
     102             :     {
     103           3 :         if( isMaster( ))
     104           0 :             syncChildren( _views );
     105             :         else
     106             :         {
     107           3 :             Views result;
     108           3 :             is.deserializeChildren( this, _views, result );
     109           3 :             _views.swap( result );
     110             :         }
     111             :     }
     112           3 : }
     113             : 
     114             : template< class C, class L, class V >
     115        1768 : void Layout< C, L, V >::setDirty( const uint64_t dirtyBits )
     116             : {
     117        1768 :     Object::setDirty( dirtyBits );
     118        1768 :     _config->setDirty( C::DIRTY_LAYOUTS );
     119        1768 : }
     120             : 
     121             : template< class C, class L, class V >
     122           6 : void Layout< C, L, V >::notifyDetach()
     123             : {
     124           6 :     Object::notifyDetach();
     125           6 :     releaseChildren< L, V >( _views );
     126           6 : }
     127             : 
     128             : template< class C, class L, class V >
     129           2 : void Layout< C, L, V >::create( V** view )
     130             : {
     131           2 :     *view = getConfig()->getServer()->getNodeFactory()->createView(
     132             :         static_cast< L* >( this ));
     133           2 : }
     134             : 
     135             : template< class C, class L, class V >
     136         722 : void Layout< C, L, V >::release( V* view )
     137             : {
     138         722 :     getConfig()->getServer()->getNodeFactory()->releaseView( view );
     139         722 : }
     140             : 
     141             : namespace
     142             : {
     143             : template< class L, class V >
     144       18383 : VisitorResult _accept( L* layout, V& visitor )
     145             : {
     146       18383 :     VisitorResult result = visitor.visitPre( layout );
     147       18383 :     if( result != TRAVERSE_CONTINUE )
     148        1580 :         return result;
     149             : 
     150       16803 :     const typename L::Views& views = layout->getViews();
     151      107106 :     for( typename L::Views::const_iterator i = views.begin();
     152       71404 :          i != views.end(); ++i )
     153             :     {
     154       18903 :         switch( (*i)->accept( visitor ))
     155             :         {
     156             :             case TRAVERSE_TERMINATE:
     157           4 :                 return TRAVERSE_TERMINATE;
     158             : 
     159             :             case TRAVERSE_PRUNE:
     160           0 :                 result = TRAVERSE_PRUNE;
     161           0 :                 break;
     162             : 
     163             :             case TRAVERSE_CONTINUE:
     164             :             default:
     165       18899 :                 break;
     166             :         }
     167             :     }
     168             : 
     169       16799 :     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       16799 :             break;
     180             :     }
     181             : 
     182       16799 :     return result;
     183             : }
     184             : }
     185             : 
     186             : template< class C, class L, class V >
     187       18383 : VisitorResult Layout< C, L, V >::accept( Visitor& visitor )
     188             : {
     189       18383 :     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         724 : void Layout< C, L, V >::_addChild( V* view )
     200             : {
     201         724 :     LBASSERT( view );
     202         724 :     LBASSERT( view->getLayout() == this );
     203         724 :     _views.push_back( view );
     204         724 :     setDirty( DIRTY_VIEWS );
     205         724 : }
     206             : 
     207             : template< class C, class L, class V >
     208        1444 : bool Layout< C, L, V >::_removeChild( V* view )
     209             : {
     210        1444 :     typename Views::iterator i = lunchbox::find( _views, view );
     211        1444 :     if( i == _views.end( ))
     212         722 :         return false;
     213             : 
     214         722 :     LBASSERT( view->getLayout() == this );
     215         722 :     _views.erase( i );
     216         722 :     setDirty( DIRTY_VIEWS );
     217         722 :     if( !isMaster( ))
     218         722 :         postRemove( view );
     219         722 :     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           0 : bool Layout< C, L, V >::isActive() const
     241             : {
     242           0 :     const typename C::Canvases& canvases = _config->getCanvases();
     243           0 :     for( typename C::Canvases::const_iterator i = canvases.begin();
     244           0 :          i != canvases.end(); ++i )
     245             :     {
     246           0 :         if( (*i)->getActiveLayout() == this )
     247           0 :             return true;
     248             :     }
     249           0 :     return false;
     250             : }
     251             : 
     252             : template< class C, class L, class V >
     253        2872 : V* Layout< C, L, V >::getView( const ViewPath& path )
     254             : {
     255        2872 :     LBASSERTINFO( _views.size() > path.viewIndex,
     256             :                   _views.size() << " <= " << path.viewIndex << " " << this );
     257             : 
     258        2872 :     if( _views.size() <= path.viewIndex )
     259           0 :         return 0;
     260             : 
     261        2872 :     return _views[ path.viewIndex ];
     262             : }
     263             : 
     264             : template< class C, class L, class V >
     265         900 : LayoutPath Layout< C, L, V >::getPath() const
     266             : {
     267         900 :     LBASSERT( _config );
     268         900 :     const std::vector< L* >& layouts = _config->getLayouts();
     269             :     typename std::vector< L* >::const_iterator i = std::find( layouts.begin(),
     270             :                                                               layouts.end(),
     271         900 :                                                               this );
     272         900 :     LBASSERT( i != layouts.end( ));
     273             : 
     274         900 :     LayoutPath path;
     275         900 :     path.layoutIndex = std::distance( layouts.begin(), i );
     276         900 :     return path;
     277             : }
     278             : 
     279             : template< class C, class L, class V >
     280           2 : V* Layout< C, L, V >::findView( const std::string& name )
     281             : {
     282           2 :     NameFinder< V, Visitor > finder( name );
     283           2 :     accept( finder );
     284           2 :     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         328 : std::ostream& operator << ( std::ostream& os, const Layout< C, L, V >& layout )
     323             : {
     324         328 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "layout"
     325             :        << std::endl;
     326         328 :     os << "{" << std::endl << lunchbox::indent;
     327             : 
     328         328 :     const std::string& name = layout.getName();
     329         328 :     if( !name.empty( ))
     330         150 :         os << "name     \"" << name << "\"" << std::endl;
     331             : 
     332         328 :     const std::vector< V* >& views = layout.getViews();
     333        2070 :     for( typename std::vector< V* >::const_iterator i = views.begin();
     334        1380 :          i != views.end(); ++i )
     335             :     {
     336         362 :         os << **i;
     337             :     }
     338         328 :     os << lunchbox::exdent << "}" << std::endl << lunchbox::enableHeader
     339             :        << lunchbox::enableFlush;
     340         328 :     return os;
     341             : }
     342             : 
     343             : }
     344             : }

Generated by: LCOV version 1.11