gui/auxiliary/iterator/policy_order.hpp

Go to the documentation of this file.
00001 /* $Id: policy_order.hpp 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 #ifndef GUI_WIDGETS_AUXILIARY_ITERATOR_POLICY_ORDER_HPP_INCLUDED
00017 #define GUI_WIDGETS_AUXILIARY_ITERATOR_POLICY_ORDER_HPP_INCLUDED
00018 
00019 #include "gui/auxiliary/iterator/exception.hpp"
00020 #include "gui/auxiliary/iterator/policy_visit.hpp"
00021 #include "gui/auxiliary/log.hpp"
00022 #include "gui/widgets/widget.hpp"
00023 
00024 #include <iostream>
00025 
00026 namespace gui2 {
00027 
00028 namespace iterator {
00029 
00030 namespace policy {
00031 
00032 namespace order {
00033 
00034 template<
00035       bool visit_widget
00036     , bool visit_grid
00037     , bool visit_child
00038     >
00039 class tbottom_up
00040     : public tvisit<visit_widget, twalker_::widget>
00041     , public tvisit<visit_grid, twalker_::grid>
00042     , public tvisit<visit_child, twalker_::child>
00043 {
00044     typedef tvisit<visit_widget, twalker_::widget> tvisit_widget;
00045     typedef tvisit<visit_grid, twalker_::grid> tvisit_grid;
00046     typedef tvisit<visit_child, twalker_::child> tvisit_child;
00047 public:
00048     explicit tbottom_up(twidget& root)
00049         : root_(root.create_walker())
00050         , stack_()
00051     {
00052         TST_GUI_I << "Constructor: ";
00053         while(!tvisit_child::at_end(*root_)) {
00054             stack_.push_back(root_);
00055             root_ = tvisit_child::get(*root_)->create_walker();
00056             TST_GUI_I << " Down widget '" << operator*().id() << "'.";
00057         }
00058 
00059         if(!at_end()) {
00060             TST_GUI_I << " Finished at '" << operator*().id() << "'.\n";
00061         } else {
00062             TST_GUI_I << " Finished at the end.\n";
00063         }
00064     }
00065 
00066     ~tbottom_up()
00067     {
00068         delete root_;
00069         for(std::vector<iterator::twalker_*>::iterator itor = stack_.begin()
00070                 ; itor != stack_.end()
00071                 ; ++itor) {
00072 
00073             delete *itor;
00074         }
00075     }
00076 
00077     bool at_end() const
00078     {
00079         return tvisit_widget::at_end(*root_)
00080                 && tvisit_grid::at_end(*root_)
00081                 && tvisit_child::at_end(*root_);
00082     }
00083 
00084     bool next()
00085     {
00086         if(at_end()) {
00087             ERR_GUI_I << "Tried to move beyond end of the iteration range.\n";
00088             throw trange_error("Tried to move beyond end of range.");
00089         }
00090 
00091         TST_GUI_I << "At '" << operator*().id() << "'.";
00092 
00093         /***** WIDGET *****/
00094         TST_GUI_I << " Iterate widget:";
00095         if(!tvisit_widget::at_end(*root_)) {
00096             switch(tvisit_widget::next(*root_)) {
00097                 case twalker_::valid :
00098                     TST_GUI_I << " visit '" << operator*().id() << "'.\n";
00099                     return true;
00100                 case twalker_::invalid :
00101                     TST_GUI_I << " reached the end.";
00102                     break;
00103                 case twalker_::fail:
00104                     TST_GUI_I << "\n";
00105                     ERR_GUI_E << "Tried to move beyond end of "
00106                             "the widget iteration range.\n";
00107                     throw trange_error("Tried to move beyond end of range.");
00108             }
00109         } else {
00110             TST_GUI_I << " failed.";
00111         }
00112 
00113         /***** GRID *****/
00114         TST_GUI_I << " Iterate grid:";
00115         if(!tvisit_grid::at_end(*root_)) {
00116             switch(tvisit_grid::next(*root_)) {
00117                 case twalker_::valid :
00118                     TST_GUI_I << " visit '" << operator*().id() << "'.\n";
00119                     return true;
00120                 case twalker_::invalid :
00121                     TST_GUI_I << " reached the end.";
00122                     break;
00123                 case twalker_::fail:
00124                     TST_GUI_I << "\n";
00125                     ERR_GUI_E << "Tried to move beyond end of "
00126                             "the grid iteration range.\n";
00127                     throw trange_error("Tried to move beyond end of range.");
00128             }
00129         } else {
00130             TST_GUI_I << " failed.";
00131         }
00132 
00133         /***** TRAVERSE CHILDREN *****/
00134 
00135         TST_GUI_I << " Iterate child:";
00136         if(tvisit_child::at_end(*root_)) {
00137             if(stack_.empty()) {
00138                 TST_GUI_I << " Finished iteration.\n";
00139                 return false;
00140             } else {
00141                 delete root_;
00142 
00143                 root_ = stack_.back();
00144                 stack_.pop_back();
00145                 TST_GUI_I << " Up '" << operator*().id() << "'.";
00146             }
00147         }
00148         TST_GUI_I << " Iterate child:";
00149         if(!tvisit_child::at_end(*root_)) {
00150             switch(tvisit_child::next(*root_)) {
00151                 case twalker_::valid :
00152                     TST_GUI_I << " visit '" << operator*().id() << "'.";
00153                     break;
00154                 case twalker_::invalid :
00155                     TST_GUI_I << " reached the end.";
00156                     break;
00157                 case twalker_::fail:
00158                     TST_GUI_I << "\n";
00159                     ERR_GUI_E << "Tried to move beyond end of "
00160                             "the child iteration range.\n";
00161                     throw trange_error("Tried to move beyond end of range.");
00162             }
00163         } else {
00164             TST_GUI_I << " already at the end.";
00165         }
00166 
00167         while(!tvisit_child::at_end(*root_)) {
00168             stack_.push_back(root_);
00169             root_ = tvisit_child::get(*root_)->create_walker();
00170             TST_GUI_I << " Down widget '"
00171                 << operator*().id() << "'.";
00172         }
00173         TST_GUI_I << " Visit '" << operator*().id() << "'.\n";
00174         return true;
00175     }
00176 
00177     twidget& operator*()
00178     {
00179         if(at_end()) {
00180             ERR_GUI_I << "Tried to defer beyond end its "
00181                     "iteration range iterator.\n";
00182             throw tlogic_error("Tried to defer an invalid iterator.");
00183         }
00184         if(!tvisit_widget::at_end(*root_)) {
00185             return *tvisit_widget::get(*root_);
00186         }
00187         if(!tvisit_grid::at_end(*root_)) {
00188             return *tvisit_grid::get(*root_);
00189         }
00190         if(!tvisit_child::at_end(*root_)) {
00191             return *tvisit_child::get(*root_);
00192         }
00193         ERR_GUI_I << "The iterator ended in an unknown "
00194                 "state while deferring iteself.\n";
00195         throw tlogic_error("Tried to defer an invalid iterator.");
00196     }
00197 
00198 private:
00199 
00200     iterator::twalker_* root_;
00201 
00202     std::vector<iterator::twalker_*> stack_;
00203 };
00204 
00205 template<
00206       bool visit_widget
00207     , bool visit_grid
00208     , bool visit_child
00209     >
00210 class ttop_down
00211     : public tvisit<visit_widget, twalker_::widget>
00212     , public tvisit<visit_grid, twalker_::grid>
00213     , public tvisit<visit_child, twalker_::child>
00214 {
00215     typedef tvisit<visit_widget, twalker_::widget> tvisit_widget;
00216     typedef tvisit<visit_grid, twalker_::grid> tvisit_grid;
00217     typedef tvisit<visit_child, twalker_::child> tvisit_child;
00218 public:
00219     explicit ttop_down (twidget& root)
00220         : root_(root.create_walker())
00221         , stack_()
00222     {
00223     }
00224 
00225     ~ttop_down()
00226     {
00227         delete root_;
00228         for(std::vector<iterator::twalker_*>::iterator itor = stack_.begin()
00229                 ; itor != stack_.end()
00230                 ; ++itor) {
00231 
00232             delete *itor;
00233         }
00234     }
00235 
00236     bool at_end() const
00237     {
00238         return tvisit_widget::at_end(*root_)
00239                 && tvisit_grid::at_end(*root_)
00240                 && tvisit_child::at_end(*root_);
00241     }
00242 
00243     bool next()
00244     {
00245         if(at_end()) {
00246             ERR_GUI_I << "Tried to move beyond end of the iteration range.\n";
00247             throw trange_error("Tried to move beyond end of range.");
00248         }
00249 
00250         TST_GUI_I << "At '" << operator*().id() << "'.";
00251 
00252         /***** WIDGET *****/
00253         TST_GUI_I << " Iterate widget:";
00254         if(!tvisit_widget::at_end(*root_)) {
00255             switch(tvisit_widget::next(*root_)) {
00256                 case twalker_::valid :
00257                     TST_GUI_I << " visit '" << operator*().id() << "'.\n";
00258                     return true;
00259                 case twalker_::invalid :
00260                     TST_GUI_I << " reached the end.";
00261                     break;
00262                 case twalker_::fail:
00263                     TST_GUI_I << "\n";
00264                     ERR_GUI_E << "Tried to move beyond end of the "
00265                             "widget iteration range.\n";
00266                     throw trange_error("Tried to move beyond end of range.");
00267             }
00268         } else {
00269             TST_GUI_I << " failed.";
00270         }
00271 
00272         /***** GRID *****/
00273         TST_GUI_I << " Iterate grid:";
00274         if(!tvisit_grid::at_end(*root_)) {
00275             switch(tvisit_grid::next(*root_)) {
00276                 case twalker_::valid :
00277                     TST_GUI_I << " visit '" << operator*().id() << "'.\n";
00278                     return true;
00279                 case twalker_::invalid :
00280                     TST_GUI_I << " reached the end.";
00281                     break;
00282                 case twalker_::fail:
00283                     TST_GUI_I << "\n";
00284                     ERR_GUI_E << "Tried to move beyond end of the grid "
00285                             "iteration range.\n";
00286                     throw trange_error("Tried to move beyond end of range.");
00287             }
00288         } else {
00289             TST_GUI_I << " failed.";
00290         }
00291 
00292         /***** TRAVERSE CHILDREN *****/
00293 
00294         TST_GUI_I << " Iterate child:";
00295         if(tvisit_child::at_end(*root_)) {
00296             TST_GUI_I << " reached the end.";
00297             up();
00298         } else {
00299             TST_GUI_I << " proceed.";
00300         }
00301 
00302         if(!tvisit_child::at_end(*root_)) {
00303             stack_.push_back(root_);
00304             root_ = tvisit_child::get(*root_)->create_walker();
00305 
00306             assert(root_);
00307             assert(!at_end());
00308             TST_GUI_I << " Down and visit '" << operator*().id() << "'.\n";
00309             return true;
00310         }
00311 
00312         TST_GUI_I << " Finished iteration.\n";
00313         return false;
00314     }
00315 
00316     twidget& operator*()
00317     {
00318         if(at_end()) {
00319             ERR_GUI_I << "Tried to defer beyond end of the iteration "
00320                     "range iterator.\n";
00321             throw tlogic_error("Tried to defer an invalid iterator.");
00322         }
00323         if(!tvisit_widget::at_end(*root_)) {
00324             return *tvisit_widget::get(*root_);
00325         }
00326         if(!tvisit_grid::at_end(*root_)) {
00327             return *tvisit_grid::get(*root_);
00328         }
00329         if(!tvisit_child::at_end(*root_)) {
00330             return *tvisit_child::get(*root_);
00331         }
00332         ERR_GUI_I << "The iterator ended in an unknown "
00333                 "state while deferring iteself.\n";
00334         throw tlogic_error("Tried to defer an invalid iterator.");
00335     }
00336 
00337 private:
00338 
00339     bool up()
00340     {
00341         while(!stack_.empty()) {
00342             delete root_;
00343 
00344             root_ = stack_.back();
00345             stack_.pop_back();
00346             TST_GUI_I << " Up widget '" << operator*().id() << "'. Iterate:";
00347             switch(tvisit_child::next(*root_)) {
00348                 case twalker_::valid:
00349                     TST_GUI_I << " reached '" << operator*().id() << "'.";
00350                     return true;
00351                 case twalker_::invalid:
00352                     TST_GUI_I << " failed.";
00353                     break;
00354                 case twalker_::fail:
00355                     throw trange_error("Tried to move beyond end of range.");
00356             }
00357         }
00358         return true;
00359     }
00360 
00361     iterator::twalker_* root_;
00362 
00363     std::vector<iterator::twalker_*> stack_;
00364 };
00365 
00366 } // namespace order
00367 
00368 } // namespace policy
00369 
00370 } // namespace iterator
00371 
00372 } // namespace gui2
00373 
00374 #endif
00375 
00376 
 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