diff --git a/dev/tests/network_http.lua b/dev/tests/network_http.lua new file mode 100644 index 00000000..9bae830d --- /dev/null +++ b/dev/tests/network_http.lua @@ -0,0 +1,8 @@ +local response_received = false + +network.get("https://api.github.com/repos/MihailRis/VoxelEngine-Cpp/releases/latest", function (s) + print(json.parse(s).name) + response_received = true +end) + +app.sleep_until(function () return response_received end, nil, 10) diff --git a/dev/tests/network_tcp.lua b/dev/tests/network_tcp.lua new file mode 100644 index 00000000..eb6b1880 --- /dev/null +++ b/dev/tests/network_tcp.lua @@ -0,0 +1,45 @@ +for i=1,3 do + print(string.format("iteration %s", i + 1)) + local text = "" + local complete = false + + for j=1,100 do + text = text .. math.random(0, 9) + end + + local server = network.tcp_open(7645, function (client) + print("client connected") + start_coroutine(function() + print("client-listener started") + local received_text = "" + while client:is_alive() and #received_text < #text do + local received = client:recv(512) + if received then + received_text = received_text .. utf8.tostring(received) + print(string.format("received %s byte(s) from client", #received)) + end + coroutine.yield() + end + asserts.equals (text, received_text) + complete = true + end, "client-listener") + end) + + network.tcp_connect("localhost", 7645, function (socket) + print("connected to server") + start_coroutine(function() + print("data-sender started") + local ptr = 1 + while ptr <= #text do + local n = math.random(1, 20) + socket:send(string.sub(text, ptr, ptr + n - 1)) + print(string.format("sent %s byte(s) to server", n)) + ptr = ptr + n + end + socket:close() + end, "data-sender") + end) + + app.sleep_until(function () return complete end, nil, 5) + server:close() +end diff --git a/res/layouts/pages/scripts.xml.lua b/res/layouts/pages/scripts.xml.lua index 3529b3d2..dad0d1ff 100644 --- a/res/layouts/pages/scripts.xml.lua +++ b/res/layouts/pages/scripts.xml.lua @@ -13,9 +13,9 @@ end function refresh() document.list:clear() - local available = pack.get_available() - local infos = pack.get_info(available) - for _, name in ipairs(available) do + local allpacks = table.merge(pack.get_available(), pack.get_installed()) + local infos = pack.get_info(allpacks) + for _, name in ipairs(allpacks) do local info = infos[name] local scripts_dir = info.path.."/scripts/app" if not file.exists(scripts_dir) then diff --git a/res/modules/internal/asserts.lua b/res/modules/internal/asserts.lua new file mode 100644 index 00000000..2317bb7c --- /dev/null +++ b/res/modules/internal/asserts.lua @@ -0,0 +1,10 @@ +local this = {} + +function this.equals(expected, fact) + assert(fact == expected, string.format( + "(fact == expected) assertion failed\n Expected: %s\n Fact: %s", + expected, fact + )) +end + +return this diff --git a/res/project_client.lua b/res/project_client.lua index a1952c08..03c43a4b 100644 --- a/res/project_client.lua +++ b/res/project_client.lua @@ -23,4 +23,5 @@ function on_menu_setup() menubg = gui.root.menubg controller.resize_menu_bg() menu.page = "main" + menu.visible = true end diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 2a0c0173..b07d9387 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -79,13 +79,20 @@ local function complete_app_lib(app) coroutine.yield() end - function app.sleep_until(predicate, max_ticks) + function app.sleep_until(predicate, max_ticks, max_time) max_ticks = max_ticks or 1e9 + max_time = max_time or 1e9 local ticks = 0 - while ticks < max_ticks and not predicate() do + local start_time = os.clock() + while ticks < max_ticks and + os.clock() - start_time < max_time + and not predicate() do app.tick() ticks = ticks + 1 end + if os.clock() - start_time >= max_time then + error("timeout") + end if ticks == max_ticks then error("max ticks exceed") end @@ -174,6 +181,7 @@ if enable_experimental then require "core:internal/maths_inline" end +asserts = require "core:internal/asserts" events = require "core:internal/events" function pack.unload(prefix) @@ -531,15 +539,18 @@ 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() - 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) + + 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 diff --git a/src/network/Network.cpp b/src/network/Network.cpp index d60dcb67..b175a809 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -96,7 +96,7 @@ public: onResponse, onReject, maxSize, - false, + true, "", std::move(headers)}; processRequest(std::move(request)); @@ -590,10 +590,12 @@ public: } int opt = 1; int flags = SO_REUSEADDR; -# ifndef _WIN32 +# if !defined(_WIN32) && !defined(__APPLE__) flags |= SO_REUSEPORT; # endif if (setsockopt(descriptor, SOL_SOCKET, flags, (const char*)&opt, sizeof(opt))) { + logger.error() << "setsockopt(SO_REUSEADDR) failed with errno: " + << errno << "(" << std::strerror(errno) << ")"; closesocket(descriptor); throw std::runtime_error("setsockopt"); }