Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef FORMULA_CALLABLE_HPP_INCLUDED
00017 #define FORMULA_CALLABLE_HPP_INCLUDED
00018
00019 #include "reference_counted_object.hpp"
00020 #include "variant.hpp"
00021
00022 namespace game_logic
00023 {
00024
00025 enum FORMULA_ACCESS_TYPE { FORMULA_READ_ONLY, FORMULA_WRITE_ONLY, FORMULA_READ_WRITE };
00026 struct formula_input {
00027 std::string name;
00028 FORMULA_ACCESS_TYPE access;
00029 explicit formula_input(const std::string& name, FORMULA_ACCESS_TYPE access=FORMULA_READ_WRITE)
00030 : name(name), access(access)
00031 {}
00032 };
00033
00034
00035 class formula_callable : public reference_counted_object {
00036 public:
00037 explicit formula_callable(bool has_self=true) : type_(FORMULA_C), has_self_(has_self)
00038 {}
00039
00040 variant query_value(const std::string& key) const {
00041 if(has_self_ && key == "self") {
00042 return variant(this);
00043 }
00044 return get_value(key);
00045 }
00046
00047 void mutate_value(const std::string& key, const variant& value) {
00048 set_value(key, value);
00049 }
00050
00051 std::vector<formula_input> inputs() const {
00052 std::vector<formula_input> res;
00053 get_inputs(&res);
00054 return res;
00055 }
00056
00057 bool equals(const formula_callable* other) const {
00058 return do_compare(other) == 0;
00059 }
00060
00061 bool less(const formula_callable* other) const {
00062 return do_compare(other) < 0;
00063 }
00064
00065 virtual void get_inputs(std::vector<formula_input>* ) const {};
00066
00067
00068 void serialize(std::string& str) const {
00069 serialize_to_string(str);
00070 }
00071
00072 bool has_key(const std::string& key) const
00073 { return !query_value(key).is_null(); }
00074
00075 protected:
00076 virtual ~formula_callable() {}
00077
00078 virtual void set_value(const std::string& key, const variant& value);
00079 virtual int do_compare(const formula_callable* callable) const {
00080 if( type_ < callable->type_ )
00081 return -1;
00082
00083 if( type_ > callable->type_ )
00084 return 1;
00085
00086 return this < callable ? -1 : (this == callable ? 0 : 1);
00087 }
00088
00089
00090 virtual void serialize_to_string(std::string& ) const {
00091 throw type_error("Tried to serialize type which cannot be serialized");
00092 }
00093
00094
00095
00096
00097 enum TYPE { FORMULA_C, TERRAIN_C, LOCATION_C, UNIT_TYPE_C, UNIT_C,
00098 ATTACK_TYPE_C, MOVE_PARTIAL_C, MOVE_C, ATTACK_C, MOVE_MAP_C };
00099
00100 TYPE type_;
00101 private:
00102 virtual variant get_value(const std::string& key) const = 0;
00103 bool has_self_;
00104 };
00105
00106 class formula_callable_no_ref_count : public formula_callable {
00107 public:
00108 formula_callable_no_ref_count() {
00109 turn_reference_counting_off();
00110 }
00111 virtual ~formula_callable_no_ref_count() {}
00112 };
00113
00114 class formula_callable_with_backup : public formula_callable {
00115 const formula_callable& main_;
00116 const formula_callable& backup_;
00117 variant get_value(const std::string& key) const {
00118 variant var = main_.query_value(key);
00119 if(var.is_null()) {
00120 return backup_.query_value(key);
00121 }
00122
00123 return var;
00124 }
00125
00126 void get_inputs(std::vector<formula_input>* inputs) const {
00127 main_.get_inputs(inputs);
00128 backup_.get_inputs(inputs);
00129 }
00130 public:
00131 formula_callable_with_backup(const formula_callable& main, const formula_callable& backup) : formula_callable(false), main_(main), backup_(backup)
00132 {}
00133 };
00134
00135 class formula_variant_callable_with_backup : public formula_callable {
00136 variant var_;
00137 const formula_callable& backup_;
00138 variant get_value(const std::string& key) const {
00139 variant var = var_.get_member(key);
00140 if(var.is_null()) {
00141 return backup_.query_value(key);
00142 }
00143
00144 return var;
00145 }
00146
00147 void get_inputs(std::vector<formula_input>* inputs) const {
00148 backup_.get_inputs(inputs);
00149 }
00150
00151 public:
00152 formula_variant_callable_with_backup(const variant& var, const formula_callable& backup) : formula_callable(false), var_(var), backup_(backup)
00153 {}
00154 };
00155
00156 class map_formula_callable : public formula_callable {
00157 public:
00158 explicit map_formula_callable(const formula_callable* fallback=NULL);
00159 map_formula_callable& add(const std::string& key, const variant& value);
00160 void set_fallback(const formula_callable* fallback) { fallback_ = fallback; }
00161 bool empty() const { return values_.empty(); }
00162 void clear() { values_.clear(); }
00163
00164 typedef std::map<std::string,variant>::const_iterator const_iterator;
00165
00166 const_iterator begin() const { return values_.begin(); }
00167 const_iterator end() const { return values_.end(); }
00168
00169 private:
00170 variant get_value(const std::string& key) const;
00171 void get_inputs(std::vector<formula_input>* inputs) const;
00172 void set_value(const std::string& key, const variant& value);
00173 std::map<std::string,variant> values_;
00174 const formula_callable* fallback_;
00175 };
00176
00177 typedef boost::intrusive_ptr<map_formula_callable> map_formula_callable_ptr;
00178 typedef boost::intrusive_ptr<const map_formula_callable> const_map_formula_callable_ptr;
00179
00180 }
00181
00182 #endif