summaryrefslogtreecommitdiff
path: root/src/script/scripting_server.cpp
diff options
context:
space:
mode:
authorsfan5 <sfan5@live.de>2022-05-02 20:55:04 +0200
committersfan5 <sfan5@live.de>2022-05-02 20:56:06 +0200
commite7659883cc6fca343785da2a1af3890ae273abbf (patch)
treeb8d2e3bdbe10ed0e99074207113e24ccca3fb5df /src/script/scripting_server.cpp
parent663c9364289dae45aeb86a87cba826f577d84a9c (diff)
downloadminetest-e7659883cc6fca343785da2a1af3890ae273abbf.tar.gz
minetest-e7659883cc6fca343785da2a1af3890ae273abbf.tar.bz2
minetest-e7659883cc6fca343785da2a1af3890ae273abbf.zip
Async environment for mods to do concurrent tasks (#11131)
Diffstat (limited to 'src/script/scripting_server.cpp')
-rw-r--r--src/script/scripting_server.cpp67
1 files changed, 65 insertions, 2 deletions
diff --git a/src/script/scripting_server.cpp b/src/script/scripting_server.cpp
index 85411ded4..5b99468dc 100644
--- a/src/script/scripting_server.cpp
+++ b/src/script/scripting_server.cpp
@@ -47,11 +47,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_storage.h"
extern "C" {
-#include "lualib.h"
+#include <lualib.h>
}
ServerScripting::ServerScripting(Server* server):
- ScriptApiBase(ScriptingType::Server)
+ ScriptApiBase(ScriptingType::Server),
+ asyncEngine(server)
{
setGameDef(server);
@@ -88,6 +89,47 @@ ServerScripting::ServerScripting(Server* server):
infostream << "SCRIPTAPI: Initialized game modules" << std::endl;
}
+void ServerScripting::initAsync()
+{
+ // Save globals to transfer
+ {
+ lua_State *L = getStack();
+ lua_getglobal(L, "core");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ lua_getfield(L, -1, "get_globals_to_transfer");
+ lua_call(L, 0, 1);
+ luaL_checktype(L, -1, LUA_TSTRING);
+ getServer()->m_async_globals_data.set(readParam<std::string>(L, -1));
+ lua_pushnil(L);
+ lua_setfield(L, -3, "get_globals_to_transfer"); // unset function too
+ lua_pop(L, 2); // pop 'core', return value
+ }
+
+ infostream << "SCRIPTAPI: Initializing async engine" << std::endl;
+ asyncEngine.registerStateInitializer(InitializeAsync);
+ asyncEngine.registerStateInitializer(ModApiUtil::InitializeAsync);
+ asyncEngine.registerStateInitializer(ModApiCraft::InitializeAsync);
+ asyncEngine.registerStateInitializer(ModApiItemMod::InitializeAsync);
+ asyncEngine.registerStateInitializer(ModApiServer::InitializeAsync);
+ // not added: ModApiMapgen is a minefield for thread safety
+ // not added: ModApiHttp async api can't really work together with our jobs
+ // not added: ModApiStorage is probably not thread safe(?)
+
+ asyncEngine.initialize(0);
+}
+
+void ServerScripting::stepAsync()
+{
+ asyncEngine.step(getStack());
+}
+
+u32 ServerScripting::queueAsync(std::string &&serialized_func,
+ PackedValue *param, const std::string &mod_origin)
+{
+ return asyncEngine.queueAsyncJob(std::move(serialized_func),
+ param, mod_origin);
+}
+
void ServerScripting::InitializeModApi(lua_State *L, int top)
{
// Register reference classes (userdata)
@@ -125,3 +167,24 @@ void ServerScripting::InitializeModApi(lua_State *L, int top)
ModApiStorage::Initialize(L, top);
ModApiChannels::Initialize(L, top);
}
+
+void ServerScripting::InitializeAsync(lua_State *L, int top)
+{
+ // classes
+ LuaItemStack::Register(L);
+ LuaPerlinNoise::Register(L);
+ LuaPerlinNoiseMap::Register(L);
+ LuaPseudoRandom::Register(L);
+ LuaPcgRandom::Register(L);
+ LuaSecureRandom::Register(L);
+ LuaVoxelManip::Register(L);
+ LuaSettings::Register(L);
+
+ // globals data
+ lua_getglobal(L, "core");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ std::string s = ModApiBase::getServer(L)->m_async_globals_data.get();
+ lua_pushlstring(L, s.c_str(), s.size());
+ lua_setfield(L, -2, "transferred_globals");
+ lua_pop(L, 1); // pop 'core'
+}