Merge branch 'wfl_memleak_fix'
This commit is contained in:
commit
795592fe12
23 changed files with 237 additions and 190 deletions
|
@ -342,7 +342,7 @@ public:
|
|||
{
|
||||
std::vector<wfl::variant> vars;
|
||||
for(attacks_vector::const_iterator i = value.begin(); i != value.end(); ++i) {
|
||||
vars.emplace_back(new attack_analysis(*i));
|
||||
vars.emplace_back(std::make_shared<attack_analysis>(*i));
|
||||
}
|
||||
var = wfl::variant(vars);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ static lg::log_domain log_ai("ai/attack");
|
|||
|
||||
namespace ai {
|
||||
|
||||
extern ai_context& get_ai_context(const wfl::formula_callable* for_fai);
|
||||
extern ai_context& get_ai_context(wfl::const_formula_callable_ptr for_fai);
|
||||
|
||||
void attack_analysis::analyze(const gamemap& map, unit_map& units,
|
||||
const readonly_context& ai_obj,
|
||||
|
@ -335,13 +335,13 @@ wfl::variant attack_analysis::get_value(const std::string& key) const
|
|||
{
|
||||
using namespace wfl;
|
||||
if(key == "target") {
|
||||
return variant(new location_callable(target));
|
||||
return variant(std::make_shared<location_callable>(target));
|
||||
} else if(key == "movements") {
|
||||
std::vector<variant> res;
|
||||
for(size_t n = 0; n != movements.size(); ++n) {
|
||||
map_formula_callable* item = new map_formula_callable(nullptr);
|
||||
item->add("src", variant(new location_callable(movements[n].first)));
|
||||
item->add("dst", variant(new location_callable(movements[n].second)));
|
||||
auto item = std::make_shared<map_formula_callable>(nullptr);
|
||||
item->add("src", variant(std::make_shared<location_callable>(movements[n].first)));
|
||||
item->add("dst", variant(std::make_shared<location_callable>(movements[n].second)));
|
||||
res.emplace_back(item);
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ wfl::variant attack_analysis::get_value(const std::string& key) const
|
|||
} else if(key == "units") {
|
||||
std::vector<variant> res;
|
||||
for(size_t n = 0; n != movements.size(); ++n) {
|
||||
res.emplace_back(new location_callable(movements[n].first));
|
||||
res.emplace_back(std::make_shared<location_callable>(movements[n].first));
|
||||
}
|
||||
|
||||
return variant(res);
|
||||
|
@ -429,7 +429,7 @@ wfl::variant attack_analysis::execute_self(wfl::variant ctxt) {
|
|||
//check if target is still valid
|
||||
unit = units.find(att_dst);
|
||||
if(unit == units.end()) {
|
||||
return wfl::variant(new wfl::safe_call_result(this, attack_result::E_EMPTY_DEFENDER, move_from));
|
||||
return wfl::variant(std::make_shared<wfl::safe_call_result>(fake_ptr(), attack_result::E_EMPTY_DEFENDER, move_from));
|
||||
}
|
||||
|
||||
//check if we need to move
|
||||
|
@ -437,14 +437,14 @@ wfl::variant attack_analysis::execute_self(wfl::variant ctxt) {
|
|||
//now check if location to which we want to move is still unoccupied
|
||||
unit = units.find(att_src);
|
||||
if(unit != units.end()) {
|
||||
return wfl::variant(new wfl::safe_call_result(this, move_result::E_NO_UNIT, move_from));
|
||||
return wfl::variant(std::make_shared<wfl::safe_call_result>(fake_ptr(), move_result::E_NO_UNIT, move_from));
|
||||
}
|
||||
|
||||
ai::move_result_ptr result = get_ai_context(ctxt.as_callable()).execute_move_action(move_from, att_src);
|
||||
if(!result->is_ok()) {
|
||||
//move part failed
|
||||
LOG_AI << "ERROR #" << result->get_status() << " while executing 'attack' formula function\n" << std::endl;
|
||||
return wfl::variant(new wfl::safe_call_result(this, result->get_status(), result->get_unit_location()));
|
||||
return wfl::variant(std::make_shared<wfl::safe_call_result>(fake_ptr(), result->get_status(), result->get_unit_location()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,7 +453,7 @@ wfl::variant attack_analysis::execute_self(wfl::variant ctxt) {
|
|||
if(!result->is_ok()) {
|
||||
//attack failed
|
||||
LOG_AI << "ERROR #" << result->get_status() << " while executing 'attack' formula function\n" << std::endl;
|
||||
return wfl::variant(new wfl::safe_call_result(this, result->get_status()));
|
||||
return wfl::variant(std::make_shared<wfl::safe_call_result>(fake_ptr(), result->get_status()));
|
||||
}
|
||||
}
|
||||
return wfl::variant(true);
|
||||
|
|
|
@ -105,6 +105,7 @@ formula_ai::formula_ai(readonly_context &context, const config &cfg)
|
|||
cfg_(cfg),
|
||||
recursion_counter_(context.get_recursion_count()),
|
||||
keeps_cache_(),
|
||||
attacks_callable(*this, resources::gameboard->units()),
|
||||
// infinite_loop_guardian_(),
|
||||
vars_(),
|
||||
function_table_(*this)
|
||||
|
@ -162,13 +163,13 @@ std::string formula_ai::evaluate(const std::string& formula_str)
|
|||
|
||||
formula f(formula_str, &function_table_);
|
||||
|
||||
map_formula_callable callable(this);
|
||||
map_formula_callable callable(fake_ptr());
|
||||
|
||||
//formula_debugger fdb;
|
||||
const variant v = f.evaluate(callable,nullptr);
|
||||
|
||||
if (ai_ptr_) {
|
||||
variant var = variant(this).execute_variant(v);
|
||||
variant var = variant(this->fake_ptr()).execute_variant(v);
|
||||
|
||||
if ( !var.is_empty() ) {
|
||||
return "Made move: " + var.to_debug_string();
|
||||
|
@ -194,7 +195,7 @@ wfl::variant formula_ai::make_action(wfl::const_formula_ptr formula_, const wfl:
|
|||
variant res;
|
||||
|
||||
if (ai_ptr_) {
|
||||
res = variant(this).execute_variant(var);
|
||||
res = variant(this->fake_ptr()).execute_variant(var);
|
||||
} else {
|
||||
ERR_AI << "skipped execution of action because ai context is not set correctly" << std::endl;
|
||||
}
|
||||
|
@ -276,7 +277,7 @@ variant villages_from_set(const Container& villages,
|
|||
if(exclude && exclude->count(loc)) {
|
||||
continue;
|
||||
}
|
||||
vars.emplace_back(new location_callable(loc));
|
||||
vars.emplace_back(std::make_shared<location_callable>(loc));
|
||||
}
|
||||
|
||||
return variant(vars);
|
||||
|
@ -368,7 +369,7 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
|
||||
} else if(key == "my_side")
|
||||
{
|
||||
return variant(new team_callable(resources::gameboard->teams()[get_side()-1]));
|
||||
return variant(std::make_shared<team_callable>(resources::gameboard->teams()[get_side()-1]));
|
||||
|
||||
} else if(key == "my_side_number")
|
||||
{
|
||||
|
@ -378,7 +379,7 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
{
|
||||
std::vector<variant> vars;
|
||||
for(std::vector<team>::const_iterator i = resources::gameboard->teams().begin(); i != resources::gameboard->teams().end(); ++i) {
|
||||
vars.emplace_back(new team_callable(*i));
|
||||
vars.emplace_back(std::make_shared<team_callable>(*i));
|
||||
}
|
||||
return variant(vars);
|
||||
|
||||
|
@ -415,7 +416,7 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
const unit_type *ut = unit_types.find(*i);
|
||||
if (ut)
|
||||
{
|
||||
vars.emplace_back(new unit_type_callable(*ut));
|
||||
vars.emplace_back(std::make_shared<unit_type_callable>(*ut));
|
||||
}
|
||||
}
|
||||
return variant(vars);
|
||||
|
@ -441,7 +442,7 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
const unit_type *ut = unit_types.find(*str_it);
|
||||
if (ut)
|
||||
{
|
||||
tmp[i].emplace_back(new unit_type_callable(*ut));
|
||||
tmp[i].emplace_back(std::make_shared<unit_type_callable>(*ut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +455,7 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
{
|
||||
std::vector<variant> vars;
|
||||
for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
|
||||
vars.emplace_back(new unit_callable(*i));
|
||||
vars.emplace_back(std::make_shared<unit_callable>(*i));
|
||||
}
|
||||
return variant(vars);
|
||||
|
||||
|
@ -468,7 +469,7 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
tmp.push_back( v );
|
||||
}
|
||||
for(const unit &u : units) {
|
||||
tmp[u.side() - 1].emplace_back(new unit_callable(u));
|
||||
tmp[u.side() - 1].emplace_back(std::make_shared<unit_callable>(u));
|
||||
}
|
||||
for( size_t i = 0; i<tmp.size(); ++i)
|
||||
vars.emplace_back(tmp[i]);
|
||||
|
@ -479,7 +480,7 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
std::vector<variant> vars;
|
||||
for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
|
||||
if (i->side() == get_side()) {
|
||||
vars.emplace_back(new unit_callable(*i));
|
||||
vars.emplace_back(std::make_shared<unit_callable>(*i));
|
||||
}
|
||||
}
|
||||
return variant(vars);
|
||||
|
@ -490,7 +491,7 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
|
||||
if (current_team().is_enemy(i->side())) {
|
||||
if (!i->incapacitated()) {
|
||||
vars.emplace_back(new unit_callable(*i));
|
||||
vars.emplace_back(std::make_shared<unit_callable>(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -498,14 +499,14 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
|
||||
} else if(key == "my_moves")
|
||||
{
|
||||
return variant(new move_map_callable(get_srcdst(), get_dstsrc(), units));
|
||||
return variant(std::make_shared<move_map_callable>(get_srcdst(), get_dstsrc(), units));
|
||||
|
||||
} else if(key == "my_attacks")
|
||||
{
|
||||
return variant(new attack_map_callable(*this, units));
|
||||
return variant(attacks_callable.fake_ptr());
|
||||
} else if(key == "enemy_moves")
|
||||
{
|
||||
return variant(new move_map_callable(get_enemy_srcdst(), get_enemy_dstsrc(), units));
|
||||
return variant(std::make_shared<move_map_callable>(get_enemy_srcdst(), get_enemy_dstsrc(), units));
|
||||
|
||||
} else if(key == "my_leader")
|
||||
{
|
||||
|
@ -513,27 +514,27 @@ variant formula_ai::get_value(const std::string& key) const
|
|||
if(i == units.end()) {
|
||||
return variant();
|
||||
}
|
||||
return variant(new unit_callable(*i));
|
||||
return variant(std::make_shared<unit_callable>(*i));
|
||||
|
||||
} else if(key == "recall_list")
|
||||
{
|
||||
std::vector<variant> tmp;
|
||||
|
||||
for(std::vector<unit_ptr >::const_iterator i = current_team().recall_list().begin(); i != current_team().recall_list().end(); ++i) {
|
||||
tmp.push_back( variant( new unit_callable(**i) ) );
|
||||
tmp.push_back( variant(std::make_shared<unit_callable>(**i) ) );
|
||||
}
|
||||
|
||||
return variant(tmp);
|
||||
|
||||
} else if(key == "vars")
|
||||
{
|
||||
return variant(&vars_);
|
||||
return variant(vars_.fake_ptr());
|
||||
} else if(key == "keeps")
|
||||
{
|
||||
return get_keeps();
|
||||
} else if(key == "map")
|
||||
{
|
||||
return variant(new gamemap_callable(resources::gameboard->map()));
|
||||
return variant(std::make_shared<gamemap_callable>(resources::gameboard->map()));
|
||||
} else if(key == "villages")
|
||||
{
|
||||
return villages_from_set(resources::gameboard->map().villages());
|
||||
|
@ -609,7 +610,7 @@ variant formula_ai::get_keeps() const
|
|||
get_adjacent_tiles(loc,adj);
|
||||
for(size_t n = 0; n != 6; ++n) {
|
||||
if(resources::gameboard->map().is_castle(adj[n])) {
|
||||
vars.emplace_back(new location_callable(loc));
|
||||
vars.emplace_back(std::make_shared<location_callable>(loc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -683,7 +684,7 @@ void formula_ai::evaluate_candidate_action(ca_ptr fai_ca)
|
|||
|
||||
bool formula_ai::execute_candidate_action(ca_ptr fai_ca)
|
||||
{
|
||||
map_formula_callable callable(this);
|
||||
map_formula_callable callable(fake_ptr());
|
||||
fai_ca->update_callable_map( callable );
|
||||
const_formula_ptr move_formula(fai_ca->get_action());
|
||||
return !make_action(move_formula, callable).is_empty();
|
||||
|
|
|
@ -166,13 +166,14 @@ private:
|
|||
virtual void get_inputs(wfl::formula_input_vector& inputs) const override;
|
||||
|
||||
mutable wfl::variant keeps_cache_;
|
||||
wfl::attack_map_callable attacks_callable;
|
||||
|
||||
// gamestate_change_observer infinite_loop_guardian_;
|
||||
wfl::map_formula_callable vars_;
|
||||
wfl::ai_function_symbol_table function_table_;
|
||||
|
||||
friend class ai_default;
|
||||
friend ai_context& get_ai_context(const formula_callable* for_fai);
|
||||
friend ai_context& get_ai_context(wfl::const_formula_callable_ptr for_fai);
|
||||
};
|
||||
|
||||
} //end of namespace ai
|
||||
|
|
|
@ -33,10 +33,10 @@ static lg::log_domain log_formula_ai("ai/engine/fai");
|
|||
|
||||
namespace ai {
|
||||
|
||||
ai_context& get_ai_context(const wfl::formula_callable* for_fai) {
|
||||
const formula_ai* fai = dynamic_cast<const formula_ai*>(for_fai);
|
||||
assert(fai != nullptr); // Why not just use dynamic_cast<formula_ai&> instead then?
|
||||
return *const_cast<formula_ai*>(fai)->ai_ptr_;
|
||||
ai_context& get_ai_context(wfl::const_formula_callable_ptr for_fai) {
|
||||
auto fai = std::dynamic_pointer_cast<const formula_ai>(for_fai);
|
||||
assert(fai != nullptr);
|
||||
return *std::const_pointer_cast<formula_ai>(fai)->ai_ptr_;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ variant move_map_callable::get_value(const std::string& key) const
|
|||
std::vector<variant> vars;
|
||||
for(move_map::const_iterator i = srcdst_.begin(); i != srcdst_.end(); ++i) {
|
||||
if( i->first == i->second || units_.count(i->second) == 0) {
|
||||
move_callable* item = new move_callable(i->first, i->second);
|
||||
auto item = std::make_shared<move_callable>(i->first, i->second);
|
||||
vars.emplace_back(item);
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ variant move_callable::execute_self(variant ctxt) {
|
|||
|
||||
if(!move_result->is_ok()) {
|
||||
LOG_AI << "ERROR #" << move_result->get_status() << " while executing 'move' formula function\n" << std::endl;
|
||||
return variant(new safe_call_result(this, move_result->get_status(), move_result->get_unit_location()));
|
||||
return variant(std::make_shared<safe_call_result>(fake_ptr(), move_result->get_status(), move_result->get_unit_location()));
|
||||
}
|
||||
|
||||
return variant(move_result->is_gamestate_changed());
|
||||
|
@ -120,7 +120,7 @@ variant move_partial_callable::execute_self(variant ctxt) {
|
|||
|
||||
if(!move_result->is_ok()) {
|
||||
LOG_AI << "ERROR #" << move_result->get_status() << " while executing 'move_partial' formula function\n" << std::endl;
|
||||
return variant(new safe_call_result(this, move_result->get_status(), move_result->get_unit_location()));
|
||||
return variant(std::make_shared<safe_call_result>(fake_ptr(), move_result->get_status(), move_result->get_unit_location()));
|
||||
}
|
||||
|
||||
return variant(move_result->is_gamestate_changed());
|
||||
|
@ -169,11 +169,11 @@ attack_callable::attack_callable(const map_location& move_from,
|
|||
|
||||
variant attack_callable::get_value(const std::string& key) const {
|
||||
if(key == "attack_from") {
|
||||
return variant(new location_callable(src_));
|
||||
return variant(std::make_shared<location_callable>(src_));
|
||||
} else if(key == "defender") {
|
||||
return variant(new location_callable(dst_));
|
||||
return variant(std::make_shared<location_callable>(dst_));
|
||||
} else if(key == "move_from") {
|
||||
return variant(new location_callable(move_from_));
|
||||
return variant(std::make_shared<location_callable>(move_from_));
|
||||
} else {
|
||||
return variant();
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ variant attack_callable::execute_self(variant ctxt) {
|
|||
if(!move_result->is_ok()) {
|
||||
//move part failed
|
||||
LOG_AI << "ERROR #" << move_result->get_status() << " while executing 'attack' formula function\n" << std::endl;
|
||||
return variant(new safe_call_result(this, move_result->get_status(), move_result->get_unit_location()));
|
||||
return variant(std::make_shared<safe_call_result>(fake_ptr(), move_result->get_status(), move_result->get_unit_location()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ variant attack_callable::execute_self(variant ctxt) {
|
|||
if(!attack_result->is_ok()) {
|
||||
//attack failed
|
||||
LOG_AI << "ERROR #" << attack_result->get_status() << " while executing 'attack' formula function\n" << std::endl;
|
||||
return variant(new safe_call_result(this, attack_result->get_status()));
|
||||
return variant(std::make_shared<safe_call_result>(fake_ptr(), attack_result->get_status()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ void attack_map_callable::collect_possible_attacks(std::vector<variant>& vars, m
|
|||
unit->invisible(unit->get_location(), *resources::gameboard))
|
||||
continue;
|
||||
/* add attacks with default weapon */
|
||||
attack_callable* item = new attack_callable(attacker_location, attack_position, adj[n], -1);
|
||||
auto item = std::make_shared<attack_callable>(attacker_location, attack_position, adj[n], -1);
|
||||
vars.emplace_back(item);
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ variant recall_callable::get_value(const std::string& key) const {
|
|||
if( key == "id")
|
||||
return variant(id_);
|
||||
if( key == "loc")
|
||||
return variant(new location_callable(loc_));
|
||||
return variant(std::make_shared<location_callable>(loc_));
|
||||
return variant();
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ variant recall_callable::execute_self(variant ctxt) {
|
|||
recall_result->execute();
|
||||
} else {
|
||||
LOG_AI << "ERROR #" << recall_result->get_status() << " while executing 'recall' formula function\n" << std::endl;
|
||||
return variant(new safe_call_result(this, recall_result->get_status()));
|
||||
return variant(std::make_shared<safe_call_result>(fake_ptr(), recall_result->get_status()));
|
||||
}
|
||||
|
||||
return variant(recall_result->is_gamestate_changed());
|
||||
|
@ -324,7 +324,7 @@ variant recruit_callable::get_value(const std::string& key) const {
|
|||
if( key == "unit_type")
|
||||
return variant(type_);
|
||||
if( key == "recruit_loc")
|
||||
return variant(new location_callable(loc_));
|
||||
return variant(std::make_shared<location_callable>(loc_));
|
||||
return variant();
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ variant recruit_callable::execute_self(variant ctxt) {
|
|||
recruit_result->execute();
|
||||
} else {
|
||||
LOG_AI << "ERROR #" << recruit_result->get_status() << " while executing 'recruit' formula function\n" << std::endl;
|
||||
return variant(new safe_call_result(this, recruit_result->get_status()));
|
||||
return variant(std::make_shared<safe_call_result>(fake_ptr(), recruit_result->get_status()));
|
||||
}
|
||||
|
||||
//is_gamestate_changed()==true means that the game state was somehow changed by action.
|
||||
|
@ -353,7 +353,7 @@ variant recruit_callable::execute_self(variant ctxt) {
|
|||
|
||||
variant set_unit_var_callable::get_value(const std::string& key) const {
|
||||
if(key == "loc")
|
||||
return variant(new location_callable(loc_));
|
||||
return variant(std::make_shared<location_callable>(loc_));
|
||||
|
||||
if(key == "key")
|
||||
return variant(key_);
|
||||
|
@ -390,7 +390,7 @@ variant set_unit_var_callable::execute_self(variant ctxt) {
|
|||
}
|
||||
|
||||
ERR_AI << "ERROR #" << status << " while executing 'set_unit_var' formula function" << std::endl;
|
||||
return variant(new safe_call_result(this, status));
|
||||
return variant(std::make_shared<safe_call_result>(fake_ptr(), status));
|
||||
}
|
||||
|
||||
variant fallback_callable::execute_self(variant) {
|
||||
|
|
|
@ -72,9 +72,9 @@ class move_callable : public action_callable {
|
|||
map_location src_, dst_;
|
||||
variant get_value(const std::string& key) const override {
|
||||
if(key == "src") {
|
||||
return variant(new location_callable(src_));
|
||||
return variant(std::make_shared<location_callable>(src_));
|
||||
} else if(key == "dst") {
|
||||
return variant(new location_callable(dst_));
|
||||
return variant(std::make_shared<location_callable>(dst_));
|
||||
} else {
|
||||
return variant();
|
||||
}
|
||||
|
@ -101,9 +101,9 @@ class move_partial_callable : public action_callable {
|
|||
map_location src_, dst_;
|
||||
variant get_value(const std::string& key) const override {
|
||||
if(key == "src") {
|
||||
return variant(new location_callable(src_));
|
||||
return variant(std::make_shared<location_callable>(src_));
|
||||
} else if(key == "dst") {
|
||||
return variant(new location_callable(dst_));
|
||||
return variant(std::make_shared<location_callable>(dst_));
|
||||
} else {
|
||||
return variant();
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ candidate_action_with_filters::candidate_action_with_filters(
|
|||
|
||||
variant candidate_action_with_filters::do_filtering(ai::formula_ai* ai, variant& input, const_formula_ptr formula)
|
||||
{
|
||||
map_formula_callable callable(static_cast<const formula_callable*>(ai));
|
||||
map_formula_callable callable(ai->fake_ptr());
|
||||
callable.add("input", input);
|
||||
|
||||
return formula::evaluate(formula, callable);
|
||||
|
@ -102,7 +102,7 @@ void move_candidate_action::evaluate(ai::formula_ai* ai, unit_map& units)
|
|||
for(unit_map::unit_iterator i = units.begin() ; i != units.end() ; ++i)
|
||||
{
|
||||
if (i->side() == ai->get_side() && i->movement_left() > 0) {
|
||||
unit_vector.emplace_back(new unit_callable(*i));
|
||||
unit_vector.emplace_back(std::make_shared<unit_callable>(*i));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ void move_candidate_action::evaluate(ai::formula_ai* ai, unit_map& units)
|
|||
|
||||
for(variant_iterator i = filtered_units.begin() ; i != filtered_units.end() ; ++i)
|
||||
{
|
||||
map_formula_callable callable(static_cast<const formula_callable*>(ai));
|
||||
map_formula_callable callable(ai->fake_ptr());
|
||||
callable.add("me", *i);
|
||||
|
||||
int res = execute_formula(eval_, callable, ai);
|
||||
|
@ -161,12 +161,12 @@ void attack_candidate_action::evaluate(ai::formula_ai* ai, unit_map& units)
|
|||
if (i->side() == ai->get_side())
|
||||
{
|
||||
if (i->attacks_left()) {
|
||||
my_res.emplace_back(new unit_callable(*i));
|
||||
my_res.emplace_back(std::make_shared<unit_callable>(*i));
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (ai->current_team().is_enemy(i->side()) && !i->incapacitated() && !i->invisible(i->get_location(), *resources::gameboard)) {
|
||||
enemy_res.emplace_back(new unit_callable(*i));
|
||||
enemy_res.emplace_back(std::make_shared<unit_callable>(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,33 +199,35 @@ void attack_candidate_action::evaluate(ai::formula_ai* ai, unit_map& units)
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector< const unit_callable* > my_units_flt;
|
||||
std::vector< const unit_callable* > enemy_units_flt;
|
||||
std::vector<variant> my_units_flt;
|
||||
std::vector<variant> enemy_units_flt;
|
||||
|
||||
for(variant_iterator i = filtered_my_units.begin() ; i != filtered_my_units.end() ; ++i) {
|
||||
const unit_callable* u_callable = (*i).try_convert<const unit_callable>();
|
||||
if(u_callable == nullptr) {
|
||||
auto u_callable = (*i).try_convert<const unit_callable>();
|
||||
if(!u_callable) {
|
||||
ERR_AI << "ERROR in "<< get_name() << "Candidate Action: Filter formula returned table that does not contain units" << std::endl;
|
||||
return;
|
||||
}
|
||||
my_units_flt.push_back(u_callable);
|
||||
my_units_flt.emplace_back(u_callable);
|
||||
}
|
||||
|
||||
for(variant_iterator i = filtered_enemy_units.begin() ; i != filtered_enemy_units.end() ; ++i) {
|
||||
const unit_callable* u_callable = (*i).try_convert<const unit_callable>();
|
||||
if(u_callable == nullptr) {
|
||||
auto u_callable = (*i).try_convert<const unit_callable>();
|
||||
if(!u_callable) {
|
||||
ERR_AI << "ERROR in "<< get_name() << "Candidate Action: Filter formula returned table that does not contain units" << std::endl;
|
||||
return;
|
||||
}
|
||||
enemy_units_flt.push_back(u_callable);
|
||||
enemy_units_flt.emplace_back(u_callable);
|
||||
}
|
||||
|
||||
for( size_t my_unit = 0 ; my_unit < my_units_flt.size() ; ++my_unit){
|
||||
const unit_callable* my_unit_callalbe = my_units_flt[my_unit];
|
||||
auto my_unit_callable = my_units_flt[my_unit].convert_to<unit_callable>();
|
||||
auto enemy_unit_callable = my_units_flt[my_unit].convert_to<unit_callable>();
|
||||
for( size_t enemy_unit = 0 ; enemy_unit < enemy_units_flt.size() ; ++enemy_unit){
|
||||
if( ai->can_reach_unit( my_unit_callalbe->get_location(), enemy_units_flt[enemy_unit]->get_location() )) {
|
||||
auto enemy_unit_callable = enemy_units_flt[enemy_unit].convert_to<unit_callable>();
|
||||
if(ai->can_reach_unit(my_unit_callable->get_location(), enemy_unit_callable->get_location())) {
|
||||
|
||||
map_formula_callable callable(static_cast<const formula_callable*>(ai));
|
||||
map_formula_callable callable(ai->fake_ptr());
|
||||
callable.add("me", filtered_my_units[my_unit]);
|
||||
callable.add("target", filtered_enemy_units[enemy_unit]);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace {
|
|||
class unit_adapter {
|
||||
public:
|
||||
unit_adapter(const variant& arg) : unit_type_(), unit_() {
|
||||
const unit_callable* unit = arg.try_convert<unit_callable>();
|
||||
auto unit = arg.try_convert<unit_callable>();
|
||||
|
||||
if (unit) {
|
||||
unit_ = &unit->get_unit();
|
||||
|
@ -361,9 +361,9 @@ private:
|
|||
|
||||
if( valid ) {
|
||||
if( enemy_border )
|
||||
res.insert( std::pair<variant, variant>(variant(new location_callable(map_location(x, y))), variant(scores[0][i] + 10000) ));
|
||||
res.emplace(variant(std::make_shared<location_callable>(map_location(x, y))), variant(scores[0][i] + 10000));
|
||||
else
|
||||
res.insert( std::pair<variant, variant>(variant(new location_callable(map_location(x, y))), variant(scores[0][i] ) ));
|
||||
res.emplace(variant(std::make_shared<location_callable>(map_location(x, y))), variant(scores[0][i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ private:
|
|||
}
|
||||
|
||||
if( best_i != -1)
|
||||
return variant(new location_callable(items[best_i].convert_to<location_callable>()->loc()));
|
||||
return variant(std::make_shared<location_callable>(items[best_i].convert_to<location_callable>()->loc()));
|
||||
else
|
||||
return variant();
|
||||
}
|
||||
|
@ -423,7 +423,7 @@ private:
|
|||
std::vector<variant> v;
|
||||
for(int n = 0; n != 6; ++n) {
|
||||
if (resources::gameboard->map().on_board(adj[n]) )
|
||||
v.emplace_back(new location_callable(adj[n]));
|
||||
v.emplace_back(std::make_shared<location_callable>(adj[n]));
|
||||
}
|
||||
|
||||
return variant(v);
|
||||
|
@ -448,7 +448,7 @@ private:
|
|||
return variant();
|
||||
|
||||
if(!range)
|
||||
return variant(new location_callable(loc));
|
||||
return variant(std::make_shared<location_callable>(loc));
|
||||
|
||||
std::vector<map_location> res;
|
||||
|
||||
|
@ -456,11 +456,11 @@ private:
|
|||
|
||||
std::vector<variant> v;
|
||||
v.reserve(res.size()+1);
|
||||
v.emplace_back(new location_callable(loc));
|
||||
v.emplace_back(std::make_shared<location_callable>(loc));
|
||||
|
||||
for(size_t n = 0; n != res.size(); ++n) {
|
||||
if (resources::gameboard->map().on_board(res[n]) )
|
||||
v.emplace_back(new location_callable(res[n]));
|
||||
v.emplace_back(std::make_shared<location_callable>(res[n]));
|
||||
}
|
||||
|
||||
return variant(v);
|
||||
|
@ -548,7 +548,7 @@ private:
|
|||
|
||||
std::vector<variant> res;
|
||||
for (const map_location& ml : visited_locs) {
|
||||
res.push_back( variant(new location_callable( ml ) ) );
|
||||
res.push_back( variant(std::make_shared<location_callable>( ml ) ) );
|
||||
}
|
||||
|
||||
return variant(res);
|
||||
|
@ -577,9 +577,9 @@ private:
|
|||
return variant();
|
||||
}
|
||||
|
||||
const unit_callable* u_call = u.try_convert<unit_callable>();
|
||||
auto u_call = u.try_convert<unit_callable>();
|
||||
|
||||
if (u_call == nullptr) {
|
||||
if(!u_call) {
|
||||
return variant();
|
||||
}
|
||||
|
||||
|
@ -625,7 +625,7 @@ private:
|
|||
}
|
||||
|
||||
if( best_i != -1)
|
||||
return variant(new location_callable(ai_.get_keeps_cache()[best_i].convert_to<location_callable>()->loc()));
|
||||
return variant(std::make_shared<location_callable>(ai_.get_keeps_cache()[best_i].convert_to<location_callable>()->loc()));
|
||||
else
|
||||
return variant();
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ private:
|
|||
return variant();
|
||||
}
|
||||
const pathfind::paths unit_paths(*u, false, true, ai_.current_team());
|
||||
return variant(new location_callable(ai_.suitable_keep(loc,unit_paths)));
|
||||
return variant(std::make_shared<location_callable>(ai_.suitable_keep(loc,unit_paths)));
|
||||
}
|
||||
|
||||
formula_ai& ai_;
|
||||
|
@ -683,7 +683,7 @@ private:
|
|||
for(int i = 0; i < w; ++i)
|
||||
for(int j = 0; j < h; ++j) {
|
||||
if(ai_.current_team().shrouded(map_location(i,j)))
|
||||
vars.emplace_back(new location_callable(map_location(i, j)));
|
||||
vars.emplace_back(std::make_shared<location_callable>(map_location(i, j)));
|
||||
}
|
||||
|
||||
return variant(vars);
|
||||
|
@ -714,7 +714,7 @@ private:
|
|||
while (un != end) {
|
||||
if (distance_between(loc, un->get_location()) <= range) {
|
||||
if (un->side() != ai_.get_side()) {//fixme: ignores allied units
|
||||
vars.emplace_back(new unit_callable(*un));
|
||||
vars.emplace_back(std::make_shared<unit_callable>(*un));
|
||||
}
|
||||
}
|
||||
++un;
|
||||
|
@ -780,7 +780,7 @@ private:
|
|||
status.emplace_back("Stoned");
|
||||
if (bc.get_defender_stats().plagues && hitLeft[0].as_int() == 0)
|
||||
status.emplace_back("Zombiefied");
|
||||
vars.emplace_back(new outcome_callable(hitLeft, prob, status));
|
||||
vars.emplace_back(std::make_shared<outcome_callable>(hitLeft, prob, status));
|
||||
hitLeft.clear();
|
||||
prob.clear();
|
||||
status.clear();
|
||||
|
@ -803,7 +803,7 @@ private:
|
|||
status.emplace_back("Stoned");
|
||||
if (bc.get_attacker_stats().plagues && hitLeft[0].as_int() == 0)
|
||||
status.emplace_back("Zombiefied");
|
||||
vars.emplace_back(new outcome_callable(hitLeft, prob, status));
|
||||
vars.emplace_back(std::make_shared<outcome_callable>(hitLeft, prob, status));
|
||||
return variant(vars);
|
||||
}
|
||||
};
|
||||
|
@ -819,7 +819,7 @@ public:
|
|||
private:
|
||||
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
|
||||
variant attack = args()[0]->evaluate(variables,add_debug_info(fdb,0,"outcomes:attack"));
|
||||
ai::attack_analysis* analysis = attack.convert_to<ai::attack_analysis>();
|
||||
auto analysis = attack.convert_to<ai::attack_analysis>();
|
||||
//unit_map units_with_moves(resources::gameboard->units());
|
||||
//typedef std::pair<map_location, map_location> mv;
|
||||
//for(const mv &m : analysis->movements) {
|
||||
|
@ -830,13 +830,13 @@ private:
|
|||
if(analysis->chance_to_kill > 0.0) {
|
||||
//unit_map units(units_with_moves);
|
||||
//units.erase(analysis->target);
|
||||
vars.emplace_back(new position_callable(/*&units,*/ static_cast<int>(analysis->chance_to_kill*100)));
|
||||
vars.emplace_back(std::make_shared<position_callable>(/*&units,*/ static_cast<int>(analysis->chance_to_kill*100)));
|
||||
|
||||
}
|
||||
|
||||
if(analysis->chance_to_kill < 1.0) {
|
||||
//unit_map units(units_with_moves);
|
||||
vars.emplace_back(new position_callable(/*&units,*/ static_cast<int>(100 - analysis->chance_to_kill*100)));
|
||||
vars.emplace_back(std::make_shared<position_callable>(/*&units,*/ static_cast<int>(100 - analysis->chance_to_kill*100)));
|
||||
}
|
||||
|
||||
return variant(vars);
|
||||
|
@ -872,7 +872,7 @@ private:
|
|||
|
||||
const unit_type *ut = unit_types.find(type);
|
||||
if(ut) {
|
||||
return variant(new unit_type_callable(*ut));
|
||||
return variant(std::make_shared<unit_type_callable>(*ut));
|
||||
}
|
||||
|
||||
return variant();
|
||||
|
@ -889,7 +889,7 @@ public:
|
|||
private:
|
||||
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
|
||||
variant act = args()[0]->evaluate(variables,add_debug_info(fdb,0,"rate_action:action"));
|
||||
ai::attack_analysis* analysis = act.convert_to<ai::attack_analysis>();
|
||||
auto analysis = act.convert_to<ai::attack_analysis>();
|
||||
|
||||
return variant(analysis->rating(ai_.get_aggression(),ai_)*1000,variant::DECIMAL_VARIANT);
|
||||
}
|
||||
|
@ -911,7 +911,7 @@ private:
|
|||
loc = args()[1]->evaluate(variables, add_debug_info(fdb, 1, "recall:location")).convert_to<location_callable>()->loc();
|
||||
}
|
||||
|
||||
return variant(new recall_callable(loc, id));
|
||||
return variant(std::make_shared<recall_callable>(loc, id));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -929,7 +929,7 @@ private:
|
|||
loc = args()[1]->evaluate(variables, add_debug_info(fdb, 1, "recruit:location")).convert_to<location_callable>()->loc();
|
||||
}
|
||||
|
||||
return variant(new recruit_callable(loc, type));
|
||||
return variant(std::make_shared<recruit_callable>(loc, type));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -974,7 +974,7 @@ private:
|
|||
}
|
||||
|
||||
for (std::vector<map_location>::const_iterator loc_iter = route.steps.begin() + 1 ; loc_iter !=route.steps.end(); ++loc_iter) {
|
||||
locations.push_back( variant( new location_callable(*loc_iter) ));
|
||||
locations.push_back( variant(std::make_shared<location_callable>(*loc_iter) ));
|
||||
}
|
||||
|
||||
return variant(locations);
|
||||
|
@ -1027,7 +1027,7 @@ private:
|
|||
|
||||
for (std::vector<map_location>::const_iterator loc_iter = route.steps.begin() + 1 ; loc_iter !=route.steps.end(); ++loc_iter) {
|
||||
if (unit_it->movement_cost((resources::gameboard->map())[*loc_iter]) < movetype::UNREACHABLE )
|
||||
locations.push_back( variant( new location_callable(*loc_iter) ));
|
||||
locations.push_back( variant(std::make_shared<location_callable>(*loc_iter) ));
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
@ -1095,7 +1095,7 @@ private:
|
|||
if (loc==map_location::null_location()) {
|
||||
return variant();
|
||||
}
|
||||
return variant(new location_callable(loc));
|
||||
return variant(std::make_shared<location_callable>(loc));
|
||||
}
|
||||
|
||||
const formula_ai& ai_;
|
||||
|
@ -1113,7 +1113,7 @@ private:
|
|||
const map_location src = args()[0]->evaluate(variables, add_debug_info(fdb, 0, "move:src")).convert_to<location_callable>()->loc();
|
||||
const map_location dst = args()[1]->evaluate(variables, add_debug_info(fdb, 1, "move:dst")).convert_to<location_callable>()->loc();
|
||||
LOG_AI << "move(): " << src << ", " << dst << ")\n";
|
||||
return variant(new move_callable(src, dst));
|
||||
return variant(std::make_shared<move_callable>(src, dst));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1128,7 +1128,7 @@ private:
|
|||
const map_location src = args()[0]->evaluate(variables, add_debug_info(fdb, 0, "move_partial:src")).convert_to<location_callable>()->loc();
|
||||
const map_location dst = args()[1]->evaluate(variables, add_debug_info(fdb, 1, "move_partial:dst")).convert_to<location_callable>()->loc();
|
||||
LOG_AI << "move_partial(): " << src << ", " << dst << ")\n";
|
||||
return variant(new move_partial_callable(src, dst));
|
||||
return variant(std::make_shared<move_partial_callable>(src, dst));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1140,7 +1140,7 @@ public:
|
|||
{}
|
||||
private:
|
||||
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
|
||||
return variant(new set_unit_var_callable(args()[0]->evaluate(variables,add_debug_info(fdb,0,"set_unit_var:key")).as_string(), args()[1]->evaluate(variables,add_debug_info(fdb,1,"set_unit_var:value")), args()[2]->evaluate(variables,add_debug_info(fdb,2,"set_unit_var:unit_location")).convert_to<location_callable>()->loc()));
|
||||
return variant(std::make_shared<set_unit_var_callable>(args()[0]->evaluate(variables,add_debug_info(fdb,0,"set_unit_var:key")).as_string(), args()[1]->evaluate(variables,add_debug_info(fdb,1,"set_unit_var:value")), args()[2]->evaluate(variables,add_debug_info(fdb,2,"set_unit_var:unit_location")).convert_to<location_callable>()->loc()));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1155,7 +1155,7 @@ private:
|
|||
// The parameter is not used, but is accepted for legacy compatibility
|
||||
if(args().size() == 1 && args()[0]->evaluate(variables).as_string() != "human")
|
||||
return variant();
|
||||
return variant(new fallback_callable);
|
||||
return variant(std::make_shared<fallback_callable>());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1175,7 +1175,7 @@ private:
|
|||
ERR_AI << "AI ERROR: Formula produced illegal attack: " << move_from << " -> " << src << " -> " << dst << std::endl;
|
||||
return variant();
|
||||
}
|
||||
return variant(new attack_callable(move_from, src, dst, weapon));
|
||||
return variant(std::make_shared<attack_callable>(move_from, src, dst, weapon));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1284,10 +1284,10 @@ private:
|
|||
if (loc_var.is_null()) {
|
||||
return variant();
|
||||
}
|
||||
const location_callable* loc = loc_var.convert_to<location_callable>();
|
||||
auto loc = loc_var.convert_to<location_callable>();
|
||||
const unit_map::const_iterator i = resources::gameboard->units().find(loc->loc());
|
||||
if(i != resources::gameboard->units().end()) {
|
||||
return variant(new unit_callable(*i));
|
||||
return variant(std::make_shared<unit_callable>(*i));
|
||||
} else {
|
||||
return variant();
|
||||
}
|
||||
|
@ -1314,7 +1314,7 @@ private:
|
|||
std::pair<Itor,Itor> range = srcdst.equal_range(loc);
|
||||
|
||||
for(Itor i = range.first; i != range.second; ++i) {
|
||||
vars.emplace_back(new location_callable(i->second));
|
||||
vars.emplace_back(std::make_shared<location_callable>(i->second));
|
||||
}
|
||||
|
||||
return variant(vars);
|
||||
|
@ -1339,7 +1339,7 @@ private:
|
|||
while(range.first != range.second) {
|
||||
unit_map::const_iterator un = resources::gameboard->units().find(range.first->second);
|
||||
assert(un != resources::gameboard->units().end());
|
||||
vars.emplace_back(new unit_callable(*un));
|
||||
vars.emplace_back(std::make_shared<unit_callable>(*un));
|
||||
++range.first;
|
||||
}
|
||||
|
||||
|
@ -1361,8 +1361,8 @@ private:
|
|||
return variant();
|
||||
}
|
||||
|
||||
const unit_callable* u_call = u.try_convert<unit_callable>();
|
||||
const unit_type_callable* u_type = u.try_convert<unit_type_callable>();
|
||||
auto u_call = u.try_convert<unit_callable>();
|
||||
auto u_type = u.try_convert<unit_type_callable>();
|
||||
const map_location& loc = loc_var.convert_to<location_callable>()->loc();
|
||||
|
||||
if (u_call)
|
||||
|
@ -1411,8 +1411,8 @@ private:
|
|||
return variant();
|
||||
}
|
||||
|
||||
const unit_callable* u_call = u.try_convert<unit_callable>();
|
||||
const unit_type_callable* u_type = u.try_convert<unit_type_callable>();
|
||||
auto u_call = u.try_convert<unit_callable>();
|
||||
auto u_type = u.try_convert<unit_type_callable>();
|
||||
const map_location& loc = loc_var.convert_to<location_callable>()->loc();
|
||||
|
||||
if (u_call)
|
||||
|
@ -1455,8 +1455,8 @@ private:
|
|||
return variant();
|
||||
}
|
||||
//we can pass to this function either unit_callable or unit_type callable
|
||||
const unit_callable* u_call = u.try_convert<unit_callable>();
|
||||
const unit_type_callable* u_type = u.try_convert<unit_type_callable>();
|
||||
auto u_call = u.try_convert<unit_callable>();
|
||||
auto u_type = u.try_convert<unit_type_callable>();
|
||||
const map_location& loc = loc_var.convert_to<location_callable>()->loc();
|
||||
|
||||
if (u_call)
|
||||
|
|
|
@ -45,7 +45,7 @@ stage_side_formulas::~stage_side_formulas()
|
|||
|
||||
bool stage_side_formulas::do_play_stage()
|
||||
{
|
||||
wfl::map_formula_callable callable(&fai_);
|
||||
wfl::map_formula_callable callable(fai_.fake_ptr());
|
||||
try {
|
||||
if (move_formula_) {
|
||||
while( !fai_.make_action(move_formula_,callable).is_empty() ) { }
|
||||
|
|
|
@ -66,8 +66,8 @@ bool stage_unit_formulas::do_play_stage()
|
|||
try {
|
||||
wfl::const_formula_ptr priority_formula(fai_.create_optional_formula(i->formula_manager().get_priority_formula()));
|
||||
if (priority_formula) {
|
||||
wfl::map_formula_callable callable(&fai_);
|
||||
callable.add("me", wfl::variant(new wfl::unit_callable(*i)));
|
||||
wfl::map_formula_callable callable(fai_.fake_ptr());
|
||||
callable.add("me", wfl::variant(std::make_shared<wfl::unit_callable>(*i)));
|
||||
priority = (wfl::formula::evaluate(priority_formula, callable)).as_int();
|
||||
} else {
|
||||
WRN_AI << "priority formula skipped, maybe it's empty or incorrect"<< std::endl;
|
||||
|
@ -99,8 +99,8 @@ bool stage_unit_formulas::do_play_stage()
|
|||
try {
|
||||
wfl::const_formula_ptr formula(fai_.create_optional_formula(i->formula_manager().get_formula()));
|
||||
if (formula) {
|
||||
wfl::map_formula_callable callable(&fai_);
|
||||
callable.add("me", wfl::variant(new wfl::unit_callable(*i)));
|
||||
wfl::map_formula_callable callable(fai_.fake_ptr());
|
||||
callable.add("me", wfl::variant(std::make_shared<wfl::unit_callable>(*i)));
|
||||
fai_.make_action(formula, callable);
|
||||
} else {
|
||||
WRN_AI << "unit formula skipped, maybe it's empty or incorrect" << std::endl;
|
||||
|
@ -121,8 +121,8 @@ bool stage_unit_formulas::do_play_stage()
|
|||
try {
|
||||
wfl::const_formula_ptr loop_formula(fai_.create_optional_formula(i->formula_manager().get_loop_formula()));
|
||||
if (loop_formula) {
|
||||
wfl::map_formula_callable callable(&fai_);
|
||||
callable.add("me", wfl::variant(new wfl::unit_callable(*i)));
|
||||
wfl::map_formula_callable callable(fai_.fake_ptr());
|
||||
callable.add("me", wfl::variant(std::make_shared<wfl::unit_callable>(*i)));
|
||||
while ( !fai_.make_action(loop_formula, callable).is_empty() && i.valid() )
|
||||
{
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef FORMULA_CALLABLE_HPP_INCLUDED
|
||||
#define FORMULA_CALLABLE_HPP_INCLUDED
|
||||
|
||||
#include "formula/callable_fwd.hpp"
|
||||
#include "formula/variant.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
@ -30,12 +31,26 @@ class formula_callable
|
|||
public:
|
||||
explicit formula_callable(bool has_self = true) : type_(FORMULA_C), has_self_(has_self) {}
|
||||
|
||||
virtual ~formula_callable() {}
|
||||
virtual ~formula_callable() {
|
||||
for(auto& d : dtor_notify) {
|
||||
if(d) {
|
||||
d->notify_dead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formula_callable_ptr fake_ptr() {
|
||||
return formula_callable_ptr(this, [](const formula_callable*){});
|
||||
}
|
||||
|
||||
const_formula_callable_ptr fake_ptr() const {
|
||||
return const_formula_callable_ptr(this, [](const formula_callable*){});
|
||||
}
|
||||
|
||||
variant query_value(const std::string& key) const
|
||||
{
|
||||
if(has_self_ && key == "self") {
|
||||
return variant(this);
|
||||
return variant(fake_ptr());
|
||||
}
|
||||
return get_value(key);
|
||||
}
|
||||
|
@ -54,14 +69,14 @@ public:
|
|||
|
||||
virtual void get_inputs(formula_input_vector& /*inputs*/) const {}
|
||||
|
||||
bool equals(const formula_callable* other) const
|
||||
bool equals(const formula_callable& other) const
|
||||
{
|
||||
return do_compare(other) == 0;
|
||||
return do_compare(&other) == 0;
|
||||
}
|
||||
|
||||
bool less(const formula_callable* other) const
|
||||
bool less(const formula_callable& other) const
|
||||
{
|
||||
return do_compare(other) < 0;
|
||||
return do_compare(&other) < 0;
|
||||
}
|
||||
|
||||
bool has_key(const std::string& key) const
|
||||
|
@ -76,6 +91,14 @@ public:
|
|||
serialize_to_string(str);
|
||||
}
|
||||
|
||||
void subscribe_dtor(callable_die_subscriber* d) const {
|
||||
dtor_notify.insert(d);
|
||||
}
|
||||
|
||||
void unsubscribe_dtor(callable_die_subscriber* d) const {
|
||||
dtor_notify.erase(d);
|
||||
}
|
||||
|
||||
protected:
|
||||
template<typename T, typename K>
|
||||
static variant convert_map(const std::map<T, K>& input_map)
|
||||
|
@ -150,6 +173,8 @@ protected:
|
|||
|
||||
TYPE type_;
|
||||
|
||||
mutable std::set<callable_die_subscriber*> dtor_notify;
|
||||
|
||||
private:
|
||||
virtual variant get_value(const std::string& key) const = 0;
|
||||
bool has_self_;
|
||||
|
@ -219,7 +244,7 @@ private:
|
|||
class map_formula_callable : public formula_callable
|
||||
{
|
||||
public:
|
||||
explicit map_formula_callable(const formula_callable* fallback = nullptr)
|
||||
explicit map_formula_callable(const_formula_callable_ptr fallback = nullptr)
|
||||
: formula_callable(false)
|
||||
, values_()
|
||||
, fallback_(fallback)
|
||||
|
@ -231,7 +256,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
void set_fallback(const formula_callable* fallback)
|
||||
void set_fallback(const_formula_callable_ptr fallback)
|
||||
{
|
||||
fallback_ = fallback;
|
||||
}
|
||||
|
@ -275,7 +300,7 @@ private:
|
|||
}
|
||||
|
||||
std::map<std::string, variant> values_;
|
||||
const formula_callable* fallback_;
|
||||
const_formula_callable_ptr fallback_;
|
||||
};
|
||||
|
||||
using map_formula_callable_ptr = std::shared_ptr<map_formula_callable>;
|
||||
|
|
|
@ -17,12 +17,17 @@
|
|||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace wfl
|
||||
{
|
||||
class formula_callable;
|
||||
class formula_debugger;
|
||||
|
||||
struct callable_die_subscriber {
|
||||
virtual void notify_dead() {}
|
||||
};
|
||||
|
||||
enum FORMULA_ACCESS_TYPE { FORMULA_READ_ONLY, FORMULA_WRITE_ONLY, FORMULA_READ_WRITE };
|
||||
|
||||
struct formula_input {
|
||||
|
@ -36,7 +41,8 @@ struct formula_input {
|
|||
using formula_input_vector = std::vector<formula_input>;
|
||||
using formula_callable_ptr = std::shared_ptr<formula_callable>;
|
||||
using const_formula_callable_ptr = std::shared_ptr<const formula_callable>;
|
||||
using formula_seen_stack = std::vector<const formula_callable*>;
|
||||
using formula_seen_stack = std::vector<const_formula_callable_ptr>;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -169,7 +169,7 @@ variant unit_callable::get_value(const std::string& key) const
|
|||
return variant();
|
||||
}
|
||||
|
||||
return variant(new location_callable(loc_));
|
||||
return variant(std::make_shared<location_callable>(loc_));
|
||||
} else if(key == "id") {
|
||||
return variant(u_.id());
|
||||
} else if(key == "type") {
|
||||
|
@ -185,7 +185,7 @@ variant unit_callable::get_value(const std::string& key) const
|
|||
} else if(key == "attacks") {
|
||||
std::vector<variant> res;
|
||||
for(const attack_type& att : u_.attacks()) {
|
||||
res.emplace_back(new attack_type_callable(att));
|
||||
res.emplace_back(std::make_shared<attack_type_callable>(att));
|
||||
}
|
||||
|
||||
return variant(res);
|
||||
|
@ -249,12 +249,12 @@ variant unit_callable::get_value(const std::string& key) const
|
|||
return variant(map_location::write_direction(u_.facing()));
|
||||
} else if(key == "vars") {
|
||||
if(u_.formula_manager().formula_vars()) {
|
||||
return variant(u_.formula_manager().formula_vars().get());
|
||||
return variant(u_.formula_manager().formula_vars());
|
||||
}
|
||||
|
||||
return variant();
|
||||
} else if(key == "wml_vars") {
|
||||
return variant(new config_callable(u_.variables()));
|
||||
return variant(std::make_shared<config_callable>(u_.variables()));
|
||||
} else if(key == "n" || key == "s" || key == "ne" || key == "se" || key == "nw" || key == "sw" ||
|
||||
key == "lawful" || key == "neutral" || key == "chaotic" || key == "liminal" ||
|
||||
key == "male" || key == "female")
|
||||
|
@ -340,7 +340,7 @@ variant unit_type_callable::get_value(const std::string& key) const
|
|||
} else if(key == "attacks") {
|
||||
std::vector<variant> res;
|
||||
for(const attack_type& att : u_.attacks()) {
|
||||
res.emplace_back(new attack_type_callable(att));
|
||||
res.emplace_back(std::make_shared<attack_type_callable>(att));
|
||||
}
|
||||
|
||||
return variant(res);
|
||||
|
@ -419,15 +419,15 @@ variant config_callable::get_value(const std::string& key) const
|
|||
} else if(cfg_.has_child(key)) {
|
||||
std::vector<variant> result;
|
||||
for(const auto& child : cfg_.child_range(key)) {
|
||||
result.emplace_back(new config_callable(child));
|
||||
result.emplace_back(std::make_shared<config_callable>(child));
|
||||
}
|
||||
|
||||
return variant(result);
|
||||
} else if(key == "__all_children") {
|
||||
std::vector<variant> result;
|
||||
for(const auto& child : cfg_.all_children_range()) {
|
||||
const variant cfg_child(new config_callable(child.cfg));
|
||||
const variant kv(new key_value_pair(variant(child.key), cfg_child));
|
||||
const variant cfg_child(std::make_shared<config_callable>(child.cfg));
|
||||
const variant kv(std::make_shared<key_value_pair>(variant(child.key), cfg_child));
|
||||
result.push_back(kv);
|
||||
}
|
||||
|
||||
|
@ -435,7 +435,7 @@ variant config_callable::get_value(const std::string& key) const
|
|||
} else if(key == "__children") {
|
||||
std::map<std::string, std::vector<variant> > build;
|
||||
for(const auto& child : cfg_.all_children_range()) {
|
||||
const variant cfg_child(new config_callable(child.cfg));
|
||||
const variant cfg_child(std::make_shared<config_callable>(child.cfg));
|
||||
build[child.key].push_back(cfg_child);
|
||||
}
|
||||
|
||||
|
@ -491,7 +491,7 @@ variant terrain_callable::get_value(const std::string& key) const
|
|||
} else if(key == "y") {
|
||||
return variant(loc_.wml_y());
|
||||
} else if(key == "loc") {
|
||||
return variant(new location_callable(loc_));
|
||||
return variant(std::make_shared<location_callable>(loc_));
|
||||
} else if(key == "id") {
|
||||
return variant(std::string(t_.id()));
|
||||
} else if(key == "name") {
|
||||
|
@ -563,7 +563,7 @@ variant gamemap_callable::get_value(const std::string& key) const
|
|||
for(int i = 0; i < w; i++) {
|
||||
for(int j = 0; j < h; j++) {
|
||||
const map_location loc(i, j);
|
||||
vars.emplace_back(new terrain_callable(gamemap_.get_terrain_info(loc), loc));
|
||||
vars.emplace_back(std::make_shared<terrain_callable>(gamemap_.get_terrain_info(loc), loc));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -667,7 +667,7 @@ variant team_callable::get_value(const std::string& key) const
|
|||
|
||||
return variant(result);
|
||||
} else if(key == "wml_vars") {
|
||||
return variant(new config_callable(team_.variables()));
|
||||
return variant(std::make_shared<config_callable>(team_.variables()));
|
||||
}
|
||||
|
||||
return variant();
|
||||
|
@ -693,7 +693,7 @@ void set_var_callable::get_inputs(formula_input_vector& inputs) const
|
|||
variant set_var_callable::execute_self(variant ctxt)
|
||||
{
|
||||
//if(infinite_loop_guardian_.set_var_check()) {
|
||||
if(formula_callable* obj = ctxt.try_convert<formula_callable>()) {
|
||||
if(auto obj = ctxt.try_convert<formula_callable>()) {
|
||||
LOG_SF << "Setting variable: " << key_ << " -> " << value_.to_debug_string() << "\n";
|
||||
obj->mutate_value(key_, value_);
|
||||
return variant(true);
|
||||
|
@ -702,7 +702,7 @@ variant set_var_callable::execute_self(variant ctxt)
|
|||
//too many calls in a row - possible infinite loop
|
||||
ERR_SF << "ERROR #" << 5001 << " while executing 'set_var' formula function" << std::endl;
|
||||
|
||||
return variant(new safe_call_result(this, 5001));
|
||||
return variant(std::make_shared<safe_call_result>(fake_ptr(), 5001));
|
||||
}
|
||||
|
||||
variant safe_call_callable::get_value(const std::string& key) const
|
||||
|
@ -725,7 +725,7 @@ void safe_call_callable::get_inputs(formula_input_vector& inputs) const
|
|||
variant safe_call_callable::execute_self(variant ctxt)
|
||||
{
|
||||
variant res;
|
||||
if(action_callable* action = main_.try_convert<action_callable>()) {
|
||||
if(auto action = main_.try_convert<action_callable>()) {
|
||||
res = action->execute_self(ctxt);
|
||||
}
|
||||
|
||||
|
@ -752,13 +752,13 @@ variant safe_call_result::get_value(const std::string& key) const
|
|||
if(key == "status") {
|
||||
return variant(status_);
|
||||
} else if(key == "object") {
|
||||
if(failed_callable_ != nullptr) {
|
||||
if(failed_callable_) {
|
||||
return variant(failed_callable_);
|
||||
}
|
||||
|
||||
return variant();
|
||||
} else if(key == "current_loc" && current_unit_location_ != map_location()) {
|
||||
return variant(new location_callable(current_unit_location_));
|
||||
return variant(std::make_shared<location_callable>(current_unit_location_));
|
||||
}
|
||||
|
||||
return variant();
|
||||
|
|
|
@ -224,14 +224,14 @@ private:
|
|||
class safe_call_result : public formula_callable
|
||||
{
|
||||
public:
|
||||
safe_call_result(const formula_callable* callable, int status, const map_location& loc = map_location())
|
||||
safe_call_result(const_formula_callable_ptr callable, int status, const map_location& loc = map_location())
|
||||
: failed_callable_(callable)
|
||||
, current_unit_location_(loc)
|
||||
, status_(status)
|
||||
{}
|
||||
|
||||
private:
|
||||
const formula_callable* failed_callable_;
|
||||
const_formula_callable_ptr failed_callable_;
|
||||
const map_location current_unit_location_;
|
||||
const int status_;
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ public:
|
|||
private:
|
||||
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
|
||||
variant var = args()[0]->evaluate(variables, fdb);
|
||||
const formula_callable* callable = var.as_callable();
|
||||
auto callable = var.as_callable();
|
||||
formula_input_vector inputs = callable->inputs();
|
||||
std::vector<variant> res;
|
||||
for(size_t i=0; i<inputs.size(); ++i) {
|
||||
|
@ -422,7 +422,7 @@ private:
|
|||
} else
|
||||
{
|
||||
for(variant_iterator it = var_1.begin(); it != var_1.end(); ++it) {
|
||||
if (key_value_pair* kv = (*it).try_convert<key_value_pair>())
|
||||
if(auto 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 );
|
||||
|
@ -1427,7 +1427,7 @@ public:
|
|||
{}
|
||||
private:
|
||||
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
|
||||
return variant(new location_callable(map_location(
|
||||
return variant(std::make_shared<location_callable>(map_location(
|
||||
args()[0]->evaluate(variables,add_debug_info(fdb,0,"loc:x")).as_int(),
|
||||
args()[1]->evaluate(variables,add_debug_info(fdb,1,"loc:y")).as_int(), wml_loc())));
|
||||
}
|
||||
|
@ -1440,7 +1440,7 @@ public:
|
|||
{}
|
||||
private:
|
||||
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
|
||||
return variant(new key_value_pair(
|
||||
return variant(std::make_shared<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"))
|
||||
));
|
||||
|
@ -1487,7 +1487,7 @@ private:
|
|||
const variant main = args()[0]->evaluate(variables, fdb);
|
||||
const expression_ptr backup_formula = args()[1];
|
||||
|
||||
return variant(new safe_call_callable(main, backup_formula));
|
||||
return variant(std::make_shared<safe_call_callable>(main, backup_formula));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1497,7 +1497,7 @@ public:
|
|||
: function_expression("set_var", args, 2, 2) {}
|
||||
private:
|
||||
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
|
||||
return variant(new set_var_callable(args()[0]->evaluate(variables, add_debug_info(fdb, 0, "set_var:key")).as_string(), args()[1]->evaluate(variables, add_debug_info(fdb, 1, "set_var:value"))));
|
||||
return variant(std::make_shared<set_var_callable>(args()[0]->evaluate(variables, add_debug_info(fdb, 0, "set_var:key")).as_string(), args()[1]->evaluate(variables, add_debug_info(fdb, 1, "set_var:value"))));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -162,12 +162,6 @@ variant::variant(double n, variant::DECIMAL_VARIANT_TYPE)
|
|||
assert(value_.get());
|
||||
}
|
||||
|
||||
variant::variant(const formula_callable* callable)
|
||||
: value_(std::make_shared<variant_callable>(callable))
|
||||
{
|
||||
assert(value_.get());
|
||||
}
|
||||
|
||||
variant::variant(const std::vector<variant>& vec)
|
||||
: value_((std::make_shared<variant_list>(vec)))
|
||||
{
|
||||
|
@ -682,7 +676,7 @@ variant variant::execute_variant(const variant& var)
|
|||
continue;
|
||||
}
|
||||
|
||||
if(action_callable* action = vars.top().try_convert<action_callable>()) {
|
||||
if(auto action = vars.top().try_convert<action_callable>()) {
|
||||
variant res = action->execute_self(*this);
|
||||
if(res.is_int() && res.as_bool()) {
|
||||
made_moves.push_back(vars.top());
|
||||
|
|
|
@ -34,11 +34,17 @@ public:
|
|||
explicit variant(int n);
|
||||
variant(int n, DECIMAL_VARIANT_TYPE /*type*/);
|
||||
variant(double n, DECIMAL_VARIANT_TYPE /*type*/);
|
||||
explicit variant(const formula_callable* callable);
|
||||
explicit variant(const std::vector<variant>& array);
|
||||
explicit variant(const std::string& str);
|
||||
explicit variant(const std::map<variant, variant>& map);
|
||||
|
||||
template<typename T>
|
||||
variant(std::shared_ptr<T> callable)
|
||||
: value_(std::make_shared<variant_callable>(callable))
|
||||
{
|
||||
assert(value_.get());
|
||||
}
|
||||
|
||||
variant& operator=(const variant& v);
|
||||
|
||||
variant operator[](size_t n) const;
|
||||
|
@ -71,26 +77,26 @@ public:
|
|||
|
||||
const std::string& as_string() const;
|
||||
|
||||
const formula_callable* as_callable() const
|
||||
const_formula_callable_ptr as_callable() const
|
||||
{
|
||||
must_be(VARIANT_TYPE::TYPE_CALLABLE);
|
||||
return value_cast<variant_callable>()->get_callable();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* try_convert() const
|
||||
std::shared_ptr<T> try_convert() const
|
||||
{
|
||||
if(!is_callable()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dynamic_cast<T*>(const_cast<formula_callable*>(as_callable()));
|
||||
return std::dynamic_pointer_cast<T>(std::const_pointer_cast<formula_callable>(as_callable()));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* convert_to() const
|
||||
std::shared_ptr<T> convert_to() const
|
||||
{
|
||||
T* res = dynamic_cast<T*>(const_cast<formula_callable*>(as_callable()));
|
||||
std::shared_ptr<T> res = std::dynamic_pointer_cast<T>(std::const_pointer_cast<formula_callable>(as_callable()));
|
||||
if(!res) {
|
||||
throw type_error("could not convert type");
|
||||
}
|
||||
|
|
|
@ -75,9 +75,19 @@ std::string variant_decimal::to_string_impl(const bool sign_value) const
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
variant_callable::variant_callable(const formula_callable* callable)
|
||||
variant_callable::variant_callable(const_formula_callable_ptr callable)
|
||||
: callable_(callable)
|
||||
{}
|
||||
{
|
||||
if(callable_) {
|
||||
callable_->subscribe_dtor(this);
|
||||
}
|
||||
}
|
||||
|
||||
variant_callable::~variant_callable() {
|
||||
if(callable_) {
|
||||
callable_->unsubscribe_dtor(this);
|
||||
}
|
||||
}
|
||||
|
||||
std::string variant_callable::get_serialized_string() const
|
||||
{
|
||||
|
@ -133,13 +143,13 @@ std::string variant_callable::get_debug_string(formula_seen_stack& seen, bool ve
|
|||
bool variant_callable::equals(variant_value_base& other) const
|
||||
{
|
||||
variant_callable& other_ref = value_ref_cast<variant_callable>(other);
|
||||
return callable_ ? callable_->equals(other_ref.callable_) : callable_ == other_ref.callable_;
|
||||
return callable_ ? callable_->equals(*other_ref.callable_) : callable_ == other_ref.callable_;
|
||||
}
|
||||
|
||||
bool variant_callable::less_than(variant_value_base& other) const
|
||||
{
|
||||
variant_callable& other_ref = value_ref_cast<variant_callable>(other);
|
||||
return callable_ ? callable_->less(other_ref.callable_) : other_ref.callable_ != nullptr;
|
||||
return callable_ ? callable_->less(*other_ref.callable_) : other_ref.callable_ != nullptr;
|
||||
}
|
||||
|
||||
boost::iterator_range<variant_iterator> variant_callable::make_iterator() const
|
||||
|
@ -359,7 +369,7 @@ bool variant_map::less_than(variant_value_base& other) const
|
|||
variant variant_map::deref_iterator(const boost::any& iter) const
|
||||
{
|
||||
const variant_map_raw::value_type& p = *boost::any_cast<const variant_map_raw::const_iterator&>(iter);
|
||||
key_value_pair* the_pair = new key_value_pair(p.first, p.second);
|
||||
auto the_pair = std::make_shared<key_value_pair>(p.first, p.second);
|
||||
return variant(the_pair);
|
||||
}
|
||||
|
||||
|
|
|
@ -311,10 +311,11 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class variant_callable : public variant_value_base
|
||||
class variant_callable : public variant_value_base, private callable_die_subscriber
|
||||
{
|
||||
public:
|
||||
explicit variant_callable(const formula_callable* callable);
|
||||
explicit variant_callable(const_formula_callable_ptr callable);
|
||||
~variant_callable();
|
||||
|
||||
virtual bool as_bool() const override
|
||||
{
|
||||
|
@ -326,7 +327,7 @@ public:
|
|||
return 1;
|
||||
}
|
||||
|
||||
const formula_callable* get_callable() const
|
||||
const_formula_callable_ptr get_callable() const
|
||||
{
|
||||
return callable_;
|
||||
}
|
||||
|
@ -360,9 +361,10 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
const formula_callable* callable_;
|
||||
void notify_dead() override {callable_.reset();}
|
||||
|
||||
mutable formula_input_vector inputs; // for iteration
|
||||
const_formula_callable_ptr callable_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1320,7 +1320,7 @@ void image_shape::draw(surface& canvas,
|
|||
local_variables.add("clip_y", wfl::variant(clip_y));
|
||||
|
||||
// Execute the provided actions for this context.
|
||||
wfl::variant(&variables).execute_variant(actions_formula_.evaluate(local_variables));
|
||||
wfl::variant(variables.fake_ptr()).execute_variant(actions_formula_.evaluate(local_variables));
|
||||
|
||||
// Copy the data to local variables to avoid overwriting the originals.
|
||||
SDL_Rect src_clip = src_clip_;
|
||||
|
|
|
@ -140,7 +140,7 @@ void luaW_pushfaivariant(lua_State* L, variant val) {
|
|||
}
|
||||
} else if(val.is_callable()) {
|
||||
// First try a few special cases
|
||||
if(unit_callable* u_ref = val.try_convert<unit_callable>()) {
|
||||
if(auto u_ref = val.try_convert<unit_callable>()) {
|
||||
const unit& u = u_ref->get_unit();
|
||||
unit_map::iterator un_it = resources::gameboard->units().find(u.get_location());
|
||||
if(&*un_it == &u) {
|
||||
|
@ -148,11 +148,11 @@ void luaW_pushfaivariant(lua_State* L, variant val) {
|
|||
} else {
|
||||
luaW_pushunit(L, u.side(), u.underlying_id());
|
||||
}
|
||||
} else if(location_callable* loc_ref = val.try_convert<location_callable>()) {
|
||||
} else if(auto loc_ref = val.try_convert<location_callable>()) {
|
||||
luaW_pushlocation(L, loc_ref->loc());
|
||||
} else {
|
||||
// If those fail, convert generically to a map
|
||||
const formula_callable* obj = val.as_callable();
|
||||
auto obj = val.as_callable();
|
||||
formula_input_vector inputs;
|
||||
obj->get_inputs(inputs);
|
||||
lua_newtable(L);
|
||||
|
@ -179,7 +179,7 @@ variant luaW_tofaivariant(lua_State* L, int i) {
|
|||
case LUA_TSTRING:
|
||||
return variant(lua_tostring(L, i));
|
||||
case LUA_TTABLE:
|
||||
return variant(new lua_callable(L, i));
|
||||
return variant(std::make_shared<lua_callable>(L, i));
|
||||
case LUA_TUSERDATA:
|
||||
static t_string tstr;
|
||||
static vconfig vcfg = vconfig::unconstructed_vconfig();
|
||||
|
@ -187,11 +187,11 @@ variant luaW_tofaivariant(lua_State* L, int i) {
|
|||
if(luaW_totstring(L, i, tstr)) {
|
||||
return variant(tstr.str());
|
||||
} else if(luaW_tovconfig(L, i, vcfg)) {
|
||||
return variant(new config_callable(vcfg.get_parsed_config()));
|
||||
return variant(std::make_shared<config_callable>(vcfg.get_parsed_config()));
|
||||
} else if(unit* u = luaW_tounit(L, i)) {
|
||||
return variant(new unit_callable(*u));
|
||||
return variant(std::make_shared<unit_callable>(*u));
|
||||
} else if(luaW_tolocation(L, i, loc)) {
|
||||
return variant(new location_callable(loc));
|
||||
return variant(std::make_shared<location_callable>(loc));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -44,12 +44,12 @@ class mock_party : public formula_callable {
|
|||
i_[2].add("strength",variant(14));
|
||||
std::vector<variant> members;
|
||||
for(int n = 0; n != 3; ++n) {
|
||||
members.emplace_back(&i_[n]);
|
||||
members.emplace_back(i_[n].fake_ptr());
|
||||
}
|
||||
|
||||
return variant(members);
|
||||
} else if(key == "char") {
|
||||
return variant(&c_);
|
||||
return variant(c_.fake_ptr());
|
||||
} else {
|
||||
return variant(0);
|
||||
}
|
||||
|
|
|
@ -591,10 +591,10 @@ bool basic_unit_filter_impl::internal_matches_filter(const unit & u, const map_l
|
|||
if (!vcfg["formula"].blank()) {
|
||||
try {
|
||||
const wfl::unit_callable main(loc,u);
|
||||
wfl::map_formula_callable callable(&main);
|
||||
wfl::map_formula_callable callable(main.fake_ptr());
|
||||
if (u2) {
|
||||
std::shared_ptr<wfl::unit_callable> secondary(new wfl::unit_callable(*u2));
|
||||
callable.add("other", wfl::variant(secondary.get()));
|
||||
callable.add("other", wfl::variant(secondary));
|
||||
// It's not destroyed upon scope exit because the variant holds a reference
|
||||
}
|
||||
const wfl::formula form(vcfg["formula"]);
|
||||
|
|
Loading…
Add table
Reference in a new issue