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
| Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:54 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |