added stdlib.lua + lua errors handling update

This commit is contained in:
MihailRis 2024-01-22 08:14:52 +03:00
parent e4ef813705
commit ff7f18fa7b
2 changed files with 73 additions and 9 deletions

51
res/scripts/stdlib.lua Normal file
View File

@ -0,0 +1,51 @@
-- kit of standard functions
-- Check if given table is an array
function is_array(x)
if #t > 0 then
return true
end
for k, v in pairs(x) do
return false
end
return true
end
local __cached_scripts = {}
local __cached_results = {}
-- Get entry-point and filename from `entry-point:filename` path
function parse_path(path)
local index = string.find(path, ':')
if index == nil then
error("invalid path syntax (':' missing)")
end
return string.sub(path, 1, index-1), string.sub(path, index+1, -1)
end
-- Load script with caching
--
-- path - script path `contentpack:filename`.
-- Example `base:scripts/tests.lua`
--
-- nocache - ignore cached script, load anyway
function load_script(path, nocache)
local packname, filename = parse_path(path)
local packpath = pack.get_folder(packname)
local fullpath = packpath..filename
-- __cached_scripts used in condition because cached result may be nil
if not nocache and __cached_scripts[fullpath] ~= nil then
return __cached_results[fullpath]
end
local script = loadfile(fullpath)
if script == nil then
error("script '"..filename.."' not found in '"..packname.."'")
end
local result = script()
if not nocache then
__cached_scripts[fullpath] = script
__cached_results[fullpath] = result
end
return result
end

View File

@ -26,6 +26,10 @@ Level* scripting::level = nullptr;
const Content* scripting::content = nullptr;
BlocksController* scripting::blocks = nullptr;
static void handleError(lua_State* L) {
std::cerr << "lua error: " << lua_tostring(L,-1) << std::endl;
}
inline int lua_pushivec3(lua_State* L, int x, int y, int z) {
lua_pushinteger(L, x);
lua_pushinteger(L, y);
@ -51,13 +55,24 @@ bool rename_global(lua_State* L, const char* src, const char* dst) {
int call_func(lua_State* L, int argc, const std::string& name) {
if (lua_pcall(L, argc, LUA_MULTRET, 0)) {
std::cerr << "Lua error in " << name << ": ";
std::cerr << lua_tostring(L,-1) << std::endl;
handleError(L);
return 0;
}
return 1;
}
void load_script(fs::path name) {
auto paths = scripting::engine->getPaths();
fs::path file = paths->getResources()/fs::path("scripts")/name;
std::string src = files::read_string(file);
if (luaL_loadbuffer(L, src.c_str(), src.length(), file.u8string().c_str())) {
handleError(L);
return;
}
call_func(L, 0, file.u8string());
}
void scripting::initialize(Engine* engine) {
scripting::engine = engine;
@ -81,17 +96,15 @@ void scripting::initialize(Engine* engine) {
# endif // LUAJIT_VERSION
apilua::create_funcs(L);
load_script(fs::path("stdlib.lua"));
}
void scripting::on_world_load(Level* level, BlocksController* blocks) {
scripting::level = level;
scripting::content = level->content;
scripting::blocks = blocks;
auto paths = scripting::engine->getPaths();
fs::path file = paths->getResources()/fs::path("scripts/world.lua");
std::string src = files::read_string(file);
luaL_loadbuffer(L, src.c_str(), src.length(), file.string().c_str());
call_func(L, 0, "<script>");
load_script("world.lua");
}
void scripting::on_world_quit() {
@ -165,7 +178,7 @@ void scripting::load_block_script(std::string prefix, fs::path file, block_funcs
std::string src = files::read_string(file);
std::cout << "loading script " << file.u8string() << std::endl;
if (luaL_loadbuffer(L, src.c_str(), src.size(), file.string().c_str())) {
std::cerr << "Lua error:" << lua_tostring(L,-1) << std::endl;
handleError(L);
return;
}
call_func(L, 0, "<script>");
@ -181,7 +194,7 @@ void scripting::load_item_script(std::string prefix, fs::path file, item_funcs_s
std::string src = files::read_string(file);
std::cout << "loading script " << file.u8string() << std::endl;
if (luaL_loadbuffer(L, src.c_str(), src.size(), file.string().c_str())) {
std::cerr << "Lua error:" << lua_tostring(L,-1) << std::endl;
handleError(L);
return;
}
call_func(L, 0, "<script>");