Skip to content

Commit

Permalink
Add core.compare_block_status function (#11247)
Browse files Browse the repository at this point in the history
Makes it possible to check the status of the mapblock in a future-extensible way.
  • Loading branch information
SmallJoker committed May 30, 2021
1 parent 89f3991 commit c9144ae
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 4 deletions.
13 changes: 13 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/emerge.cpp
Expand Up @@ -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
//
Expand Down
2 changes: 2 additions & 0 deletions src/emerge.h
Expand Up @@ -174,6 +174,8 @@ class EmergeManager {
EmergeCompletionCallback callback,
void *callback_param);

bool isBlockInQueue(v3s16 pos);

v3s16 getContainingChunk(v3s16 blockpos);

Mapgen *getCurrentMapgen();
Expand Down
5 changes: 5 additions & 0 deletions src/map.cpp
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/map.h
Expand Up @@ -365,6 +365,8 @@ class ServerMap : public Map
*/
MapBlock *getBlockOrEmerge(v3s16 p3d);

bool isBlockInQueue(v3s16 pos);

/*
Database functions
*/
Expand Down
2 changes: 1 addition & 1 deletion src/mapblock.h
Expand Up @@ -140,7 +140,7 @@ class MapBlock
//// Flags
////

inline bool isDummy()
inline bool isDummy() const
{
return !data;
}
Expand Down
30 changes: 29 additions & 1 deletion src/script/lua_api/l_env.cpp
Expand Up @@ -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},
};

///////////////////////////////////////////////////////////////////////////////


Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}

Expand Down
6 changes: 5 additions & 1 deletion src/script/lua_api/l_env.h
Expand Up @@ -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);

Expand All @@ -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 {
Expand Down
15 changes: 15 additions & 0 deletions src/serverenvironment.cpp
Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion src/serverenvironment.h
Expand Up @@ -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
Expand Down

0 comments on commit c9144ae

Please sign in to comment.