Minor improvements to metadata handling

This commit is contained in:
sfan5 2024-09-25 23:24:30 +02:00
parent 610ddaba7c
commit 700fbc803d
6 changed files with 31 additions and 29 deletions

@ -89,11 +89,11 @@ void ItemStackMetadata::deSerialize(std::istream &is)
while (!fnd.at_end()) { while (!fnd.at_end()) {
std::string name = fnd.next(DESERIALIZE_KV_DELIM_STR); std::string name = fnd.next(DESERIALIZE_KV_DELIM_STR);
std::string var = fnd.next(DESERIALIZE_PAIR_DELIM_STR); std::string var = fnd.next(DESERIALIZE_PAIR_DELIM_STR);
m_stringvars[name] = var; m_stringvars[name] = std::move(var);
} }
} else { } else {
// BACKWARDS COMPATIBILITY // BACKWARDS COMPATIBILITY
m_stringvars[""] = in; m_stringvars[""] = std::move(in);
} }
} }
updateToolCapabilities(); updateToolCapabilities();

@ -62,14 +62,14 @@ void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk) const
void NodeMetadata::deSerialize(std::istream &is, u8 version) void NodeMetadata::deSerialize(std::istream &is, u8 version)
{ {
clear(); clear();
int num_vars = readU32(is); u32 num_vars = readU32(is);
for(int i=0; i<num_vars; i++){ for (u32 i = 0; i < num_vars; i++){
std::string name = deSerializeString16(is); std::string name = deSerializeString16(is);
std::string var = deSerializeString32(is); std::string var = deSerializeString32(is);
m_stringvars[name] = var; m_stringvars[name] = std::move(var);
if (version >= 2) { if (version >= 2) {
if (readU8(is) == 1) if (readU8(is) == 1)
markPrivate(name, true); m_privatevars.insert(name);
} }
} }
@ -89,12 +89,12 @@ bool NodeMetadata::empty() const
} }
void NodeMetadata::markPrivate(const std::string &name, bool set) bool NodeMetadata::markPrivate(const std::string &name, bool set)
{ {
if (set) if (set)
m_privatevars.insert(name); return m_privatevars.insert(name).second;
else else
m_privatevars.erase(name); return m_privatevars.erase(name) > 0;
} }
int NodeMetadata::countNonPrivate() const int NodeMetadata::countNonPrivate() const
@ -144,6 +144,8 @@ void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk,
writeS16(os, p.Z); writeS16(os, p.Z);
} else { } else {
// Serialize positions within a mapblock // Serialize positions within a mapblock
static_assert(MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE <= U16_MAX,
"position too big to serialize");
u16 p16 = (p.Z * MAP_BLOCKSIZE + p.Y) * MAP_BLOCKSIZE + p.X; u16 p16 = (p.Z * MAP_BLOCKSIZE + p.Y) * MAP_BLOCKSIZE + p.X;
writeU16(os, p16); writeU16(os, p16);
} }
@ -246,8 +248,7 @@ void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
void NodeMetadataList::clear() void NodeMetadataList::clear()
{ {
if (m_is_metadata_owner) { if (m_is_metadata_owner) {
NodeMetadataMap::const_iterator it; for (auto it = m_data.begin(); it != m_data.end(); ++it)
for (it = m_data.begin(); it != m_data.end(); ++it)
delete it->second; delete it->second;
} }
m_data.clear(); m_data.clear();

@ -57,7 +57,10 @@ public:
{ {
return m_privatevars.count(name) != 0; return m_privatevars.count(name) != 0;
} }
void markPrivate(const std::string &name, bool set);
/// Marks a key as private.
/// @return metadata modified?
bool markPrivate(const std::string &name, bool set);
private: private:
int countNonPrivate() const; int countNonPrivate() const;

@ -41,7 +41,7 @@ void ItemStackMetaRef::clearMeta()
void ItemStackMetaRef::reportMetadataChange(const std::string *name) void ItemStackMetaRef::reportMetadataChange(const std::string *name)
{ {
// TODO // nothing to do
} }
// Exported functions // Exported functions
@ -89,7 +89,6 @@ ItemStackMetaRef::~ItemStackMetaRef()
void ItemStackMetaRef::create(lua_State *L, LuaItemStack *istack) void ItemStackMetaRef::create(lua_State *L, LuaItemStack *istack)
{ {
ItemStackMetaRef *o = new ItemStackMetaRef(istack); ItemStackMetaRef *o = new ItemStackMetaRef(istack);
//infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
*(void **)(lua_newuserdata(L, sizeof(void *))) = o; *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, className); luaL_getmetatable(L, className);
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
@ -98,9 +97,6 @@ void ItemStackMetaRef::create(lua_State *L, LuaItemStack *istack)
void ItemStackMetaRef::Register(lua_State *L) void ItemStackMetaRef::Register(lua_State *L)
{ {
registerMetadataClass(L, className, methods); registerMetadataClass(L, className, methods);
// Cannot be created from Lua
//lua_register(L, className, create_object);
} }
const char ItemStackMetaRef::className[] = "ItemStackMetaRef"; const char ItemStackMetaRef::className[] = "ItemStackMetaRef";

@ -58,6 +58,8 @@ void NodeMetaRef::reportMetadataChange(const std::string *name)
// Inform other things that the metadata has changed // Inform other things that the metadata has changed
NodeMetadata *meta = dynamic_cast<NodeMetadata*>(getmeta(false)); NodeMetadata *meta = dynamic_cast<NodeMetadata*>(getmeta(false));
bool is_private_change = meta && name && meta->isPrivate(*name);
// If the metadata is now empty, get rid of it // If the metadata is now empty, get rid of it
if (meta && meta->empty()) { if (meta && meta->empty()) {
clearMeta(); clearMeta();
@ -67,7 +69,7 @@ void NodeMetaRef::reportMetadataChange(const std::string *name)
MapEditEvent event; MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED; event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
event.setPositionModified(m_p); event.setPositionModified(m_p);
event.is_private_change = name && meta && meta->isPrivate(*name); event.is_private_change = is_private_change;
m_env->getMap().dispatchEvent(event); m_env->getMap().dispatchEvent(event);
} }
@ -94,21 +96,24 @@ int NodeMetaRef::l_mark_as_private(lua_State *L)
NodeMetaRef *ref = checkObject<NodeMetaRef>(L, 1); NodeMetaRef *ref = checkObject<NodeMetaRef>(L, 1);
NodeMetadata *meta = dynamic_cast<NodeMetadata*>(ref->getmeta(true)); NodeMetadata *meta = dynamic_cast<NodeMetadata*>(ref->getmeta(true));
assert(meta); if (!meta)
return 0;
bool modified = false;
if (lua_istable(L, 2)) { if (lua_istable(L, 2)) {
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, 2) != 0) { while (lua_next(L, 2) != 0) {
// key at index -2 and value at index -1 // key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING); luaL_checktype(L, -1, LUA_TSTRING);
meta->markPrivate(readParam<std::string>(L, -1), true); modified |= meta->markPrivate(readParam<std::string>(L, -1), true);
// removes value, keeps key for next iteration // removes value, keeps key for next iteration
lua_pop(L, 1); lua_pop(L, 1);
} }
} else if (lua_isstring(L, 2)) { } else if (lua_isstring(L, 2)) {
meta->markPrivate(readParam<std::string>(L, 2), true); modified |= meta->markPrivate(readParam<std::string>(L, 2), true);
} }
ref->reportMetadataChange(); if (modified)
ref->reportMetadataChange();
return 0; return 0;
} }
@ -145,12 +150,13 @@ bool NodeMetaRef::handleFromTable(lua_State *L, int table, IMetadata *_meta)
Inventory *inv = meta->getInventory(); Inventory *inv = meta->getInventory();
lua_getfield(L, table, "inventory"); lua_getfield(L, table, "inventory");
if (lua_istable(L, -1)) { if (lua_istable(L, -1)) {
auto *gamedef = getGameDef(L);
int inventorytable = lua_gettop(L); int inventorytable = lua_gettop(L);
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, inventorytable) != 0) { while (lua_next(L, inventorytable) != 0) {
// key at index -2 and value at index -1 // key at index -2 and value at index -1
std::string name = luaL_checkstring(L, -2); const char *name = luaL_checkstring(L, -2);
read_inventory_list(L, -1, inv, name.c_str(), getServer(L)); read_inventory_list(L, -1, inv, name, gamedef);
lua_pop(L, 1); // Remove value, keep key for next iteration lua_pop(L, 1); // Remove value, keep key for next iteration
} }
lua_pop(L, 1); lua_pop(L, 1);
@ -177,7 +183,6 @@ NodeMetaRef::NodeMetaRef(IMetadata *meta):
void NodeMetaRef::create(lua_State *L, v3s16 p, ServerEnvironment *env) void NodeMetaRef::create(lua_State *L, v3s16 p, ServerEnvironment *env)
{ {
NodeMetaRef *o = new NodeMetaRef(p, env); NodeMetaRef *o = new NodeMetaRef(p, env);
//infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
*(void **)(lua_newuserdata(L, sizeof(void *))) = o; *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, className); luaL_getmetatable(L, className);
lua_setmetatable(L, -2); lua_setmetatable(L, -2);

@ -38,7 +38,7 @@ void PlayerMetaRef::clearMeta()
void PlayerMetaRef::reportMetadataChange(const std::string *name) void PlayerMetaRef::reportMetadataChange(const std::string *name)
{ {
// TODO // the server saves these on its own
} }
// Creates an PlayerMetaRef and leaves it on top of stack // Creates an PlayerMetaRef and leaves it on top of stack
@ -54,9 +54,6 @@ void PlayerMetaRef::create(lua_State *L, IMetadata *metadata)
void PlayerMetaRef::Register(lua_State *L) void PlayerMetaRef::Register(lua_State *L)
{ {
registerMetadataClass(L, className, methods); registerMetadataClass(L, className, methods);
// Cannot be created from Lua
// lua_register(L, className, create_object);
} }
const char PlayerMetaRef::className[] = "PlayerMetaRef"; const char PlayerMetaRef::className[] = "PlayerMetaRef";