Ver Fonte

Get rid of node metadata when it becomes empty

fixes #8943
sfan5 há 2 anos atrás
pai
commit
8908a91016

+ 20 - 0
games/devtest/mods/unittests/misc.lua

@@ -48,3 +48,23 @@ local function test_v3s16_metatable(player, pos)
 	assert(vector.check(found_pos))
 end
 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})

+ 8 - 5
src/script/lua_api/l_nodemeta.cpp

@@ -40,7 +40,7 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg)
 Metadata* NodeMetaRef::getmeta(bool auto_create)
 {
 	if (m_is_local)
-		return m_meta;
+		return m_local_meta;
 
 	NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p);
 	if (meta == NULL && auto_create) {
@@ -62,9 +62,12 @@ void NodeMetaRef::clearMeta()
 void NodeMetaRef::reportMetadataChange(const std::string *name)
 {
 	SANITY_CHECK(!m_is_local);
-	// NOTE: This same code is in rollback_interface.cpp
 	// 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;
 	event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
@@ -174,8 +177,8 @@ NodeMetaRef::NodeMetaRef(v3s16 p, ServerEnvironment *env):
 }
 
 NodeMetaRef::NodeMetaRef(Metadata *meta):
-	m_meta(meta),
-	m_is_local(true)
+	m_is_local(true),
+	m_local_meta(meta)
 {
 }
 

+ 4 - 2
src/script/lua_api/l_nodemeta.h

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