]> git.lizzy.rs Git - minetest.git/blob - src/script/lua_api/l_storage.cpp
Joystick: Remap joystick-specific KeyTypes to generic ones
[minetest.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 "content/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 = readParam<std::string>(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                 delete store;
41                 assert(false); // this should not happen
42         }
43
44         StorageRef::create(L, store);
45         int object = lua_gettop(L);
46
47         lua_pushvalue(L, object);
48         return 1;
49 }
50
51 void ModApiStorage::Initialize(lua_State *L, int top)
52 {
53         API_FCT(get_mod_storage);
54 }
55
56 StorageRef::StorageRef(ModMetadata *object):
57         m_object(object)
58 {
59 }
60
61 StorageRef::~StorageRef()
62 {
63         delete m_object;
64 }
65
66 void StorageRef::create(lua_State *L, ModMetadata *object)
67 {
68         StorageRef *o = new StorageRef(object);
69         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
70         luaL_getmetatable(L, className);
71         lua_setmetatable(L, -2);
72 }
73
74 int StorageRef::gc_object(lua_State *L)
75 {
76         StorageRef *o = *(StorageRef **)(lua_touserdata(L, 1));
77         // Server side
78         if (IGameDef *gamedef = getGameDef(L))
79                 gamedef->unregisterModStorage(getobject(o)->getModName());
80         delete o;
81         return 0;
82 }
83
84 void StorageRef::Register(lua_State *L)
85 {
86         lua_newtable(L);
87         int methodtable = lua_gettop(L);
88         luaL_newmetatable(L, className);
89         int metatable = lua_gettop(L);
90
91         lua_pushliteral(L, "__metatable");
92         lua_pushvalue(L, methodtable);
93         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
94
95         lua_pushliteral(L, "metadata_class");
96         lua_pushlstring(L, className, strlen(className));
97         lua_settable(L, metatable);
98
99         lua_pushliteral(L, "__index");
100         lua_pushvalue(L, methodtable);
101         lua_settable(L, metatable);
102
103         lua_pushliteral(L, "__gc");
104         lua_pushcfunction(L, gc_object);
105         lua_settable(L, metatable);
106
107         lua_pushliteral(L, "__eq");
108         lua_pushcfunction(L, l_equals);
109         lua_settable(L, metatable);
110
111         lua_pop(L, 1);  // drop metatable
112
113         luaL_openlib(L, 0, methods, 0);  // fill methodtable
114         lua_pop(L, 1);  // drop methodtable
115 }
116
117 StorageRef* StorageRef::checkobject(lua_State *L, int narg)
118 {
119         luaL_checktype(L, narg, LUA_TUSERDATA);
120         void *ud = luaL_checkudata(L, narg, className);
121         if (!ud) luaL_typerror(L, narg, className);
122         return *(StorageRef**)ud;  // unbox pointer
123 }
124
125 ModMetadata* StorageRef::getobject(StorageRef *ref)
126 {
127         ModMetadata *co = ref->m_object;
128         return co;
129 }
130
131 Metadata* StorageRef::getmeta(bool auto_create)
132 {
133         return m_object;
134 }
135
136 void StorageRef::clearMeta()
137 {
138         m_object->clear();
139 }
140
141 const char StorageRef::className[] = "StorageRef";
142 const luaL_Reg StorageRef::methods[] = {
143         luamethod(MetaDataRef, contains),
144         luamethod(MetaDataRef, get),
145         luamethod(MetaDataRef, get_string),
146         luamethod(MetaDataRef, set_string),
147         luamethod(MetaDataRef, get_int),
148         luamethod(MetaDataRef, set_int),
149         luamethod(MetaDataRef, get_float),
150         luamethod(MetaDataRef, set_float),
151         luamethod(MetaDataRef, to_table),
152         luamethod(MetaDataRef, from_table),
153         luamethod(MetaDataRef, equals),
154         {0,0}
155 };