From 47c97ccd46d262185585b2db15f61161d113e598 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Jul 2025 18:08:10 +0300 Subject: [PATCH] fix 'resume dead coroutine' for client --- res/scripts/classes.lua | 51 ++++++++++++------- res/scripts/stdlib.lua | 2 +- src/logic/scripting/lua/libs/libnetwork.cpp | 54 +++++++++++---------- 3 files changed, 63 insertions(+), 44 deletions(-) diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index 9ab70132..41406892 100644 --- a/res/scripts/classes.lua +++ b/res/scripts/classes.lua @@ -46,14 +46,6 @@ local Socket = {__index={ get_address=function(self) return network.__get_address(self.id) end, }} -network.tcp_connect = function(address, port, callback) - local socket = setmetatable({id=0}, Socket) - socket.id = network.__connect(address, port, function(id) - callback(socket) - end) - return socket -end - local ServerSocket = {__index={ close=function(self) return network.__closeserver(self.id) end, is_open=function(self) return network.__is_serveropen(self.id) end, @@ -62,34 +54,57 @@ local ServerSocket = {__index={ local _tcp_server_callbacks = {} +local _tcp_client_callbacks = {} network.tcp_open = function (port, handler) local socket = setmetatable({id=network.__open(port)}, ServerSocket) - _tcp_server_callbacks[socket.id] = function(id) + _tcp_server_callbacks[socket.id] = function(id) handler(setmetatable({id=id}, Socket)) end return socket end -network.__pull_events = function() - local cleaned = false - local connections = network.__pull_connections() - for i, pair in ipairs(connections) do - local sid, cid = unpack(pair) - local callback = _tcp_server_callbacks[sid] +network.tcp_connect = function(address, port, callback) + local socket = setmetatable({id=0}, Socket) + socket.id = network.__connect(address, port) + _tcp_client_callbacks[socket.id] = function() callback(socket) end + return socket +end - if callback then - callback(cid) +network.__process_events = function() + local CLIENT_CONNECTED = 1 + local CONNECTED_TO_SERVER = 2 + + local cleaned = false + local events = network.__pull_events() + for i, event in ipairs(events) do + local etype, sid, cid = unpack(event) + + if etype == CLIENT_CONNECTED then + local callback = _tcp_server_callbacks[sid] + if callback then + callback(cid) + end + elseif etype == CONNECTED_TO_SERVER then + local callback = _tcp_client_callbacks[cid] + if callback then + callback() + end end -- remove dead servers if not cleaned then - for sid, callback in pairs(_tcp_server_callbacks) do + for sid, _ in pairs(_tcp_server_callbacks) do if not network.__is_serveropen(sid) then _tcp_server_callbacks[sid] = nil end end + for cid, _ in pairs(_tcp_client_callbacks) do + if not network.__is_alive(cid) then + _tcp_client_callbacks[cid] = nil + end + end cleaned = true end end diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 6eb2bbca..3729d516 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -36,7 +36,7 @@ local function complete_app_lib(app) app.set_setting = core.set_setting app.tick = function() coroutine.yield() - network.__pull_events() + network.__process_events() end app.get_version = core.get_version app.get_setting_info = core.get_setting_info diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index 66a82681..ed6799bd 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -89,20 +89,6 @@ static int l_post(lua::State* L, network::Network& network) { return 0; } -static int l_connect(lua::State* L, network::Network& network) { - std::string address = lua::require_string(L, 1); - int port = lua::tointeger(L, 2); - lua::pushvalue(L, 3); - auto callback = lua::create_lambda_nothrow(L); - u64id_t id = network.connect(address, port, [callback](u64id_t id) { - engine->postRunnable([=]() { - callback({id}); - }); - }); - return lua::pushinteger(L, id); -} - - static int l_close(lua::State* L, network::Network& network) { u64id_t id = lua::tointeger(L, 1); if (auto connection = network.getConnection(id)) { @@ -182,17 +168,32 @@ static int l_available(lua::State* L, network::Network& network) { return 0; } -struct ConnectionEvent { +enum NetworkEventType { + CLIENT_CONNECTED = 1, + CONNECTED_TO_SERVER +}; + +struct NetworkEvent { + NetworkEventType type; u64id_t server; u64id_t client; }; -static std::vector clients_queue {}; +static std::vector events_queue {}; + +static int l_connect(lua::State* L, network::Network& network) { + std::string address = lua::require_string(L, 1); + int port = lua::tointeger(L, 2); + u64id_t id = network.connect(address, port, [](u64id_t cid) { + events_queue.push_back({CONNECTED_TO_SERVER, 0, cid}); + }); + return lua::pushinteger(L, id); +} static int l_open(lua::State* L, network::Network& network) { int port = lua::tointeger(L, 1); u64id_t id = network.openServer(port, [](u64id_t sid, u64id_t id) { - clients_queue.push_back({sid, id}); + events_queue.push_back({CLIENT_CONNECTED, sid, id}); }); return lua::pushinteger(L, id); } @@ -253,20 +254,23 @@ static int l_get_total_download(lua::State* L, network::Network& network) { return lua::pushinteger(L, network.getTotalDownload()); } -static int l_pull_connections(lua::State* L, network::Network& network) { - lua::createtable(L, clients_queue.size(), 0); - for (size_t i = 0; i < clients_queue.size(); i++) { - lua::createtable(L, 2, 0); +static int l_pull_events(lua::State* L, network::Network& network) { + lua::createtable(L, events_queue.size(), 0); + for (size_t i = 0; i < events_queue.size(); i++) { + lua::createtable(L, 3, 0); - lua::pushinteger(L, clients_queue[i].server); + lua::pushinteger(L, events_queue[i].type); lua::rawseti(L, 1); - lua::pushinteger(L, clients_queue[i].client); + lua::pushinteger(L, events_queue[i].server); lua::rawseti(L, 2); + + lua::pushinteger(L, events_queue[i].client); + lua::rawseti(L, 3); lua::rawseti(L, i + 1); } - clients_queue.clear(); + events_queue.clear(); return 1; } @@ -293,7 +297,7 @@ const luaL_Reg networklib[] = { {"post", wrap}, {"get_total_upload", wrap}, {"get_total_download", wrap}, - {"__pull_connections", wrap}, + {"__pull_events", wrap}, {"__open", wrap}, {"__closeserver", wrap}, {"__connect", wrap},