Add player:get_meta(), deprecate player attributes (#7202)
[oweals/minetest.git] / src / script / lua_api / l_itemstackmeta.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.com>
5 Copyright (C) 2017 raymoo
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include "lua_api/l_itemstackmeta.h"
23 #include "lua_api/l_internal.h"
24 #include "common/c_content.h"
25
26 /*
27         NodeMetaRef
28 */
29 ItemStackMetaRef* ItemStackMetaRef::checkobject(lua_State *L, int narg)
30 {
31         luaL_checktype(L, narg, LUA_TUSERDATA);
32         void *ud = luaL_checkudata(L, narg, className);
33         if (!ud)
34                 luaL_typerror(L, narg, className);
35
36         return *(ItemStackMetaRef**)ud;  // unbox pointer
37 }
38
39 Metadata* ItemStackMetaRef::getmeta(bool auto_create)
40 {
41         return &istack->metadata;
42 }
43
44 void ItemStackMetaRef::clearMeta()
45 {
46         istack->metadata.clear();
47 }
48
49 void ItemStackMetaRef::reportMetadataChange()
50 {
51         // TODO
52 }
53
54 // Exported functions
55 int ItemStackMetaRef::l_set_tool_capabilities(lua_State *L)
56 {
57         ItemStackMetaRef *metaref = checkobject(L, 1);
58         if (lua_isnoneornil(L, 2)) {
59                 metaref->clearToolCapabilities();
60         } else if (lua_istable(L, 2)) {
61                 ToolCapabilities caps = read_tool_capabilities(L, 2);
62                 metaref->setToolCapabilities(caps);
63         } else {
64                 luaL_typerror(L, 2, "table or nil");
65         }
66
67         return 0;
68 }
69
70 // garbage collector
71 int ItemStackMetaRef::gc_object(lua_State *L) {
72         ItemStackMetaRef *o = *(ItemStackMetaRef **)(lua_touserdata(L, 1));
73         delete o;
74         return 0;
75 }
76
77 // Creates an NodeMetaRef and leaves it on top of stack
78 // Not callable from Lua; all references are created on the C side.
79 void ItemStackMetaRef::create(lua_State *L, ItemStack *istack)
80 {
81         ItemStackMetaRef *o = new ItemStackMetaRef(istack);
82         //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
83         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
84         luaL_getmetatable(L, className);
85         lua_setmetatable(L, -2);
86 }
87
88 void ItemStackMetaRef::Register(lua_State *L)
89 {
90         lua_newtable(L);
91         int methodtable = lua_gettop(L);
92         luaL_newmetatable(L, className);
93         int metatable = lua_gettop(L);
94
95         lua_pushliteral(L, "__metatable");
96         lua_pushvalue(L, methodtable);
97         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
98
99         lua_pushliteral(L, "metadata_class");
100         lua_pushlstring(L, className, strlen(className));
101         lua_settable(L, metatable);
102
103         lua_pushliteral(L, "__index");
104         lua_pushvalue(L, methodtable);
105         lua_settable(L, metatable);
106
107         lua_pushliteral(L, "__gc");
108         lua_pushcfunction(L, gc_object);
109         lua_settable(L, metatable);
110
111         lua_pushliteral(L, "__eq");
112         lua_pushcfunction(L, l_equals);
113         lua_settable(L, metatable);
114
115         lua_pop(L, 1);  // drop metatable
116
117         luaL_openlib(L, 0, methods, 0);  // fill methodtable
118         lua_pop(L, 1);  // drop methodtable
119
120         // Cannot be created from Lua
121         //lua_register(L, className, create_object);
122 }
123
124 const char ItemStackMetaRef::className[] = "ItemStackMetaRef";
125 const luaL_Reg ItemStackMetaRef::methods[] = {
126         luamethod(MetaDataRef, get_string),
127         luamethod(MetaDataRef, set_string),
128         luamethod(MetaDataRef, get_int),
129         luamethod(MetaDataRef, set_int),
130         luamethod(MetaDataRef, get_float),
131         luamethod(MetaDataRef, set_float),
132         luamethod(MetaDataRef, to_table),
133         luamethod(MetaDataRef, from_table),
134         luamethod(MetaDataRef, equals),
135         luamethod(ItemStackMetaRef, set_tool_capabilities),
136         {0,0}
137 };