lib/client/canvas.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "canvas.h"
00019
00020 #include "canvasVisitor.h"
00021 #include "config.h"
00022 #include "global.h"
00023 #include "layout.h"
00024 #include "nodeFactory.h"
00025 #include "segment.h"
00026
00027 #include <eq/net/dataIStream.h>
00028 #include <eq/net/dataOStream.h>
00029
00030 namespace eq
00031 {
00032
00033 Canvas::Canvas()
00034 : _config( 0 )
00035 , _activeLayout( 0 )
00036 {
00037 }
00038
00039 Canvas::~Canvas()
00040 {
00041 EQASSERT( !_config );
00042 }
00043
00044 void Canvas::serialize( net::DataOStream& os, const uint64_t dirtyBits )
00045 {
00046 Frustum::serialize( os, dirtyBits );
00047
00048 if( dirtyBits & DIRTY_LAYOUT )
00049 os << _activeLayout;
00050
00051 EQASSERT( !(dirtyBits & DIRTY_CHILDREN ));
00052 }
00053
00054 void Canvas::deserialize( net::DataIStream& is, const uint64_t dirtyBits )
00055 {
00056 Frustum::deserialize( is, dirtyBits );
00057
00058 if( dirtyBits & DIRTY_LAYOUT )
00059 is >> _activeLayout;
00060
00061 if( dirtyBits & DIRTY_CHILDREN )
00062 {
00063 EQASSERT( _segments.empty( ));
00064 EQASSERT( _config );
00065
00066 NodeFactory* nodeFactory = Global::getNodeFactory();
00067 uint32_t id;
00068 for( is >> id; id != EQ_ID_INVALID; is >> id )
00069 {
00070 Segment* segment = nodeFactory->createSegment();
00071 segment->_canvas = this;
00072 _segments.push_back( segment );
00073
00074 _config->mapObject( segment, id );
00075
00076 }
00077 for( is >> id; id != EQ_ID_INVALID; is >> id )
00078 {
00079 EQASSERT( _config );
00080 if( id == EQ_ID_NONE )
00081 _layouts.push_back( 0 );
00082 else
00083 {
00084 Layout* layout = _config->findLayout( id );
00085 _layouts.push_back( layout );
00086 EQASSERT( layout );
00087 }
00088 }
00089 }
00090 }
00091
00092 void Canvas::_deregister()
00093 {
00094 EQASSERT( _config );
00095 EQASSERT( isMaster( ));
00096 NodeFactory* nodeFactory = Global::getNodeFactory();
00097
00098 for( SegmentVector::const_iterator i = _segments.begin();
00099 i != _segments.end(); ++i )
00100 {
00101 Segment* segment = *i;
00102 EQASSERT( segment->getID() != EQ_ID_INVALID );
00103 EQASSERT( !segment->isMaster( ));
00104
00105 _config->unmapObject( segment );
00106 segment->_canvas = 0;
00107 nodeFactory->releaseSegment( segment );
00108 }
00109
00110 _segments.clear();
00111 _config->deregisterObject( this );
00112 }
00113
00114 const Layout* Canvas::getActiveLayout() const
00115 {
00116 EQASSERT( _activeLayout < _layouts.size( ));
00117 return _layouts[ _activeLayout ];
00118 }
00119
00120 void Canvas::useLayout( const uint32_t index )
00121 {
00122 if( _activeLayout == index )
00123 return;
00124
00125 _activeLayout = index;
00126 setDirty( DIRTY_LAYOUT );
00127 }
00128
00129 namespace
00130 {
00131 template< class C >
00132 VisitorResult _accept( C* canvas, CanvasVisitor& visitor )
00133 {
00134 VisitorResult result = visitor.visitPre( canvas );
00135 if( result != TRAVERSE_CONTINUE )
00136 return result;
00137
00138 const SegmentVector& segments = canvas->getSegments();
00139 for( SegmentVector::const_iterator i = segments.begin();
00140 i != segments.end(); ++i )
00141 {
00142 switch( (*i)->accept( visitor ))
00143 {
00144 case TRAVERSE_TERMINATE:
00145 return TRAVERSE_TERMINATE;
00146
00147 case TRAVERSE_PRUNE:
00148 result = TRAVERSE_PRUNE;
00149 break;
00150
00151 case TRAVERSE_CONTINUE:
00152 default:
00153 break;
00154 }
00155 }
00156
00157 switch( visitor.visitPost( canvas ))
00158 {
00159 case TRAVERSE_TERMINATE:
00160 return TRAVERSE_TERMINATE;
00161
00162 case TRAVERSE_PRUNE:
00163 return TRAVERSE_PRUNE;
00164
00165 case TRAVERSE_CONTINUE:
00166 default:
00167 break;
00168 }
00169
00170 return result;
00171 }
00172 }
00173
00174 VisitorResult Canvas::accept( CanvasVisitor& visitor )
00175 {
00176 return _accept( this, visitor );
00177 }
00178
00179 VisitorResult Canvas::accept( CanvasVisitor& visitor ) const
00180 {
00181 return _accept( this, visitor );
00182 }
00183
00184 }