From f2aa2c6a986dec47856c49ae5f54fbf3c688e027 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Tue, 31 Jan 2017 19:49:01 +0000 Subject: Add ItemStack key-value meta storage --- src/script/lua_api/CMakeLists.txt | 1 + src/script/lua_api/l_env.cpp | 2 +- src/script/lua_api/l_item.cpp | 38 +++++++++-- src/script/lua_api/l_item.h | 5 ++ src/script/lua_api/l_itemstackmeta.cpp | 115 +++++++++++++++++++++++++++++++++ src/script/lua_api/l_itemstackmeta.h | 59 +++++++++++++++++ 6 files changed, 215 insertions(+), 5 deletions(-) create mode 100644 src/script/lua_api/l_itemstackmeta.cpp create mode 100644 src/script/lua_api/l_itemstackmeta.h (limited to 'src/script/lua_api') diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt index efccce515..070234eba 100644 --- a/src/script/lua_api/CMakeLists.txt +++ b/src/script/lua_api/CMakeLists.txt @@ -5,6 +5,7 @@ set(common_SCRIPT_LUA_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_itemstackmeta.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_metadata.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 3d9db7917..2722e35a4 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -284,7 +284,7 @@ int ModApiEnvMod::l_place_node(lua_State *L) return 1; } // Create item to place - ItemStack item(ndef->get(n).name, 1, 0, "", idef); + ItemStack item(ndef->get(n).name, 1, 0, idef); // Make pointed position PointedThing pointed; pointed.type = POINTEDTHING_NODE; diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index ff0baea14..f0293bed8 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "lua_api/l_item.h" +#include "lua_api/l_itemstackmeta.h" #include "lua_api/l_internal.h" #include "common/c_converter.h" #include "common/c_content.h" @@ -137,16 +138,28 @@ int LuaItemStack::l_set_wear(lua_State *L) return 1; } +// get_meta(self) -> string +int LuaItemStack::l_get_meta(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStackMetaRef::create(L, &o->m_stack); + return 1; +} + +// DEPRECATED // get_metadata(self) -> string int LuaItemStack::l_get_metadata(lua_State *L) { NO_MAP_LOCK_REQUIRED; LuaItemStack *o = checkobject(L, 1); ItemStack &item = o->m_stack; - lua_pushlstring(L, item.metadata.c_str(), item.metadata.size()); + const std::string &value = item.metadata.getString(""); + lua_pushlstring(L, value.c_str(), value.size()); return 1; } +// DEPRECATED // set_metadata(self, string) int LuaItemStack::l_set_metadata(lua_State *L) { @@ -156,7 +169,7 @@ int LuaItemStack::l_set_metadata(lua_State *L) size_t len = 0; const char *ptr = luaL_checklstring(L, 2, &len); - item.metadata.assign(ptr, len); + item.metadata.setString("", std::string(ptr, len)); lua_pushboolean(L, true); return 1; @@ -211,8 +224,24 @@ int LuaItemStack::l_to_table(lua_State *L) lua_setfield(L, -2, "count"); lua_pushinteger(L, item.wear); lua_setfield(L, -2, "wear"); - lua_pushlstring(L, item.metadata.c_str(), item.metadata.size()); - lua_setfield(L, -2, "metadata"); + + if (item.metadata.size() == 1 && item.metadata.contains("")) { + const std::string &value = item.metadata.getString(""); + lua_pushlstring(L, value.c_str(), value.size()); + lua_setfield(L, -2, "metadata"); + } else { + lua_newtable(L); + const StringMap &fields = item.metadata.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, "metadata"); + } } return 1; } @@ -443,6 +472,7 @@ const luaL_reg LuaItemStack::methods[] = { luamethod(LuaItemStack, set_count), luamethod(LuaItemStack, get_wear), luamethod(LuaItemStack, set_wear), + luamethod(LuaItemStack, get_meta), luamethod(LuaItemStack, get_metadata), luamethod(LuaItemStack, set_metadata), luamethod(LuaItemStack, clear), diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h index be919b701..1ba5d79e0 100644 --- a/src/script/lua_api/l_item.h +++ b/src/script/lua_api/l_item.h @@ -56,9 +56,14 @@ private: // set_wear(self, number) static int l_set_wear(lua_State *L); + // get_meta(self) -> string + static int l_get_meta(lua_State *L); + + // DEPRECATED // get_metadata(self) -> string static int l_get_metadata(lua_State *L); + // DEPRECATED // set_metadata(self, string) static int l_set_metadata(lua_State *L); diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp new file mode 100644 index 000000000..304a7cdf3 --- /dev/null +++ b/src/script/lua_api/l_itemstackmeta.cpp @@ -0,0 +1,115 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +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_itemstackmeta.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" + +/* + NodeMetaRef +*/ +ItemStackMetaRef* ItemStackMetaRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(ItemStackMetaRef**)ud; // unbox pointer +} + +Metadata* ItemStackMetaRef::getmeta(bool auto_create) +{ + return &istack->metadata; +} + +void ItemStackMetaRef::clearMeta() +{ + istack->metadata.clear(); +} + +void ItemStackMetaRef::reportMetadataChange() +{ + // TODO +} + +// Exported functions + +// garbage collector +int ItemStackMetaRef::gc_object(lua_State *L) { + ItemStackMetaRef *o = *(ItemStackMetaRef **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +// Creates an NodeMetaRef and leaves it on top of stack +// Not callable from Lua; all references are created on the C side. +void ItemStackMetaRef::create(lua_State *L, ItemStack *istack) +{ + ItemStackMetaRef *o = new ItemStackMetaRef(istack); + //infostream<<"NodeMetaRef::create: o="< + +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_ITEMSTACKMETA_H_ +#define L_ITEMSTACKMETA_H_ + +#include "lua_api/l_base.h" +#include "lua_api/l_metadata.h" +#include "irrlichttypes_bloated.h" +#include "inventory.h" + +class ItemStackMetaRef : public MetaDataRef +{ +private: + ItemStack *istack; + + static const char className[]; + static const luaL_reg methods[]; + + static ItemStackMetaRef *checkobject(lua_State *L, int narg); + + virtual Metadata* getmeta(bool auto_create); + + virtual void clearMeta(); + + virtual void reportMetadataChange(); + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); +public: + ItemStackMetaRef(ItemStack *istack): istack(istack) {} + ~ItemStackMetaRef() {} + + // 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, ItemStack *istack); + + static void Register(lua_State *L); +}; + +#endif -- cgit v1.2.3