formula_callable.hpp

Go to the documentation of this file.
00001 /* $Id: formula_callable.hpp 25895 2008-04-17 18:57:13Z mordante $ */
00002 /*
00003    Copyright (C) 2008 by David White <dave@whitevine.net>
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 version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 #ifndef FORMULA_CALLABLE_HPP_INCLUDED
00016 #define FORMULA_CALLABLE_HPP_INCLUDED
00017 
00018 #include <map>
00019 #include <string>
00020 
00021 #include "reference_counted_object.hpp"
00022 #include "variant.hpp"
00023 
00024 namespace game_logic
00025 {
00026 
00027 enum FORMULA_ACCESS_TYPE { FORMULA_READ_ONLY, FORMULA_WRITE_ONLY, FORMULA_READ_WRITE };
00028 struct formula_input {
00029     std::string name;
00030     FORMULA_ACCESS_TYPE access;
00031     explicit formula_input(const std::string& name, FORMULA_ACCESS_TYPE access=FORMULA_READ_WRITE)
00032             : name(name), access(access)
00033     {}
00034 };
00035 
00036 //interface for objects that can have formulae run on them
00037 class formula_callable : public reference_counted_object {
00038 public:
00039     explicit formula_callable(bool has_self=true) : has_self_(has_self)
00040     {}
00041 
00042     variant query_value(const std::string& key) const {
00043         if(has_self_ && key == "self") {
00044             return variant(this);
00045         }
00046         return get_value(key);
00047     }
00048 
00049     void mutate_value(const std::string& key, const variant& value) {
00050         set_value(key, value);
00051     }
00052 
00053     std::vector<formula_input> inputs() const {
00054         std::vector<formula_input> res;
00055         get_inputs(&res);
00056         return res;
00057     }
00058 
00059     bool equals(const formula_callable* other) const {
00060         return do_compare(other) == 0;
00061     }
00062 
00063     bool less(const formula_callable* other) const {
00064         return do_compare(other) < 0;
00065     }
00066 
00067     virtual void get_inputs(std::vector<formula_input>* /*inputs*/) const {};
00068 
00069     void serialize(std::string& str) const {
00070         serialize_to_string(str);
00071     }
00072 
00073     bool has_key(const std::string& key) const 
00074         { return !query_value(key).is_null(); }
00075 
00076 protected:
00077     virtual ~formula_callable() {}
00078 
00079     virtual void set_value(const std::string& key, const variant& value);
00080     virtual int do_compare(const formula_callable* callable) const {
00081         return this < callable ? -1 : (this == callable ? 0 : 1);
00082     }
00083 
00084     virtual void serialize_to_string(std::string& /*str*/) const {
00085         throw type_error("Tried to serialize type which cannot be serialized");
00086     }
00087 private:
00088     virtual variant get_value(const std::string& key) const = 0;
00089     bool has_self_;
00090 };
00091 
00092 class formula_callable_no_ref_count : public formula_callable {
00093 public:
00094     formula_callable_no_ref_count() {
00095         turn_reference_counting_off();
00096     }
00097     virtual ~formula_callable_no_ref_count() {}
00098 };
00099 
00100 class formula_callable_with_backup : public formula_callable {
00101     const formula_callable& main_;
00102     const formula_callable& backup_;
00103     variant get_value(const std::string& key) const {
00104         variant var = main_.query_value(key);
00105         if(var.is_null()) {
00106             return backup_.query_value(key);
00107         }
00108 
00109         return var;
00110     }
00111 
00112     void get_inputs(std::vector<formula_input>* inputs) const {
00113         main_.get_inputs(inputs);
00114         backup_.get_inputs(inputs);
00115     }
00116 public:
00117     formula_callable_with_backup(const formula_callable& main, const formula_callable& backup) : formula_callable(false), main_(main), backup_(backup)
00118     {}
00119 };
00120 
00121 class formula_variant_callable_with_backup : public formula_callable {
00122     variant var_;
00123     const formula_callable& backup_;
00124     variant get_value(const std::string& key) const {
00125         variant var = var_.get_member(key);
00126         if(var.is_null()) {
00127             return backup_.query_value(key);
00128         }
00129 
00130         return var;
00131     }
00132 
00133     void get_inputs(std::vector<formula_input>* inputs) const {
00134         backup_.get_inputs(inputs);
00135     }
00136 
00137 public:
00138     formula_variant_callable_with_backup(const variant& var, const formula_callable& backup) : formula_callable(false), var_(var), backup_(backup)
00139     {}
00140 };
00141 
00142 class map_formula_callable : public formula_callable {
00143 public:
00144     explicit map_formula_callable(const formula_callable* fallback=NULL);
00145     map_formula_callable& add(const std::string& key, const variant& value);
00146     void set_fallback(const formula_callable* fallback) { fallback_ = fallback; }
00147     bool empty() const { return values_.empty(); }
00148     void clear() { values_.clear(); }
00149 
00150     typedef std::map<std::string,variant>::const_iterator const_iterator;
00151 
00152     const_iterator begin() const { return values_.begin(); }
00153     const_iterator end() const { return values_.end(); }
00154 
00155 private:
00156     variant get_value(const std::string& key) const;
00157     void get_inputs(std::vector<formula_input>* inputs) const;
00158     void set_value(const std::string& key, const variant& value);
00159     std::map<std::string,variant> values_;
00160     const formula_callable* fallback_;
00161 };
00162 
00163 typedef boost::intrusive_ptr<map_formula_callable> map_formula_callable_ptr;
00164 typedef boost::intrusive_ptr<const map_formula_callable> const_map_formula_callable_ptr;
00165 
00166 }
00167 
00168 #endif

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs