Get rid of node metadata when it becomes empty

fixes #8943
This commit is contained in:
sfan5 2022-05-26 15:45:34 +02:00
parent 261a8db9dd
commit 8908a91016
3 changed files with 32 additions and 7 deletions

@ -48,3 +48,23 @@ local function test_v3s16_metatable(player, pos)
assert(vector.check(found_pos)) assert(vector.check(found_pos))
end end
unittests.register("test_v3s16_metatable", test_v3s16_metatable, {map=true}) unittests.register("test_v3s16_metatable", test_v3s16_metatable, {map=true})
local function test_clear_meta(_, pos)
local ref = core.get_meta(pos)
for way = 1, 3 do
ref:set_string("foo", "bar")
assert(ref:contains("foo"))
if way == 1 then
ref:from_table({})
elseif way == 2 then
ref:from_table(nil)
else
ref:set_string("foo", "")
end
assert(#core.find_nodes_with_meta(pos, pos) == 0, "clearing failed " .. way)
end
end
unittests.register("test_clear_meta", test_clear_meta, {map=true})

@ -40,7 +40,7 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg)
Metadata* NodeMetaRef::getmeta(bool auto_create) Metadata* NodeMetaRef::getmeta(bool auto_create)
{ {
if (m_is_local) if (m_is_local)
return m_meta; return m_local_meta;
NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p); NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p);
if (meta == NULL && auto_create) { if (meta == NULL && auto_create) {
@ -62,9 +62,12 @@ void NodeMetaRef::clearMeta()
void NodeMetaRef::reportMetadataChange(const std::string *name) void NodeMetaRef::reportMetadataChange(const std::string *name)
{ {
SANITY_CHECK(!m_is_local); SANITY_CHECK(!m_is_local);
// NOTE: This same code is in rollback_interface.cpp
// Inform other things that the metadata has changed // Inform other things that the metadata has changed
NodeMetadata *meta = dynamic_cast<NodeMetadata*>(m_meta); NodeMetadata *meta = dynamic_cast<NodeMetadata*>(getmeta(false));
// If the metadata is now empty, get rid of it
if (meta && meta->empty())
clearMeta();
MapEditEvent event; MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED; event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
@ -174,8 +177,8 @@ NodeMetaRef::NodeMetaRef(v3s16 p, ServerEnvironment *env):
} }
NodeMetaRef::NodeMetaRef(Metadata *meta): NodeMetaRef::NodeMetaRef(Metadata *meta):
m_meta(meta), m_is_local(true),
m_is_local(true) m_local_meta(meta)
{ {
} }

@ -33,10 +33,12 @@ class NodeMetadata;
class NodeMetaRef : public MetaDataRef { class NodeMetaRef : public MetaDataRef {
private: private:
bool m_is_local = false;
// Set for server metadata
v3s16 m_p; v3s16 m_p;
ServerEnvironment *m_env = nullptr; ServerEnvironment *m_env = nullptr;
Metadata *m_meta = nullptr; // Set for client metadata
bool m_is_local = false; Metadata *m_local_meta = nullptr;
static const char className[]; static const char className[];
static const luaL_Reg methodsServer[]; static const luaL_Reg methodsServer[];