diff --git a/res/project.toml b/res/project.toml index b641ad00f..281964857 100644 --- a/res/project.toml +++ b/res/project.toml @@ -3,5 +3,6 @@ name = "default" base_packs = ["base"] permissions = [ "network", - "record-audio" + "record-audio", + "sub-instances", ] diff --git a/src/constants.hpp b/src/constants.hpp index f43314f4a..0396f59a6 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -16,6 +16,8 @@ inline constexpr bool ENGINE_DEBUG_BUILD = true; inline const std::string ENGINE_VERSION_STRING = "0.32"; +inline constexpr uint MAX_SUBPROCESS_DEPTH = 2; + /// @brief world regions format version inline constexpr uint REGION_FORMAT_VERSION = 3; diff --git a/src/devtools/Project.hpp b/src/devtools/Project.hpp index 4906b9373..571a8b2c5 100644 --- a/src/devtools/Project.hpp +++ b/src/devtools/Project.hpp @@ -13,6 +13,7 @@ struct Permissions { static inline std::string NETWORK = "network"; static inline std::string RECORD_AUDIO = "record-audio"; static inline std::string WRITE_TO_USER = "write-to-user"; + static inline std::string SUB_INSTANCES = "sub-instances"; std::set permissions; diff --git a/src/engine/CoreParameters.hpp b/src/engine/CoreParameters.hpp index b9f585f47..b5d8074ce 100644 --- a/src/engine/CoreParameters.hpp +++ b/src/engine/CoreParameters.hpp @@ -14,5 +14,6 @@ struct CoreParameters { std::filesystem::path projectFolder; std::string debugServerString; int tps = 20; + int subProcessDepth = 0; std::unordered_map projectArgs; }; diff --git a/src/logic/scripting/lua/libs/libapp.cpp b/src/logic/scripting/lua/libs/libapp.cpp index 4d932c272..e3d41d8c7 100644 --- a/src/logic/scripting/lua/libs/libapp.cpp +++ b/src/logic/scripting/lua/libs/libapp.cpp @@ -341,6 +341,10 @@ static int l_start_debug_instance(lua::State* L) { if (!engine->getProject().permissions.has(Permissions::DEBUGGING)) { throw std::runtime_error("project has no debugging permission"); } + const auto& params = engine->getCoreParameters(); + if (params.subProcessDepth >= MAX_SUBPROCESS_DEPTH) { + throw std::runtime_error("max subprocess depth exceeded"); + } int port = lua::tointeger(L, 1); if (port == 0) { @@ -361,6 +365,8 @@ static int l_start_debug_instance(lua::State* L) { "--res", paths.getResourcesFolder().u8string(), "--dir", paths.getUserFilesFolder().u8string(), "--dbg-server", "tcp:" + std::to_string(port), + "--sub-depth", std::to_string(engine->getCoreParameters() + .subProcessDepth + 1), }; if (!projectPath.empty()) { args.emplace_back("--project"); @@ -376,15 +382,25 @@ static int l_start_debug_instance(lua::State* L) { } static int l_start_background_instance(lua::State* L) { + if (!engine->getProject().permissions.has(Permissions::SUB_INSTANCES)) { + throw std::runtime_error("project has no sub-instances permission"); + } + const auto& params = engine->getCoreParameters(); + if (params.subProcessDepth >= MAX_SUBPROCESS_DEPTH) { + throw std::runtime_error("max subprocess depth exceeded"); + } + auto scriptPath = lua::require_lstring(L, 1); - io::path outputPath = "user:background.log"; // TODO: + io::path outputPath = lua::isstring(L, 2) ? lua::require_lstring(L, 2) : ""; const auto& paths = engine->getPaths(); std::vector args { - // "--headless", + "--headless", "--res", paths.getResourcesFolder().u8string(), "--dir", paths.getUserFilesFolder().u8string(), "--script", io::resolve(scriptPath).u8string(), + "--sub-depth", std::to_string(engine->getCoreParameters() + .subProcessDepth + 1), }; args.emplace_back("--project"); args.emplace_back(io::resolve(engine->getProject().path).u8string()); diff --git a/src/main.cpp b/src/main.cpp index 2438d5f50..83887422a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,8 @@ int main(int argc, char** argv) { if (!parse_cmdline(argc, argv, coreParameters)) { return EXIT_SUCCESS; } + logger.debug() << "sub-process depth: " + << coreParameters.subProcessDepth; } catch (const std::runtime_error& err) { std::cerr << err.what() << std::endl; return EXIT_FAILURE; diff --git a/src/util/command_line.cpp b/src/util/command_line.cpp index 7f34bcea4..14f49caf4 100644 --- a/src/util/command_line.cpp +++ b/src/util/command_line.cpp @@ -78,12 +78,19 @@ static bool perform_keyword( params.debugServerString = reader.next(); return true; }, "", "open debugging server where is {transport}:{port}"), + ArgC("--sub-depth", [¶ms, &reader]() -> bool { + params.subProcessDepth = reader.nextInt(); + return true; + }, "", "sub-process depth"), ArgC("--help", []() -> bool { std::cout << "VoxelCore v" << ENGINE_VERSION_STRING << "\n\n"; std::cout << "Command-line arguments:\n"; - for (auto& a : argumentsCommandline) { - std::cout << std::setw(24) << std::left << (a.keyword + " " + a.args); - std::cout << "- " << a.help << std::endl; + for (auto& arg : argumentsCommandline) { + if (arg.help.empty()) { + continue; + } + std::cout << std::setw(24) << std::left << (arg.keyword + " " + arg.args); + std::cout << "- " << arg.help << std::endl; } std::cout << std::endl; return false;