aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_metadata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/lua_api/l_metadata.cpp')
-rw-r--r--src/script/lua_api/l_metadata.cpp76
1 files changed, 46 insertions, 30 deletions
diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp
index 5f07989eb..8388bc089 100644
--- a/src/script/lua_api/l_metadata.cpp
+++ b/src/script/lua_api/l_metadata.cpp
@@ -25,28 +25,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#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;
- }
+MetaDataRef *MetaDataRef::checkAnyMetadata(lua_State *L, int narg)
+{
+ void *ud = lua_touserdata(L, narg);
+
+ bool ok = ud && luaL_getmetafield(L, narg, "metadata_class");
+ if (ok) {
+ ok = lua_isstring(L, -1);
+ lua_pop(L, 1);
}
- 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)
+ if (!ok)
luaL_typerror(L, narg, "MetaDataRef");
- return *(MetaDataRef**)ud; // unbox pointer
+ return *(MetaDataRef **)ud; // unbox pointer
+}
+
+int MetaDataRef::gc_object(lua_State *L)
+{
+ MetaDataRef *o = *(MetaDataRef **)lua_touserdata(L, 1);
+ delete o;
+ return 0;
}
// Exported functions
@@ -56,7 +55,7 @@ int MetaDataRef::l_contains(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
IMetadata *meta = ref->getmeta(false);
@@ -72,7 +71,7 @@ int MetaDataRef::l_get(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
IMetadata *meta = ref->getmeta(false);
@@ -93,7 +92,7 @@ int MetaDataRef::l_get_string(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
IMetadata *meta = ref->getmeta(false);
@@ -113,7 +112,7 @@ int MetaDataRef::l_set_string(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
size_t len = 0;
const char *s = lua_tolstring(L, 3, &len);
@@ -130,7 +129,7 @@ int MetaDataRef::l_get_int(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
IMetadata *meta = ref->getmeta(false);
@@ -150,7 +149,7 @@ int MetaDataRef::l_set_int(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
int a = luaL_checkint(L, 3);
std::string str = itos(a);
@@ -166,7 +165,7 @@ int MetaDataRef::l_get_float(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
IMetadata *meta = ref->getmeta(false);
@@ -186,7 +185,7 @@ int MetaDataRef::l_set_float(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
std::string name = luaL_checkstring(L, 2);
float a = readParam<float>(L, 3);
std::string str = ftos(a);
@@ -202,7 +201,7 @@ int MetaDataRef::l_to_table(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
IMetadata *meta = ref->getmeta(true);
if (meta == NULL) {
@@ -221,7 +220,7 @@ int MetaDataRef::l_from_table(lua_State *L)
{
MAP_LOCK_REQUIRED;
- MetaDataRef *ref = checkobject(L, 1);
+ MetaDataRef *ref = checkAnyMetadata(L, 1);
int base = 2;
ref->clearMeta();
@@ -286,9 +285,9 @@ bool MetaDataRef::handleFromTable(lua_State *L, int table, IMetadata *meta)
// equals(self, other)
int MetaDataRef::l_equals(lua_State *L)
{
- MetaDataRef *ref1 = checkobject(L, 1);
+ MetaDataRef *ref1 = checkAnyMetadata(L, 1);
IMetadata *data1 = ref1->getmeta(false);
- MetaDataRef *ref2 = checkobject(L, 2);
+ MetaDataRef *ref2 = checkAnyMetadata(L, 2);
IMetadata *data2 = ref2->getmeta(false);
if (data1 == NULL || data2 == NULL)
lua_pushboolean(L, data1 == data2);
@@ -296,3 +295,20 @@ int MetaDataRef::l_equals(lua_State *L)
lua_pushboolean(L, *data1 == *data2);
return 1;
}
+
+void MetaDataRef::registerMetadataClass(lua_State *L, const char *name,
+ const luaL_Reg *methods)
+{
+ const luaL_Reg metamethods[] = {
+ {"__eq", l_equals},
+ {"__gc", gc_object},
+ {0, 0}
+ };
+ registerClass(L, name, methods, metamethods);
+
+ // Set metadata_class in the metatable for MetaDataRef::checkAnyMetadata.
+ luaL_getmetatable(L, name);
+ lua_pushstring(L, name);
+ lua_setfield(L, -2, "metadata_class");
+ lua_pop(L, 1);
+}