Equalizer  1.6.1
removeWindow.h
1 
2 /* Copyright (c) 2010, Stefan Eilemann <eile@eyescale.ch>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer. Redistributions in binary
9  * form must reproduce the above copyright notice, this list of conditions and
10  * the following disclaimer in the documentation and/or other materials provided
11  * with the distribution. Neither the name of Eyescale Software GmbH nor the
12  * names of its contributors may be used to endorse or promote products derived
13  * from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef EQ_ADMIN_REMOVE_WINDOW_H
29 #define EQ_ADMIN_REMOVE_WINDOW_H
30 
31 #include "findPipe.h"
32 
33 #include <eq/admin/base.h>
34 
35 namespace eqAdmin
36 {
37 namespace
38 {
39 class FindChannelSegments : public eq::admin::ConfigVisitor
40 {
41 public:
42  FindChannelSegments( eq::admin::Channel* channel ) : _channel( channel ) {}
43  virtual ~FindChannelSegments() {}
44 
45  virtual eq::admin::VisitorResult visit( eq::admin::Segment* segment )
46  {
47  if( segment->getChannel() == _channel )
48  _segments.push_back( segment );
49  return eq::admin::TRAVERSE_CONTINUE;
50  }
51 
52  const eq::admin::Segments& getResult() const { return _segments; }
53 
54 private:
55  eq::admin::Channel* const _channel;
56  eq::admin::Segments _segments;
57 };
58 
59 class FindCanvasLayouts : public eq::admin::ConfigVisitor
60 {
61 public:
62  FindCanvasLayouts( const eq::admin::Canvas* canvas )
63  : _canvas( canvas ), _layout( 0 ) {}
64  virtual ~FindCanvasLayouts() {}
65 
66  virtual eq::admin::VisitorResult visitPre( eq::admin::Canvas* canvas )
67  {
68  if( canvas == _canvas && !_layout )
69  {
70  const eq::admin::Layouts& layouts = canvas->getLayouts();
71  eq::admin::Config* config = canvas->getConfig();
72  for( eq::admin::Layouts::const_iterator i = layouts.begin();
73  i != layouts.end(); ++i )
74  {
75  _layout = *i;
76  if( _layout &&
77  config->accept(*this) == eq::admin::TRAVERSE_CONTINUE )
78  {
79  _layouts.push_back( _layout );
80  }
81  }
82  _layout = 0;
83  return eq::admin::TRAVERSE_TERMINATE;
84  }
85  else if( canvas != _canvas && _layout )
86  {
87  const eq::admin::Layouts& layouts = canvas->getLayouts();
88  if( stde::find( layouts, _layout ) != layouts.end( ))
89  return eq::admin::TRAVERSE_TERMINATE; // layout used by this canvas
90  }
91  return eq::admin::TRAVERSE_CONTINUE;
92  }
93 
94  const eq::admin::Layouts& getResult() const { return _layouts; }
95 
96 private:
97  const eq::admin::Canvas* const _canvas;
98  eq::admin::Layout* _layout;
99  eq::admin::Layouts _layouts;
100 };
101 
102 class FindLayoutObservers : public eq::admin::ConfigVisitor
103 {
104 public:
105  FindLayoutObservers( const eq::admin::Layout* layout )
106  : _layout( layout ), _observer( 0 ) {}
107  virtual ~FindLayoutObservers() {}
108 
109  virtual eq::admin::VisitorResult visit( eq::admin::View* view )
110  {
111  if( view->getLayout() == _layout && !_observer )
112  {
113  eq::admin::Config* config = view->getConfig();
114  _observer = view->getObserver();
115  if( _observer &&
116  config->accept(*this) == eq::admin::TRAVERSE_CONTINUE )
117  {
118  _observers.push_back( _observer );
119  view->setObserver( 0 ); // observer will be deleted
120  }
121  _observer = 0;
122  return eq::admin::TRAVERSE_TERMINATE;
123  }
124  else if( view->getLayout() != _layout && _observer )
125  {
126  if( _observer == view->getObserver( ))
127  return eq::admin::TRAVERSE_TERMINATE; // used by layout
128  }
129  return eq::admin::TRAVERSE_CONTINUE;
130  }
131 
132  const eq::admin::Observers& getResult() const { return _observers; }
133 
134 private:
135  const eq::admin::Layout* const _layout;
136  eq::admin::Observer* _observer;
137  eq::admin::Observers _observers;
138 };
139 
140 }
141 
142 inline bool removeWindow( eq::admin::ServerPtr server )
143 {
144  if( !server )
145  return false;
146 
147  // Find first pipe...
148  eq::admin::Pipe* pipe = findPipe( server );
149  if( !pipe )
150  return false;
151 
152  const eq::admin::Windows& windows = pipe->getWindows();
153  if( windows.size() < 2 )
154  return false;
155 
156  // Remove last window (->channels->segment->canvas->layout->view)
157  eq::admin::Window* window = windows.back();
158  eq::admin::Config* config = pipe->getConfig();
159 
160  const eq::admin::Channels& channels = window->getChannels();
161  for( eq::admin::Channels::const_iterator i = channels.begin();
162  i != channels.end(); ++i )
163  {
164  // delete dependent segments
165  eq::admin::Channel* channel = *i;
166  FindChannelSegments channelSegments( channel );
167  config->accept( channelSegments );
168  const eq::admin::Segments& segments = channelSegments.getResult();
169 
170  for( eq::admin::Segments::const_iterator j = segments.begin();
171  j != segments.end(); ++j )
172  {
173  eq::admin::Segment* segment = *j;
174  eq::admin::Canvas* canvas = segment->getCanvas();
175  delete segment;
176 
177  // delete now-empty canvases
178  if( !canvas->getSegments().empty( ))
179  continue;
180 
181  // delete now-empty layouts
182  FindCanvasLayouts canvasLayouts( canvas );
183  config->accept( canvasLayouts );
184  const eq::admin::Layouts& layouts = canvasLayouts.getResult();
185  for( eq::admin::Layouts::const_iterator k = layouts.begin();
186  k != layouts.end(); ++k )
187  {
188  eq::admin::Layout* layout = *k;
189  FindLayoutObservers layoutObservers( layout );
190  config->accept( layoutObservers );
191  eq::admin::Observers observers = layoutObservers.getResult();
192  stde::usort( observers );
193 
194  for( eq::admin::Observers::const_iterator l = observers.begin();
195  l != observers.end(); ++l )
196  {
197  delete *l;
198  }
199  delete layout;
200  }
201  delete canvas;
202  }
203  }
204 
205  delete window;
206  config->commit();
207  return true;
208 }
209 
210 }
211 #endif // EQ_ADMIN_REMOVE_WINDOW_H