Add core.compare_block_status function (#11247)

Makes it possible to check the status of the mapblock in a future-extensible way.
This commit is contained in:
SmallJoker 2021-05-30 20:24:12 +02:00 committed by GitHub
parent 89f3991351
commit c9144ae5e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 89 additions and 4 deletions

@ -5863,6 +5863,19 @@ Misc.
* If `transient` is `false` or absent, frees a persistent forceload. * If `transient` is `false` or absent, frees a persistent forceload.
If `true`, frees a transient 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 * `minetest.request_insecure_environment()`: returns an environment containing
insecure functions if the calling mod has been listed as trusted in the insecure functions if the calling mod has been listed as trusted in the
`secure.trusted_mods` setting or security is disabled, otherwise returns `secure.trusted_mods` setting or security is disabled, otherwise returns

@ -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 // Mapgen-related helper functions
// //

@ -174,6 +174,8 @@ public:
EmergeCompletionCallback callback, EmergeCompletionCallback callback,
void *callback_param); void *callback_param);
bool isBlockInQueue(v3s16 pos);
v3s16 getContainingChunk(v3s16 blockpos); v3s16 getContainingChunk(v3s16 blockpos);
Mapgen *getCurrentMapgen(); Mapgen *getCurrentMapgen();

@ -1549,6 +1549,11 @@ MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d)
return block; 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 // N.B. This requires no synchronization, since data will not be modified unless
// the VoxelManipulator being updated belongs to the same thread. // the VoxelManipulator being updated belongs to the same thread.
void ServerMap::updateVManip(v3s16 pos) void ServerMap::updateVManip(v3s16 pos)

@ -365,6 +365,8 @@ public:
*/ */
MapBlock *getBlockOrEmerge(v3s16 p3d); MapBlock *getBlockOrEmerge(v3s16 p3d);
bool isBlockInQueue(v3s16 pos);
/* /*
Database functions Database functions
*/ */

@ -140,7 +140,7 @@ public:
//// Flags //// Flags
//// ////
inline bool isDummy() inline bool isDummy() const
{ {
return !data; return !data;
} }

@ -46,13 +46,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/client.h" #include "client/client.h"
#endif #endif
struct EnumString ModApiEnvMod::es_ClearObjectsMode[] = const EnumString ModApiEnvMod::es_ClearObjectsMode[] =
{ {
{CLEAR_OBJECTS_MODE_FULL, "full"}, {CLEAR_OBJECTS_MODE_FULL, "full"},
{CLEAR_OBJECTS_MODE_QUICK, "quick"}, {CLEAR_OBJECTS_MODE_QUICK, "quick"},
{0, NULL}, {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; 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) // forceload_free_block(blockpos)
// blockpos = {x=num, y=num, z=num} // blockpos = {x=num, y=num, z=num}
int ModApiEnvMod::l_forceload_free_block(lua_State *L) 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(transforming_liquid_add);
API_FCT(forceload_block); API_FCT(forceload_block);
API_FCT(forceload_free_block); API_FCT(forceload_free_block);
API_FCT(compare_block_status);
API_FCT(get_translated_string); API_FCT(get_translated_string);
} }

@ -195,6 +195,9 @@ private:
// stops forceloading a position // stops forceloading a position
static int l_forceload_free_block(lua_State *L); 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 // Get a string translated server side
static int l_get_translated_string(lua_State * L); static int l_get_translated_string(lua_State * L);
@ -207,7 +210,8 @@ public:
static void Initialize(lua_State *L, int top); static void Initialize(lua_State *L, int top);
static void InitializeClient(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 { class LuaABM : public ActiveBlockModifier {

@ -1542,6 +1542,21 @@ void ServerEnvironment::step(float dtime)
m_server->sendDetachedInventories(PEER_ID_INEXISTENT, true); 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) u32 ServerEnvironment::addParticleSpawner(float exptime)
{ {
// Timers with lifetime 0 do not expire // Timers with lifetime 0 do not expire

@ -342,7 +342,16 @@ public:
void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; } void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; }
float getMaxLagEstimate() { return m_max_lag_estimate; } 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 // Sets the static object status all the active objects in the specified block
// This is only really needed for deleting blocks from the map // This is only really needed for deleting blocks from the map