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()) {
std::string name = fnd.next(DESERIALIZE_KV_DELIM_STR);
std::string var = fnd.next(DESERIALIZE_PAIR_DELIM_STR);
m_stringvars[name] = var;
m_stringvars[name] = std::move(var);
}
} else {
// BACKWARDS COMPATIBILITY
m_stringvars[""] = in;
m_stringvars[""] = std::move(in);
}
}
updateToolCapabilities();

@ -62,14 +62,14 @@ void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk) const
void NodeMetadata::deSerialize(std::istream &is, u8 version)
{
clear();
int num_vars = readU32(is);
for(int i=0; i<num_vars; i++){
u32 num_vars = readU32(is);
for (u32 i = 0; i < num_vars; i++){
std::string name = deSerializeString16(is);
std::string var = deSerializeString32(is);
m_stringvars[name] = var;
m_stringvars[name] = std::move(var);
if (version >= 2) {
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)
m_privatevars.insert(name);
return m_privatevars.insert(name).second;
else
m_privatevars.erase(name);
return m_privatevars.erase(name) > 0;
}
int NodeMetadata::countNonPrivate() const
@ -144,6 +144,8 @@ void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk,
writeS16(os, p.Z);
} else {
// 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;
writeU16(os, p16);
}
@ -246,8 +248,7 @@ void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
void NodeMetadataList::clear()
{
if (m_is_metadata_owner) {
NodeMetadataMap::const_iterator it;
for (it = m_data.begin(); it != m_data.end(); ++it)
for (auto it = m_data.begin(); it != m_data.end(); ++it)
delete it->second;
}
m_data.clear();

@ -57,7 +57,10 @@ public:
{
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:
int countNonPrivate() const;

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

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

@ -38,7 +38,7 @@ void PlayerMetaRef::clearMeta()
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
@ -54,9 +54,6 @@ void PlayerMetaRef::create(lua_State *L, IMetadata *metadata)
void PlayerMetaRef::Register(lua_State *L)
{
registerMetadataClass(L, className, methods);
// Cannot be created from Lua
// lua_register(L, className, create_object);
}
const char PlayerMetaRef::className[] = "PlayerMetaRef";