]> git.lizzy.rs Git - minetest.git/commitdiff
Add core.compare_block_status function (#11247)
authorSmallJoker <SmallJoker@users.noreply.github.com>
Sun, 30 May 2021 18:24:12 +0000 (20:24 +0200)
committerGitHub <noreply@github.com>
Sun, 30 May 2021 18:24:12 +0000 (20:24 +0200)
Makes it possible to check the status of the mapblock in a future-extensible way.

doc/lua_api.txt
src/emerge.cpp
src/emerge.h
src/map.cpp
src/map.h
src/mapblock.h
src/script/lua_api/l_env.cpp
src/script/lua_api/l_env.h
src/serverenvironment.cpp
src/serverenvironment.h

index 956919c89708a65e43a2f1626a2e07c224d97b44..0f57f1f2824fe7de4f10b50d59800160e7979805 100644 (file)
@@ -5863,6 +5863,19 @@ Misc.
     * If `transient` is `false` or absent, frees a persistent forceload.
       If `true`, frees a transient forceload.
 
+* `minetest.compare_block_status(pos, condition)`
+    * Checks whether the mapblock at positition `pos` is in the wanted condition.
+    * `condition` may be one of the following values:
+        * `"unknown"`: not in memory
+        * `"emerging"`: in the queue for loading from disk or generating
+        * `"loaded"`: in memory but inactive (no ABMs are executed)
+        * `"active"`: in memory and active
+        * Other values are reserved for future functionality extensions
+    * Return value, the comparison status:
+        * `false`: Mapblock does not fulfil the wanted condition
+        * `true`: Mapblock meets the requirement
+        * `nil`: Unsupported `condition` value
+
 * `minetest.request_insecure_environment()`: returns an environment containing
   insecure functions if the calling mod has been listed as trusted in the
   `secure.trusted_mods` setting or security is disabled, otherwise returns
index 32e7d9f24d0492de3fc96a3df17599a8857329ad..3a2244d7e78b7ec2beb3869a4f619281c4ee03bf 100644 (file)
@@ -358,6 +358,13 @@ bool EmergeManager::enqueueBlockEmergeEx(
 }
 
 
+bool EmergeManager::isBlockInQueue(v3s16 pos)
+{
+       MutexAutoLock queuelock(m_queue_mutex);
+       return m_blocks_enqueued.find(pos) != m_blocks_enqueued.end();
+}
+
+
 //
 // Mapgen-related helper functions
 //
index aac3e7dd3b018887fb7ed29ece07cdcb2bf13b47..b060226f80042228e7ee6477187534c9e47a2a5c 100644 (file)
@@ -174,6 +174,8 @@ class EmergeManager {
                EmergeCompletionCallback callback,
                void *callback_param);
 
+       bool isBlockInQueue(v3s16 pos);
+
        v3s16 getContainingChunk(v3s16 blockpos);
 
        Mapgen *getCurrentMapgen();
index 7c59edbaa3609421b42c09f2c5833efec6f94ac3..641287c3d9a427a72178a40e764ad06d6942952f 100644 (file)
@@ -1549,6 +1549,11 @@ MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d)
        return block;
 }
 
+bool ServerMap::isBlockInQueue(v3s16 pos)
+{
+       return m_emerge && m_emerge->isBlockInQueue(pos);
+}
+
 // N.B.  This requires no synchronization, since data will not be modified unless
 // the VoxelManipulator being updated belongs to the same thread.
 void ServerMap::updateVManip(v3s16 pos)
index e68795c4a14443fa9935c72e7a10b5570aa0c648..8d20c4a44855a6129534cc443dba0394a9beef7c 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -365,6 +365,8 @@ class ServerMap : public Map
        */
        MapBlock *getBlockOrEmerge(v3s16 p3d);
 
+       bool isBlockInQueue(v3s16 pos);
+
        /*
                Database functions
        */
index 7b82301e9812492e204c0c341b712a0c3686dc94..2e3eb0d76ab9e768c84bebd34b2f41674214c1a1 100644 (file)
@@ -140,7 +140,7 @@ class MapBlock
        //// Flags
        ////
 
-       inline bool isDummy()
+       inline bool isDummy() const
        {
                return !data;
        }
index 39c229ee41d75a566021addbf8dcb3555b8614cb..98f8861faef9560e138184c5a0f3f02efefb1881 100644 (file)
@@ -46,13 +46,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "client/client.h"
 #endif
 
