Author: tschmitz
Date: Tue Aug  2 12:17:19 2011
New Revision: 50562

URL: http://svn.gna.org/viewcvs/wesnoth?rev=50562&view=rev
Log:
Added class template visitor_base.

Modified:
    trunk/src/whiteboard/visitor.hpp

Modified: trunk/src/whiteboard/visitor.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/whiteboard/visitor.hpp?rev=50562&r1=50561&r2=50562&view=diff
==============================================================================
--- trunk/src/whiteboard/visitor.hpp (original)
+++ trunk/src/whiteboard/visitor.hpp Tue Aug  2 12:17:19 2011
@@ -20,12 +20,89 @@
 #ifndef WB_VISITOR_HPP_
 #define WB_VISITOR_HPP_
 
+#include "action.hpp"
+#include "side_actions.hpp"
 #include "typedefs.hpp"
+
+#include "play_controller.hpp"
+#include "resources.hpp"
+#include "team.hpp"
 
 #include <boost/noncopyable.hpp>
 
 namespace wb
 {
+
+/**
+ * visitor_base: A base class template, using the so-called CRTP
+ * If you want visit_all() and reverse_visit_all() in your class,
+ *   you should derive from this class.
+ * Derived classes can "override" the following:
+ *   visit, pre_visit_team, post_visit_team
+ * Derived classes should declare visitor_base<Derived> as a friend, or
+ *   else make the overridden functions public.
+ * I recommend making the inheritance private or protected.
+ */
+template<typename Derived>
+class visitor_base
+{
+public:
+       void visit_all() {visit_all_helper<false>();}
+       void reverse_visit_all() {visit_all_helper<true>();}
+
+protected:
+       /**
+        * visit():
+        *   @return Whether or not to continue any visitation after this 
action.
+        * The fcn is commented out because derived classes are required to 
implement it.
+        */
+       //bool visit(size_t team_index, team&, side_actions&, 
side_actions::iterator);
+
+       ///@return Whether or not to visit any of the contents of sa.
+       bool pre_visit_team(size_t team_index, team& t, side_actions& sa) 
{return true;}
+       ///@return Whether or not to visit any more teams after this one.
+       bool post_visit_team(size_t team_index, team& t, side_actions& sa) 
{return true;}
+
+private:
+       template<bool reverse>
+       void visit_all_helper()
+       {
+               Derived* const new_this = static_cast<Derived*>(this);
+
+               size_t const current_team = 
resources::controller->current_side() - 1;
+               size_t const num_teams = resources::teams->size();
+               for(size_t iteration = 0; iteration < num_teams; ++iteration)
+               {
+                       size_t const team_index
+                                       = (current_team+num_teams+(reverse? 
-1-iteration: iteration)) % num_teams;
+                       team& t = resources::teams->at(team_index);
+                       side_actions& sa = *t.get_side_actions();
+                       if(!new_this->pre_visit_team(team_index,t,sa))
+                               continue; //< Skip this team's actions
+
+                       if(reverse)
+                       {
+                               side_actions::reverse_iterator itor = 
sa.rbegin();
+                               side_actions::reverse_iterator end  = sa.rend();
+                               while(itor!=end) {
+                                       ++itor;
+                                       
if(!new_this->visit(team_index,t,sa,itor.base()))
+                                               return; //< Early abort
+                               }
+                       }
+                       else //forward
+                       {
+                               side_actions::iterator itor = sa.begin();
+                               side_actions::iterator end  = sa.end();
+                               for(; itor!=end; ++itor)
+                                       
if(!new_this->visit(team_index,t,sa,itor))
+                                               return; //< Early abort
+                       }
+                       if(!new_this->post_visit_team(team_index,t,sa))
+                               break; //< Early abort
+               }
+       }
+};
 
 /**
  * Abstract base class for all the visitors (cf GoF Visitor Design Pattern)


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to