The Battle for Wesnoth  1.17.0-dev
iterator.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2021
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
19 
20 namespace gui2
21 {
22 
23 namespace iteration
24 {
25 
26 
27 } // namespace iteration
28 
29 } // namespace gui2
30 
31 
32 /**
33  * @page gui2_iterator GUI2 Iterator.
34  *
35  * The iterator class allows the user to iterate over a group of widgets.
36  * The idea is to add a visitor class later as well, where the two classes
37  * can be combined.
38  *
39  * This page describes how the iterator class works. The iterator is build
40  * from several parts:
41  * - level, the part and subparts of the widget to visit.
42  * - walker, iterates over a single widget at several levels.
43  * - visit policy, whether a level should be visited or not.
44  * - order policy, the order in which the several levels are traversed.
45  * - iterator, the user interface for iteration.
46  *
47  *
48  * @section gui2_iterator_level Level
49  *
50  * The levels are defined in @ref gui2::iteration::walker_base::level. The
51  * level allows the user to only visit a part of the widget tree.
52  *
53  * @note At the moment when gui2::iteration::walker_base::widget is skipped the
54  * child class also skips its children. This behavior might change.
55  *
56  *
57  * @section gui2_iterator_walker Walker
58  *
59  * The is a group of classes inheriting from @ref gui2::iteration::walker_base
60  * the objects are created from @ref gui2::widget::create_walker. The
61  * walker allows to visit the several levels of the widget. This means
62  * several widgets need to override the function in a subclass. For example
63  * most @em simple widgets don't have a grid or children so they can use the
64  * walker created from @ref gui2::styled_widget. But containers need to create a
65  * different walker.
66  *
67  *
68  * @section gui2_iterator_visit_policy Visit policy
69  *
70  * This policy simply defines whether or not to visit the widgets at a
71  * certain level. There are two visit policies:
72  * - @ref gui2::iteration::policy::visit::visit_level visits the widget at the level.
73  * - @ref gui2::iteration::policy::visit::skip_level skips the widget at the level.
74  *
75  * There are no more visit policies expected for the future. These policies
76  * are normally not used directly, but set from the @ref
77  * gui2_iterator_order_policy.
78  *
79  *
80  * @section gui2_iterator_order_policy Order policy
81  *
82  * This policy determines in which order the widgets are traversed, children
83  * first, this level before diving down etc. @ref tests/gui/iterator.cpp
84  * shows more information.
85  * The following policies have been defined:
86  * - @ref gui2::iteration::policy::order::top_down
87  * - @ref gui2::iteration::policy::order::bottom_up
88  *
89  * The next sections describe in which order the widgets are visited. In the
90  * description we use the following widget tree.
91  *
92  * [0] @n
93  * \ @n
94  * [1|2|3|4] @n
95  * \ @n
96  * [5|6|7|8] @n
97  *
98  * The types are:
99  * - grid 0, 1
100  * - styled_widget 2, 3, 4, 6, 7, 8
101  *
102  * The examples assume all levels will be visited.
103  *
104  *
105  * @subsection gui2_iterator_visit_policy_top_down Top down
106  *
107  * The widgets visited first is the initial widget. After that it tries to go
108  * down to a child widget and will continue down. Once that fails it will visit
109  * the siblings at that level before going up again.
110  *
111  * @todo Write the entire visiting algorithm.
112  *
113  * The visiting order in our example is:
114  * 0, 1, 5, 6, 7, 8, 2, 3, 4
115  *
116  *
117  * @subsection gui2_iterator_visit_policy_bottom_up Bottom up
118  *
119  * When the iterator is created the iterator tries to go down all the child
120  * widgets to get at the bottom level. That widget will be visited first. Then
121  * it will first visit all siblings before going up the the next layer.
122  *
123  * @todo Write the entire visiting algorithm.
124  *
125  * The visiting order in our example is:
126  * 5, 6, 7, 8, 1, 2, 3, 4, 0
127  *
128  *
129  * @section gui2_iterator_iterator Iterator
130  *
131  * The iterator is the class the users should care about. The user creates the
132  * iterator with the selected policy and the root widget. Then the user can
133  * visit the widgets.
134  *
135  * When during the iteration a widget is added to or removed from the
136  * widget-tree being walked the iterator becomes invalid. Using the iterator
137  * when it is invalid results in Undefined Behavior.
138  *
139  * When it's certain there's at least one widget to visit a simple do while loop
140  * can be used. It the policy visits the widget, it's certain there is at least
141  * one widget to visit. Below some sample code:
142 @code
143 iterator<policy> itor(root);
144 assert(!itor.at_end());
145 do {
146  ...
147  ...
148 } while(itor.next());
149 @endcode
150  *
151  * When there might be no widget to visit a simple for loop can be used:
152 @code
153 for(iterator<policy> itor(root); !itor.at_end(); ++itor) {
154  ...
155  ...
156 }
157 @endcode
158  *
159  *
160  * @subsection gui2_iterator_iterator_design Design
161  *
162  * As seen in the examples above the iterator doesn't look like a iterator in
163  * the C++ standard library. The iterator is more designed after the iterator
164  * design of the Gang of Four [GoF]. The reason for the different design is that
165  * GoF design fits better to the classes as a normal C++ iterator. The rest of
166  * this section explains some of the reasons why this design is chosen. The main
167  * reason is simple; the iteration of the widgets feels better suited for the
168  * GoF-style iteration as the C++-style iteration.
169  *
170  * The iterator is not lightweight like most C++ iterators, therefore the class
171  * in non-copyable. (This is for example also the reason why a std::list has no
172  * operator[].) Since operator++(int) should return a copy of the original
173  * object it's also omitted.
174  *
175  * The design makes it hard to back-track the iteration (or costs more memory),
176  * so the iterator is forward only. The order policy is added to allow the
177  * wanted walking direction, but one-way only.
178  *
179  * The iterator has a begin, but it's not easy to go back to it and the
180  * operation involves rewinding the state, which might be costly. Therefore no
181  * begin() function.
182  *
183  * The end is known at the moment it's reached, but not upfront. That combined
184  * with the forward only, makes implementing an end() hard and therefore it is
185  * omitted.
186  *
187  *
188  * [GoF] http://en.wikipedia.org/wiki/Design_Patterns_%28book%29
189  */
Generic file dialog.
Definition: field-fwd.hpp:23
Contains the base iterator class for the gui2 widgets.