From c5950234c54bc7fc3bbd30943d037d2b53dc60da Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 11 Oct 2003 12:42:29 +0000 Subject: [PATCH] Made it possible to add attributes luabind c++ class objects. --- src/class_rep.cpp | 27 +++++++++++++++++++++------ test/test_attributes.cpp | 10 ++++++++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/class_rep.cpp b/src/class_rep.cpp index 246b9b8..ea6f359 100755 --- a/src/class_rep.cpp +++ b/src/class_rep.cpp @@ -157,9 +157,10 @@ luabind::detail::class_rep::allocate(lua_State* L) const } //#include - +// lua stack: userdata, key int luabind::detail::class_rep::gettable(lua_State* L) { + // if key is nil, return nil if (lua_isnil(L, 2)) { lua_pushnil(L); @@ -172,6 +173,7 @@ int luabind::detail::class_rep::gettable(lua_State* L) // a method that is not present in this class (but in a subclass) const char* key = lua_tostring(L, 2); + // special case to see if this is a null-pointer if (key && !strcmp(key, "__ok")) { class_rep* crep = obj->crep(); @@ -219,12 +221,11 @@ int luabind::detail::class_rep::gettable(lua_State* L) // called from the metamethod for __newindex // the object pointer is passed on the lua stack +// lua stack: userdata, key, value bool luabind::detail::class_rep::settable(lua_State* L) { - if (lua_isnil(L, 2)) - { - return false; - } + // if the key is 'nil' fail + if (lua_isnil(L, 2)) return false; // we have to ignore the first argument since this may point to // a method that is not present in this class (but in a subclass) @@ -237,7 +238,21 @@ bool luabind::detail::class_rep::settable(lua_State* L) return true; } - return false; // false means that we don't have a member with the given name + if (m_getters.find(key) != m_getters.end()) + { + // this means that we have a getter but no + // setter for an attribute. We will then fail + // because that attribute is read-only + return false; + } + + // set the attribute to the object's table + getref(L, table_ref()); + lua_pushvalue(L, 2); + lua_pushvalue(L, 3); + lua_settable(L, 4); + lua_pop(L, 3); + return true; } int class_rep::gettable_dispatcher(lua_State* L) diff --git a/test/test_attributes.cpp b/test/test_attributes.cpp index d8a3ad2..ffd081c 100644 --- a/test/test_attributes.cpp +++ b/test/test_attributes.cpp @@ -123,6 +123,14 @@ bool test_attributes() if (feedback != 0) return false; if (str != "Dew") return false; + if (dostring(L, "test.foo = 5")) return false; + if (dostring(L, "if (test.foo == 5) then feedback = 3 end")) return false; + + object glob = get_globals(L); + if (object_cast(glob["feedback"]) != 3) return false; + object test = glob["test"]; + if (object_cast(test["foo"]) != 5) return false; + if (dostring(L, "function d(x) end d(test.a)")) return false; if (feedback != 5) return false; @@ -133,8 +141,6 @@ bool test_attributes() if (dostring(L, "tester(test.o)")) return false; if (feedback != 6) return false; - object glob = get_globals(L); - if (dostring(L, "a = 4")) return false; if (glob["a"].type() != LUA_TNUMBER) return false; if (dostring(L, "a = test[nil]")) return false; -- 2.11.4.GIT