Equalizer
1.4.1
|
00001 00002 /* Copyright (c) 2010, Stefan Eilemann <eile@eyescale.ch> 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * 00007 * Redistributions of source code must retain the above copyright notice, this 00008 * list of conditions and the following disclaimer. Redistributions in binary 00009 * form must reproduce the above copyright notice, this list of conditions and 00010 * the following disclaimer in the documentation and/or other materials provided 00011 * with the distribution. Neither the name of Eyescale Software GmbH nor the 00012 * names of its contributors may be used to endorse or promote products derived 00013 * from this software without specific prior written permission. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00019 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00025 * POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 #ifndef EQ_ADMIN_REMOVE_WINDOW_H 00029 #define EQ_ADMIN_REMOVE_WINDOW_H 00030 00031 #include "findPipe.h" 00032 00033 #include <eq/admin/base.h> 00034 00035 namespace eqAdmin 00036 { 00037 namespace 00038 { 00039 class FindChannelSegments : public eq::admin::ConfigVisitor 00040 { 00041 public: 00042 FindChannelSegments( eq::admin::Channel* channel ) : _channel( channel ) {} 00043 virtual ~FindChannelSegments() {} 00044 00045 virtual eq::admin::VisitorResult visit( eq::admin::Segment* segment ) 00046 { 00047 if( segment->getChannel() == _channel ) 00048 _segments.push_back( segment ); 00049 return eq::admin::TRAVERSE_CONTINUE; 00050 } 00051 00052 const eq::admin::Segments& getResult() const { return _segments; } 00053 00054 private: 00055 eq::admin::Channel* const _channel; 00056 eq::admin::Segments _segments; 00057 }; 00058 00059 class FindCanvasLayouts : public eq::admin::ConfigVisitor 00060 { 00061 public: 00062 FindCanvasLayouts( const eq::admin::Canvas* canvas ) 00063 : _canvas( canvas ), _layout( 0 ) {} 00064 virtual ~FindCanvasLayouts() {} 00065 00066 virtual eq::admin::VisitorResult visitPre( eq::admin::Canvas* canvas ) 00067 { 00068 if( canvas == _canvas && !_layout ) 00069 { 00070 const eq::admin::Layouts& layouts = canvas->getLayouts(); 00071 eq::admin::Config* config = canvas->getConfig(); 00072 for( eq::admin::Layouts::const_iterator i = layouts.begin(); 00073 i != layouts.end(); ++i ) 00074 { 00075 _layout = *i; 00076 if( _layout && 00077 config->accept(*this) == eq::admin::TRAVERSE_CONTINUE ) 00078 { 00079 _layouts.push_back( _layout ); 00080 } 00081 } 00082 _layout = 0; 00083 return eq::admin::TRAVERSE_TERMINATE; 00084 } 00085 else if( canvas != _canvas && _layout ) 00086 { 00087 const eq::admin::Layouts& layouts = canvas->getLayouts(); 00088 if( stde::find( layouts, _layout ) != layouts.end( )) 00089 return eq::admin::TRAVERSE_TERMINATE; // layout used by this canvas 00090 } 00091 return eq::admin::TRAVERSE_CONTINUE; 00092 } 00093 00094 const eq::admin::Layouts& getResult() const { return _layouts; } 00095 00096 private: 00097 const eq::admin::Canvas* const _canvas; 00098 eq::admin::Layout* _layout; 00099 eq::admin::Layouts _layouts; 00100 }; 00101 00102 class FindLayoutObservers : public eq::admin::ConfigVisitor 00103 { 00104 public: 00105 FindLayoutObservers( const eq::admin::Layout* layout ) 00106 : _layout( layout ), _observer( 0 ) {} 00107 virtual ~FindLayoutObservers() {} 00108 00109 virtual eq::admin::VisitorResult visit( eq::admin::View* view ) 00110 { 00111 if( view->getLayout() == _layout && !_observer ) 00112 { 00113 eq::admin::Config* config = view->getConfig(); 00114 _observer = view->getObserver(); 00115 if( _observer && 00116 config->accept(*this) == eq::admin::TRAVERSE_CONTINUE ) 00117 { 00118 _observers.push_back( _observer ); 00119 view->setObserver( 0 ); // observer will be deleted 00120 } 00121 _observer = 0; 00122 return eq::admin::TRAVERSE_TERMINATE; 00123 } 00124 else if( view->getLayout() != _layout && _observer ) 00125 { 00126 if( _observer == view->getObserver( )) 00127 return eq::admin::TRAVERSE_TERMINATE; // used by layout 00128 } 00129 return eq::admin::TRAVERSE_CONTINUE; 00130 } 00131 00132 const eq::admin::Observers& getResult() const { return _observers; } 00133 00134 private: 00135 const eq::admin::Layout* const _layout; 00136 eq::admin::Observer* _observer; 00137 eq::admin::Observers _observers; 00138 }; 00139 00140 } 00141 00142 inline bool removeWindow( eq::admin::ServerPtr server ) 00143 { 00144 if( !server ) 00145 return false; 00146 00147 // Find first pipe... 00148 eq::admin::Pipe* pipe = findPipe( server ); 00149 if( !pipe ) 00150 return false; 00151 00152 const eq::admin::Windows& windows = pipe->getWindows(); 00153 if( windows.size() < 2 ) 00154 return false; 00155 00156 // Remove last window (->channels->segment->canvas->layout->view) 00157 eq::admin::Window* window = windows.back(); 00158 eq::admin::Config* config = pipe->getConfig(); 00159 00160 const eq::admin::Channels& channels = window->getChannels(); 00161 for( eq::admin::Channels::const_iterator i = channels.begin(); 00162 i != channels.end(); ++i ) 00163 { 00164 // delete dependent segments 00165 eq::admin::Channel* channel = *i; 00166 FindChannelSegments channelSegments( channel ); 00167 config->accept( channelSegments ); 00168 const eq::admin::Segments& segments = channelSegments.getResult(); 00169 00170 for( eq::admin::Segments::const_iterator j = segments.begin(); 00171 j != segments.end(); ++j ) 00172 { 00173 eq::admin::Segment* segment = *j; 00174 eq::admin::Canvas* canvas = segment->getCanvas(); 00175 delete segment; 00176 00177 // delete now-empty canvases 00178 if( !canvas->getSegments().empty( )) 00179 continue; 00180 00181 // delete now-empty layouts 00182 FindCanvasLayouts canvasLayouts( canvas ); 00183 config->accept( canvasLayouts ); 00184 const eq::admin::Layouts& layouts = canvasLayouts.getResult(); 00185 for( eq::admin::Layouts::const_iterator k = layouts.begin(); 00186 k != layouts.end(); ++k ) 00187 { 00188 eq::admin::Layout* layout = *k; 00189 FindLayoutObservers layoutObservers( layout ); 00190 config->accept( layoutObservers ); 00191 eq::admin::Observers observers = layoutObservers.getResult(); 00192 stde::usort( observers ); 00193 00194 for( eq::admin::Observers::const_iterator l = observers.begin(); 00195 l != observers.end(); ++l ) 00196 { 00197 delete *l; 00198 } 00199 delete layout; 00200 } 00201 delete canvas; 00202 } 00203 } 00204 00205 delete window; 00206 config->commit(); 00207 return true; 00208 } 00209 00210 } 00211 #endif // EQ_ADMIN_REMOVE_WINDOW_H