Formula engine: Add pair() function

This commit is contained in:
Celtic Minstrel 2016-04-02 08:27:15 -04:00
parent cc7c124744
commit 5c9923daba
3 changed files with 40 additions and 9 deletions

View file

@ -214,6 +214,7 @@ Version 1.13.4+dev:
This counts backwards from the specified offset
A size of -1 is the same as 1.
* if() can take two arguments; returns null if the condition is false
* tolist() will now invert the effect of tomap()
* debug_print() now shows in console if debug mode is on
* New core functions:
* Trig functions tan, acos, asin, atan have been added. (Sin and cos
@ -230,6 +231,9 @@ Version 1.13.4+dev:
* replace() replaces a sequence within a string
* type() function checks the type of a formula result
* distance_between() - this was promoted from FormulaAI to core
* pair() function that produces a key-value pair suitable for
passing to tomap() - this also means key-value pairs are now
serializable (relevant in FormulaAI)
* Bugfixes:
* Dice operator is now synced (where possible)
* Modulus (%) operator now works on decimal numbers

View file

@ -406,11 +406,16 @@ private:
} else
{
for(variant_iterator it = var_1.begin(); it != var_1.end(); ++it) {
std::map<variant, variant>::iterator map_it = tmp.find( *it );
if (map_it == tmp.end())
tmp[ *it ] = variant( 1 );
else
map_it->second = variant(map_it->second.as_int() + 1);
if (key_value_pair* kv = (*it).try_convert<key_value_pair>())
tmp[kv->query_value("key")] = kv->query_value("value");
else {
std::map<variant, variant>::iterator map_it = tmp.find( *it );
if (map_it == tmp.end()) {
tmp[*it] = variant(1);
} else {
map_it->second = variant(map_it->second.as_int() + 1);
}
}
}
}
@ -1355,6 +1360,20 @@ private:
}
};
class pair_function : public function_expression {
public:
explicit pair_function(const args_list& args)
: function_expression("pair", args, 2, 2)
{}
private:
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
return variant(new key_value_pair(
args()[0]->evaluate(variables,add_debug_info(fdb,0,"pair:key")),
args()[1]->evaluate(variables,add_debug_info(fdb,1,"pair_value"))
));
}
};
class distance_between_function : public function_expression {
public:
explicit distance_between_function(const args_list& args)
@ -1402,6 +1421,15 @@ void key_value_pair::get_inputs(std::vector<game_logic::formula_input>* inputs)
inputs->push_back(game_logic::formula_input("value", game_logic::FORMULA_READ_ONLY));
}
void key_value_pair::serialize_to_string(std::string& str) const {
str += "pair(";
key_.serialize_to_string(str);
str += ",";
value_.serialize_to_string(str);
str += ")";
}
formula_function_expression::formula_function_expression(const std::string& name, const args_list& args, const_formula_ptr formula, const_formula_ptr precondition, const std::vector<std::string>& arg_names)
: function_expression(name, args, arg_names.size(), arg_names.size()),
formula_(formula), precondition_(precondition), arg_names_(arg_names), star_arg_(-1)
@ -1516,6 +1544,7 @@ function_symbol_table& get_functions_map() {
FUNCTION(round);
FUNCTION(as_decimal);
FUNCTION(refcount);
FUNCTION(pair);
FUNCTION(loc);
FUNCTION(distance_between);
FUNCTION(index_of);
@ -1544,10 +1573,6 @@ function_symbol_table& get_functions_map() {
#undef FUNCTION
}
#ifdef HAVE_VISUAL_LEAK_DETECTOR
VLDEnable();
#endif
return functions_table;
}

View file

@ -80,6 +80,8 @@ class key_value_pair : public formula_callable {
void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
public:
explicit key_value_pair(const variant& key, const variant& value) : key_(key), value_(value) {}
void serialize_to_string(std::string& str) const;
};
class formula_function_expression : public function_expression {