]> git.lizzy.rs Git - minetest.git/blobdiff - src/script/lua_api/l_vmanip.cpp
Async environment for mods to do concurrent tasks (#11131)
[minetest.git] / src / script / lua_api / l_vmanip.cpp
index b99b1d98cfd32e0b129a59118e56eaa07fc72d0c..6187a47db2c2b238605702201e021c5d2d96a6cc 100644 (file)
@@ -17,11 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-
+#include <map>
 #include "lua_api/l_vmanip.h"
 #include "lua_api/l_internal.h"
 #include "common/c_content.h"
 #include "common/c_converter.h"
+#include "common/c_packer.h"
 #include "emerge.h"
 #include "environment.h"
 #include "map.h"
@@ -45,6 +46,8 @@ int LuaVoxelManip::l_read_from_map(lua_State *L)
 
        LuaVoxelManip *o = checkobject(L, 1);
        MMVManip *vm = o->vm;
+       if (vm->isOrphan())
+               return 0;
 
        v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 2));
        v3s16 bp2 = getNodeBlockPos(check_v3s16(L, 3));
@@ -112,23 +115,23 @@ int LuaVoxelManip::l_write_to_map(lua_State *L)
 
        LuaVoxelManip *o = checkobject(L, 1);
        bool update_light = !lua_isboolean(L, 2) || readParam<bool>(L, 2);
+
        GET_ENV_PTR;
        ServerMap *map = &(env->getServerMap());
+
+       std::map<v3s16, MapBlock*> modified_blocks;
        if (o->is_mapgen_vm || !update_light) {
-               o->vm->blitBackAll(&(o->modified_blocks));
+               o->vm->blitBackAll(&modified_blocks);
        } else {
-               voxalgo::blit_back_with_light(map, o->vm,
-                       &(o->modified_blocks));
+               voxalgo::blit_back_with_light(map, o->vm, &modified_blocks);
        }
 
        MapEditEvent event;
        event.type = MEET_OTHER;
-       for (const auto &modified_block : o->modified_blocks)
-               event.modified_blocks.insert(modified_block.first);
-
+       for (const auto &it : modified_blocks)
+               event.modified_blocks.insert(it.first);
        map->dispatchEvent(event);
 
-       o->modified_blocks.clear();
        return 0;
 }
 
@@ -166,7 +169,7 @@ int LuaVoxelManip::l_update_liquids(lua_State *L)
 
        LuaVoxelManip *o = checkobject(L, 1);
 
-       Map *map = &(env->getMap());
+       ServerMap *map = &(env->getServerMap());
        const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
        MMVManip *vm = o->vm;
 
@@ -429,6 +432,34 @@ LuaVoxelManip *LuaVoxelManip::checkobject(lua_State *L, int narg)
        return *(LuaVoxelManip **)ud;  // unbox pointer
 }
 
+void *LuaVoxelManip::packIn(lua_State *L, int idx)
+{
+       LuaVoxelManip *o = checkobject(L, idx);
+
+       if (o->is_mapgen_vm)
+               throw LuaError("nope");
+       return o->vm->clone();
+}
+
+void LuaVoxelManip::packOut(lua_State *L, void *ptr)
+{
+       MMVManip *vm = reinterpret_cast<MMVManip*>(ptr);
+       if (!L) {
+               delete vm;
+               return;
+       }
+
+       // Associate vmanip with map if the Lua env has one
+       Environment *env = getEnv(L);
+       if (env)
+               vm->reparent(&(env->getMap()));
+
+       LuaVoxelManip *o = new LuaVoxelManip(vm, false);
+       *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+       luaL_getmetatable(L, className);
+       lua_setmetatable(L, -2);
+}
+
 void LuaVoxelManip::Register(lua_State *L)
 {
        lua_newtable(L);
@@ -450,11 +481,13 @@ void LuaVoxelManip::Register(lua_State *L)
 
        lua_pop(L, 1);  // drop metatable
 
-       luaL_openlib(L, 0, methods, 0);  // fill methodtable
+       luaL_register(L, nullptr, methods);  // fill methodtable
        lua_pop(L, 1);  // drop methodtable
 
        // Can be created from Lua (VoxelManip())
        lua_register(L, className, create_object);
+
+       script_register_packer(L, className, packIn, packOut);
 }
 
 const char LuaVoxelManip::className[] = "VoxelManip";