lib/client/layout.cpp

00001 
00002 /* Copyright (c) 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 "layout.h"
00019 
00020 #include "config.h"
00021 #include "global.h"
00022 #include "layoutVisitor.h"
00023 #include "nodeFactory.h"
00024 #include "view.h"
00025 
00026 #include <eq/net/dataIStream.h>
00027 #include <eq/net/dataOStream.h>
00028 
00029 using namespace eq::base;
00030 
00031 namespace eq
00032 {
00033 
00034 Layout::Layout()
00035         : _config( 0 )
00036 {
00037 }
00038 
00039 Layout::~Layout()
00040 {
00041     for( ViewVector::const_iterator i = _views.begin(); i != _views.end(); ++i )
00042     {
00043         View* view = *i;
00044         EQCHECK( _removeView( view ));
00045         delete view;
00046     }
00047 
00048     _views.clear();
00049     EQASSERT( !_config );
00050 }
00051 
00052 void Layout::deserialize( net::DataIStream& is, const uint64_t dirtyBits )
00053 {
00054     Object::deserialize( is, dirtyBits );
00055 
00056     if( dirtyBits & DIRTY_VIEWS )
00057     {
00058         EQASSERT( _views.empty( ));
00059         EQASSERT( _config );
00060         const uint32_t latency = _config->getLatency();
00061 
00062         NodeFactory* nodeFactory = Global::getNodeFactory();
00063         uint32_t id;
00064         for( is >> id; id != EQ_ID_INVALID; is >> id )
00065         {
00066             View* view = nodeFactory->createView();
00067             view->_layout = this;
00068             _views.push_back( view );
00069 
00070             _config->mapObject( view, id );
00071             view->becomeMaster();
00072             
00073             // Note: Views are potentially mapped by source channels in
00074             // frameFoo(), which means that we have to keep #latency copies
00075             view->setAutoObsolete( latency );
00076         }
00077     }
00078 }
00079 
00080 void Layout::deregister()
00081 {
00082     EQASSERT( _config );
00083     EQASSERT( !isMaster( ));
00084 
00085     NodeFactory* nodeFactory = Global::getNodeFactory();
00086 
00087     for( ViewVector::const_iterator i = _views.begin(); i != _views.end(); ++i )
00088     {
00089         View* view = *i;
00090         EQASSERT( view->getID() != EQ_ID_INVALID );
00091         EQASSERT( view->isMaster( ));
00092 
00093         _config->deregisterObject( view );
00094         view->_layout = 0;
00095         nodeFactory->releaseView( view );
00096     }
00097 
00098     _views.clear();
00099     _config->unmapObject( this );
00100 }
00101 
00102 VisitorResult Layout::accept( LayoutVisitor& visitor )
00103 { 
00104     VisitorResult result = visitor.visitPre( this );
00105     if( result != TRAVERSE_CONTINUE )
00106         return result;
00107 
00108     for( ViewVector::const_iterator i = _views.begin(); 
00109          i != _views.end(); ++i )
00110     {
00111         View* view = *i;
00112         switch( view->accept( visitor ))
00113         {
00114             case TRAVERSE_TERMINATE:
00115                 return TRAVERSE_TERMINATE;
00116 
00117             case TRAVERSE_PRUNE:
00118                 result = TRAVERSE_PRUNE;
00119                 break;
00120                 
00121             case TRAVERSE_CONTINUE:
00122             default:
00123                 break;
00124         }
00125     }
00126 
00127     switch( visitor.visitPost( this ))
00128     {
00129         case TRAVERSE_TERMINATE:
00130             return TRAVERSE_TERMINATE;
00131 
00132         case TRAVERSE_PRUNE:
00133             return TRAVERSE_PRUNE;
00134                 
00135         case TRAVERSE_CONTINUE:
00136         default:
00137             break;
00138     }
00139 
00140     return result;
00141 }
00142 
00143 void Layout::_addView( View* view )
00144 {
00145     EQASSERT( view );
00146     view->_layout = this;
00147     _views.push_back( view );
00148 }
00149 
00150 bool Layout::_removeView( View* view )
00151 {
00152     ViewVector::iterator i = find( _views.begin(), _views.end(), view );
00153     if( i == _views.end( ))
00154         return false;
00155 
00156     _views.erase( i );
00157     view->_layout = 0;
00158     return true;
00159 }
00160 
00161 
00162 std::ostream& operator << ( std::ostream& os, const Layout* layout )
00163 {
00164     if( !layout )
00165         return os;
00166     
00167     os << disableFlush << disableHeader << "layout" << std::endl;
00168     os << "{" << std::endl << indent; 
00169 
00170     const std::string& name = layout->getName();
00171     if( !name.empty( ))
00172         os << "name     \"" << name << "\"" << std::endl;
00173 
00174     const ViewVector& views = layout->getViews();
00175     for( ViewVector::const_iterator i = views.begin(); i != views.end(); ++i )
00176         os << *i;
00177 
00178     os << exdent << "}" << std::endl << enableHeader << enableFlush;
00179     return os;
00180 }
00181 
00182 }
Generated on Mon Aug 10 18:58:39 2009 for Equalizer 0.9 by  doxygen 1.5.8