]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/lua_api/l_storage.cpp
Node definition manager refactor (#7016)
[dragonfireclient.git] / src / script / lua_api / l_storage.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "lua_api/l_storage.h"
22 #include "l_internal.h"
23 #include "mods.h"
24 #include "server.h"
25
26 int ModApiStorage::l_get_mod_storage(lua_State *L)
27 {
28         lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
29         if (!lua_isstring(L, -1)) {
30                 return 0;
31         }
32
33         std::string mod_name = lua_tostring(L, -1);
34
35         ModMetadata *store = new ModMetadata(mod_name);
36         if (IGameDef *gamedef = getGameDef(L)) {
37                 store->load(gamedef->getModStoragePath());
38                 gamedef->registerModStorage(store);
39         } else {
40                 assert(false); // this should not happen
41         }
42
43         StorageRef::create(L, store);
44         int object = lua_gettop(L);
45
46         lua_pushvalue(L, object);
47         return 1;
48 }
49
50 void ModApiStorage::Initialize(lua_State *L, int top)
51 {
52         API_FCT(get_mod_storage);
53 }
54
55 StorageRef::StorageRef(ModMetadata *object):
56         m_object(object)
57 {
58 }
59
60 void StorageRef::create(lua_State *L, ModMetadata *object)
61 {
62         StorageRef *o = new StorageRef(object);
63         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
64         luaL_getmetatable(L, className);
65         lua_setmetatable(L, -2);
66 }
67
68 int StorageRef::gc_object(lua_State *L)
69 {
70         StorageRef *o = *(StorageRef **)(lua_touserdata(L, 1));
71         // Server side
72         if (IGameDef *gamedef = getGameDef(L))
73                 gamedef->unregisterModStorage(getobject(o)->getModName());
74         delete o;
75         return 0;
76 }
77
78 void StorageRef::Register(lua_State *L)
79 {
80         lua_newtable(L);
81         int methodtable = lua_gettop(L);
82         luaL_newmetatable(L, className);
83         int metatable = lua_gettop(L);
84
85         lua_pushliteral(L, "__metatable");
86         lua_pushvalue(L, methodtable);
87         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
88
89         lua_pushliteral(L, "metadata_class");
90         lua_pushlstring(L, className, strlen(className));
91         lua_settable(L, metatable);
92
93         lua_pushliteral(L, "__index");
94         lua_pushvalue(L, methodtable);
95         lua_settable(L, metatable);
96
97         lua_pushliteral(L, "__gc");
98         lua_pushcfunction(L, gc_object);
99         lua_settable(L, metatable);
100
101         lua_pushliteral(L, "__eq");
102         lua_pushcfunction(L, l_equals);
103         lua_settable(L, metatable);
104
105         lua_pop(L, 1);  // drop metatable
106
107         luaL_openlib(L, 0, methods, 0);  // fill methodtable
108         lua_pop(L, 1);  // drop methodtable
109 }
110
111 StorageRef* StorageRef::checkobject(lua_State *L, int narg)
112 {
113         luaL_checktype(L, narg, LUA_TUSERDATA);
114         void *ud = luaL_checkudata(L, narg, className);
115         if (!ud) luaL_typerror(L, narg, className);
116         return *(StorageRef**)ud;  // unbox pointer
117 }
118
119 ModMetadata* StorageRef::getobject(StorageRef *ref)
120 {
121         ModMetadata *co = ref->m_object;
122         return co;
123 }
124
125 Metadata* StorageRef::getmeta(bool auto_create)
126 {
127         return m_object;
128 }
129
130 void StorageRef::clearMeta()
131 {
132         m_object->clear();
133 }
134
135 const char StorageRef::className[] = "StorageRef";
136 const luaL_Reg StorageRef::methods[] = {
137         luamethod(MetaDataRef, get_string),
138         luamethod(MetaDataRef, set_string),
139         luamethod(MetaDataRef, get_int),
140         luamethod(MetaDataRef, set_int),
141         luamethod(MetaDataRef, get_float),
142         luamethod(MetaDataRef, set_float),
143         luamethod(MetaDataRef, to_table),
144         luamethod(MetaDataRef, from_table),
145         luamethod(MetaDataRef, equals),
146         {0,0}
147 };