The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
policy_order.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #ifndef GUI_WIDGETS_AUXILIARY_ITERATOR_POLICY_ORDER_HPP_INCLUDED
16 #define GUI_WIDGETS_AUXILIARY_ITERATOR_POLICY_ORDER_HPP_INCLUDED
17 
20 #include "gui/core/log.hpp"
21 #include "gui/widgets/widget.hpp"
22 
23 #include <iostream>
24 
25 namespace gui2
26 {
27 
28 namespace iterator
29 {
30 
31 namespace policy
32 {
33 
34 namespace order
35 {
36 
37 template <bool visit_widget, bool visit_grid, bool visit_child>
38 class tbottom_up : public tvisit<visit_widget, twalker_::widget>,
39  public tvisit<visit_grid, twalker_::grid>,
40  public tvisit<visit_child, twalker_::child>
41 {
45 
46 public:
47  explicit tbottom_up(twidget& root) : root_(root.create_walker()), stack_()
48  {
49  TST_GUI_I << "Constructor: ";
50  while(!tvisit_child::at_end(*root_)) {
51  stack_.push_back(root_);
52  root_ = tvisit_child::get(*root_)->create_walker();
53  TST_GUI_I << " Down widget '" << operator*().id() << "'.";
54  }
55 
56  if(!at_end()) {
57  TST_GUI_I << " Finished at '" << operator*().id() << "'.\n";
58  } else {
59  TST_GUI_I << " Finished at the end.\n";
60  }
61  }
62 
64  {
65  delete root_;
67  itor != stack_.end();
68  ++itor) {
69 
70  delete *itor;
71  }
72  }
73 
74  bool at_end() const
75  {
76  return tvisit_widget::at_end(*root_) && tvisit_grid::at_end(*root_)
77  && tvisit_child::at_end(*root_);
78  }
79 
80  bool next()
81  {
82  if(at_end()) {
83  ERR_GUI_I << "Tried to move beyond end of the iteration range."
84  << std::endl;
85  throw trange_error("Tried to move beyond end of range.");
86  }
87 
88  TST_GUI_I << "At '" << operator*().id() << "'.";
89 
90  /***** WIDGET *****/
91  TST_GUI_I << " Iterate widget:";
92  if(!tvisit_widget::at_end(*root_)) {
93  switch(tvisit_widget::next(*root_)) {
94  case twalker_::valid:
95  TST_GUI_I << " visit '" << operator*().id() << "'.\n";
96  return true;
97  case twalker_::invalid:
98  TST_GUI_I << " reached the end.";
99  break;
100  case twalker_::fail:
101  TST_GUI_I << "\n";
102  ERR_GUI_E << "Tried to move beyond end of "
103  "the widget iteration range.\n";
104  throw trange_error("Tried to move beyond end of range.");
105  }
106  } else {
107  TST_GUI_I << " failed.";
108  }
109 
110  /***** GRID *****/
111  TST_GUI_I << " Iterate grid:";
112  if(!tvisit_grid::at_end(*root_)) {
113  switch(tvisit_grid::next(*root_)) {
114  case twalker_::valid:
115  TST_GUI_I << " visit '" << operator*().id() << "'.\n";
116  return true;
117  case twalker_::invalid:
118  TST_GUI_I << " reached the end.";
119  break;
120  case twalker_::fail:
121  TST_GUI_I << "\n";
122  ERR_GUI_E << "Tried to move beyond end of "
123  "the grid iteration range.\n";
124  throw trange_error("Tried to move beyond end of range.");
125  }
126  } else {
127  TST_GUI_I << " failed.";
128  }
129 
130  /***** TRAVERSE CHILDREN *****/
131 
132  TST_GUI_I << " Iterate child:";
133  if(tvisit_child::at_end(*root_)) {
134  if(stack_.empty()) {
135  TST_GUI_I << " Finished iteration.\n";
136  return false;
137  } else {
138  delete root_;
139 
140  root_ = stack_.back();
141  stack_.pop_back();
142  TST_GUI_I << " Up '" << operator*().id() << "'.";
143  }
144  }
145  TST_GUI_I << " Iterate child:";
146  if(!tvisit_child::at_end(*root_)) {
147  switch(tvisit_child::next(*root_)) {
148  case twalker_::valid:
149  TST_GUI_I << " visit '" << operator*().id() << "'.";
150  break;
151  case twalker_::invalid:
152  TST_GUI_I << " reached the end.";
153  break;
154  case twalker_::fail:
155  TST_GUI_I << "\n";
156  ERR_GUI_E << "Tried to move beyond end of "
157  "the child iteration range.\n";
158  throw trange_error("Tried to move beyond end of range.");
159  }
160  } else {
161  TST_GUI_I << " already at the end.";
162  }
163 
164  while(!tvisit_child::at_end(*root_)) {
165  stack_.push_back(root_);
166  root_ = tvisit_child::get(*root_)->create_walker();
167  TST_GUI_I << " Down widget '" << operator*().id() << "'.";
168  }
169  TST_GUI_I << " Visit '" << operator*().id() << "'.\n";
170  return true;
171  }
172 
174  {
175  if(at_end()) {
176  ERR_GUI_I << "Tried to defer beyond end its "
177  "iteration range iterator.\n";
178  throw tlogic_error("Tried to defer an invalid iterator.");
179  }
180  if(!tvisit_widget::at_end(*root_)) {
181  return *tvisit_widget::get(*root_);
182  }
183  if(!tvisit_grid::at_end(*root_)) {
184  return *tvisit_grid::get(*root_);
185  }
186  if(!tvisit_child::at_end(*root_)) {
187  return *tvisit_child::get(*root_);
188  }
189  ERR_GUI_I << "The iterator ended in an unknown "
190  "state while deferring itself.\n";
191  throw tlogic_error("Tried to defer an invalid iterator.");
192  }
193 
194 private:
196 
197  std::vector<iterator::twalker_*> stack_;
198 };
199 
200 template <bool visit_widget, bool visit_grid, bool visit_child>
201 class ttop_down : public tvisit<visit_widget, twalker_::widget>,
202  public tvisit<visit_grid, twalker_::grid>,
203  public tvisit<visit_child, twalker_::child>
204 {
208 
209 public:
210  explicit ttop_down(twidget& root) : root_(root.create_walker()), stack_()
211  {
212  }
213 
215  {
216  delete root_;
218  itor != stack_.end();
219  ++itor) {
220 
221  delete *itor;
222  }
223  }
224 
225  bool at_end() const
226  {
227  return tvisit_widget::at_end(*root_) && tvisit_grid::at_end(*root_)
228  && tvisit_child::at_end(*root_);
229  }
230 
231  bool next()
232  {
233  if(at_end()) {
234  ERR_GUI_I << "Tried to move beyond end of the iteration range."
235  << std::endl;
236  throw trange_error("Tried to move beyond end of range.");
237  }
238 
239  TST_GUI_I << "At '" << operator*().id() << "'.";
240 
241  /***** WIDGET *****/
242  TST_GUI_I << " Iterate widget:";
243  if(!tvisit_widget::at_end(*root_)) {
244  switch(tvisit_widget::next(*root_)) {
245  case twalker_::valid:
246  TST_GUI_I << " visit '" << operator*().id() << "'.\n";
247  return true;
248  case twalker_::invalid:
249  TST_GUI_I << " reached the end.";
250  break;
251  case twalker_::fail:
252  TST_GUI_I << "\n";
253  ERR_GUI_E << "Tried to move beyond end of the "
254  "widget iteration range.\n";
255  throw trange_error("Tried to move beyond end of range.");
256  }
257  } else {
258  TST_GUI_I << " failed.";
259  }
260 
261  /***** GRID *****/
262  TST_GUI_I << " Iterate grid:";
263  if(!tvisit_grid::at_end(*root_)) {
264  switch(tvisit_grid::next(*root_)) {
265  case twalker_::valid:
266  TST_GUI_I << " visit '" << operator*().id() << "'.\n";
267  return true;
268  case twalker_::invalid:
269  TST_GUI_I << " reached the end.";
270  break;
271  case twalker_::fail:
272  TST_GUI_I << "\n";
273  ERR_GUI_E << "Tried to move beyond end of the grid "
274  "iteration range.\n";
275  throw trange_error("Tried to move beyond end of range.");
276  }
277  } else {
278  TST_GUI_I << " failed.";
279  }
280 
281  /***** TRAVERSE CHILDREN *****/
282 
283  TST_GUI_I << " Iterate child:";
284  if(tvisit_child::at_end(*root_)) {
285  TST_GUI_I << " reached the end.";
286  up();
287  } else {
288  TST_GUI_I << " proceed.";
289  }
290 
291  if(!tvisit_child::at_end(*root_)) {
292  stack_.push_back(root_);
293  root_ = tvisit_child::get(*root_)->create_walker();
294 
295  assert(root_);
296  assert(!at_end());
297  TST_GUI_I << " Down and visit '" << operator*().id() << "'.\n";
298  return true;
299  }
300 
301  TST_GUI_I << " Finished iteration.\n";
302  return false;
303  }
304 
306  {
307  if(at_end()) {
308  ERR_GUI_I << "Tried to defer beyond end of the iteration "
309  "range iterator.\n";
310  throw tlogic_error("Tried to defer an invalid iterator.");
311  }
312  if(!tvisit_widget::at_end(*root_)) {
313  return *tvisit_widget::get(*root_);
314  }
315  if(!tvisit_grid::at_end(*root_)) {
316  return *tvisit_grid::get(*root_);
317  }
318  if(!tvisit_child::at_end(*root_)) {
319  return *tvisit_child::get(*root_);
320  }
321  ERR_GUI_I << "The iterator ended in an unknown "
322  "state while deferring iteself.\n";
323  throw tlogic_error("Tried to defer an invalid iterator.");
324  }
325 
326 private:
327  bool up()
328  {
329  while(!stack_.empty()) {
330  delete root_;
331 
332  root_ = stack_.back();
333  stack_.pop_back();
334  TST_GUI_I << " Up widget '" << operator*().id() << "'. Iterate:";
335  switch(tvisit_child::next(*root_)) {
336  case twalker_::valid:
337  TST_GUI_I << " reached '" << operator*().id() << "'.";
338  return true;
339  case twalker_::invalid:
340  TST_GUI_I << " failed.";
341  break;
342  case twalker_::fail:
343  throw trange_error("Tried to move beyond end of range.");
344  }
345  }
346  return true;
347  }
348 
350 
351  std::vector<iterator::twalker_*> stack_;
352 };
353 
354 } // namespace order
355 
356 } // namespace policy
357 
358 } // namespace iterator
359 
360 } // namespace gui2
361 
362 #endif
Define the common log macros for the gui toolkit.
#define ERR_GUI_E
Definition: log.hpp:38
Thrown when deferring an invalid iterator.
Definition: exception.hpp:39
GLuint GLdouble GLdouble GLint GLint order
Definition: glew.h:2972
Helper class to select to visit or skip a level.
tvisit< visit_widget, twalker_::widget > tvisit_widget
Thrown when moving an invalid iterator.
Definition: exception.hpp:57
tvisit< visit_child, twalker_::child > tvisit_child
Contains the exceptions throw by the gui2::iterator::titerator classes.
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
std::vector< iterator::twalker_ * > stack_
tvisit< visit_widget, twalker_::widget > tvisit_widget
When calling next the following it has the following results.
Definition: walker.hpp:60
tvisit< visit_grid, twalker_::grid > tvisit_grid
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
#define TST_GUI_I
Definition: log.hpp:47
std::vector< iterator::twalker_ * > stack_
When calling next the following it has the following results.
Definition: walker.hpp:71
tvisit< visit_grid, twalker_::grid > tvisit_grid
const std::string & id() const
Definition: widget.cpp:109
CURSOR_TYPE get()
Definition: cursor.cpp:194
tvisit< visit_child, twalker_::child > tvisit_child
#define ERR_GUI_I
Definition: log.hpp:55
#define next(ls)
Definition: llex.cpp:27
Base class for all widgets.
Definition: widget.hpp:49
The walker abstract base class.
Definition: walker.hpp:27
std::string::const_iterator iterator
Definition: tokenizer.hpp:21