Derive NodeMetaRef from MetaDataRef
authorrubenwardy <rubenwardy@gmail.com>
Tue, 31 Jan 2017 16:43:45 +0000 (16:43 +0000)
committerrubenwardy <rubenwardy@gmail.com>
Sat, 4 Feb 2017 22:07:55 +0000 (22:07 +0000)
.gitignore
build/android/jni/Android.mk
src/metadata.cpp
src/metadata.h
src/script/lua_api/CMakeLists.txt
src/script/lua_api/l_metadata.cpp [new file with mode: 0644]
src/script/lua_api/l_metadata.h [new file with mode: 0644]
src/script/lua_api/l_nodemeta.cpp
src/script/lua_api/l_nodemeta.h

index d7e0daab4cba4b0e4410e75dc9433515a6fcf815..c2600afeba0ff805da2ffbe5d09a499fce42de78 100644 (file)
@@ -74,6 +74,7 @@ locale/
 *.a
 *.ninja
 .ninja*
+*.gch
 
 ## Android build files
 build/android/src/main/assets
@@ -86,4 +87,3 @@ build/android/obj
 build/android/local.properties
 build/android/.gradle
 timestamp
-
index 8f333c3d41329be1747e9ba954e24a87524dbc46..70a3d29c082b62ab64dff93c97f4f4819e4e7aeb 100644 (file)
@@ -307,6 +307,7 @@ LOCAL_SRC_FILES += \
                jni/src/script/lua_api/l_item.cpp         \
                jni/src/script/lua_api/l_mainmenu.cpp     \
                jni/src/script/lua_api/l_mapgen.cpp       \
+               jni/src/script/lua_api/l_metadata.cpp     \
                jni/src/script/lua_api/l_nodemeta.cpp     \
                jni/src/script/lua_api/l_nodetimer.cpp    \
                jni/src/script/lua_api/l_noise.cpp        \
index 8e04aa2d35a0b41638bce7d861dae1c5e17301eb..96453d710849e0578fa8f03bc20b8048f2b6143c 100644 (file)
@@ -37,12 +37,39 @@ bool Metadata::empty() const
        return m_stringvars.size() == 0;
 }
 
-std::string Metadata::getString(const std::string &name,
-       u16 recursion) const
+size_t Metadata::size() const
+{
+       return m_stringvars.size();
+}
+
+bool Metadata::contains(const std::string &name) const
+{
+       return m_stringvars.find(name) != m_stringvars.end();
+}
+
+bool Metadata::operator==(const Metadata &other) const
+{
+       if (size() != other.size())
+               return false;
+
+       for (StringMap::const_iterator it = m_stringvars.begin();
+                       it != m_stringvars.end(); ++it) {
+               if (!other.contains(it->first) ||
+                               other.getString(it->first) != it->second)
+                       return false;
+       }
+
+       return true;
+}
+
+const std::string &Metadata::getString(const std::string &name,
+               u16 recursion) const
 {
        StringMap::const_iterator it = m_stringvars.find(name);
-       if (it == m_stringvars.end())
-               return "";
+       if (it == m_stringvars.end()) {
+               static const std::string empty_string = std::string("");
+               return empty_string;
+       }
 
        return resolveString(it->second, recursion);
 }
@@ -56,14 +83,13 @@ void Metadata::setString(const std::string &name, const std::string &var)
        }
 }
 
-std::string Metadata::resolveString(const std::string &str,
-       u16 recursion) const
+const std::string &Metadata::resolveString(const std::string &str,
+               u16 recursion) const
 {
-       if (recursion > 1) {
-               return str;
-       }
-       if (str.substr(0, 2) == "${" && str[str.length() - 1] == '}') {
+       if (recursion <= 1 &&
+                       str.substr(0, 2) == "${" && str[str.length() - 1] == '}') {
                return getString(str.substr(2, str.length() - 3), recursion + 1);
+       } else {
+               return str;
        }
-       return str;
 }
index a96bfc408d20333850da7fb9ff4e24f69b0a3907..a629c0615d251253ca1edceeebb06613f0bb4d4c 100644 (file)
@@ -44,10 +44,10 @@ public:
        bool empty() const;
 
        // Generic key/value store
-       std::string getString(const std::string &name, u16 recursion = 0) const;
+       const std::string &getString(const std::string &name, u16 recursion = 0) const;
        void setString(const std::string &name, const std::string &var);
        // Support variable names in values
-       std::string resolveString(const std::string &str, u16 recursion = 0) const;
+       const std::string &resolveString(const std::string &str, u16 recursion = 0) const;
        const StringMap &getStrings() const
        {
                return m_stringvars;
index d507dcf70e50b531c8095af935e77b5a1e28d096..efccce515952909000de2b22648054112fa8301c 100644 (file)
@@ -6,6 +6,7 @@ set(common_SCRIPT_LUA_API_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/l_metadata.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp
@@ -22,4 +23,3 @@ set(common_SCRIPT_LUA_API_SRCS
 set(client_SCRIPT_LUA_API_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp
        PARENT_SCOPE)
-
diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp
new file mode 100644 (file)
index 0000000..b54005b
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_metadata.h"
+#include "lua_api/l_internal.h"
+#include "common/c_content.h"
+#include "serverenvironment.h"
+#include "map.h"
+#include "server.h"
+
+// LUALIB_API
+void *luaL_checkudata_is_metadataref(lua_State *L, int ud) {
+       void *p = lua_touserdata(L, ud);
+       if (p != NULL &&  // value is a userdata?
+                       lua_getmetatable(L, ud)) {  // does it have a metatable?
+               lua_getfield(L, -1, "metadata_class");
+               if (lua_type(L, -1) == LUA_TSTRING) { // does it have a metadata_class field?
+                       return p;
+               }
+       }
+       luaL_typerror(L, ud, "MetaDataRef");
+       return NULL;
+}
+
+MetaDataRef* MetaDataRef::checkobject(lua_State *L, int narg)
+{
+       luaL_checktype(L, narg, LUA_TUSERDATA);
+       void *ud = luaL_checkudata_is_metadataref(L, narg);
+       if (!ud)
+               luaL_typerror(L, narg, "MetaDataRef");
+
+       return *(MetaDataRef**)ud;  // unbox pointer
+}
+
+// Exported functions
+
+// get_string(self, name)
+int MetaDataRef::l_get_string(lua_State *L)
+{
+       MAP_LOCK_REQUIRED;
+
+       MetaDataRef *ref = checkobject(L, 1);
+       std::string name = luaL_checkstring(L, 2);
+
+       Metadata *meta = ref->getmeta(false);
+       if (meta == NULL) {
+               lua_pushlstring(L, "", 0);
+               return 1;
+       }
+
+       const std::string &str = meta->getString(name);
+       lua_pushlstring(L, str.c_str(), str.size());
+       return 1;
+}
+
+// set_string(self, name, var)
+int MetaDataRef::l_set_string(lua_State *L)
+{
+       MAP_LOCK_REQUIRED;
+
+       MetaDataRef *ref = checkobject(L, 1);
+       std::string name = luaL_checkstring(L, 2);
+       size_t len = 0;
+       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();
+       return 0;
+}
+
+// get_int(self, name)
+int MetaDataRef::l_get_int(lua_State *L)
+{
+       MAP_LOCK_REQUIRED;
+
+       MetaDataRef *ref = checkobject(L, 1);
+       std::string name = lua_tostring(L, 2);
+
+       Metadata *meta = ref->getmeta(false);
+       if (meta == NULL) {
+               lua_pushnumber(L, 0);
+               return 1;
+       }
+
+       const std::string &str = meta->getString(name);
+       lua_pushnumber(L, stoi(str));
+       return 1;
+}
+
+// set_int(self, name, var)
+int MetaDataRef::l_set_int(lua_State *L)
+{
+       MAP_LOCK_REQUIRED;
+
+       MetaDataRef *ref = checkobject(L, 1);
+       std::string name = lua_tostring(L, 2);
+       int a = lua_tointeger(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();
+       return 0;
+}
+
+// get_float(self, name)
+int MetaDataRef::l_get_float(lua_State *L)
+{
+       MAP_LOCK_REQUIRED;
+
+       MetaDataRef *ref = checkobject(L, 1);
+       std::string name = lua_tostring(L, 2);
+
+       Metadata *meta = ref->getmeta(false);
+       if (meta == NULL) {
+               lua_pushnumber(L, 0);
+               return 1;
+       }
+
+       const std::string &str = meta->getString(name);
+       lua_pushnumber(L, stof(str));
+       return 1;
+}
+
+// set_float(self, name, var)
+int MetaDataRef::l_set_float(lua_State *L)
+{
+       MAP_LOCK_REQUIRED;
+
+       MetaDataRef *ref = checkobject(L, 1);
+       std::string name = lua_tostring(L, 2);
+       float a = lua_tonumber(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();
+       return 0;
+}
+
+// to_table(self)
+int MetaDataRef::l_to_table(lua_State *L)
+{
+       MAP_LOCK_REQUIRED;
+
+       MetaDataRef *ref = checkobject(L, 1);
+
+       Metadata *meta = ref->getmeta(true);
+       if (meta == NULL) {
+               lua_pushnil(L);
+               return 1;
+       }
+       lua_newtable(L);
+
+       ref->handleToTable(L, meta);
+
+       return 1;
+}
+
+// from_table(self, table)
+int MetaDataRef::l_from_table(lua_State *L)
+{
+       MAP_LOCK_REQUIRED;
+
+       MetaDataRef *ref = checkobject(L, 1);
+       int base = 2;
+
+       ref->clearMeta();
+
+       if (!lua_istable(L, base)) {
+               // No metadata
+               lua_pushboolean(L, true);
+               return 1;
+       }
+
+       // Create new metadata
+       Metadata *meta = ref->getmeta(true);
+       if (meta == NULL) {
+               lua_pushboolean(L, false);
+               return 1;
+       }
+
+       bool was_successful = ref->handleFromTable(L, base, meta);
+       ref->reportMetadataChange();
+       lua_pushboolean(L, was_successful);
+       return 1;
+}
+
+void MetaDataRef::handleToTable(lua_State *L, Metadata *meta)
+{
+       lua_newtable(L);
+       {
+               const StringMap &fields = meta->getStrings();
+               for (StringMap::const_iterator
+                               it = fields.begin(); it != fields.end(); ++it) {
+                       const std::string &name = it->first;
+                       const std::string &value = it->second;
+                       lua_pushlstring(L, name.c_str(), name.size());
+                       lua_pushlstring(L, value.c_str(), value.size());
+                       lua_settable(L, -3);
+               }
+       }
+       lua_setfield(L, -2, "fields");
+}
+
+bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta)
+{
+       // Set fields
+       lua_getfield(L, table, "fields");
+       if (lua_istable(L, -1)) {
+               int fieldstable = lua_gettop(L);
+               lua_pushnil(L);
+               while (lua_next(L, fieldstable) != 0) {
+                       // key at index -2 and value at index -1
+                       std::string name = lua_tostring(L, -2);
+                       size_t cl;
+                       const char *cs = lua_tolstring(L, -1, &cl);
+                       meta->setString(name, std::string(cs, cl));
+                       lua_pop(L, 1); // Remove value, keep key for next iteration
+               }
+               lua_pop(L, 1);
+       }
+
+       return true;
+}
diff --git a/src/script/lua_api/l_metadata.h b/src/script/lua_api/l_metadata.h
new file mode 100644 (file)
index 0000000..561be6a
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#ifndef L_METADATA_H_
+#define L_METADATA_H_
+
+#include "lua_api/l_base.h"
+#include "irrlichttypes_bloated.h"
+
+class Metadata;
+
+/*
+       NodeMetaRef
+*/
+
+class MetaDataRef : public ModApiBase {
+public:
+       virtual ~MetaDataRef() {}
+protected:
+       static MetaDataRef *checkobject(lua_State *L, int narg);
+
+       virtual void reportMetadataChange() {}
+       virtual Metadata* 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);
+
+       // Exported functions
+
+       // get_string(self, name)
+       static int l_get_string(lua_State *L);
+
+       // set_string(self, name, var)
+       static int l_set_string(lua_State *L);
+
+       // get_int(self, name)
+       static int l_get_int(lua_State *L);
+
+       // set_int(self, name, var)
+       static int l_set_int(lua_State *L);
+
+       // get_float(self, name)
+       static int l_get_float(lua_State *L);
+
+       // set_float(self, name, var)
+       static int l_set_float(lua_State *L);
+
+       // to_table(self)
+       static int l_to_table(lua_State *L);
+
+       // from_table(self, table)
+       static int l_from_table(lua_State *L);
+};
+
+#endif /* L_NODEMETA_H_ */
index 8391de03ce82f71d5b8ef8aa111070e9e1fa26c5..4b2b392dab29e871ea0815293abb623d92c8837f 100644 (file)
@@ -36,7 +36,7 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg)
        return *(NodeMetaRef**)ud;  // unbox pointer
 }
 
-NodeMetadata* NodeMetaRef::getmeta(bool auto_create)
+Metadata* NodeMetaRef::getmeta(bool auto_create)
 {
        NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p);
        if (meta == NULL && auto_create) {
@@ -49,17 +49,22 @@ NodeMetadata* NodeMetaRef::getmeta(bool auto_create)
        return meta;
 }
 
-void NodeMetaRef::reportMetadataChange(NodeMetaRef *ref)
+void NodeMetaRef::clearMeta()
+{
+       m_env->getMap().removeNodeMetadata(m_p);
+}
+
+void NodeMetaRef::reportMetadataChange()
 {
        // NOTE: This same code is in rollback_interface.cpp
        // Inform other things that the metadata has changed
-       v3s16 blockpos = getNodeBlockPos(ref->m_p);
+       v3s16 blockpos = getNodeBlockPos(m_p);
        MapEditEvent event;
        event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
        event.p = blockpos;
-       ref->m_env->getMap().dispatchEvent(&event);
+       m_env->getMap().dispatchEvent(&event);
        // Set the block to be saved
-       MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
+       MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
        if (block) {
                block->raiseModified(MOD_STATE_WRITE_NEEDED,
                        MOD_REASON_REPORT_META_CHANGE);
@@ -75,115 +80,6 @@ int NodeMetaRef::gc_object(lua_State *L) {
        return 0;
 }
 
-// get_string(self, name)
-int NodeMetaRef::l_get_string(lua_State *L)
-{
-       MAP_LOCK_REQUIRED;
-
-       NodeMetaRef *ref = checkobject(L, 1);
-       std::string name = luaL_checkstring(L, 2);
-
-       NodeMetadata *meta = ref->getmeta(false);
-       if(meta == NULL){
-               lua_pushlstring(L, "", 0);
-               return 1;
-       }
-       std::string str = meta->getString(name);
-       lua_pushlstring(L, str.c_str(), str.size());
-       return 1;
-}
-
-// set_string(self, name, var)
-int NodeMetaRef::l_set_string(lua_State *L)
-{
-       MAP_LOCK_REQUIRED;
-
-       NodeMetaRef *ref = checkobject(L, 1);
-       std::string name = luaL_checkstring(L, 2);
-       size_t len = 0;
-       const char *s = lua_tolstring(L, 3, &len);
-       std::string str(s, len);
-
-       NodeMetadata *meta = ref->getmeta(!str.empty());
-       if(meta == NULL || str == meta->getString(name))
-               return 0;
-       meta->setString(name, str);
-       reportMetadataChange(ref);
-       return 0;
-}
-
-// get_int(self, name)
-int NodeMetaRef::l_get_int(lua_State *L)
-{
-       MAP_LOCK_REQUIRED;
-
-       NodeMetaRef *ref = checkobject(L, 1);
-       std::string name = lua_tostring(L, 2);
-
-       NodeMetadata *meta = ref->getmeta(false);
-       if(meta == NULL){
-               lua_pushnumber(L, 0);
-               return 1;
-       }
-       std::string str = meta->getString(name);
-       lua_pushnumber(L, stoi(str));
-       return 1;
-}
-
-// set_int(self, name, var)
-int NodeMetaRef::l_set_int(lua_State *L)
-{
-       MAP_LOCK_REQUIRED;
-
-       NodeMetaRef *ref = checkobject(L, 1);
-       std::string name = lua_tostring(L, 2);
-       int a = lua_tointeger(L, 3);
-       std::string str = itos(a);
-
-       NodeMetadata *meta = ref->getmeta(true);
-       if(meta == NULL || str == meta->getString(name))
-               return 0;
-       meta->setString(name, str);
-       reportMetadataChange(ref);
-       return 0;
-}
-
-// get_float(self, name)
-int NodeMetaRef::l_get_float(lua_State *L)
-{
-       MAP_LOCK_REQUIRED;
-
-       NodeMetaRef *ref = checkobject(L, 1);
-       std::string name = lua_tostring(L, 2);
-
-       NodeMetadata *meta = ref->getmeta(false);
-       if(meta == NULL){
-               lua_pushnumber(L, 0);
-               return 1;
-       }
-       std::string str = meta->getString(name);
-       lua_pushnumber(L, stof(str));
-       return 1;
-}
-
-// set_float(self, name, var)
-int NodeMetaRef::l_set_float(lua_State *L)
-{
-       MAP_LOCK_REQUIRED;
-
-       NodeMetaRef *ref = checkobject(L, 1);
-       std::string name = lua_tostring(L, 2);
-       float a = lua_tonumber(L, 3);
-       std::string str = ftos(a);
-
-       NodeMetadata *meta = ref->getmeta(true);
-       if(meta == NULL || str == meta->getString(name))
-               return 0;
-       meta->setString(name, str);
-       reportMetadataChange(ref);
-       return 0;
-}
-
 // get_inventory(self)
 int NodeMetaRef::l_get_inventory(lua_State *L)
 {
@@ -195,34 +91,12 @@ int NodeMetaRef::l_get_inventory(lua_State *L)
        return 1;
 }
 
-// to_table(self)
-int NodeMetaRef::l_to_table(lua_State *L)
+void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta)
 {
-       MAP_LOCK_REQUIRED;
-
-       NodeMetaRef *ref = checkobject(L, 1);
-
-       NodeMetadata *meta = ref->getmeta(true);
-       if (meta == NULL) {
-               lua_pushnil(L);
-               return 1;
-       }
-       lua_newtable(L);
-
        // fields
-       lua_newtable(L);
-       {
-               StringMap fields = meta->getStrings();
-               for (StringMap::const_iterator
-                               it = fields.begin(); it != fields.end(); ++it) {
-                       const std::string &name = it->first;
-                       const std::string &value = it->second;
-                       lua_pushlstring(L, name.c_str(), name.size());
-                       lua_pushlstring(L, value.c_str(), value.size());
-                       lua_settable(L, -3);
-               }
-       }
-       lua_setfield(L, -2, "fields");
+       MetaDataRef::handleToTable(L, _meta);
+
+       NodeMetadata *meta = (NodeMetadata*) _meta;
 
        // inventory
        lua_newtable(L);
@@ -236,52 +110,20 @@ int NodeMetaRef::l_to_table(lua_State *L)
                }
        }
        lua_setfield(L, -2, "inventory");
-       return 1;
 }
 
 // from_table(self, table)
-int NodeMetaRef::l_from_table(lua_State *L)
+bool NodeMetaRef::handleFromTable(lua_State *L, int table, Metadata *_meta)
 {
-       MAP_LOCK_REQUIRED;
-
-       NodeMetaRef *ref = checkobject(L, 1);
-       int base = 2;
-
-       // clear old metadata first
-       ref->m_env->getMap().removeNodeMetadata(ref->m_p);
-
-       if (!lua_istable(L, base)) {
-               // No metadata
-               lua_pushboolean(L, true);
-               return 1;
-       }
+       // fields
+       if (!MetaDataRef::handleFromTable(L, table, _meta))
+               return false;
 
-       // Create new metadata
-       NodeMetadata *meta = ref->getmeta(true);
-       if (meta == NULL) {
-               lua_pushboolean(L, false);
-               return 1;
-       }
+       NodeMetadata *meta = (NodeMetadata*) _meta;
 
-       // Set fields
-       lua_getfield(L, base, "fields");
-       if (lua_istable(L, -1)) {
-               int fieldstable = lua_gettop(L);
-               lua_pushnil(L);
-               while (lua_next(L, fieldstable) != 0) {
-                       // key at index -2 and value at index -1
-                       std::string name = lua_tostring(L, -2);
-                       size_t cl;
-                       const char *cs = lua_tolstring(L, -1, &cl);
-                       meta->setString(name, std::string(cs, cl));
-                       lua_pop(L, 1); // Remove value, keep key for next iteration
-               }
-               lua_pop(L, 1);
-       }
-
-       // Set inventory
+       // inventory
        Inventory *inv = meta->getInventory();
-       lua_getfield(L, base, "inventory");
+       lua_getfield(L, table, "inventory");
        if (lua_istable(L, -1)) {
                int inventorytable = lua_gettop(L);
                lua_pushnil(L);
@@ -294,9 +136,7 @@ int NodeMetaRef::l_from_table(lua_State *L)
                lua_pop(L, 1);
        }
 
-       reportMetadataChange(ref);
-       lua_pushboolean(L, true);
-       return 1;
+       return true;
 }
 
 
@@ -332,6 +172,10 @@ void NodeMetaRef::Register(lua_State *L)
        lua_pushvalue(L, methodtable);
        lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
 
+       lua_pushliteral(L, "metadata_class");
+       lua_pushlstring(L, className, strlen(className));
+       lua_settable(L, metatable);
+
        lua_pushliteral(L, "__index");
        lua_pushvalue(L, methodtable);
        lua_settable(L, metatable);
@@ -351,14 +195,14 @@ void NodeMetaRef::Register(lua_State *L)
 
 const char NodeMetaRef::className[] = "NodeMetaRef";
 const luaL_reg NodeMetaRef::methods[] = {
-       luamethod(NodeMetaRef, get_string),
-       luamethod(NodeMetaRef, set_string),
-       luamethod(NodeMetaRef, get_int),
-       luamethod(NodeMetaRef, set_int),
-       luamethod(NodeMetaRef, get_float),
-       luamethod(NodeMetaRef, set_float),
+       luamethod(MetaDataRef, get_string),
+       luamethod(MetaDataRef, set_string),
+       luamethod(MetaDataRef, get_int),
+       luamethod(MetaDataRef, set_int),
+       luamethod(MetaDataRef, get_float),
+       luamethod(MetaDataRef, set_float),
+       luamethod(MetaDataRef, to_table),
+       luamethod(MetaDataRef, from_table),
        luamethod(NodeMetaRef, get_inventory),
-       luamethod(NodeMetaRef, to_table),
-       luamethod(NodeMetaRef, from_table),
        {0,0}
 };
index 4ce338b18864dcc9eeb6deff2ab5bf5cc2c9fa7c..d03f086c9db97874c2dcfbfa829c0f61af252ac8 100644 (file)
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define L_NODEMETA_H_
 
 #include "lua_api/l_base.h"
+#include "lua_api/l_metadata.h"
 #include "irrlichttypes_bloated.h"
 
 class ServerEnvironment;
@@ -29,7 +30,7 @@ class NodeMetadata;
        NodeMetaRef
 */
 
-class NodeMetaRef : public ModApiBase {
+class NodeMetaRef : public MetaDataRef {
 private:
        v3s16 m_p;
        ServerEnvironment *m_env;
@@ -52,42 +53,22 @@ 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 NodeMetadata* getmeta(bool auto_create);
+       virtual Metadata* getmeta(bool auto_create);
+       virtual void clearMeta();
 
-       static void reportMetadataChange(NodeMetaRef *ref);
+       virtual void reportMetadataChange();
+
+       virtual void handleToTable(lua_State *L, Metadata *_meta);
+       virtual bool handleFromTable(lua_State *L, int table, Metadata *_meta);
 
        // Exported functions
 
        // garbage collector
        static int gc_object(lua_State *L);
 
-       // get_string(self, name)
-       static int l_get_string(lua_State *L);
-
-       // set_string(self, name, var)
-       static int l_set_string(lua_State *L);
-
-       // get_int(self, name)
-       static int l_get_int(lua_State *L);
-
-       // set_int(self, name, var)
-       static int l_set_int(lua_State *L);
-
-       // get_float(self, name)
-       static int l_get_float(lua_State *L);
-
-       // set_float(self, name, var)
-       static int l_set_float(lua_State *L);
-
        // get_inventory(self)
        static int l_get_inventory(lua_State *L);
 
-       // to_table(self)
-       static int l_to_table(lua_State *L);
-
-       // from_table(self, table)
-       static int l_from_table(lua_State *L);
-
 public:
        NodeMetaRef(v3s16 p, ServerEnvironment *env);