diff --git a/res/layouts/pages/content.xml b/res/layouts/pages/content.xml
index dfa7b6546..63474effd 100644
--- a/res/layouts/pages/content.xml
+++ b/res/layouts/pages/content.xml
@@ -15,7 +15,7 @@
-
@@ -38,4 +38,4 @@
-
\ No newline at end of file
+
diff --git a/res/layouts/pages/content_menu.xml b/res/layouts/pages/content_menu.xml
index 85dd54d0d..6718a3028 100644
--- a/res/layouts/pages/content_menu.xml
+++ b/res/layouts/pages/content_menu.xml
@@ -9,7 +9,7 @@
-
diff --git a/res/layouts/pages/main.xml b/res/layouts/pages/main.xml
index b1fab2c9e..b05ac7158 100644
--- a/res/layouts/pages/main.xml
+++ b/res/layouts/pages/main.xml
@@ -3,5 +3,5 @@
-
+
diff --git a/res/layouts/pages/new_world.xml.lua b/res/layouts/pages/new_world.xml.lua
index 694ca9565..ad95aad0d 100644
--- a/res/layouts/pages/new_world.xml.lua
+++ b/res/layouts/pages/new_world.xml.lua
@@ -21,7 +21,7 @@ function create_world()
local seed = document.seed_box.text
local generator = settings.generator
session.reset_entry('new_world')
- core.new_world(name, seed, generator)
+ app.new_world(name, seed, generator)
end
function world_name_placeholder()
diff --git a/res/layouts/pages/pause.xml b/res/layouts/pages/pause.xml
index 63d827e10..3e4427cae 100644
--- a/res/layouts/pages/pause.xml
+++ b/res/layouts/pages/pause.xml
@@ -2,7 +2,7 @@
-
diff --git a/res/modules/internal/gui_util.lua b/res/modules/internal/gui_util.lua
index f9b29c193..3309e94a0 100644
--- a/res/modules/internal/gui_util.lua
+++ b/res/modules/internal/gui_util.lua
@@ -34,7 +34,7 @@ function gui_util.load_page(query)
local filename = file.find(string.format("layouts/pages/%s.xml", name))
if filename then
name = file.prefix(filename)..":pages/"..name
- gui.load_document(filename, name, args)
+ gui.load_document(filename, name, args, { app = __vc_app })
return name
end
end
@@ -52,19 +52,21 @@ end
-- class designed for simple UI-nodes access via properties syntax
local Element = {}
+local __gui_getattr = gui.getattr
+local __gui_setattr = gui.setattr
function Element.new(docname, name)
return setmetatable({docname=docname, name=name}, {
__index=function(self, k)
- return gui.getattr(self.docname, self.name, k)
+ return __gui_getattr(self.docname, self.name, k)
end,
__newindex=function(self, k, v)
- gui.setattr(self.docname, self.name, k, v)
+ __gui_setattr(self.docname, self.name, k, v)
end,
__ipairs=function(self)
local i = 0
return function()
i = i + 1
- local elem = gui.getattr(self.docname, self.name, i)
+ local elem = __gui_getattr(self.docname, self.name, i)
if elem == nil then
return
end
@@ -102,8 +104,8 @@ function RadioGroup:set(key)
end
function RadioGroup:__call(elements, onset, default)
local group = setmetatable({
- elements=elements,
- callback=onset,
+ elements=elements,
+ callback=onset,
current=nil
}, {__index=self})
group:set(default)
@@ -161,7 +163,7 @@ function gui.show_input_dialog(text, actual_callback, validator, confirm_text)
callback=callback,
validator=validator or function() return #text > 0 end
})
- input.add_callback("key:escape", callback, gui.root[id])
+ input.add_callback("key:escape", function() gui.root[id]:destruct() end, gui.root[id])
input.add_callback("key:enter", callback, gui.root[id])
gui.root[id.."_input"].focused = true
end
diff --git a/res/scripts/hud.lua b/res/scripts/hud.lua
index 59d8de36a..322f03db5 100644
--- a/res/scripts/hud.lua
+++ b/res/scripts/hud.lua
@@ -29,7 +29,7 @@ local function configure_SSAO()
end
events.on("core:setting.graphics.ssao.set", update_ssao_quality)
- update_ssao_quality(core.get_setting("graphics.ssao"))
+ update_ssao_quality(__vc_app.get_setting("graphics.ssao"))
end
local function update_hand()
diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua
index 1a8954172..4eb6dd17e 100644
--- a/res/scripts/stdlib.lua
+++ b/res/scripts/stdlib.lua
@@ -1,4 +1,4 @@
-local enable_experimental = core.get_setting("debug.enable-experimental")
+local enable_experimental = __vc_app.get_setting("debug.enable-experimental")
------------------------------------------------
------ Extended kit of standard functions ------
@@ -24,41 +24,48 @@ function tb_frame_tostring(frame)
return s
end
-local core_set_setting = core.set_setting
-function core.set_setting(name, value, ...)
- core_set_setting(name, value, ...)
- events.emit("core:setting."..name..".set", value)
-end
+local __vc__app_script_coroutine
local function complete_app_lib(app)
+ local __app_load_content = app.load_content
+ local __app_reset_content = app.reset_content
+ local __app_reconfig_packs = app.reconfig_packs
+ local __app_tick = coroutine.yield
+ local __app_set_setting = app.set_setting
+ local __app_quit = app.quit
+
app.sleep = sleep
app.script = __VC_SCRIPT_NAME
- app.new_world = core.new_world
- app.open_world = core.open_world
- app.save_world = core.save_world
- app.close_world = core.close_world
- app.reopen_world = core.reopen_world
- app.delete_world = core.delete_world
- app.reconfig_packs = core.reconfig_packs
- app.get_setting = core.get_setting
- app.set_setting = core.set_setting
- app.tick = function()
- coroutine.yield()
+
+ app.set_setting = function(name, value, ...)
+ __app_set_setting(name, value, ...)
+ events.emit("core:setting."..name..".set", value)
end
- app.get_version = core.get_version
- app.get_setting_info = core.get_setting_info
- app.load_content = function()
- core.load_content()
- app.tick()
+ app.tick = __app_tick
+
+ local function call_in_app_script_co(func, ...)
+ local running = coroutine.running()
+ if not running or running ~= __vc__app_script_coroutine then
+ error("content must be reload in application script coroutine")
+ end
+ func(...)
+ __app_tick()
end
- app.reset_content = core.reset_content
- app.is_content_loaded = core.is_content_loaded
- app.set_title = core.set_title
-
+
+ app.reconfig_packs = function(...)
+ call_in_app_script_co(__app_reconfig_packs, ...)
+ end
+ app.load_content = function(...)
+ call_in_app_script_co(__app_load_content, ...)
+ end
+ app.reset_content = function(...)
+ call_in_app_script_co(__app_reset_content, ...)
+ end
+
function app.config_packs(packs_list)
-- Check if packs are valid and add dependencies to the configuration
packs_list = pack.assemble(packs_list)
-
+
local installed = pack.get_installed()
local toremove = {}
for _, packid in ipairs(installed) do
@@ -75,15 +82,16 @@ local function complete_app_lib(app)
app.reconfig_packs(toadd, toremove)
end
- function app.quit()
- local tb = debug.get_traceback(1)
- local s = "app.quit() traceback:"
- for i, frame in ipairs(tb) do
- s = s .. "\n\t"..tb_frame_tostring(frame)
+ function app.quit(silent)
+ if not silent then
+ local tb = debug.get_traceback(1)
+ local s = "app.quit() traceback:"
+ for i, frame in ipairs(tb) do
+ s = s .. "\n\t"..tb_frame_tostring(frame)
+ end
+ debug.log(s)
end
- debug.log(s)
- core.quit()
- coroutine.yield()
+ __app_quit()
end
function app.sleep_until(predicate, max_ticks, max_time)
@@ -123,6 +131,66 @@ function pack.unload(prefix)
events.remove_by_prefix(prefix)
end
+local __vc_coroutines = {}
+local __vc_named_coroutines = {}
+local __vc_next_coroutine = 1
+
+function __vc_start_coroutine(chunk)
+ local co = coroutine.create(chunk)
+ local id = __vc_next_coroutine
+ __vc_next_coroutine = __vc_next_coroutine + 1
+ __vc_coroutines[id] = co
+ return id
+end
+
+function __vc_resume_coroutine(id)
+ local co = __vc_coroutines[id]
+ if co then
+ local success, err = coroutine.resume(co)
+ if not success then
+ debug.error(err)
+ error(err)
+ end
+ return coroutine.status(co) ~= "dead"
+ end
+ return false
+end
+
+function __vc_stop_coroutine(id)
+ local co = __vc_coroutines[id]
+ if co then
+ if coroutine.close then
+ coroutine.close(co)
+ end
+ __vc_coroutines[id] = nil
+ end
+end
+
+function start_coroutine(chunk, name)
+ local co = coroutine.create(function()
+ local status, error = xpcall(chunk, function(err)
+ local fullmsg = "error: "..string.match(err, ": (.+)").."\n"..debug.traceback()
+
+ if hud then
+ gui.alert(fullmsg, function()
+ if world.is_open() then
+ __vc_app.close_world()
+ else
+ __vc_app.reset_content()
+ menu:reset()
+ menu.page = "main"
+ end
+ end)
+ end
+ return fullmsg
+ end)
+ if not status then
+ debug.error(error)
+ end
+ end)
+ __vc_named_coroutines[name] = co
+end
+
function __vc_start_app_script(path, name)
debug.log("starting application script "..path)
@@ -134,9 +202,13 @@ function __vc_start_app_script(path, name)
local script_env = setmetatable({app = app or __vc_app}, {__index=_G})
chunk = setfenv(chunk, script_env)
if name then
- return start_coroutine(chunk, name)
+ start_coroutine(chunk, name)
+ __vc__app_script_coroutine = __vc_named_coroutines[name]
+ return
else
- return __vc_start_coroutine(chunk)
+ local id = __vc_start_coroutine(chunk)
+ __vc__app_script_coroutine = __vc_coroutines[id]
+ return id
end
end
@@ -435,66 +507,6 @@ function __vc_on_world_quit()
file.__close_all_descriptors()
end
-local __vc_coroutines = {}
-local __vc_named_coroutines = {}
-local __vc_next_coroutine = 1
-
-function __vc_start_coroutine(chunk)
- local co = coroutine.create(chunk)
- local id = __vc_next_coroutine
- __vc_next_coroutine = __vc_next_coroutine + 1
- __vc_coroutines[id] = co
- return id
-end
-
-function __vc_resume_coroutine(id)
- local co = __vc_coroutines[id]
- if co then
- local success, err = coroutine.resume(co)
- if not success then
- debug.error(err)
- error(err)
- end
- return coroutine.status(co) ~= "dead"
- end
- return false
-end
-
-function __vc_stop_coroutine(id)
- local co = __vc_coroutines[id]
- if co then
- if coroutine.close then
- coroutine.close(co)
- end
- __vc_coroutines[id] = nil
- end
-end
-
-function start_coroutine(chunk, name)
- local co = coroutine.create(function()
- local status, error = xpcall(chunk, function(err)
- local fullmsg = "error: "..string.match(err, ": (.+)").."\n"..debug.traceback()
-
- if hud then
- gui.alert(fullmsg, function()
- if world.is_open() then
- __vc_app.close_world()
- else
- __vc_app.reset_content()
- menu:reset()
- menu.page = "main"
- end
- end)
- end
- return fullmsg
- end)
- if not status then
- debug.error(error)
- end
- end)
- __vc_named_coroutines[name] = co
-end
-
local __post_runnables = {}
local fn_audio_reset_fetch_buffer = audio.__reset_fetch_buffer
diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp
index 5cb0e7ca6..5a63991bb 100644
--- a/src/engine/Engine.cpp
+++ b/src/engine/Engine.cpp
@@ -139,7 +139,8 @@ void Engine::initialize(CoreParameters coreParameters) {
editor = std::make_unique(*this);
cmd = std::make_unique();
- if (project->permissions.has(Permissions::NETWORK)) {
+ if (project->permissions.has(Permissions::NETWORK) ||
+ !params.debugServerString.empty()) {
network = network::Network::create(settings.network);
}
@@ -177,7 +178,7 @@ void Engine::initialize(CoreParameters coreParameters) {
scripting::initialize(this);
if (!isHeadless()) {
- gui->setPageLoader(scripting::create_page_loader());
+ gui->getMenu()->setPageLoader(scripting::create_page_loader());
}
keepAlive(settings.ui.language.observe([this](auto lang) {
langs::setup(lang, paths->resPaths.collectRoots());
diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp
index dc6dd6ac5..e69c20e3b 100644
--- a/src/graphics/ui/GUI.cpp
+++ b/src/graphics/ui/GUI.cpp
@@ -67,15 +67,6 @@ GUI::GUI(Engine& engine)
GUI::~GUI() = default;
-void GUI::setPageLoader(PageLoaderFunc pageLoader) {
- this->pagesLoader = std::move(pageLoader);
- menu->setPageLoader(this->pagesLoader);
-}
-
-PageLoaderFunc GUI::getPagesLoader() {
- return pagesLoader;
-}
-
std::shared_ptr