gui/auxiliary/iterator/iterator.cpp

Go to the documentation of this file.
00001 /* $Id: iterator.cpp 52869 2012-02-03 20:18:33Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2011 - 2012 by Mark de Wever <koraq@xs4all.nl>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #define GETTEXT_DOMAIN "wesnoth-lib"
00017 
00018 #include "gui/auxiliary/iterator/iterator.hpp"
00019 
00020 namespace gui2 {
00021 
00022 namespace iterator {
00023 
00024 
00025 } // namespace iterator
00026 
00027 } // namespace gui2
00028 
00029 
00030 /**
00031  * @page gui2_iterator GUI2 Iterator.
00032  *
00033  * The iterator class allows the user to iterate over a group of widgets.
00034  * The idea is to add a visitor class later as well, where the two classes
00035  * can be combined.
00036  *
00037  * This page describes how the iterator class works. The iterator is build
00038  * from several parts:
00039  * - level, the part and subparts of the widget to visit.
00040  * - walker, iterates over a single widget at several levels.
00041  * - visit policy, whether a level should be visited or not.
00042  * - order policy, the order in which the several levels are traversed.
00043  * - iterator, the user interface for iteration.
00044  *
00045  *
00046  * @section gui2_iterator_level Level
00047  *
00048  * The levels are defined in @ref gui2::iterator::twalker_::tlevel. The
00049  * level allows the user to only visit a part of the widget tree.
00050  *
00051  * @note At the moment when gui2::iterator::twalker_::widget is skipped the
00052  * child class also skips its children. This behaviour might change.
00053  *
00054  *
00055  * @section gui2_iterator_walker Walker
00056  *
00057  * The is a group of classes inheriting from @ref gui2::iterator::twalker_
00058  * the objects are created from @ref gui2::twidget::create_walker. The
00059  * walker allows to visit the several levels of the widget. This means
00060  * several widgets need to override the function in a subclass. For example
00061  * most @em simple widgets don't have a grid or children so they can use the
00062  * walker created from @ref gui2::tcontrol. But containers need to create a
00063  * different walker.
00064  *
00065  *
00066  * @section gui2_iterator_visit_policy Visit policy
00067  *
00068  * This policy simply defines whether or not to visit the widgets at a
00069  * certain level. There are two visit policies:
00070  * - @ref gui2::iterator::policy::visit::tvisit visits the widget at the level.
00071  * - @ref gui2::iterator::policy::visit::tskip skips the widget at the level.
00072  *
00073  * There are no more visit policies expected for the future. These policies
00074  * are normally not used directly, but set from the @ref
00075  * gui2_iterator_order_policy.
00076  *
00077  *
00078  * @section gui2_iterator_order_policy Order policy
00079  *
00080  * This policy determines in which order the widgets are traversed, children
00081  * first, this level before diving down etc. @ref tests/gui/iterator.cpp
00082  * shows more information.
00083  * The following policies have been defined:
00084  * - @ref gui2::iterator::policy::order::ttop_down
00085  * - @ref gui2::iterator::policy::order::tbottom_up
00086  *
00087  * The next sections describe in which order the widgets are visited. In the
00088  * description we use the following widget tree.
00089  *
00090  * [0]          @n
00091  *  \           @n
00092  *   [1|2|3|4]  @n
00093  *    \         @n
00094  *    [5|6|7|8] @n
00095  *
00096  * The types are:
00097  * - grid 0, 1
00098  * - control 2, 3, 4, 6, 7, 8
00099  *
00100  * The examples assume all levels will be visited.
00101  *
00102  *
00103  * @subsection gui2_iterator_visit_policy_top_down Top down
00104  *
00105  * The widgets visited first is the initial widget. After that it tries to go
00106  * down to a child widget and will continue down. Once that fails it will visit
00107  * the siblings at that level before going up again.
00108  *
00109  * @todo Write the entire visiting algorithm.
00110  *
00111  * The visiting order in our example is:
00112  * 0, 1, 5, 6, 7, 8, 2, 3, 4
00113  *
00114  *
00115  * @subsection gui2_iterator_visit_policy_bottom_up Bottom up
00116  *
00117  * When the iterator is created the iterator tries to go down all the child
00118  * widgets to get at the bottom level. That widget will be visited first. Then
00119  * it will first visit all sibblings before going up the the next layer.
00120  *
00121  * @todo Write the entire visiting algorithm.
00122  *
00123  * The visiting order in our example is:
00124  * 5, 6, 7, 8, 1, 2, 3, 4, 0
00125  *
00126  *
00127  * @section gui2_iterator_iterator Iterator
00128  *
00129  * The iterator is the class the users should care about. The user creates the
00130  * iterator with the selected policy and the root widget. Then the user can
00131  * visit the widgets.
00132  *
00133  * When during the iteration a widget is added to or removed from the
00134  * widget-tree being walked the iterator becomes invalid. Using the iterator
00135  * when it is invalid results in Undefined Behaviour.
00136  *
00137  * When it's certain there's at least one widget to visit a simple do while loop
00138  * can be used. It the policy visits the widget, it's certain there is at least
00139  * one widget to visit. Below some sample code:
00140 @code
00141 titerator<policy> itor(root);
00142 assert(!itor.at_end());
00143 do {
00144     ...
00145     ...
00146 } while(itor.next());
00147 @endcode
00148  *
00149  * When there might be no widget to visit a simple for loop can be used:
00150 @code
00151 for(titerator<policy> itor(root); !itor.at_end(); ++itor) {
00152     ...
00153     ...
00154 }
00155 @endcode
00156  *
00157  *
00158  * @subsection gui2_iterator_iterator_design Design
00159  *
00160  * As seen in the examples above the iterator doesn't look like a iterator in
00161  * the C++ standard library. The iterator is more designed after the iterator
00162  * design of the Gang of Four [GoF]. The reason for the different design is that
00163  * GoF design fits better to the classes as a normal C++ iterator. The rest of
00164  * this section explains some of the reasons why this design is chosen. The main
00165  * reason is simple; the iteration of the widgets feels better suited for the
00166  * GoF-style iteration as the C++-style iteration.
00167  *
00168  * The iterator is not lightweight like most C++ iterators, therefore the class
00169  * in non-copyable. (This is for example also the reason why a std::list has no
00170  * operator[].) Since operator++(int) should return a copy of the original
00171  * object it's also omitted.
00172  *
00173  * The design makes it hard to back-track the iteration (or costs more memory),
00174  * so the iterator is forward only. The order policy is added to allow the
00175  * wanted walking direction, but one-way only.
00176  *
00177  * The iterator has a begin, but it's not easy to go back to it and the
00178  * operation involves rewinding the state, which might be costly. Therefore no
00179  * begin() function.
00180  *
00181  * The end is known at the moment it's reached, but not upfront. That combined
00182  * with the forward only, makes implementing an end() hard and therefore it is
00183  * omitted.
00184  *
00185  *
00186  * [GoF] http://en.wikipedia.org/wiki/Design_Patterns_%28book%29
00187  */
00188 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:54 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs