mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-08 12:31:51 +00:00
commit
c4d5812b4f
46 changed files with 754 additions and 342 deletions
|
|
@ -350,6 +350,7 @@ static int l_start_debug_instance(lua::State* L) {
|
|||
}
|
||||
}
|
||||
auto projectPath = lua::isstring(L, 2) ? lua::require_lstring(L, 2) : "";
|
||||
auto outputPath = lua::isstring(L, 3) ? lua::require_lstring(L, 3) : "";
|
||||
const auto& paths = engine->getPaths();
|
||||
|
||||
std::vector<std::string> args {
|
||||
|
|
@ -362,7 +363,10 @@ static int l_start_debug_instance(lua::State* L) {
|
|||
args.emplace_back(io::resolve(std::string(projectPath)).string());
|
||||
}
|
||||
|
||||
platform::new_engine_instance(std::move(args));
|
||||
platform::new_engine_instance(
|
||||
std::move(args),
|
||||
outputPath.empty() ? "" : io::resolve(std::string(outputPath))
|
||||
);
|
||||
return lua::pushinteger(L, port);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1011,8 +1011,9 @@ static int l_gui_get_env(lua::State* L) {
|
|||
"document '" + std::string(name) + "' not found"
|
||||
);
|
||||
}
|
||||
lua::getglobal(L, lua::env_name(*doc->getEnvironment()));
|
||||
return 1;
|
||||
return lua::getregistry(
|
||||
L, lua::ENVS_TABLE, lua::env_name(*doc->getEnvironment())
|
||||
);
|
||||
}
|
||||
|
||||
static int l_gui_str(lua::State* L) {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ static int l_set_params(lua::State* L) {
|
|||
static int l_set_array(lua::State* L) {
|
||||
size_t index = static_cast<size_t>(lua::tointeger(L, 1));
|
||||
auto key = lua::require_string(L, 2);
|
||||
auto data = lua::require_lstring(L, 3);
|
||||
auto data = lua::bytearray_as_string(L, 3);
|
||||
auto effect = post_processing->getEffect(index);
|
||||
if (effect == nullptr) {
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,20 @@ static int l_set_rotation(lua::State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_get_entity(lua::State* L) {
|
||||
if (auto note = renderer->texts->get(lua::tointeger(L, 1))) {
|
||||
return lua::pushinteger(L, note->getEntity());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_set_entity(lua::State* L) {
|
||||
if (auto note = renderer->texts->get(lua::tointeger(L, 1))) {
|
||||
note->setEntity(lua::touinteger(L, 2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg text3dlib[] = {
|
||||
{"show", wrap_hud<l_show>},
|
||||
{"hide", wrap_hud<l_hide>},
|
||||
|
|
@ -108,5 +122,7 @@ const luaL_Reg text3dlib[] = {
|
|||
{"set_axis_y", wrap_hud<l_set_axis_y>},
|
||||
{"set_rotation", wrap_hud<l_set_rotation>},
|
||||
{"update_settings", wrap_hud<l_update_settings>},
|
||||
{"get_entity", wrap_hud<l_get_entity>},
|
||||
{"set_entity", wrap_hud<l_set_entity>},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -64,12 +64,13 @@ static void create_libs(State* L, StateType stateType) {
|
|||
openlib(L, "vec4", vec4lib);
|
||||
openlib(L, "yaml", yamllib);
|
||||
|
||||
openlib(L, "__vc_app", applib);
|
||||
lua::getglobal(L, "__vc_app");
|
||||
lua::setregistry(L, "app");
|
||||
|
||||
if (stateType == StateType::SCRIPT) {
|
||||
openlib(L, "app", applib);
|
||||
lua::getglobal(L, "app");
|
||||
lua::setglobal(L, "__vc_app");
|
||||
} else if (stateType == StateType::BASE) {
|
||||
openlib(L, "__vc_app", applib);
|
||||
lua::getregistry(L, "app");
|
||||
lua::setglobal(L, "app");
|
||||
}
|
||||
if (stateType == StateType::BASE || stateType == StateType::SCRIPT) {
|
||||
openlib(L, "assets", assetslib);
|
||||
|
|
@ -95,10 +96,18 @@ static void create_libs(State* L, StateType stateType) {
|
|||
}
|
||||
|
||||
addfunc(L, "print", lua::wrap<l_print>);
|
||||
addfunc(L, "_crc32", lua::wrap<l_crc32>);
|
||||
addfunc(L, "crc32", lua::wrap<l_crc32>);
|
||||
}
|
||||
|
||||
static int l_panic_handler(lua::State* L) {
|
||||
logger.error() << "PANIC: unprotected error in call to Lua API: " << lua::tostring(L, -1);
|
||||
logger.flush();
|
||||
abort();
|
||||
}
|
||||
|
||||
void lua::init_state(State* L, StateType stateType) {
|
||||
lua_atpanic(L, l_panic_handler);
|
||||
|
||||
// Allowed standard libraries
|
||||
luaL_openlibs(L);
|
||||
|
||||
|
|
@ -112,21 +121,25 @@ void lua::init_state(State* L, StateType stateType) {
|
|||
setglobal(L, "io");
|
||||
|
||||
createtable(L, 0, 0);
|
||||
pushvalue(L, -1);
|
||||
setglobal(L, "__vc__pack_envs");
|
||||
setregistry(L, lua::PACK_ENVS_TABLE);
|
||||
|
||||
const char* removed_os[] {
|
||||
"execute", "exit", "remove", "rename", "setlocale", "tmpname", nullptr};
|
||||
remove_lib_funcs(L, "os", removed_os);
|
||||
create_libs(L, stateType);
|
||||
|
||||
createtable(L, 0, 0);
|
||||
setregistry(L, LAMBDAS_TABLE);
|
||||
|
||||
createtable(L, 0, 0);
|
||||
setregistry(L, CHUNKS_TABLE);
|
||||
|
||||
createtable(L, 0, 0);
|
||||
pushglobals(L);
|
||||
setglobal(L, env_name(0));
|
||||
|
||||
createtable(L, 0, 0);
|
||||
setglobal(L, LAMBDAS_TABLE);
|
||||
|
||||
createtable(L, 0, 0);
|
||||
setglobal(L, CHUNKS_TABLE);
|
||||
setfield(L, env_name(0));
|
||||
setregistry(L, ENVS_TABLE);
|
||||
|
||||
initialize_libs_extends(L);
|
||||
|
||||
|
|
@ -144,6 +157,9 @@ void lua::initialize(const EnginePaths& paths, const CoreParameters& params) {
|
|||
);
|
||||
lua::pushstring(main_thread, params.scriptFile.stem().u8string());
|
||||
lua::setglobal(main_thread, "__VC_SCRIPT_NAME");
|
||||
|
||||
lua::pushboolean(main_thread, params.headless);
|
||||
lua::setglobal(main_thread, "__VC_HEADLESS");
|
||||
}
|
||||
|
||||
void lua::finalize() {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
using namespace lua;
|
||||
|
||||
static int nextEnvironment = 1;
|
||||
static int next_environment = 1;
|
||||
|
||||
std::unordered_map<std::type_index, std::string> lua::usertypeNames;
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ int lua::userdata_destructor(lua::State* L) {
|
|||
}
|
||||
|
||||
std::string lua::env_name(int env) {
|
||||
return "_ENV" + util::mangleid(env);
|
||||
return std::to_string(env);
|
||||
}
|
||||
|
||||
int lua::pushvalue(State* L, const dv::value& value) {
|
||||
|
|
@ -220,7 +220,7 @@ void lua::dump_stack(State* L) {
|
|||
static std::shared_ptr<std::string> create_lambda_handler(State* L) {
|
||||
auto ptr = reinterpret_cast<ptrdiff_t>(topointer(L, -1));
|
||||
auto name = util::mangleid(ptr);
|
||||
requireglobal(L, LAMBDAS_TABLE);
|
||||
requireregistry(L, LAMBDAS_TABLE);
|
||||
pushvalue(L, -2);
|
||||
setfield(L, name);
|
||||
pop(L, 2);
|
||||
|
|
@ -229,7 +229,7 @@ static std::shared_ptr<std::string> create_lambda_handler(State* L) {
|
|||
new std::string(name),
|
||||
[=](std::string* name) {
|
||||
auto L = lua::get_main_state();
|
||||
requireglobal(L, LAMBDAS_TABLE);
|
||||
requireregistry(L, LAMBDAS_TABLE);
|
||||
pushnil(L);
|
||||
setfield(L, *name);
|
||||
pop(L);
|
||||
|
|
@ -242,8 +242,9 @@ runnable lua::create_runnable(State* L) {
|
|||
auto funcptr = create_lambda_handler(L);
|
||||
return [=]() {
|
||||
auto L = lua::get_main_state();
|
||||
if (!get_from(L, LAMBDAS_TABLE, *funcptr, false))
|
||||
if (!get_from_registry(L, LAMBDAS_TABLE, *funcptr, false)) {
|
||||
return;
|
||||
}
|
||||
call_nothrow(L, 0, 0);
|
||||
pop(L);
|
||||
};
|
||||
|
|
@ -252,8 +253,9 @@ runnable lua::create_runnable(State* L) {
|
|||
KeyCallback lua::create_simple_handler(State* L) {
|
||||
auto funcptr = create_lambda_handler(L);
|
||||
return [=]() -> bool {
|
||||
if (!get_from(L, LAMBDAS_TABLE, *funcptr, false))
|
||||
if (!get_from_registry(L, LAMBDAS_TABLE, *funcptr, false)) {
|
||||
return false;
|
||||
}
|
||||
int top = gettop(L) - 1;
|
||||
if (call_nothrow(L, 0)) {
|
||||
int nres = gettop(L) - top;
|
||||
|
|
@ -271,8 +273,9 @@ KeyCallback lua::create_simple_handler(State* L) {
|
|||
scripting::common_func lua::create_lambda(State* L) {
|
||||
auto funcptr = create_lambda_handler(L);
|
||||
return [=](const std::vector<dv::value>& args) -> dv::value {
|
||||
if (!get_from(L, LAMBDAS_TABLE, *funcptr, false))
|
||||
if (!get_from_registry(L, LAMBDAS_TABLE, *funcptr, false)) {
|
||||
return nullptr;
|
||||
}
|
||||
int top = gettop(L) - 1;
|
||||
for (const auto& arg : args) {
|
||||
pushvalue(L, arg);
|
||||
|
|
@ -294,8 +297,9 @@ scripting::common_func lua::create_lambda(State* L) {
|
|||
scripting::common_func lua::create_lambda_nothrow(State* L) {
|
||||
auto funcptr = create_lambda_handler(L);
|
||||
return [=](const std::vector<dv::value>& args) -> dv::value {
|
||||
if (!get_from(L, LAMBDAS_TABLE, *funcptr, false))
|
||||
if (!get_from_registry(L, LAMBDAS_TABLE, *funcptr, false)) {
|
||||
return nullptr;
|
||||
}
|
||||
int top = gettop(L) - 1;
|
||||
for (const auto& arg : args) {
|
||||
pushvalue(L, arg);
|
||||
|
|
@ -313,8 +317,16 @@ scripting::common_func lua::create_lambda_nothrow(State* L) {
|
|||
};
|
||||
}
|
||||
|
||||
static void store_env(lua::State* L, int id) {
|
||||
requireregistry(L, ENVS_TABLE);
|
||||
pushvalue(L, -2);
|
||||
lua_remove(L, -3);
|
||||
setfield(L, env_name(id));
|
||||
pop(L);
|
||||
}
|
||||
|
||||
int lua::create_environment(State* L, int parent) {
|
||||
int id = nextEnvironment++;
|
||||
int id = next_environment++;
|
||||
|
||||
// local env = {}
|
||||
createtable(L, 0, 1);
|
||||
|
|
@ -331,24 +343,22 @@ int lua::create_environment(State* L, int parent) {
|
|||
setfield(L, "__index");
|
||||
setmetatable(L);
|
||||
|
||||
// envname = env
|
||||
setglobal(L, env_name(id));
|
||||
store_env(L, id);
|
||||
return id;
|
||||
}
|
||||
|
||||
int lua::restore_pack_environment(lua::State* L, const std::string& packid) {
|
||||
if(!lua::getglobal(L, "__vc__pack_envs")) {
|
||||
if(!requireregistry(L, PACK_ENVS_TABLE)) {
|
||||
return -1;
|
||||
}
|
||||
int id = nextEnvironment++;
|
||||
int id = next_environment++;
|
||||
|
||||
if (lua::getfield(L, packid)) {
|
||||
// envname = env
|
||||
setglobal(L, env_name(id));
|
||||
lua::pop(L);
|
||||
if (getfield(L, packid)) {
|
||||
store_env(L, id);
|
||||
pop(L);
|
||||
return id;
|
||||
}
|
||||
lua::pop(L);
|
||||
pop(L);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -357,5 +367,5 @@ void lua::remove_environment(State* L, int id) {
|
|||
return;
|
||||
}
|
||||
pushnil(L);
|
||||
setglobal(L, env_name(id));
|
||||
store_env(L, id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,21 +14,35 @@
|
|||
namespace lua {
|
||||
inline std::string LAMBDAS_TABLE = "$L"; // lambdas storage
|
||||
inline std::string CHUNKS_TABLE = "$C"; // precompiled lua chunks
|
||||
inline std::string PACK_ENVS_TABLE = "$P";
|
||||
inline std::string ENVS_TABLE = "$E";
|
||||
extern std::unordered_map<std::type_index, std::string> usertypeNames;
|
||||
int userdata_destructor(lua::State* L);
|
||||
|
||||
std::string env_name(int env);
|
||||
void dump_stack(lua::State*);
|
||||
|
||||
inline bool getglobal(lua::State* L, const std::string& name) {
|
||||
lua_getglobal(L, name.c_str());
|
||||
if (isnil(L, -1)) {
|
||||
inline bool isnoneornil(lua::State* L, int idx) {
|
||||
return lua_isnoneornil(L, idx);
|
||||
}
|
||||
|
||||
inline bool getfield(lua::State* L, const std::string& name, int idx = -1) {
|
||||
lua_getfield(L, idx, name.c_str());
|
||||
if (isnoneornil(L, -1)) {
|
||||
pop(L);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool getglobal(lua::State* L, const std::string& name) {
|
||||
return getfield(L, name, LUA_GLOBALSINDEX);
|
||||
}
|
||||
|
||||
inline bool getregistry(lua::State* L, const std::string& name) {
|
||||
return getfield(L, name, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
inline int requireglobal(lua::State* L, const std::string& name) {
|
||||
if (getglobal(L, name)) {
|
||||
return 1;
|
||||
|
|
@ -37,6 +51,24 @@ namespace lua {
|
|||
}
|
||||
}
|
||||
|
||||
inline int requireregistry(lua::State* L, const std::string& name) {
|
||||
if (getregistry(L, name)) {
|
||||
return 1;
|
||||
} else {
|
||||
throw std::runtime_error("registry entry " + name + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
inline bool getregistry(lua::State* L, const std::string& name, const std::string& key) {
|
||||
requireregistry(L, name);
|
||||
if (getfield(L, key)) {
|
||||
lua_remove(L, -2);
|
||||
return true;
|
||||
}
|
||||
pop(L);
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool hasglobal(lua::State* L, const std::string& name) {
|
||||
lua_getglobal(L, name.c_str());
|
||||
if (isnil(L, -1)) {
|
||||
|
|
@ -203,9 +235,6 @@ namespace lua {
|
|||
inline int pushglobals(lua::State* L) {
|
||||
return pushvalue(L, LUA_GLOBALSINDEX);
|
||||
}
|
||||
inline bool isnoneornil(lua::State* L, int idx) {
|
||||
return lua_isnoneornil(L, idx);
|
||||
}
|
||||
inline bool isboolean(lua::State* L, int idx) {
|
||||
return lua_isboolean(L, idx);
|
||||
}
|
||||
|
|
@ -267,6 +296,9 @@ namespace lua {
|
|||
inline void setglobal(lua::State* L, const std::string& name) {
|
||||
lua_setglobal(L, name.c_str());
|
||||
}
|
||||
inline void setregistry(lua::State* L, const std::string& key) {
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, key.c_str());
|
||||
}
|
||||
template <class T>
|
||||
inline T* touserdata(lua::State* L, int idx) {
|
||||
if (void* rawptr = lua_touserdata(L, idx)) {
|
||||
|
|
@ -461,15 +493,6 @@ namespace lua {
|
|||
|
||||
[[nodiscard]] dv::value tovalue(lua::State*, int idx);
|
||||
|
||||
inline bool getfield(lua::State* L, const std::string& name, int idx = -1) {
|
||||
lua_getfield(L, idx, name.c_str());
|
||||
if (isnoneornil(L, -1)) {
|
||||
pop(L);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int requirefield(
|
||||
lua::State* L, const std::string& name, int idx = -1
|
||||
) {
|
||||
|
|
@ -538,7 +561,7 @@ namespace lua {
|
|||
if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) {
|
||||
throw luaerror(tostring(L, -1));
|
||||
}
|
||||
if (env && getglobal(L, env_name(env))) {
|
||||
if (env && getregistry(L, ENVS_TABLE, env_name(env))) {
|
||||
lua_setfenv(L, -2);
|
||||
}
|
||||
}
|
||||
|
|
@ -551,7 +574,46 @@ namespace lua {
|
|||
setfield(L, name);
|
||||
pop(L, 2);
|
||||
} else {
|
||||
throw std::runtime_error("table " + tableName + " not found");
|
||||
throw std::runtime_error("global table " + tableName + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
inline void store_in_registry(
|
||||
lua::State* L, const std::string& tableName, const std::string& name
|
||||
) {
|
||||
if (getregistry(L, tableName)) {
|
||||
pushvalue(L, -2);
|
||||
setfield(L, name);
|
||||
pop(L, 2);
|
||||
} else {
|
||||
throw std::runtime_error("table " + tableName + " not found in registry");
|
||||
}
|
||||
}
|
||||
|
||||
inline int get_from(
|
||||
lua::State* L,
|
||||
const std::string& tableName,
|
||||
const std::string& name,
|
||||
bool required,
|
||||
int idx,
|
||||
std::string_view context
|
||||
) {
|
||||
if (getfield(L, tableName, idx)) {
|
||||
if (getfield(L, name)) {
|
||||
return 1;
|
||||
} else if (required) {
|
||||
pop(L);
|
||||
throw std::runtime_error(
|
||||
std::string(context) + " table " + tableName +
|
||||
" has no member " + name
|
||||
);
|
||||
}
|
||||
pop(L);
|
||||
return 0;
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
std::string(context) + " table " + tableName + " not found"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -561,20 +623,20 @@ namespace lua {
|
|||
const std::string& name,
|
||||
bool required = false
|
||||
) {
|
||||
if (getglobal(L, tableName)) {
|
||||
if (getfield(L, name)) {
|
||||
return 1;
|
||||
} else if (required) {
|
||||
pop(L);
|
||||
throw std::runtime_error(
|
||||
"table " + tableName + " has no member " + name
|
||||
);
|
||||
}
|
||||
pop(L);
|
||||
return 0;
|
||||
} else {
|
||||
throw std::runtime_error("table " + tableName + " not found");
|
||||
}
|
||||
return get_from(
|
||||
L, tableName, name, required, LUA_GLOBALSINDEX, "global"
|
||||
);
|
||||
}
|
||||
|
||||
inline int get_from_registry(
|
||||
lua::State* L,
|
||||
const std::string& tableName,
|
||||
const std::string& name,
|
||||
bool required = false
|
||||
) {
|
||||
return get_from(
|
||||
L, tableName, name, required, LUA_REGISTRYINDEX, "registry"
|
||||
);
|
||||
}
|
||||
|
||||
int call(lua::State*, int argc, int nresults = -1);
|
||||
|
|
@ -607,10 +669,7 @@ namespace lua {
|
|||
scripting::common_func create_lambda_nothrow(lua::State*);
|
||||
|
||||
inline int pushenv(lua::State* L, int env) {
|
||||
if (getglobal(L, env_name(env))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return getregistry(L, ENVS_TABLE, env_name(env));
|
||||
}
|
||||
int create_environment(lua::State*, int parent);
|
||||
int restore_pack_environment(lua::State*, const std::string& packid);
|
||||
|
|
@ -739,14 +798,14 @@ namespace lua {
|
|||
inline void read_bytes_from_table(
|
||||
lua::State* L, int tableIndex, std::vector<ubyte>& bytes
|
||||
) {
|
||||
if (!lua::istable(L, tableIndex)) {
|
||||
if (!istable(L, tableIndex)) {
|
||||
throw std::runtime_error("table expected");
|
||||
} else {
|
||||
size_t size = lua::objlen(L, tableIndex);
|
||||
size_t size = objlen(L, tableIndex);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
lua::rawgeti(L, i + 1, tableIndex);
|
||||
const int byte = lua::tointeger(L, -1);
|
||||
lua::pop(L);
|
||||
rawgeti(L, i + 1, tableIndex);
|
||||
const int byte = tointeger(L, -1);
|
||||
pop(L);
|
||||
if (byte < 0 || byte > 255) {
|
||||
throw std::runtime_error(
|
||||
"invalid byte '" + std::to_string(byte) + "'"
|
||||
|
|
@ -758,11 +817,11 @@ namespace lua {
|
|||
}
|
||||
|
||||
inline int create_bytearray(lua::State* L, const void* bytes, size_t size) {
|
||||
lua::requireglobal(L, "Bytearray_construct");
|
||||
lua::pushlstring(
|
||||
requireglobal(L, "Bytearray_construct");
|
||||
pushlstring(
|
||||
L, std::string_view(reinterpret_cast<const char*>(bytes), size)
|
||||
);
|
||||
return lua::call(L, 1, 1);
|
||||
return call(L, 1, 1);
|
||||
}
|
||||
|
||||
inline int create_bytearray(lua::State* L, const std::vector<ubyte>& bytes) {
|
||||
|
|
@ -770,12 +829,15 @@ namespace lua {
|
|||
}
|
||||
|
||||
inline std::string_view bytearray_as_string(lua::State* L, int idx) {
|
||||
lua::pushvalue(L, idx);
|
||||
lua::requireglobal(L, "Bytearray_as_string");
|
||||
lua::pushvalue(L, -2);
|
||||
lua::call(L, 1, 1);
|
||||
auto view = lua::tolstring(L, -1);
|
||||
lua::pop(L, 2);
|
||||
if (type(L, idx) == LUA_TSTRING) {
|
||||
return tolstring(L, idx);
|
||||
}
|
||||
pushvalue(L, idx);
|
||||
requireglobal(L, "Bytearray_as_string");
|
||||
pushvalue(L, -2);
|
||||
call(L, 1, 1);
|
||||
auto view = tolstring(L, -1);
|
||||
pop(L, 2);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,11 +188,7 @@ std::unique_ptr<Process> scripting::start_app_script(const io::path& script) {
|
|||
lua::pushstring(L, pack.id);
|
||||
lua::setfield(L, "PACK_ID");
|
||||
|
||||
if(!lua::getglobal(L, "__vc__pack_envs")) {
|
||||
lua::createtable(L, 0, 0);
|
||||
lua::setglobal(L, "__vc__pack_envs");
|
||||
lua::pushvalue(L, -1);
|
||||
}
|
||||
lua::requireregistry(L, lua::PACK_ENVS_TABLE);
|
||||
lua::pushenv(L, id);
|
||||
lua::setfield(L, pack.id);
|
||||
lua::pop(L);
|
||||
|
|
@ -248,7 +244,7 @@ std::unique_ptr<Process> scripting::start_app_script(const io::path& script) {
|
|||
|
||||
void scripting::process_post_runnables() {
|
||||
auto L = lua::get_main_state();
|
||||
if (lua::getglobal(L, "__process_post_runnables")) {
|
||||
if (lua::getglobal(L, "__vc__process_post_runnables")) {
|
||||
lua::call_nothrow(L, 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -627,6 +623,26 @@ void scripting::on_ui_close(UiDocument* layout, Inventory* inventory) {
|
|||
});
|
||||
}
|
||||
|
||||
void scripting::on_scripts_loading() {
|
||||
auto L = lua::get_main_state();
|
||||
|
||||
for (auto& pack : content_control->getAllContentPacks()) {
|
||||
lua::emit_event(L, pack.id + ":.onscriptsloading", [](auto L) {
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void scripting::on_content_loaded() {
|
||||
auto L = lua::get_main_state();
|
||||
|
||||
for (auto& pack : content_control->getAllContentPacks()) {
|
||||
lua::emit_event(L, pack.id + ":.oncontentloaded", [](auto L) {
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool scripting::register_event(
|
||||
int env, const std::string& name, const std::string& id
|
||||
) {
|
||||
|
|
@ -722,7 +738,7 @@ void scripting::load_entity_component(
|
|||
std::string src = io::read_string(file);
|
||||
logger.info() << "script (component) " << file.string();
|
||||
lua::loadbuffer(L, *env, src, fileName);
|
||||
lua::store_in(L, lua::CHUNKS_TABLE, name);
|
||||
lua::store_in_registry(L, lua::CHUNKS_TABLE, name);
|
||||
}
|
||||
|
||||
void scripting::load_world_script(
|
||||
|
|
@ -761,6 +777,23 @@ void scripting::load_world_script(
|
|||
register_event(env, "on_inventory_open", prefix + ":.inventoryopen");
|
||||
funcsset.oninventoryclosed =
|
||||
register_event(env, "on_inventory_closed", prefix + ":.inventoryclosed");
|
||||
funcsset.onentityspawn =
|
||||
register_event(env, "on_entity_spawn", prefix + ":.entityspawn");
|
||||
funcsset.onentitydespawn =
|
||||
register_event(env, "on_entity_despawn", prefix + ":.entitydespawn");
|
||||
}
|
||||
|
||||
void scripting::load_content_script(
|
||||
const scriptenv& senv,
|
||||
const std::string& prefix,
|
||||
const io::path& file,
|
||||
const std::string& fileName
|
||||
) {
|
||||
int env = *senv;
|
||||
lua::pop(lua::get_main_state(), load_script(env, "content", file, fileName));
|
||||
|
||||
register_event(env, "on_scripts_loading", prefix + ":.onscriptsloading");
|
||||
register_event(env, "on_content_loaded", prefix + ":.oncontentloaded");
|
||||
}
|
||||
|
||||
void scripting::load_layout_script(
|
||||
|
|
|
|||
|
|
@ -160,6 +160,12 @@ namespace scripting {
|
|||
/// @brief Called on UI view close
|
||||
void on_ui_close(UiDocument* layout, Inventory* inventory);
|
||||
|
||||
/// @brief Called on Content loading
|
||||
void on_scripts_loading();
|
||||
|
||||
/// @brief Called on Content loading finish
|
||||
void on_content_loaded();
|
||||
|
||||
/// @brief Load script associated with a Block
|
||||
/// @param env environment
|
||||
/// @param prefix pack id
|
||||
|
|
@ -221,6 +227,13 @@ namespace scripting {
|
|||
WorldFuncsSet& funcsset
|
||||
);
|
||||
|
||||
void load_content_script(
|
||||
const scriptenv& env,
|
||||
const std::string& packid,
|
||||
const io::path& file,
|
||||
const std::string& fileName
|
||||
);
|
||||
|
||||
/// @brief Load script associated with an UiDocument
|
||||
/// @param env environment
|
||||
/// @param prefix pack id
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
#include "scripting.hpp"
|
||||
|
||||
#include "debug/Logger.hpp"
|
||||
#include "lua/lua_engine.hpp"
|
||||
#include "objects/Entities.hpp"
|
||||
#include "objects/EntityDef.hpp"
|
||||
#include "objects/Entity.hpp"
|
||||
#include "objects/Player.hpp"
|
||||
#include "util/stringutil.hpp"
|
||||
#include "content/Content.hpp"
|
||||
#include "content/ContentPack.hpp"
|
||||
|
||||
using namespace scripting;
|
||||
|
||||
static debug::Logger logger("scripting-entities");
|
||||
static inline const std::string STDCOMP = "stdcomp";
|
||||
|
||||
[[nodiscard]] static scriptenv create_component_environment(
|
||||
|
|
@ -52,6 +56,24 @@ dv::value scripting::get_component_value(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static void init_component_events(
|
||||
lua::State* L, const scriptenv& env, UserComponent& component
|
||||
) {
|
||||
lua::pushenv(L, *env);
|
||||
auto& funcsset = component.funcsset;
|
||||
funcsset.on_grounded = lua::hasfield(L, "on_grounded");
|
||||
funcsset.on_fall = lua::hasfield(L, "on_fall");
|
||||
funcsset.on_despawn = lua::hasfield(L, "on_despawn");
|
||||
funcsset.on_sensor_enter = lua::hasfield(L, "on_sensor_enter");
|
||||
funcsset.on_sensor_exit = lua::hasfield(L, "on_sensor_exit");
|
||||
funcsset.on_save = lua::hasfield(L, "on_save");
|
||||
funcsset.on_aim_on = lua::hasfield(L, "on_aim_on");
|
||||
funcsset.on_aim_off = lua::hasfield(L, "on_aim_off");
|
||||
funcsset.on_attacked = lua::hasfield(L, "on_attacked");
|
||||
funcsset.on_used = lua::hasfield(L, "on_used");
|
||||
lua::pop(L);
|
||||
}
|
||||
|
||||
static void create_component(
|
||||
lua::State* L,
|
||||
int entityIdx,
|
||||
|
|
@ -59,11 +81,20 @@ static void create_component(
|
|||
const dv::value& args,
|
||||
const dv::value& saved
|
||||
) {
|
||||
auto parentEnv = get_root_environment();
|
||||
auto prefix = ContentPack::getPrefix(component.name);
|
||||
const auto& content = *scripting::content;
|
||||
if (auto runtime = content.getPackRuntime(std::string(prefix))) {
|
||||
parentEnv = runtime->getEnvironment();
|
||||
} else {
|
||||
logger.warning() << "pack environment is not available for "
|
||||
<< component.name;
|
||||
}
|
||||
lua::pushvalue(L, entityIdx);
|
||||
auto compenv = create_component_environment(
|
||||
get_root_environment(), -1, component.name
|
||||
std::move(parentEnv), -1, component.name
|
||||
);
|
||||
lua::get_from(L, lua::CHUNKS_TABLE, component.name, true);
|
||||
lua::get_from_registry(L, lua::CHUNKS_TABLE, component.name, true);
|
||||
lua::pushenv(L, *compenv);
|
||||
|
||||
if (args != nullptr) {
|
||||
|
|
@ -95,19 +126,8 @@ static void create_component(
|
|||
lua::setfenv(L);
|
||||
lua::call_nothrow(L, 0, 0);
|
||||
|
||||
lua::pushenv(L, *compenv);
|
||||
auto& funcsset = component.funcsset;
|
||||
funcsset.on_grounded = lua::hasfield(L, "on_grounded");
|
||||
funcsset.on_fall = lua::hasfield(L, "on_fall");
|
||||
funcsset.on_despawn = lua::hasfield(L, "on_despawn");
|
||||
funcsset.on_sensor_enter = lua::hasfield(L, "on_sensor_enter");
|
||||
funcsset.on_sensor_exit = lua::hasfield(L, "on_sensor_exit");
|
||||
funcsset.on_save = lua::hasfield(L, "on_save");
|
||||
funcsset.on_aim_on = lua::hasfield(L, "on_aim_on");
|
||||
funcsset.on_aim_off = lua::hasfield(L, "on_aim_off");
|
||||
funcsset.on_attacked = lua::hasfield(L, "on_attacked");
|
||||
funcsset.on_used = lua::hasfield(L, "on_used");
|
||||
lua::pop(L, 2);
|
||||
init_component_events(L, compenv, component);
|
||||
lua::pop(L);
|
||||
|
||||
component.env = compenv;
|
||||
}
|
||||
|
|
@ -129,6 +149,15 @@ void scripting::on_entity_spawn(
|
|||
for (auto& component : components) {
|
||||
create_component(L, -1, *component, args, saved);
|
||||
}
|
||||
|
||||
for (auto& [packid, pack] : content->getPacks()) {
|
||||
if (pack->worldfuncsset.onentityspawn) {
|
||||
lua::emit_event(L, packid + ":.entityspawn", [&](lua::State* L) {
|
||||
lua::pushinteger(L, eid);
|
||||
return 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void process_entity_callback(
|
||||
|
|
@ -170,9 +199,21 @@ void scripting::on_entity_despawn(const Entity& entity) {
|
|||
process_entity_callback(
|
||||
entity, "on_despawn", &EntityFuncsSet::on_despawn, nullptr
|
||||
);
|
||||
|
||||
auto L = lua::get_main_state();
|
||||
entityid_t uid = entity.getUID();
|
||||
|
||||
for (auto& [packid, pack] : content->getPacks()) {
|
||||
if (pack->worldfuncsset.onentitydespawn) {
|
||||
lua::emit_event(L, packid + ":.entitydespawn", [&](lua::State* L) {
|
||||
lua::pushinteger(L, uid);
|
||||
return 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
lua::get_from(L, "stdcomp", "remove_Entity", true);
|
||||
lua::pushinteger(L, entity.getUID());
|
||||
lua::pushinteger(L, uid);
|
||||
lua::call(L, 1, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue