mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Avoid duplication of mod metadata in memory (#12562)
Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
parent
03428d9825
commit
f4a01f3a5d
37 changed files with 527 additions and 272 deletions
|
@ -36,7 +36,7 @@ ItemStackMetaRef* ItemStackMetaRef::checkobject(lua_State *L, int narg)
|
|||
return *(ItemStackMetaRef**)ud; // unbox pointer
|
||||
}
|
||||
|
||||
Metadata* ItemStackMetaRef::getmeta(bool auto_create)
|
||||
IMetadata* ItemStackMetaRef::getmeta(bool auto_create)
|
||||
{
|
||||
return &istack->getItem().metadata;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ private:
|
|||
|
||||
static ItemStackMetaRef *checkobject(lua_State *L, int narg);
|
||||
|
||||
virtual Metadata* getmeta(bool auto_create);
|
||||
virtual IMetadata* getmeta(bool auto_create);
|
||||
|
||||
virtual void clearMeta();
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ int MetaDataRef::l_contains(lua_State *L)
|
|||
MetaDataRef *ref = checkobject(L, 1);
|
||||
std::string name = luaL_checkstring(L, 2);
|
||||
|
||||
Metadata *meta = ref->getmeta(false);
|
||||
IMetadata *meta = ref->getmeta(false);
|
||||
if (meta == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -75,7 +75,7 @@ int MetaDataRef::l_get(lua_State *L)
|
|||
MetaDataRef *ref = checkobject(L, 1);
|
||||
std::string name = luaL_checkstring(L, 2);
|
||||
|
||||
Metadata *meta = ref->getmeta(false);
|
||||
IMetadata *meta = ref->getmeta(false);
|
||||
if (meta == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -96,13 +96,14 @@ int MetaDataRef::l_get_string(lua_State *L)
|
|||
MetaDataRef *ref = checkobject(L, 1);
|
||||
std::string name = luaL_checkstring(L, 2);
|
||||
|
||||
Metadata *meta = ref->getmeta(false);
|
||||
IMetadata *meta = ref->getmeta(false);
|
||||
if (meta == NULL) {
|
||||
lua_pushlstring(L, "", 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const std::string &str = meta->getString(name);
|
||||
std::string str_;
|
||||
const std::string &str = meta->getString(name, &str_);
|
||||
lua_pushlstring(L, str.c_str(), str.size());
|
||||
return 1;
|
||||
}
|
||||
|
@ -118,12 +119,9 @@ int MetaDataRef::l_set_string(lua_State *L)
|
|||
const char *s = lua_tolstring(L, 3, &len);
|
||||
std::string str(s, len);
|
||||
|
||||
Metadata *meta = ref->getmeta(!str.empty());
|
||||
if (meta == NULL || str == meta->getString(name))
|
||||
return 0;
|
||||
|
||||
meta->setString(name, str);
|
||||
ref->reportMetadataChange(&name);
|
||||
IMetadata *meta = ref->getmeta(!str.empty());
|
||||
if (meta != NULL && meta->setString(name, str))
|
||||
ref->reportMetadataChange(&name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -135,13 +133,14 @@ int MetaDataRef::l_get_int(lua_State *L)
|
|||
MetaDataRef *ref = checkobject(L, 1);
|
||||
std::string name = luaL_checkstring(L, 2);
|
||||
|
||||
Metadata *meta = ref->getmeta(false);
|
||||
IMetadata *meta = ref->getmeta(false);
|
||||
if (meta == NULL) {
|
||||
lua_pushnumber(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const std::string &str = meta->getString(name);
|
||||
std::string str_;
|
||||
const std::string &str = meta->getString(name, &str_);
|
||||
lua_pushnumber(L, stoi(str));
|
||||
return 1;
|
||||
}
|
||||
|
@ -156,12 +155,9 @@ int MetaDataRef::l_set_int(lua_State *L)
|
|||
int a = luaL_checkint(L, 3);
|
||||
std::string str = itos(a);
|
||||
|
||||
Metadata *meta = ref->getmeta(true);
|
||||
if (meta == NULL || str == meta->getString(name))
|
||||
return 0;
|
||||
|
||||
meta->setString(name, str);
|
||||
ref->reportMetadataChange(&name);
|
||||
IMetadata *meta = ref->getmeta(true);
|
||||
if (meta != NULL && meta->setString(name, str))
|
||||
ref->reportMetadataChange(&name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -173,13 +169,14 @@ int MetaDataRef::l_get_float(lua_State *L)
|
|||
MetaDataRef *ref = checkobject(L, 1);
|
||||
std::string name = luaL_checkstring(L, 2);
|
||||
|
||||
Metadata *meta = ref->getmeta(false);
|
||||
IMetadata *meta = ref->getmeta(false);
|
||||
if (meta == NULL) {
|
||||
lua_pushnumber(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const std::string &str = meta->getString(name);
|
||||
std::string str_;
|
||||
const std::string &str = meta->getString(name, &str_);
|
||||
lua_pushnumber(L, stof(str));
|
||||
return 1;
|
||||
}
|
||||
|
@ -194,12 +191,9 @@ int MetaDataRef::l_set_float(lua_State *L)
|
|||
float a = readParam<float>(L, 3);
|
||||
std::string str = ftos(a);
|
||||
|
||||
Metadata *meta = ref->getmeta(true);
|
||||
if (meta == NULL || str == meta->getString(name))
|
||||
return 0;
|
||||
|
||||
meta->setString(name, str);
|
||||
ref->reportMetadataChange(&name);
|
||||
IMetadata *meta = ref->getmeta(true);
|
||||
if (meta != NULL && meta->setString(name, str))
|
||||
ref->reportMetadataChange(&name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -210,7 +204,7 @@ int MetaDataRef::l_to_table(lua_State *L)
|
|||
|
||||
MetaDataRef *ref = checkobject(L, 1);
|
||||
|
||||
Metadata *meta = ref->getmeta(true);
|
||||
IMetadata *meta = ref->getmeta(true);
|
||||
if (meta == NULL) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
|
@ -239,7 +233,7 @@ int MetaDataRef::l_from_table(lua_State *L)
|
|||
}
|
||||
|
||||
// Create new metadata
|
||||
Metadata *meta = ref->getmeta(true);
|
||||
IMetadata *meta = ref->getmeta(true);
|
||||
if (meta == NULL) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
|
@ -251,11 +245,12 @@ int MetaDataRef::l_from_table(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void MetaDataRef::handleToTable(lua_State *L, Metadata *meta)
|
||||
void MetaDataRef::handleToTable(lua_State *L, IMetadata *meta)
|
||||
{
|
||||
lua_newtable(L);
|
||||
{
|
||||
const StringMap &fields = meta->getStrings();
|
||||
StringMap fields_;
|
||||
const StringMap &fields = meta->getStrings(&fields_);
|
||||
for (const auto &field : fields) {
|
||||
const std::string &name = field.first;
|
||||
const std::string &value = field.second;
|
||||
|
@ -267,7 +262,7 @@ void MetaDataRef::handleToTable(lua_State *L, Metadata *meta)
|
|||
lua_setfield(L, -2, "fields");
|
||||
}
|
||||
|
||||
bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta)
|
||||
bool MetaDataRef::handleFromTable(lua_State *L, int table, IMetadata *meta)
|
||||
{
|
||||
// Set fields
|
||||
lua_getfield(L, table, "fields");
|
||||
|
@ -292,9 +287,9 @@ bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta)
|
|||
int MetaDataRef::l_equals(lua_State *L)
|
||||
{
|
||||
MetaDataRef *ref1 = checkobject(L, 1);
|
||||
Metadata *data1 = ref1->getmeta(false);
|
||||
IMetadata *data1 = ref1->getmeta(false);
|
||||
MetaDataRef *ref2 = checkobject(L, 2);
|
||||
Metadata *data2 = ref2->getmeta(false);
|
||||
IMetadata *data2 = ref2->getmeta(false);
|
||||
if (data1 == NULL || data2 == NULL)
|
||||
lua_pushboolean(L, data1 == data2);
|
||||
else
|
||||
|
|
|
@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "irrlichttypes_bloated.h"
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
class Metadata;
|
||||
class IMetadata;
|
||||
|
||||
/*
|
||||
NodeMetaRef
|
||||
|
@ -38,11 +38,11 @@ protected:
|
|||
static MetaDataRef *checkobject(lua_State *L, int narg);
|
||||
|
||||
virtual void reportMetadataChange(const std::string *name = nullptr) {}
|
||||
virtual Metadata *getmeta(bool auto_create) = 0;
|
||||
virtual IMetadata *getmeta(bool auto_create) = 0;
|
||||
virtual void clearMeta() = 0;
|
||||
|
||||
virtual void handleToTable(lua_State *L, Metadata *meta);
|
||||
virtual bool handleFromTable(lua_State *L, int table, Metadata *meta);
|
||||
virtual void handleToTable(lua_State *L, IMetadata *meta);
|
||||
virtual bool handleFromTable(lua_State *L, int table, IMetadata *meta);
|
||||
|
||||
// Exported functions
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg)
|
|||
return *(NodeMetaRef**)ud; // unbox pointer
|
||||
}
|
||||
|
||||
Metadata* NodeMetaRef::getmeta(bool auto_create)
|
||||
IMetadata* NodeMetaRef::getmeta(bool auto_create)
|
||||
{
|
||||
if (m_is_local)
|
||||
return m_local_meta;
|
||||
|
@ -127,12 +127,13 @@ int NodeMetaRef::l_mark_as_private(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta)
|
||||
void NodeMetaRef::handleToTable(lua_State *L, IMetadata *_meta)
|
||||
{
|
||||
// fields
|
||||
MetaDataRef::handleToTable(L, _meta);
|
||||
|
||||
NodeMetadata *meta = (NodeMetadata *) _meta;
|
||||
NodeMetadata *meta = dynamic_cast<NodeMetadata*>(_meta);
|
||||
assert(meta);
|
||||
|
||||
// inventory
|
||||
Inventory *inv = meta->getInventory();
|
||||
|
@ -145,13 +146,14 @@ void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta)
|
|||
}
|
||||
|
||||
// from_table(self, table)
|
||||
bool NodeMetaRef::handleFromTable(lua_State *L, int table, Metadata *_meta)
|
||||
bool NodeMetaRef::handleFromTable(lua_State *L, int table, IMetadata *_meta)
|
||||
{
|
||||
// fields
|
||||
if (!MetaDataRef::handleFromTable(L, table, _meta))
|
||||
return false;
|
||||
|
||||
NodeMetadata *meta = (NodeMetadata*) _meta;
|
||||
NodeMetadata *meta = dynamic_cast<NodeMetadata*>(_meta);
|
||||
assert(meta);
|
||||
|
||||
// inventory
|
||||
Inventory *inv = meta->getInventory();
|
||||
|
@ -178,7 +180,7 @@ NodeMetaRef::NodeMetaRef(v3s16 p, ServerEnvironment *env):
|
|||
{
|
||||
}
|
||||
|
||||
NodeMetaRef::NodeMetaRef(Metadata *meta):
|
||||
NodeMetaRef::NodeMetaRef(IMetadata *meta):
|
||||
m_is_local(true),
|
||||
m_local_meta(meta)
|
||||
{
|
||||
|
@ -196,7 +198,7 @@ void NodeMetaRef::create(lua_State *L, v3s16 p, ServerEnvironment *env)
|
|||
}
|
||||
|
||||
// Client-sided version of the above
|
||||
void NodeMetaRef::createClient(lua_State *L, Metadata *meta)
|
||||
void NodeMetaRef::createClient(lua_State *L, IMetadata *meta)
|
||||
{
|
||||
NodeMetaRef *o = new NodeMetaRef(meta);
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
|
|
|
@ -38,7 +38,7 @@ private:
|
|||
v3s16 m_p;
|
||||
ServerEnvironment *m_env = nullptr;
|
||||
// Set for client metadata
|
||||
Metadata *m_local_meta = nullptr;
|
||||
IMetadata *m_local_meta = nullptr;
|
||||
|
||||
static const char className[];
|
||||
static const luaL_Reg methodsServer[];
|
||||
|
@ -59,13 +59,13 @@ private:
|
|||
* @param auto_create when true, try to create metadata information for the node if it has none.
|
||||
* @return pointer to a @c NodeMetadata object or @c NULL in case of error.
|
||||
*/
|
||||
virtual Metadata* getmeta(bool auto_create);
|
||||
virtual IMetadata* getmeta(bool auto_create);
|
||||
virtual void clearMeta();
|
||||
|
||||
virtual void reportMetadataChange(const std::string *name = nullptr);
|
||||
|
||||
virtual void handleToTable(lua_State *L, Metadata *_meta);
|
||||
virtual bool handleFromTable(lua_State *L, int table, Metadata *_meta);
|
||||
virtual void handleToTable(lua_State *L, IMetadata *_meta);
|
||||
virtual bool handleFromTable(lua_State *L, int table, IMetadata *_meta);
|
||||
|
||||
// Exported functions
|
||||
|
||||
|
@ -80,7 +80,7 @@ private:
|
|||
|
||||
public:
|
||||
NodeMetaRef(v3s16 p, ServerEnvironment *env);
|
||||
NodeMetaRef(Metadata *meta);
|
||||
NodeMetaRef(IMetadata *meta);
|
||||
|
||||
~NodeMetaRef() = default;
|
||||
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
static void create(lua_State *L, v3s16 p, ServerEnvironment *env);
|
||||
|
||||
// Client-sided version of the above
|
||||
static void createClient(lua_State *L, Metadata *meta);
|
||||
static void createClient(lua_State *L, IMetadata *meta);
|
||||
|
||||
static void RegisterCommon(lua_State *L);
|
||||
static void Register(lua_State *L);
|
||||
|
|
|
@ -35,7 +35,7 @@ PlayerMetaRef *PlayerMetaRef::checkobject(lua_State *L, int narg)
|
|||
return *(PlayerMetaRef **)ud; // unbox pointer
|
||||
}
|
||||
|
||||
Metadata *PlayerMetaRef::getmeta(bool auto_create)
|
||||
IMetadata *PlayerMetaRef::getmeta(bool auto_create)
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ int PlayerMetaRef::gc_object(lua_State *L)
|
|||
|
||||
// Creates an PlayerMetaRef and leaves it on top of stack
|
||||
// Not callable from Lua; all references are created on the C side.
|
||||
void PlayerMetaRef::create(lua_State *L, Metadata *metadata)
|
||||
void PlayerMetaRef::create(lua_State *L, IMetadata *metadata)
|
||||
{
|
||||
PlayerMetaRef *o = new PlayerMetaRef(metadata);
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
|
|
|
@ -29,14 +29,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
class PlayerMetaRef : public MetaDataRef
|
||||
{
|
||||
private:
|
||||
Metadata *metadata = nullptr;
|
||||
IMetadata *metadata = nullptr;
|
||||
|
||||
static const char className[];
|
||||
static const luaL_Reg methods[];
|
||||
|
||||
static PlayerMetaRef *checkobject(lua_State *L, int narg);
|
||||
|
||||
virtual Metadata *getmeta(bool auto_create);
|
||||
virtual IMetadata *getmeta(bool auto_create);
|
||||
|
||||
virtual void clearMeta();
|
||||
|
||||
|
@ -46,12 +46,12 @@ private:
|
|||
static int gc_object(lua_State *L);
|
||||
|
||||
public:
|
||||
PlayerMetaRef(Metadata *metadata) : metadata(metadata) {}
|
||||
PlayerMetaRef(IMetadata *metadata) : metadata(metadata) {}
|
||||
~PlayerMetaRef() = default;
|
||||
|
||||
// Creates an ItemStackMetaRef and leaves it on top of stack
|
||||
// Not callable from Lua; all references are created on the C side.
|
||||
static void create(lua_State *L, Metadata *metadata);
|
||||
static void create(lua_State *L, IMetadata *metadata);
|
||||
|
||||
static void Register(lua_State *L);
|
||||
};
|
||||
|
|
|
@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "lua_api/l_storage.h"
|
||||
#include "l_internal.h"
|
||||
#include "content/mods.h"
|
||||
#include "server.h"
|
||||
|
||||
int ModApiStorage::l_get_mod_storage(lua_State *L)
|
||||
|
@ -28,23 +27,12 @@ int ModApiStorage::l_get_mod_storage(lua_State *L)
|
|||
// Note that this is wrapped in Lua, see builtin/common/mod_storage.lua
|
||||
std::string mod_name = readParam<std::string>(L, 1);
|
||||
|
||||
ModMetadata *store = nullptr;
|
||||
|
||||
if (IGameDef *gamedef = getGameDef(L)) {
|
||||
store = new ModMetadata(mod_name, gamedef->getModStorageDatabase());
|
||||
if (gamedef->registerModStorage(store)) {
|
||||
StorageRef::create(L, store);
|
||||
int object = lua_gettop(L);
|
||||
lua_pushvalue(L, object);
|
||||
return 1;
|
||||
}
|
||||
StorageRef::create(L, mod_name, gamedef->getModStorageDatabase());
|
||||
} else {
|
||||
assert(false); // this should not happen
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
delete store;
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -53,19 +41,9 @@ void ModApiStorage::Initialize(lua_State *L, int top)
|
|||
API_FCT(get_mod_storage);
|
||||
}
|
||||
|
||||
StorageRef::StorageRef(ModMetadata *object):
|
||||
m_object(object)
|
||||
void StorageRef::create(lua_State *L, const std::string &mod_name, ModMetadataDatabase *db)
|
||||
{
|
||||
}
|
||||
|
||||
StorageRef::~StorageRef()
|
||||
{
|
||||
delete m_object;
|
||||
}
|
||||
|
||||
void StorageRef::create(lua_State *L, ModMetadata *object)
|
||||
{
|
||||
StorageRef *o = new StorageRef(object);
|
||||
StorageRef *o = new StorageRef(mod_name, db);
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
luaL_getmetatable(L, className);
|
||||
lua_setmetatable(L, -2);
|
||||
|
@ -74,9 +52,6 @@ void StorageRef::create(lua_State *L, ModMetadata *object)
|
|||
int StorageRef::gc_object(lua_State *L)
|
||||
{
|
||||
StorageRef *o = *(StorageRef **)(lua_touserdata(L, 1));
|
||||
// Server side
|
||||
if (IGameDef *gamedef = getGameDef(L))
|
||||
gamedef->unregisterModStorage(getobject(o)->getModName());
|
||||
delete o;
|
||||
return 0;
|
||||
}
|
||||
|
@ -122,20 +97,14 @@ StorageRef* StorageRef::checkobject(lua_State *L, int narg)
|
|||
return *(StorageRef**)ud; // unbox pointer
|
||||
}
|
||||
|
||||
ModMetadata* StorageRef::getobject(StorageRef *ref)
|
||||
IMetadata* StorageRef::getmeta(bool auto_create)
|
||||
{
|
||||
ModMetadata *co = ref->m_object;
|
||||
return co;
|
||||
}
|
||||
|
||||
Metadata* StorageRef::getmeta(bool auto_create)
|
||||
{
|
||||
return m_object;
|
||||
return &m_object;
|
||||
}
|
||||
|
||||
void StorageRef::clearMeta()
|
||||
{
|
||||
m_object->clear();
|
||||
m_object.clear();
|
||||
}
|
||||
|
||||
const char StorageRef::className[] = "StorageRef";
|
||||
|
|
|
@ -22,8 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "l_metadata.h"
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
class ModMetadata;
|
||||
#include "content/mods.h"
|
||||
|
||||
class ModApiStorage : public ModApiBase
|
||||
{
|
||||
|
@ -37,24 +36,23 @@ public:
|
|||
class StorageRef : public MetaDataRef
|
||||
{
|
||||
private:
|
||||
ModMetadata *m_object = nullptr;
|
||||
ModMetadata m_object;
|
||||
|
||||
static const char className[];
|
||||
static const luaL_Reg methods[];
|
||||
|
||||
virtual Metadata *getmeta(bool auto_create);
|
||||
virtual IMetadata *getmeta(bool auto_create);
|
||||
virtual void clearMeta();
|
||||
|
||||
// garbage collector
|
||||
static int gc_object(lua_State *L);
|
||||
|
||||
public:
|
||||
StorageRef(ModMetadata *object);
|
||||
~StorageRef();
|
||||
StorageRef(const std::string &mod_name, ModMetadataDatabase *db): m_object(mod_name, db) {}
|
||||
~StorageRef() = default;
|
||||
|
||||
static void Register(lua_State *L);
|
||||
static void create(lua_State *L, ModMetadata *object);
|
||||
static void create(lua_State *L, const std::string &mod_name, ModMetadataDatabase *db);
|
||||
|
||||
static StorageRef *checkobject(lua_State *L, int narg);
|
||||
static ModMetadata *getobject(StorageRef *ref);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue