server/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 "layoutVisitor.h"
00022 #include "nameFinder.h"
00023 #include "paths.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 namespace server
00034 {
00035 
00036 Layout::Layout()
00037         : _config( 0 )
00038 {}
00039 
00040 Layout::Layout( const Layout& from, Config* config )
00041         : Object( from )
00042         , _config( 0 )
00043 {
00044     for( ViewVector::const_iterator i = from._views.begin();
00045          i != from._views.end(); ++i )
00046     {
00047         addView( new View( **i, config ));
00048     }
00049 
00050     config->addLayout( this );
00051     EQASSERT( _config );
00052 }
00053 
00054 Layout::~Layout()
00055 {
00056     for( ViewVector::const_iterator i = _views.begin(); i != _views.end(); ++i )
00057     {
00058         View* view = *i;
00059         view->_layout = 0;
00060         delete view;
00061     }
00062     _views.clear();
00063 }
00064 
00065 void Layout::getInstanceData( net::DataOStream& os )
00066 {
00067     // This function is overwritten from eq::Object, since the class is
00068     // intended to be subclassed on the client side. When serializing a
00069     // server::Layout, we only transmit the effective bits, not all since that
00070     // potentially includes bits from subclassed eq::Layouts.
00071     const uint64_t dirty = eq::Layout::DIRTY_CUSTOM - 1;
00072     os << dirty;
00073     serialize( os, dirty );
00074 }
00075 
00076 void Layout::serialize( net::DataOStream& os, const uint64_t dirtyBits )
00077 {
00078     Object::serialize( os, dirtyBits );
00079 
00080     if( dirtyBits & eq::Layout::DIRTY_VIEWS )
00081     {
00082         for( ViewVector::const_iterator i = _views.begin();
00083              i != _views.end(); ++i )
00084         {
00085             View* view = *i;
00086             EQASSERT( view->getID() != EQ_ID_INVALID );
00087             os << view->getID();
00088         }
00089         os << EQ_ID_INVALID;
00090     }
00091 }
00092 
00093 View* Layout::getView( const ViewPath& path )
00094 {
00095     EQASSERTINFO( _views.size() > path.viewIndex,
00096                   _views.size() << " <= " << path.viewIndex );
00097 
00098     if( _views.size() <= path.viewIndex )
00099         return 0;
00100 
00101     return _views[ path.viewIndex ];
00102 }
00103 
00104 LayoutPath Layout::getPath() const
00105 {
00106     EQASSERT( _config );
00107     
00108     const LayoutVector&    layouts = _config->getLayouts();
00109     LayoutVector::const_iterator i = std::find( layouts.begin(), layouts.end(),
00110                                               this );
00111     EQASSERT( i != layouts.end( ));
00112 
00113     LayoutPath path;
00114     path.layoutIndex = std::distance( layouts.begin(), i );
00115     return path;
00116 }
00117 
00118 namespace
00119 {
00120 template< class C, class V >
00121 VisitorResult _accept( C* layout, V& visitor )
00122 { 
00123     VisitorResult result = visitor.visitPre( layout );
00124     if( result != TRAVERSE_CONTINUE )
00125         return result;
00126 
00127     const ViewVector& views = layout->getViews();
00128     for( ViewVector::const_iterator i = views.begin(); i != views.end(); ++i )
00129     {
00130         switch( (*i)->accept( visitor ))
00131         {
00132             case TRAVERSE_TERMINATE:
00133                 return TRAVERSE_TERMINATE;
00134 
00135             case TRAVERSE_PRUNE:
00136                 result = TRAVERSE_PRUNE;
00137                 break;
00138                 
00139             case TRAVERSE_CONTINUE:
00140             default:
00141                 break;
00142         }
00143     }
00144 
00145     switch( visitor.visitPost( layout ))
00146     {
00147         case TRAVERSE_TERMINATE:
00148             return TRAVERSE_TERMINATE;
00149 
00150         case TRAVERSE_PRUNE:
00151             return TRAVERSE_PRUNE;
00152                 
00153         case TRAVERSE_CONTINUE:
00154         default:
00155             break;
00156     }
00157 
00158     return result;
00159 }
00160 }
00161 
00162 VisitorResult Layout::accept( LayoutVisitor& visitor )
00163 {
00164     return _accept( this, visitor );
00165 }
00166 VisitorResult Layout::accept( ConstLayoutVisitor& visitor ) const
00167 {
00168     return _accept( this, visitor );
00169 }
00170 
00171 void Layout::addView( View* view )
00172 {
00173     EQASSERT( view );
00174     view->_layout = this;
00175     _views.push_back( view );
00176 }
00177 
00178 bool Layout::removeView( View* view )
00179 {
00180     ViewVector::iterator i = find( _views.begin(), _views.end(), view );
00181     if( i == _views.end( ))
00182         return false;
00183 
00184     _views.erase( i );
00185     view->_layout = 0;
00186     return true;
00187 }
00188 
00189 View* Layout::findView( const std::string& name )
00190 {
00191     ViewFinder finder( name );
00192     accept( finder );
00193     return finder.getResult();
00194 }
00195 
00196 void Layout::unmap()
00197 {
00198     net::Session* session = getSession();
00199     EQASSERT( session );
00200     for( ViewVector::const_iterator i = _views.begin(); i != _views.end(); ++i )
00201     {
00202         View* view = *i;
00203         EQASSERT( view->getID() != EQ_ID_INVALID );
00204         
00205         session->unmapObject( view );
00206     }
00207 
00208     EQASSERT( getID() != EQ_ID_INVALID );
00209     session->unmapObject( this );
00210 }
00211 
00212 std::ostream& operator << ( std::ostream& os, const Layout* layout )
00213 {
00214     if( !layout )
00215         return os;
00216     
00217     os << disableFlush << disableHeader << "layout" << std::endl;
00218     os << "{" << std::endl << indent; 
00219 
00220     const std::string& name = layout->getName();
00221     if( !name.empty( ))
00222         os << "name     \"" << name << "\"" << std::endl;
00223 
00224     const ViewVector& views = layout->getViews();
00225     for( ViewVector::const_iterator i = views.begin(); i != views.end(); ++i )
00226         os << *i;
00227 
00228     os << exdent << "}" << std::endl << enableHeader << enableFlush;
00229     return os;
00230 }
00231 
00232 }
00233 }
Generated on Mon Aug 10 18:58:39 2009 for Equalizer 0.9 by  doxygen 1.5.8