-struct EnumString ModApiEnvMod::es_ClearObjectsMode[] =
+const EnumString ModApiEnvMod::es_ClearObjectsMode[] =
 {
        {CLEAR_OBJECTS_MODE_FULL,  "full"},
        {CLEAR_OBJECTS_MODE_QUICK, "quick"},
        {0, NULL},
 };
 
+const EnumString ModApiEnvMod::es_BlockStatusType[] =
+{
+       {ServerEnvironment::BS_UNKNOWN, "unknown"},
+       {ServerEnvironment::BS_EMERGING, "emerging"},
+       {ServerEnvironment::BS_LOADED,  "loaded"},
+       {ServerEnvironment::BS_ACTIVE,  "active"},
+       {0, NULL},
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 
 
@@ -1389,6 +1398,24 @@ int ModApiEnvMod::l_forceload_block(lua_State *L)
        return 0;
 }
 
+// compare_block_status(nodepos)
+int ModApiEnvMod::l_compare_block_status(lua_State *L)
+{
+       GET_ENV_PTR;
+
+       v3s16 nodepos = check_v3s16(L, 1);
+       std::string condition_s = luaL_checkstring(L, 2);
+       auto status = env->getBlockStatus(getNodeBlockPos(nodepos));
+       
+       int condition_i = -1;
+       if (!string_to_enum(es_BlockStatusType, condition_i, condition_s))
+               return 0; // Unsupported
+
+       lua_pushboolean(L, status >= condition_i);
+       return 1;
+}
+
+
 // forceload_free_block(blockpos)
 // blockpos = {x=num, y=num, z=num}
 int ModApiEnvMod::l_forceload_free_block(lua_State *L)
@@ -1462,6 +1489,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
        API_FCT(transforming_liquid_add);
        API_FCT(forceload_block);
        API_FCT(forceload_free_block);
+       API_FCT(compare_block_status);
        API_FCT(get_translated_string);
 }
 
index 42c2d64f86179d51105d2df4afc0ba6eb6e128f2..979b13c40a8b480022ca4bd53dec45eef0321141 100644 (file)
@@ -195,6 +195,9 @@ class ModApiEnvMod : public ModApiBase {
        // stops forceloading a position
        static int l_forceload_free_block(lua_State *L);
 
+       // compare_block_status(nodepos)
+       static int l_compare_block_status(lua_State *L);
+
        // Get a string translated server side
        static int l_get_translated_string(lua_State * L);
 
@@ -207,7 +210,8 @@ class ModApiEnvMod : public ModApiBase {
        static void Initialize(lua_State *L, int top);
        static void InitializeClient(lua_State *L, int top);
 
-       static struct EnumString es_ClearObjectsMode[];
+       static const EnumString es_ClearObjectsMode[];
+       static const EnumString es_BlockStatusType[];
 };
 
 class LuaABM : public ActiveBlockModifier {
index 3d9ba132b3f6e539f04057914de7ff9cbc3a1ab8..413a785e624651cfe6190341e57e26dea39372d9 100644 (file)
@@ -1542,6 +1542,21 @@ void ServerEnvironment::step(float dtime)
        m_server->sendDetachedInventories(PEER_ID_INEXISTENT, true);
 }
 
+ServerEnvironment::BlockStatus ServerEnvironment::getBlockStatus(v3s16 blockpos)
+{
+       if (m_active_blocks.contains(blockpos))
+               return BS_ACTIVE;
+
+       const MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
+       if (block && !block->isDummy())
+               return BS_LOADED;
+
+       if (m_map->isBlockInQueue(blockpos))
+               return BS_EMERGING;
+
+       return BS_UNKNOWN;
+}
+
 u32 ServerEnvironment::addParticleSpawner(float exptime)
 {
        // Timers with lifetime 0 do not expire
index a11c814ed1e9e3a419b7eb22d3f99fad376cfe6c..c5ca463eeccb51adba8339cdd3584facbf98c860 100644 (file)
@@ -342,7 +342,16 @@ class ServerEnvironment : public Environment
        void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; }
        float getMaxLagEstimate() { return m_max_lag_estimate; }
 
-       std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; };
+       std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; }
+
+       // Sorted by how ready a mapblock is
+       enum BlockStatus {
+               BS_UNKNOWN,
+               BS_EMERGING,
+               BS_LOADED,
+               BS_ACTIVE // always highest value
+       };
+       BlockStatus getBlockStatus(v3s16 blockpos);
 
        // Sets the static object status all the active objects in the specified block
        // This is only really needed for deleting blocks from the map