[Lua.MapGen] Formula map filters now support taking precompiled formulas instead of a formula string.
This commit is contained in:
parent
f22f13f850
commit
5ed7f63ede
3 changed files with 29 additions and 19 deletions
|
@ -217,6 +217,28 @@ variant luaW_tofaivariant(lua_State* L, int i) {
|
|||
return variant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a formula from the stack. If @a allow_str is true, it compiles a formula string if found.
|
||||
* Otherwise, it must be an already-compiled formula.
|
||||
* Raises an error if a formula is not found, or if there's an error in compilation.
|
||||
* Thus, it never returns a null pointer.
|
||||
*/
|
||||
lua_formula_bridge::fpointer luaW_check_formula(lua_State* L, int idx, bool allow_str) {
|
||||
using namespace lua_formula_bridge;
|
||||
fpointer form;
|
||||
if(void* ud = luaL_testudata(L, idx, formulaKey)) {
|
||||
form.get_deleter() = [](fwrapper*) {};
|
||||
form.reset(static_cast<fwrapper*>(ud));
|
||||
// Setting a no-op deleter guarantees the Lua-held object is not deleted
|
||||
} else if(allow_str) {
|
||||
form.reset(new fwrapper(luaL_checkstring(L, idx)));
|
||||
// Leave deleter at default so it's deleted properly later
|
||||
} else {
|
||||
luaW_type_error(L, idx, "formula");
|
||||
}
|
||||
return form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a formula in the formula engine.
|
||||
* - Arg 1: Formula string.
|
||||
|
@ -225,14 +247,7 @@ variant luaW_tofaivariant(lua_State* L, int i) {
|
|||
*/
|
||||
int lua_formula_bridge::intf_eval_formula(lua_State *L)
|
||||
{
|
||||
bool need_delete = false;
|
||||
fwrapper* form;
|
||||
if(void* ud = luaL_testudata(L, 1, formulaKey)) {
|
||||
form = static_cast<fwrapper*>(ud);
|
||||
} else {
|
||||
need_delete = true;
|
||||
form = new fwrapper(luaL_checkstring(L, 1));
|
||||
}
|
||||
fpointer form = luaW_check_formula(L, 1, true);
|
||||
std::shared_ptr<formula_callable> context, fallback;
|
||||
if(unit* u = luaW_tounit(L, 2)) {
|
||||
context.reset(new unit_callable(*u));
|
||||
|
@ -249,9 +264,6 @@ int lua_formula_bridge::intf_eval_formula(lua_State *L)
|
|||
}
|
||||
variant result = form->evaluate(*context);
|
||||
luaW_pushfaivariant(L, result);
|
||||
if(need_delete) {
|
||||
delete form;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
@ -41,4 +42,6 @@ namespace lua_formula_bridge {
|
|||
wfl::variant evaluate(const wfl::formula_callable& variables, wfl::formula_debugger* fdb = nullptr) const;
|
||||
};
|
||||
|
||||
using fpointer = std::unique_ptr<fwrapper, std::function<void(fwrapper*)>>;
|
||||
} // end namespace lua_formula_bridge
|
||||
lua_formula_bridge::fpointer luaW_check_formula(lua_State* L, int idx, bool allow_str);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "map/map.hpp"
|
||||
#include "pathutils_impl.hpp"
|
||||
#include "scripting/lua_common.hpp"
|
||||
#include "scripting/lua_formula_bridge.hpp"
|
||||
#include "scripting/push_check.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
||||
|
@ -548,14 +549,8 @@ public:
|
|||
{
|
||||
LOG_LMG << "creating formula filter";
|
||||
lua_geti(L, -1, 2);
|
||||
std::string code = std::string(luaW_tostring(L, -1));
|
||||
formula_ = luaW_check_formula(L, 1, true);
|
||||
lua_pop(L, 1);
|
||||
|
||||
try {
|
||||
formula_ = std::make_unique<wfl::formula>(code);
|
||||
} catch(const wfl::formula_error& e) {
|
||||
ERR_LMG << "formula error" << e.what();
|
||||
}
|
||||
}
|
||||
bool matches(const gamemap_base&, map_location l) override
|
||||
{
|
||||
|
@ -569,7 +564,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
}
|
||||
std::unique_ptr<wfl::formula> formula_;
|
||||
lua_formula_bridge::fpointer formula_;
|
||||
};
|
||||
|
||||
// todo: maybe invent a general macro for this string_switch implementation.
|
||||
|
|
Loading…
Add table
Reference in a new issue