variable.hpp

Go to the documentation of this file.
00001 /* $Id: variable.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2003 by David White <dave@whitevine.net>
00004    Copyright (C) 2005 - 2012 by Philippe Plantier <ayin@anathas.org>
00005 
00006    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY.
00014 
00015    See the COPYING file for more details.
00016 */
00017 #ifndef VARIABLE_H_INCLUDED
00018 #define VARIABLE_H_INCLUDED
00019 
00020 #include "config.hpp"
00021 
00022 #include <utility>
00023 
00024 class game_state;
00025 class unit_map;
00026 
00027 /**
00028  * A variable-expanding proxy for the config class. This class roughly behaves
00029  * as a constant config object, but automatically expands variables.
00030  *
00031  */
00032 class vconfig
00033 {
00034 private:
00035 
00036 /*
00037  * Starting with the rc of gcc 4.6 the code failed to compile due to the
00038  * missing default constructor for vconfig. Not entirely sure whether it's a
00039  * bug in gcc or not. For now make the code conditional.
00040  */
00041 #if __GNUC__ == 4 && __GNUC_MINOR__ == 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
00042     template<class T1, class T2>
00043     friend class std::pair;
00044 #endif
00045 
00046     vconfig();
00047     vconfig(const config* cfg, const config* cache_key);
00048 public:
00049     vconfig(const vconfig& v);
00050     explicit vconfig(const config &cfg, bool is_volatile=false);
00051     ~vconfig();
00052 
00053     static vconfig empty_vconfig(); // Valid to dereference. Contains nothing
00054     static vconfig unconstructed_vconfig(); // Must not be dereferenced
00055 
00056     vconfig& operator=(const vconfig& cfg);
00057 
00058     bool null() const { return cfg_ == NULL; }
00059     bool is_volatile() const { return cache_key_ != NULL; }
00060     const config& get_config() const { return *cfg_; }
00061     const config get_parsed_config() const;
00062 
00063     typedef std::vector<vconfig> child_list;
00064     child_list get_children(const std::string& key) const;
00065     vconfig child(const std::string& key) const;
00066     bool has_child(const std::string& key) const;
00067 
00068     /**
00069      * Note: vconfig::operator[] returns const, and this should not be changed
00070      * because vconfig is often used as a drop-in replacement for config, and
00071      * this const will properly warn you if you try to assign vcfg["key"]=val;
00072      *
00073      * Note: The following construction is unsave:
00074      * const std::string& temp = vcfg["foo"];
00075      * This bind temp to a member of a temporary t_string. The lifetime of the
00076      * temporary is not extended by this reference binding and the temporary's
00077      * lifetime ends which causes UB. Instead use:
00078      * const std::string temp = vcfg["foo"];
00079      */
00080     const config::attribute_value operator[](const std::string &key) const
00081     { return expand(key); }
00082     config::attribute_value expand(const std::string&) const; /** < Synonym for operator[] */
00083     bool has_attribute(const std::string& key) const { return cfg_->has_attribute(key); }
00084     bool empty() const { return (null() || cfg_->empty()); }
00085 
00086     struct all_children_iterator
00087     {
00088         struct pointer_proxy;
00089 
00090         typedef std::pair<std::string, vconfig> value_type;
00091         typedef std::forward_iterator_tag iterator_category;
00092         typedef int difference_type;
00093         typedef const pointer_proxy pointer;
00094         typedef const value_type reference;
00095         typedef config::all_children_iterator Itor;
00096         explicit all_children_iterator(const Itor &i, const config *cache_key = NULL);
00097 
00098         all_children_iterator& operator++();
00099         all_children_iterator  operator++(int);
00100 
00101         reference operator*() const;
00102         pointer operator->() const;
00103 
00104         std::string get_key() const;
00105         vconfig get_child() const;
00106         void disable_insertion() { inner_index_ = -1; }
00107 
00108         bool operator==(const all_children_iterator &i) const;
00109         bool operator!=(const all_children_iterator &i) const
00110         { return !operator==(i); }
00111 
00112     private:
00113         Itor i_;
00114         int inner_index_;
00115         const config* cache_key_;
00116     };
00117 
00118     struct recursion_error : public config::error {
00119         recursion_error(const std::string& msg) : error(msg) {}
00120     };
00121 
00122     /** In-order iteration over all children. */
00123     all_children_iterator ordered_begin() const;
00124     all_children_iterator ordered_end() const;
00125 
00126 private:
00127     const config* cfg_;
00128     const config* cache_key_;
00129 };
00130 
00131 struct vconfig::all_children_iterator::pointer_proxy
00132 {
00133     value_type p;
00134     const value_type *operator->() const { return &p; }
00135 };
00136 
00137 namespace variable
00138 {
00139 
00140 /**
00141  * Used to clear the cache for variables.
00142  */
00143 class manager
00144 {
00145 public:
00146     ~manager();
00147 };
00148 
00149 }
00150 
00151 
00152 
00153 class scoped_wml_variable
00154 {
00155 public:
00156     scoped_wml_variable(const std::string& var_name);
00157     virtual ~scoped_wml_variable();
00158     const std::string& name() const { return var_name_; }
00159     virtual void activate() = 0;
00160     config &store(const config &var_value = config());
00161     bool activated() const { return activated_; }
00162 private:
00163     config previous_val_;
00164     const std::string var_name_;
00165     bool activated_;
00166 };
00167 
00168 class scoped_weapon_info : public scoped_wml_variable
00169 {
00170 public:
00171     scoped_weapon_info(const std::string& var_name, const config &data)
00172         : scoped_wml_variable(var_name), data_(data) {}
00173     void activate();
00174 private:
00175     config const &data_;
00176 };
00177 
00178 class scoped_xy_unit : public scoped_wml_variable
00179 {
00180 public:
00181     scoped_xy_unit(const std::string& var_name, const int x, const int y, const unit_map& umap)
00182         : scoped_wml_variable(var_name), x_(x), y_(y), umap_(umap) {}
00183     void activate();
00184 private:
00185     const int x_, y_;
00186     const unit_map& umap_;
00187 };
00188 
00189 class scoped_recall_unit : public scoped_wml_variable
00190 {
00191 public:
00192     scoped_recall_unit(const std::string& var_name, const std::string& player,
00193         unsigned int recall_index) : scoped_wml_variable(var_name), player_(player),
00194         recall_index_(recall_index) {}
00195     void activate();
00196 private:
00197     const std::string player_;
00198     unsigned int recall_index_;
00199 };
00200 
00201 /** Information on a WML variable. */
00202 struct variable_info
00203 {
00204     typedef config::child_itors array_range;
00205 
00206     /**
00207      * TYPE: the correct variable type should be decided by the user of the info structure
00208      * Note: an Array can also be considered a Container, since index 0 will be used by default
00209      */
00210     enum TYPE { TYPE_SCALAR,    //a Scalar variable resolves to a t_string attribute of *vars
00211                 TYPE_ARRAY,     //an Array variable is a series of Containers
00212                 TYPE_CONTAINER, //a Container is a specific index of an Array (contains Scalars)
00213                 TYPE_UNSPECIFIED };
00214 
00215     variable_info(const std::string& varname, bool force_valid=true,
00216         TYPE validation_type=TYPE_UNSPECIFIED);
00217 
00218     TYPE vartype; //default is TYPE_UNSPECIFIED
00219     bool is_valid;
00220     std::string key; //the name of the internal attribute or child
00221     bool explicit_index; //true if query ended in [...] specifier
00222     size_t index; //the index of the child
00223     config *vars; //the containing node in game_state::variables
00224 
00225     /**
00226      * Results: after deciding the desired type, these methods can retrieve the result
00227      * Note: first you should force_valid or check is_valid, otherwise these may fail
00228      */
00229     config::attribute_value &as_scalar();
00230     config& as_container();
00231     array_range as_array(); //range may be empty
00232 };
00233 
00234 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

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