mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-06 19:41:51 +00:00
Merge branch 'main' into environments
This commit is contained in:
commit
a557068b90
54 changed files with 780 additions and 539 deletions
|
|
@ -1116,28 +1116,34 @@ static int l_gui_load_document(lua::State* L) {
|
|||
auto args = lua::tovalue(L, 3);
|
||||
auto prefix = filename.entryPoint();
|
||||
|
||||
auto env = scripting::get_root_environment();
|
||||
auto parentEnv = scripting::get_root_environment();
|
||||
if (content) {
|
||||
if (auto runtime = content->getPackRuntime(prefix)) {
|
||||
env = runtime->getEnvironment();
|
||||
parentEnv = runtime->getEnvironment();
|
||||
}
|
||||
}
|
||||
|
||||
auto documentPtr = UiDocument::read(
|
||||
engine->getGUI(), std::move(env), alias, filename, filename.string()
|
||||
);
|
||||
auto document = documentPtr.get();
|
||||
engine->requireAssets().store(std::move(documentPtr), alias);
|
||||
|
||||
auto env = scripting::create_doc_environment(parentEnv, alias);
|
||||
// namespace extension
|
||||
if (lua::istable(L, 4)) {
|
||||
if (lua::get_from(L, "table", "merge")) {
|
||||
lua::pushenv(L, *document->getEnvironment());
|
||||
if (lua::get_from(L, "table", "extend")) {
|
||||
lua::pushenv(L, *env);
|
||||
lua::pushvalue(L, 4);
|
||||
lua::call(L, 2, 0);
|
||||
lua::pop(L);
|
||||
}
|
||||
}
|
||||
auto documentPtr = UiDocument::read(
|
||||
engine->getGUI(),
|
||||
nullptr,
|
||||
alias,
|
||||
filename,
|
||||
filename.string(),
|
||||
std::move(env)
|
||||
);
|
||||
auto document = documentPtr.get();
|
||||
engine->requireAssets().store(std::move(documentPtr), alias);
|
||||
|
||||
scripting::on_ui_open(document, {args});
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,11 +62,20 @@ static int l_utc_offset(lua::State* L) {
|
|||
return lua::pushnumber(L, offset);
|
||||
}
|
||||
|
||||
static auto start_time = std::chrono::steady_clock::now();
|
||||
|
||||
static int l_precise_time(lua::State* L) {
|
||||
auto time = std::chrono::steady_clock::now();
|
||||
std::chrono::duration<double> delta = time - start_time;
|
||||
return lua::pushnumber(L, delta.count());
|
||||
}
|
||||
|
||||
const luaL_Reg timelib[] = {
|
||||
{"uptime", lua::wrap<l_uptime>},
|
||||
{"delta", lua::wrap<l_delta>},
|
||||
{"utc_time", lua::wrap<l_utc_time>},
|
||||
{"utc_offset", lua::wrap<l_utc_offset>},
|
||||
{"local_time", lua::wrap<l_local_time>},
|
||||
{"precise_time", lua::wrap<l_precise_time>},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
#error LuaJIT required
|
||||
#endif
|
||||
|
||||
#ifndef LUA_TCDATA
|
||||
// unsafe, use for filtering only
|
||||
#define LUA_TCDATA 10
|
||||
#endif
|
||||
|
||||
namespace lua {
|
||||
class luaerror : public std::runtime_error {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -15,8 +15,12 @@
|
|||
#include "usertypes/lua_type_pcmstream.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
|
||||
static debug::Logger logger("lua-state");
|
||||
static lua::State* main_thread = nullptr;
|
||||
namespace {
|
||||
debug::Logger logger("lua-state");
|
||||
lua::State* main_thread = nullptr;
|
||||
bool headless_mode = false;
|
||||
const std::unordered_map<std::string, std::string>* project_args;
|
||||
}
|
||||
|
||||
using namespace lua;
|
||||
|
||||
|
|
@ -146,20 +150,53 @@ void lua::init_state(State* L, StateType stateType) {
|
|||
newusertype<LuaHeightmap>(L);
|
||||
newusertype<LuaVoxelFragment>(L);
|
||||
newusertype<LuaCanvas>(L);
|
||||
|
||||
pushboolean(L, headless_mode);
|
||||
setglobal(L, "__VC_HEADLESS");
|
||||
|
||||
createtable(L, 0, project_args->size());
|
||||
for (const auto& [key, value] : *project_args) {
|
||||
pushstring(L, value);
|
||||
setfield(L, key);
|
||||
}
|
||||
setglobal(L, "__VC_PROJECT_ARGS");
|
||||
|
||||
auto file = "res:scripts/stdmin.lua";
|
||||
auto src = io::read_string(file);
|
||||
lua::pop(L, lua::execute(L, 0, src, "core:scripts/stdmin.lua"));
|
||||
|
||||
newusertype<LuaRandom>(L);
|
||||
if (getglobal(L, "random")) {
|
||||
if (getglobal(L, "__vc_Random")) {
|
||||
setfield(L, "Random");
|
||||
}
|
||||
pop(L);
|
||||
}
|
||||
newusertype<LuaPCMStream>(L);
|
||||
if (getglobal(L, "audio")) {
|
||||
if (getglobal(L, "__vc_PCMStream")) {
|
||||
setfield(L, "PCMStream");
|
||||
}
|
||||
pop(L);
|
||||
}
|
||||
|
||||
if (stateType == StateType::GENERATOR) {
|
||||
pushnil(L);
|
||||
setglobal(L, "ffi");
|
||||
}
|
||||
}
|
||||
|
||||
void lua::initialize(const EnginePaths& paths, const CoreParameters& params) {
|
||||
logger.info() << LUA_VERSION;
|
||||
logger.info() << LUAJIT_VERSION;
|
||||
|
||||
headless_mode = params.headless;
|
||||
project_args = ¶ms.projectArgs;
|
||||
main_thread = create_state(
|
||||
paths, params.headless ? StateType::SCRIPT : StateType::BASE
|
||||
);
|
||||
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() {
|
||||
|
|
@ -191,29 +228,5 @@ State* lua::create_state(const EnginePaths& paths, StateType stateType) {
|
|||
throw luaerror("could not initialize Lua state");
|
||||
}
|
||||
init_state(L, stateType);
|
||||
|
||||
auto file = "res:scripts/stdmin.lua";
|
||||
auto src = io::read_string(file);
|
||||
lua::pop(L, lua::execute(L, 0, src, "core:scripts/stdmin.lua"));
|
||||
|
||||
newusertype<LuaRandom>(L);
|
||||
if (getglobal(L, "random")) {
|
||||
if (getglobal(L, "__vc_Random")) {
|
||||
setfield(L, "Random");
|
||||
}
|
||||
pop(L);
|
||||
}
|
||||
newusertype<LuaPCMStream>(L);
|
||||
if (getglobal(L, "audio")) {
|
||||
if (getglobal(L, "__vc_PCMStream")) {
|
||||
setfield(L, "PCMStream");
|
||||
}
|
||||
pop(L);
|
||||
}
|
||||
|
||||
if (stateType == StateType::GENERATOR) {
|
||||
pushnil(L);
|
||||
setglobal(L, "ffi");
|
||||
}
|
||||
return L;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "util/stringutil.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
#include "debug/Logger.hpp"
|
||||
|
||||
using namespace lua;
|
||||
|
||||
|
|
@ -12,6 +14,8 @@ static int next_environment = 1;
|
|||
|
||||
std::unordered_map<std::type_index, std::string> lua::usertypeNames;
|
||||
|
||||
static debug::Logger logger("lua-util");
|
||||
|
||||
int lua::userdata_destructor(lua::State* L) {
|
||||
if (auto obj = touserdata<Userdata>(L, 1)) {
|
||||
obj->~Userdata();
|
||||
|
|
@ -76,6 +80,10 @@ int lua::pushwstring(State* L, const std::wstring& str) {
|
|||
return pushstring(L, util::wstr2str_utf8(str));
|
||||
}
|
||||
|
||||
static std::string to_ptr_string(State* L, int idx) {
|
||||
return std::to_string(reinterpret_cast<ptrdiff_t>(lua_topointer(L, idx)));
|
||||
}
|
||||
|
||||
dv::value lua::tovalue(State* L, int idx) {
|
||||
using dv::value_type;
|
||||
auto type = lua::type(L, idx);
|
||||
|
|
@ -95,11 +103,16 @@ dv::value lua::tovalue(State* L, int idx) {
|
|||
}
|
||||
}
|
||||
case LUA_TFUNCTION:
|
||||
return "<function " +
|
||||
std::to_string(
|
||||
reinterpret_cast<ptrdiff_t>(lua_topointer(L, idx))
|
||||
) +
|
||||
">";
|
||||
return "<function " + to_ptr_string(L, idx) + ">";
|
||||
case LUA_TTHREAD:
|
||||
return "<thread " + to_ptr_string(L, idx) + ">";
|
||||
case LUA_TUSERDATA:
|
||||
if (auto userdata = touserdata<Userdata>(L, idx)) {
|
||||
return "<userdata:" + userdata->getTypeName() + " " + to_ptr_string(L, idx) + ">";
|
||||
}
|
||||
return "<userdata " + to_ptr_string(L, idx) + ">";
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
return "<lightuserdata " + to_ptr_string(L, idx) + ">";
|
||||
case LUA_TSTRING:
|
||||
return std::string(tostring(L, idx));
|
||||
case LUA_TTABLE: {
|
||||
|
|
@ -369,3 +382,55 @@ void lua::remove_environment(State* L, int id) {
|
|||
pushnil(L);
|
||||
store_env(L, id);
|
||||
}
|
||||
|
||||
static inline std::string_view bytearray_as_string_indirect(lua::State* L, int idx) {
|
||||
requireglobal(L, "Bytearray_as_string");
|
||||
pushvalue(L, -2);
|
||||
call(L, 1, 1);
|
||||
auto view = tolstring(L, -1);
|
||||
pop(L, 2);
|
||||
return view;
|
||||
}
|
||||
|
||||
std::string_view lua::bytearray_as_string(lua::State* L, int idx) {
|
||||
const auto& settings = scripting::engine->getSettings();
|
||||
|
||||
int luaType = type(L, idx);
|
||||
if (luaType == LUA_TSTRING) {
|
||||
return tolstring(L, idx);
|
||||
} else if (luaType == LUA_TTABLE) {
|
||||
return bytearray_as_string_indirect(L, idx);
|
||||
}
|
||||
pushvalue(L, idx);
|
||||
|
||||
if (settings.system.directScriptingDataAccess.get()) {
|
||||
requireglobal(L, "Bytearray_as_ptr");
|
||||
pushvalue(L, -2);
|
||||
call(L, 1, 2);
|
||||
auto view = tolstring(L, -2);
|
||||
if (view == "0") {
|
||||
if (luaType == LUA_TCDATA) {
|
||||
logger.error() << "FFI-based Bytearray_as_ptr returned null-pointer";
|
||||
}
|
||||
pop(L, 2);
|
||||
return bytearray_as_string_indirect(L, idx);
|
||||
}
|
||||
uint64_t size = touinteger(L, -1);
|
||||
auto ptr = (const char*)std::stoull(std::string(view), nullptr, 16);
|
||||
pop(L, 3);
|
||||
return std::string_view(ptr, size);
|
||||
} else {
|
||||
return bytearray_as_string_indirect(L, idx);
|
||||
}
|
||||
}
|
||||
|
||||
void lua::loadbuffer(
|
||||
lua::State* L, int env, const std::string& src, const std::string& file
|
||||
) {
|
||||
if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) {
|
||||
throw luaerror(tostring(L, -1));
|
||||
}
|
||||
if (env && getregistry(L, ENVS_TABLE, env_name(env))) {
|
||||
lua_setfenv(L, -2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,16 +555,9 @@ namespace lua {
|
|||
return lua_setfenv(L, idx);
|
||||
}
|
||||
|
||||
inline void loadbuffer(
|
||||
void loadbuffer(
|
||||
lua::State* L, int env, const std::string& src, const std::string& file
|
||||
) {
|
||||
if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) {
|
||||
throw luaerror(tostring(L, -1));
|
||||
}
|
||||
if (env && getregistry(L, ENVS_TABLE, env_name(env))) {
|
||||
lua_setfenv(L, -2);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
inline void store_in(
|
||||
lua::State* L, const std::string& tableName, const std::string& name
|
||||
|
|
@ -828,16 +821,5 @@ namespace lua {
|
|||
return create_bytearray(L, bytes.data(), bytes.size());
|
||||
}
|
||||
|
||||
inline std::string_view bytearray_as_string(lua::State* L, int idx) {
|
||||
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;
|
||||
}
|
||||
std::string_view bytearray_as_string(lua::State* L, int idx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ std::unique_ptr<IClientProjectScript> scripting::load_client_project_script(
|
|||
auto source = io::read_string(script);
|
||||
auto env = create_environment(nullptr);
|
||||
lua::pushenv(L, *env);
|
||||
if (lua::getglobal(L, "__vc_app")) {
|
||||
if (lua::getregistry(L, "app")) {
|
||||
lua::setfield(L, "app");
|
||||
}
|
||||
lua::pop(L);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue