Merge branch 'main' into devtools

This commit is contained in:
MihailRis 2024-05-12 11:00:42 +03:00
commit c63d350ad5
9 changed files with 80 additions and 73 deletions

View File

@ -47,7 +47,7 @@ static int l_reopen_world(lua_State*) {
static int l_close_world(lua_State* L) {
if (scripting::controller == nullptr) {
luaL_error(L, "no world open");
throw std::runtime_error("no world open");
}
bool save_world = lua_toboolean(L, 1);
if (save_world) {
@ -69,12 +69,15 @@ static int l_delete_world(lua_State* L) {
static int l_reconfig_packs(lua_State* L) {
if (!lua_istable(L, 1)) {
luaL_error(L, "strings array expected as the first argument");
throw std::runtime_error("strings array expected as the first argument");
}
if (!lua_istable(L, 2)) {
luaL_error(L, "strings array expected as the second argument");
throw std::runtime_error("strings array expected as the second argument");
}
std::vector<std::string> addPacks;
if (!lua_istable(L, 1)) {
throw std::runtime_error("an array expected as argument 1");
}
int addLen = lua_objlen(L, 1);
for (int i = 0; i < addLen; i++) {
lua_rawgeti(L, 1, i+1);
@ -83,6 +86,9 @@ static int l_reconfig_packs(lua_State* L) {
}
std::vector<std::string> remPacks;
if (!lua_istable(L, 2)) {
throw std::runtime_error("an array expected as argument 2");
}
int remLen = lua_objlen(L, 2);
for (int i = 0; i < remLen; i++) {
lua_rawgeti(L, 2, i+1);
@ -147,8 +153,7 @@ static int l_get_setting_info(lua_State* L) {
return 1;
}
lua_pop(L, 1);
luaL_error(L, "unsupported setting type");
return 0;
throw std::runtime_error("unsupported setting type");
}
static int l_quit(lua_State*) {

View File

@ -4,19 +4,15 @@
#include "../../../engine.hpp"
#include "../../../files/files.hpp"
#include "../../../files/engine_paths.hpp"
#include "../../../util/stringutil.hpp"
#include <string>
#include <filesystem>
namespace fs = std::filesystem;
static fs::path resolve_path(lua_State* L, const std::string& path) {
try {
return scripting::engine->getPaths()->resolve(path);
} catch (const files_access_error& err) {
luaL_error(L, err.what());
abort(); // unreachable
}
static fs::path resolve_path(lua_State*, const std::string& path) {
return scripting::engine->getPaths()->resolve(path);
}
static int l_file_find(lua_State* L) {
@ -37,7 +33,7 @@ static int l_file_read(lua_State* L) {
lua_pushstring(L, files::read_string(path).c_str());
return 1;
}
return luaL_error(L, "file does not exists '%s'", path.u8string().c_str());
throw std::runtime_error("file does not exists "+util::quote(path.u8string()));
}
static int l_file_write(lua_State* L) {
@ -103,27 +99,22 @@ static int l_file_read_bytes(lua_State* L) {
}
return 1;
}
return luaL_error(L, "file does not exists '%s'", path.u8string().c_str());
throw std::runtime_error("file does not exists "+util::quote(path.u8string()));
}
static int read_bytes_from_table(lua_State* L, int tableIndex, std::vector<ubyte>& bytes) {
if(!lua_istable(L, tableIndex)) {
return luaL_error(L, "table expected");
throw std::runtime_error("table expected");
} else {
lua_pushnil(L);
while(lua_next(L, tableIndex - 1) != 0) {
const int byte = lua_tointeger(L, -1);
if(byte < 0 || byte > 255) {
return luaL_error(L, "invalid byte '%i'", byte);
throw std::runtime_error("invalid byte '"+std::to_string(byte)+"'");
}
bytes.push_back(byte);
bytes.push_back(byte);
lua_pop(L, 1);
}
return 1;
}
}
@ -132,7 +123,7 @@ static int l_file_write_bytes(lua_State* L) {
int pathIndex = 1;
if(!lua_isstring(L, pathIndex)) {
return luaL_error(L, "string expected");
throw std::runtime_error("string expected");
}
fs::path path = resolve_path(L, lua_tostring(L, pathIndex));

View File

@ -34,14 +34,14 @@ struct DocumentNode {
using namespace scripting;
static DocumentNode getDocumentNode(lua_State* L, const std::string& name, const std::string& nodeName) {
static DocumentNode getDocumentNode(lua_State*, const std::string& name, const std::string& nodeName) {
auto doc = engine->getAssets()->getLayout(name);
if (doc == nullptr) {
luaL_error(L, "document '%s' not found", name.c_str());
throw std::runtime_error("document '"+name+"' not found");
}
auto node = doc->get(nodeName);
if (node == nullptr) {
luaL_error(L, "document '%s' has no element with id '%s'", name.c_str(), nodeName.c_str());
throw std::runtime_error("document '"+name+"' has no element with id '"+nodeName+"'");
}
return {doc, node};
}
@ -79,7 +79,7 @@ static int l_container_add(lua_State* L) {
node->add(subnode);
UINode::getIndices(subnode, docnode.document->getMapWriteable());
} catch (const std::exception& err) {
luaL_error(L, err.what());
throw std::runtime_error(err.what());
}
return 0;
}
@ -418,7 +418,7 @@ static int l_gui_get_env(lua_State* L) {
auto name = lua_tostring(L, 1);
auto doc = scripting::engine->getAssets()->getLayout(name);
if (doc == nullptr) {
luaL_error(L, "document '%s' not found", name);
throw std::runtime_error("document '"+std::string(name)+"' not found");
}
lua_getglobal(L, lua::LuaState::envName(*doc->getEnvironment()).c_str());
return 1;
@ -439,7 +439,7 @@ static int l_gui_reindex(lua_State* L) {
auto name = lua_tostring(L, 1);
auto doc = scripting::engine->getAssets()->getLayout(name);
if (doc == nullptr) {
luaL_error(L, "document '%s' not found", name);
throw std::runtime_error("document '"+std::string(name)+"' not found");
}
doc->rebuildIndices();
return 0;

View File

@ -10,6 +10,7 @@
#include "../../../graphics/ui/elements/InventoryView.hpp"
#include "../../../items/Inventories.hpp"
#include "../../../logic/BlocksController.hpp"
#include "../../../util/stringutil.hpp"
#include "../../../voxels/Block.hpp"
#include "../../../voxels/Chunks.hpp"
#include "../../../voxels/voxel.hpp"
@ -45,17 +46,18 @@ static int l_hud_open_block(lua_State* L) {
voxel* vox = scripting::level->chunks->get(x, y, z);
if (vox == nullptr) {
luaL_error(L, "block does not exists at %d %d %d", x, y, z);
throw std::runtime_error("block does not exists at "+
std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z)
);
}
auto def = scripting::content->getIndices()->getBlockDef(vox->id);
auto assets = scripting::engine->getAssets();
auto layout = assets->getLayout(def->uiLayout);
if (layout == nullptr) {
luaL_error(L, "block '%s' has no ui layout", def->name.c_str());
throw std::runtime_error("block '"+def->name+"' has no ui layout");
}
auto id = scripting::blocks->createBlockInventory(x, y, z);
scripting::hud->openInventory(
glm::ivec3(x, y, z), layout, scripting::level->inventories->get(id), playerInventory
);
@ -72,7 +74,7 @@ static int l_hud_show_overlay(lua_State* L) {
auto assets = scripting::engine->getAssets();
auto layout = assets->getLayout(name);
if (layout == nullptr) {
luaL_error(L, "there is no ui layout '%s'", name);
throw std::runtime_error("there is no ui layout "+util::quote(name));
}
scripting::hud->showOverlay(layout, playerInventory);
return 0;
@ -82,7 +84,7 @@ static UiDocument* require_layout(lua_State* L, const char* name) {
auto assets = scripting::engine->getAssets();
auto layout = assets->getLayout(name);
if (layout == nullptr) {
luaL_error(L, "layout '%s' is not found", name);
throw std::runtime_error("layout '"+std::string(name)+"' is not found");
}
return layout;
}

View File

@ -5,6 +5,7 @@
#include "../../../window/input.hpp"
#include "../../../window/Events.hpp"
#include "../../../util/stringutil.hpp"
#include "../../../frontend/screens/Screen.hpp"
#include "../../../frontend/hud.hpp"
#include "../../../engine.hpp"
@ -26,7 +27,7 @@ static int l_add_callback(lua_State* L) {
auto bindname = lua_tostring(L, 1);
const auto& bind = Events::bindings.find(bindname);
if (bind == Events::bindings.end()) {
luaL_error(L, "unknown binding %q", bindname);
throw std::runtime_error("unknown binding "+util::quote(bindname));
}
state->pushvalue(2);
runnable callback = state->createRunnable();

View File

@ -8,22 +8,40 @@
#include "../../../items/Inventories.hpp"
#include "../../../logic/BlocksController.hpp"
static void validate_itemid(lua_State* L, itemid_t id) {
static void validate_itemid(itemid_t id) {
if (id >= scripting::indices->countItemDefs()) {
luaL_error(L, "invalid item id");
throw std::runtime_error("invalid item id");
}
}
static std::shared_ptr<Inventory> get_inventory(int64_t id) {
auto inv = scripting::level->inventories->get(id);
if (inv == nullptr) {
throw std::runtime_error("inventory not found: "+std::to_string(id));
}
return inv;
}
static std::shared_ptr<Inventory> get_inventory(int64_t id, int arg) {
auto inv = scripting::level->inventories->get(id);
if (inv == nullptr) {
throw std::runtime_error("inventory not found: "+std::to_string(id)+
" argument "+std::to_string(arg));
}
return inv;
}
static void validate_slotid(int slotid, Inventory* inv) {
if (slotid < 0 || uint64_t(slotid) >= inv->size()) {
throw std::runtime_error("slot index is out of range [0..inventory.size(invid)]");
}
}
static int l_inventory_get(lua_State* L) {
lua::luaint invid = lua_tointeger(L, 1);
lua::luaint slotid = lua_tointeger(L, 2);
auto inv = scripting::level->inventories->get(invid);
if (inv == nullptr) {
luaL_error(L, "inventory does not exists in runtime: %d", invid);
}
if (slotid < 0 || uint64_t(slotid) >= inv->size()) {
luaL_error(L, "slot index is out of range [0, inventory.size(invid)]");
}
auto inv = get_inventory(invid);
validate_slotid(slotid, inv.get());
const ItemStack& item = inv->getSlot(slotid);
lua_pushinteger(L, item.getItemId());
lua_pushinteger(L, item.getCount());
@ -35,15 +53,11 @@ static int l_inventory_set(lua_State* L) {
lua::luaint slotid = lua_tointeger(L, 2);
lua::luaint itemid = lua_tointeger(L, 3);
lua::luaint count = lua_tointeger(L, 4);
validate_itemid(L, itemid);
validate_itemid(itemid);
auto inv = scripting::level->inventories->get(invid);
if (inv == nullptr) {
luaL_error(L, "inventory does not exists in runtime: %d", invid);
}
if (slotid < 0 || uint64_t(slotid) >= inv->size()) {
luaL_error(L, "slot index is out of range [0, inventory.size(invid)]");
}
auto inv = get_inventory(invid);
validate_slotid(slotid, inv.get());
ItemStack& item = inv->getSlot(slotid);
item.set(ItemStack(itemid, count));
return 0;
@ -51,10 +65,7 @@ static int l_inventory_set(lua_State* L) {
static int l_inventory_size(lua_State* L) {
lua::luaint invid = lua_tointeger(L, 1);
auto inv = scripting::level->inventories->get(invid);
if (inv == nullptr) {
luaL_error(L, "inventory does not exists in runtime: %d", invid);
}
auto inv = get_inventory(invid);
lua_pushinteger(L, inv->size());
return 1;
}
@ -63,12 +74,9 @@ static int l_inventory_add(lua_State* L) {
lua::luaint invid = lua_tointeger(L, 1);
lua::luaint itemid = lua_tointeger(L, 2);
lua::luaint count = lua_tointeger(L, 3);
validate_itemid(L, itemid);
validate_itemid(itemid);
auto inv = scripting::level->inventories->get(invid);
if (inv == nullptr) {
luaL_error(L, "inventory does not exists in runtime: %d", invid);
}
auto inv = get_inventory(invid);
ItemStack item(itemid, count);
inv->move(item, scripting::indices);
lua_pushinteger(L, item.getCount());
@ -115,17 +123,12 @@ static int l_inventory_clone(lua_State* L) {
static int l_inventory_move(lua_State* L) {
lua::luaint invAid = lua_tointeger(L, 1);
lua::luaint slotAid = lua_tointeger(L, 2);
auto invA = scripting::level->inventories->get(invAid);
if (invA == nullptr) {
luaL_error(L, "inventory A does not exists in runtime: %d", invAid);
}
auto invA = get_inventory(invAid, 1);
validate_slotid(slotAid, invA.get());
lua::luaint invBid = lua_tointeger(L, 3);
lua::luaint slotBid = lua_isnil(L, 4) ? -1 : lua_tointeger(L, 4);
auto invB = scripting::level->inventories->get(invBid);
if (invB == nullptr) {
luaL_error(L, "inventory B does not exists in runtime: %d", invBid);
}
auto invB = get_inventory(invBid, 3);
auto& slot = invA->getSlot(slotAid);
if (slotBid == -1) {
invB->move(slot, scripting::content->getIndices());

View File

@ -18,8 +18,7 @@ static int l_json_stringify(lua_State* L) {
lua_pushstring(L, string.c_str());
return 1;
} else {
luaL_error(L, "table expected");
return 0;
throw std::runtime_error("table expected");
}
}

View File

@ -11,6 +11,8 @@
#endif
#include <glm/glm.hpp>
#include <stdexcept>
namespace lua {
inline int pushivec3(lua_State* L, luaint x, luaint y, luaint z) {
lua_pushinteger(L, x);
@ -94,6 +96,9 @@ namespace lua {
inline glm::vec2 tovec2(lua_State* L, int idx) {
lua_pushvalue(L, idx);
if (!lua_istable(L, idx) || lua_objlen(L, idx) < 2) {
throw std::runtime_error("value must be an array of two numbers");
}
lua_rawgeti(L, -1, 1);
lua::luanumber x = lua_tonumber(L, -1); lua_pop(L, 1);
lua_rawgeti(L, -1, 2);
@ -104,8 +109,8 @@ namespace lua {
inline glm::vec4 tocolor(lua_State* L, int idx) {
lua_pushvalue(L, idx);
if (!lua_istable(L, -1)) {
luaL_error(L, "RGBA array required");
if (!lua_istable(L, -1) || lua_objlen(L, idx) < 4) {
throw std::runtime_error("RGBA array required");
}
lua_rawgeti(L, -1, 1);
lua::luanumber r = lua_tonumber(L, -1); lua_pop(L, 1);

View File

@ -5,6 +5,7 @@
#include <string>
#include <vector>
#include <stdexcept>
namespace util {
/// @brief Function used for string serialization in text formats