loader.cpp

00001 
00002 /* Copyright (c) 2006-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 "loader.h" 
00019 
00020 #include "canvas.h" 
00021 #include "compound.h" 
00022 #include "config.h" 
00023 #include "layout.h" 
00024 #include "observer.h" 
00025 #include "segment.h" 
00026 #include "serverVisitor.h" 
00027 #include "view.h" 
00028 
00029 using namespace std;
00030 
00031 namespace eq
00032 {
00033 namespace server
00034 {
00035 
00036 namespace
00037 {
00038 class UnusedOutputChannelFinder : public ConfigVisitor
00039 {
00040 public:
00041     UnusedOutputChannelFinder() : _candidate( 0 ) {}
00042 
00043     virtual VisitorResult visit( Channel* channel )
00044         {
00045             if( _candidate ) // testing a candidate (see below)
00046                 return TRAVERSE_CONTINUE;
00047 
00048             const View* view = channel->getView();
00049             if( !view )
00050                 return TRAVERSE_CONTINUE;
00051 
00052             // see if it is used as a destination channel
00053             _candidate = channel;
00054             Config* config = channel->getConfig();
00055             config->accept( *this );
00056 
00057             if( _candidate ) // survived - not a destination channel yet
00058                 _channels.push_back( _candidate );
00059             _candidate = 0;
00060 
00061             return TRAVERSE_CONTINUE;
00062         };
00063 
00064     virtual VisitorResult visit( Compound* compound )
00065         {
00066             if( !_candidate ) // not testing a candidate (see above)
00067                 return TRAVERSE_PRUNE;
00068             
00069             const Channel* channel = compound->getChannel();
00070             if( !channel )
00071                 return TRAVERSE_CONTINUE;
00072 
00073             if( _candidate == channel )
00074             {
00075                 _candidate = 0; // channel already used
00076                 return TRAVERSE_TERMINATE;
00077             }
00078             return TRAVERSE_PRUNE; // only check destination channels
00079         }
00080 
00081     const ChannelVector& getResult() const { return _channels; }
00082 
00083 private:
00084     Channel* _candidate;
00085     ChannelVector _channels;
00086 };
00087 
00088 }
00089 
00090 void Loader::addOutputCompounds( ServerPtr server )
00091 {
00092     const ConfigVector& configs = server->getConfigs();
00093     for( ConfigVector::const_iterator i = configs.begin(); 
00094          i != configs.end(); ++i )
00095     {
00096         UnusedOutputChannelFinder finder;
00097         Config* config = *i;
00098         config->accept( finder );
00099 
00100         const ChannelVector& channels = finder.getResult();
00101         if( channels.empty( ))
00102             continue;
00103 
00104         Compound* group = new Compound;
00105         config->addCompound( group );
00106 
00107         for( ChannelVector::const_iterator j = channels.begin(); 
00108              j != channels.end(); ++j )
00109         {
00110             Compound* compound = new Compound;
00111             group->addChild( compound );
00112 
00113             Channel* channel = *j;
00114             compound->setChannel( channel );
00115         }
00116     }
00117 }
00118 
00119 namespace
00120 {
00121 static void _addDestinationViews( Compound* compound )
00122 {
00123     Channel* channel = compound->getChannel();
00124     
00125     if( channel ) // stand-alone channel
00126     {
00127         if( channel->getView( ))
00128             return;
00129         
00130         Layout* layout = new Layout;
00131         View*   view   = new View;
00132         *static_cast< eq::Frustum* >( view ) = compound->getFrustum();
00133         layout->addView( view );
00134         
00135         Canvas* canvas = new Canvas;
00136         canvas->addLayout( layout );
00137         
00138         Segment* segment = new Segment;
00139         segment->setChannel( channel );
00140         canvas->addSegment( segment );
00141         
00142         Config* config = compound->getConfig();
00143         config->addLayout( layout );
00144         config->addCanvas( canvas );
00145         
00146         Channel* newChannel = config->findChannel( segment, view );
00147         EQASSERT( newChannel );
00148         
00149         compound->setChannel( newChannel );
00150         compound->setViewport( Viewport::FULL );
00151         
00152         return;
00153     }
00154        
00155     // segment group
00156     CompoundVector segments;
00157     const CompoundVector& children = compound->getChildren();
00158     for( CompoundVector::const_iterator i = children.begin();
00159          i != children.end(); ++i )
00160     {
00161         Compound* child = *i;
00162         Channel* childChannel = child->getChannel();
00163         if( childChannel )
00164         {
00165             if( !childChannel->getView( ))
00166                 segments.push_back( child );
00167         }
00168         else
00169             _addDestinationViews( child );
00170     }
00171     
00172     if( segments.empty( ))
00173         return;
00174 
00175     Layout* layout = new Layout;
00176     View*   view   = new View;
00177     layout->addView( view );
00178         
00179     Canvas* canvas = new Canvas;
00180     canvas->addLayout( layout );
00181     *static_cast< eq::Frustum* >( canvas ) = compound->getFrustum();
00182     
00183     for( CompoundVector::const_iterator i = segments.begin(); 
00184          i != segments.end(); ++i )
00185     {
00186         Compound* child = *i;
00187         Segment* segment = new Segment;
00188 
00189         segment->setChannel( child->getChannel( ));
00190         segment->setViewport( child->getViewport( ));
00191         *static_cast< eq::Frustum* >( segment ) = child->getFrustum();
00192 
00193         canvas->addSegment( segment );
00194     }
00195 
00196     Config* config = compound->getConfig();
00197     config->addLayout( layout );
00198     config->addCanvas( canvas );
00199 
00200     for( size_t i = 0; i < segments.size(); ++i )
00201     {
00202         Segment* segment = canvas->getSegments()[ i ];
00203         Channel* newChannel = config->findChannel( segment, view );
00204         EQASSERT( newChannel );
00205         
00206         segments[i]->setChannel( newChannel );
00207         segments[i]->setViewport( Viewport::FULL );
00208     }
00209 }
00210 
00211 class AddDestinationViewVisitor : public ServerVisitor
00212 {
00213     virtual VisitorResult visitPre( Config* config )
00214         {
00215             if( config->getCanvases().empty( ))
00216                 return TRAVERSE_CONTINUE;
00217 
00218             return TRAVERSE_PRUNE; // Config has already canvases, ignore.
00219         }
00220 
00221     virtual VisitorResult visit( Compound* compound )
00222         {
00223             _addDestinationViews( compound );
00224             return TRAVERSE_PRUNE;
00225         }
00226 };
00227 
00228 }
00229 
00230 void Loader::addDestinationViews( ServerPtr server )
00231 {
00232     AddDestinationViewVisitor visitor;
00233     server->accept( visitor );
00234 }
00235 
00236 namespace
00237 {
00238 class AddObserverVisitor : public ServerVisitor
00239 {
00240     virtual VisitorResult visitPre( Config* config )
00241         {
00242             const ObserverVector& observers = config->getObservers();
00243             if( !observers.empty( ))
00244                 return TRAVERSE_PRUNE;
00245 
00246             config->addObserver( new Observer );
00247             return TRAVERSE_CONTINUE;            
00248         }
00249 
00250     virtual VisitorResult visit( View* view )
00251         {
00252             const ObserverVector& observers = view->getConfig()->getObservers();
00253             EQASSERT( observers.size() == 1 );
00254 
00255             view->setObserver( observers.front( ));
00256             return TRAVERSE_CONTINUE; 
00257         }
00258 };
00259 
00260 }
00261 
00262 void Loader::addDefaultObserver( ServerPtr server )
00263 {
00264     AddObserverVisitor visitor;
00265     server->accept( visitor );
00266 }
00267 
00268 }
00269 }
Generated on Mon Aug 10 18:58:40 2009 for Equalizer 0.9 by  doxygen 1.5.8