server/view.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "view.h"
00019
00020 #include "channel.h"
00021 #include "compound.h"
00022 #include "config.h"
00023 #include "configVisitor.h"
00024 #include "layout.h"
00025 #include "observer.h"
00026 #include "paths.h"
00027
00028 #include <eq/net/dataOStream.h>
00029
00030 using namespace eq::base;
00031
00032 namespace eq
00033 {
00034 namespace server
00035 {
00036
00037 View::View()
00038 : _layout( 0 )
00039 {
00040 }
00041
00042 View::View( const View& from, Config* config )
00043 : eq::View( from )
00044 , _layout( 0 )
00045 {
00046 if( from._observer )
00047 {
00048 const Observer* oldObserver = static_cast< const Observer* >(
00049 from._observer );
00050 const ObserverPath path( oldObserver->getPath( ));
00051
00052 _observer = config->getObserver( path );
00053 EQASSERT( _observer );
00054 }
00055
00056
00057 }
00058
00059 View::~View()
00060 {
00061
00062 ChannelVector channels = _channels;
00063 for( ChannelVector::const_iterator i = channels.begin();
00064 i != channels.end(); ++i )
00065 {
00066 Channel* channel = *i;
00067 channel->unsetOutput();
00068 }
00069
00070 EQASSERT( _channels.empty( ));
00071 _channels.clear();
00072
00073 if( _layout )
00074 _layout->removeView( this );
00075 _layout = 0;
00076 }
00077
00078 void View::getInstanceData( net::DataOStream& os )
00079 {
00080
00081
00082
00083
00084 const uint64_t dirty = DIRTY_CUSTOM - 1;
00085 os << dirty;
00086 serialize( os, dirty );
00087 }
00088
00089 namespace
00090 {
00091 class ViewUpdater : public ConfigVisitor
00092 {
00093 public:
00094 ViewUpdater( const ChannelVector& channels ) : _channels( channels ) {}
00095 virtual ~ViewUpdater() {}
00096
00097 virtual VisitorResult visit( Compound* compound )
00098 {
00099 const Channel* channel = compound->getChannel();
00100 if( !channel )
00101 return TRAVERSE_CONTINUE;
00102
00103 if( !compound->isDestination( ))
00104 return TRAVERSE_PRUNE;
00105
00106 if( std::find( _channels.begin(), _channels.end(), channel ) !=
00107 _channels.end( ))
00108 {
00109 compound->updateFrustum();
00110 }
00111
00112 return TRAVERSE_PRUNE;
00113 }
00114 private:
00115 const ChannelVector& _channels;
00116 };
00117 }
00118
00119 void View::deserialize( net::DataIStream& is, const uint64_t dirtyBits )
00120 {
00121 eq::View::deserialize( is, dirtyBits );
00122
00123 if( dirtyBits & ( DIRTY_WALL | DIRTY_PROJECTION | DIRTY_OVERDRAW ))
00124 {
00125 const ChannelVector& channels = getChannels();
00126 Config* config = getConfig();
00127 EQASSERT( config );
00128
00129 ViewUpdater updater( channels );
00130 config->accept( updater );
00131 }
00132 }
00133
00134 void View::setViewport( const Viewport& viewport )
00135 {
00136 _viewport = viewport;
00137 setDirty( DIRTY_VIEWPORT );
00138 }
00139
00140 Config* View::getConfig()
00141 {
00142 EQASSERT( _layout );
00143 return _layout ? _layout->getConfig() : 0;
00144 }
00145
00146 const Config* View::getConfig() const
00147 {
00148 EQASSERT( _layout );
00149 return _layout ? _layout->getConfig() : 0;
00150 }
00151
00152 void View::addChannel( Channel* channel )
00153 {
00154 _channels.push_back( channel );
00155 }
00156
00157 bool View::removeChannel( Channel* channel )
00158 {
00159 ChannelVector::iterator i = find( _channels.begin(),
00160 _channels.end(), channel );
00161
00162 EQASSERT( i != _channels.end( ));
00163 if( i == _channels.end( ))
00164 return false;
00165
00166 _channels.erase( i );
00167 return true;
00168 }
00169
00170 ViewPath View::getPath() const
00171 {
00172 EQASSERT( _layout );
00173 ViewPath path( _layout->getPath( ));
00174
00175 const ViewVector& views = _layout->getViews();
00176 ViewVector::const_iterator i = std::find( views.begin(),
00177 views.end(), this );
00178 EQASSERT( i != views.end( ));
00179 path.viewIndex = std::distance( views.begin(), i );
00180 return path;
00181 }
00182
00183 void View::setObserver( Observer* observer )
00184 {
00185 if( _observer == observer )
00186 return;
00187
00188 _observer = observer;
00189 setDirty( DIRTY_OBSERVER );
00190 }
00191
00192 std::ostream& operator << ( std::ostream& os, const View* view )
00193 {
00194 if( !view )
00195 return os;
00196
00197 os << disableFlush << disableHeader << "view" << std::endl;
00198 os << "{" << std::endl << indent;
00199
00200 const std::string& name = view->getName();
00201 if( !name.empty( ))
00202 os << "name \"" << name << "\"" << std::endl;
00203
00204 const eq::Viewport& vp = view->getViewport();
00205 if( vp.isValid( ) && vp != eq::Viewport::FULL )
00206 os << "viewport " << vp << std::endl;
00207
00208 const Observer* observer = static_cast< const Observer* >(
00209 view->getObserver( ));
00210 if( observer )
00211 {
00212 const Config* config = view->getConfig();
00213 const std::string& observerName = observer->getName();
00214 if( observerName.empty() ||
00215 config->findObserver( observerName ) != observer )
00216 {
00217 os << observer->getPath() << std::endl;
00218 }
00219 else
00220 os << "observer \"" << observer->getName() << "\"" << std::endl;
00221 }
00222
00223 switch( view->getCurrentType( ))
00224 {
00225 case eq::View::TYPE_WALL:
00226 os << view->getWall() << std::endl;
00227 break;
00228 case eq::View::TYPE_PROJECTION:
00229 os << view->getProjection() << std::endl;
00230 break;
00231 default:
00232 break;
00233 }
00234
00235 os << exdent << "}" << std::endl << enableHeader << enableFlush;
00236 return os;
00237 }
00238
00239 }
00240 }