From: John L. <jr...@us...> - 2007-06-14 05:02:52
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv29717/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlstate.cpp wxlua_bind.cpp Log Message: Rename TLUA_NOTAG to WXLUA_NOTAG since it's only for wxLua Replace calls to lua_pushliteral with lua_pushlstring for better performance Change wxLuaState::Has/Get/SetDerivedMethods to C functions wxlua_has/get/setderivedmethods for a little better speed. Test wxLuaObject in unittest.wx.lua Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** wxlstate.cpp 14 Jun 2007 01:23:19 -0000 1.110 --- wxlstate.cpp 14 Jun 2007 05:02:48 -0000 1.111 *************** *** 79,84 **** if (lua_isuserdata(L, i) && wxlState.Ok()) { ! int nTag = wxlState.ttag(i); ! if (nTag != TLUA_NOTAG) { wxString name = wxlState.GetLuaTagName(nTag); --- 79,84 ---- if (lua_isuserdata(L, i) && wxlState.Ok()) { ! int nTag = wxlua_ttag(L, i); ! if (nTag != WXLUA_NOTAG) { wxString name = wxlState.GetLuaTagName(nTag); *************** *** 353,362 **** int LUACALL wxlua_ttag(lua_State *L, int stack_idx) { ! int tag = TLUA_NOTAG; if (lua_getmetatable(L, stack_idx) != 0) // see tnewtag { ! lua_pushliteral(L, "tag"); // get t["tag"] lua_rawget(L, -2); ! if (lua_isnumber(L, -1)) // FIXME this is really an error if this isn't true tag = (int)lua_tonumber(L, -1); --- 353,362 ---- int LUACALL wxlua_ttag(lua_State *L, int stack_idx) { ! int tag = WXLUA_NOTAG; if (lua_getmetatable(L, stack_idx) != 0) // see tnewtag { ! lua_pushlstring(L, "tag", 3); // get t["tag"] lua_rawget(L, -2); ! //if (lua_isnumber(L, -1)) // Note: lua_tonumber returns 0 == WXLUA_NOTAG if it's not a number tag = (int)lua_tonumber(L, -1); *************** *** 387,391 **** int tag = wxlua_tinsert(L, -1); // insert the table into the wxLuaReferences registry table ! lua_pushliteral(L, "tag"); // add t["tag"] = tag to new table lua_pushnumber(L, tag); lua_rawset(L, -3); --- 387,391 ---- int tag = wxlua_tinsert(L, -1); // insert the table into the wxLuaReferences registry table ! lua_pushlstring(L, "tag", 3); // add t["tag"] = tag to new table lua_pushnumber(L, tag); lua_rawset(L, -3); *************** *** 406,422 **** { if (weak_values) ! lua_pushliteral(L, "kv"); else ! lua_pushliteral(L, "k"); } else { if (weak_values) ! lua_pushliteral(L, "v"); else // yeah, we really shouldn't reach here lua_pushnil(L); } ! lua_pushliteral(L, "__mode"); lua_rawset(L, -3); // set mode of main table lua_setmetatable(L, -2); // via the metatable --- 406,422 ---- { if (weak_values) ! lua_pushlstring(L, "kv", 2); else ! lua_pushlstring(L, "k", 1); } else { if (weak_values) ! lua_pushlstring(L, "v", 1); else // yeah, we really shouldn't reach here lua_pushnil(L); } ! lua_pushlstring(L, "__mode", 6); lua_rawset(L, -3); // set mode of main table lua_setmetatable(L, -2); // via the metatable *************** *** 425,429 **** int tag = wxlua_tinsert(L, -1); // insert the table into the wxLuaReferences registry table ! lua_pushliteral(L, "tag"); // add t["tag"] = tag to new table lua_pushnumber(L, tag); lua_rawset(L, -3); --- 425,429 ---- int tag = wxlua_tinsert(L, -1); // insert the table into the wxLuaReferences registry table ! lua_pushlstring(L, "tag", 3); // add t["tag"] = tag to new table lua_pushnumber(L, tag); lua_rawset(L, -3); *************** *** 778,781 **** --- 778,930 ---- } + //---------------------------------------------------------------------------- + // Derived class member functions for classes in wxLua + //---------------------------------------------------------------------------- + + bool wxlua_setderivedmethod(lua_State* L, void *pObject, const char *method_name, wxLuaObject* wxlObj) + { + wxlua_pushstring_wxLuaDerivedMethods(L); + lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push table + + if (lua_istable(L, -1)) // else not installed or already removed? Not good in any case. + { + lua_pushlightuserdata(L, (void *)pObject); + lua_rawget(L, -2); // pop key, push table or nil + if (!lua_istable(L, -1)) + { + lua_pop(L, 1); // pop nil value + + // add new table for this object + lua_pushlightuserdata(L, (void *)pObject); + lua_newtable(L); + lua_rawset(L, -3); + + // put the new table back on the top of the stack + lua_pushlightuserdata(L, (void *)pObject); + lua_rawget(L, -2); + } + + // see if there already is a method + lua_pushstring( L, method_name ); + lua_rawget(L, -2); + + if (lua_islightuserdata(L, -1)) + { + // already have a method, delete it before replacing it + wxLuaObject* o = (wxLuaObject*)lua_touserdata( L, -1 ); + delete o; + } + + lua_pop(L, 1); // pop the deleted old object, or nil + + lua_pushstring( L, method_name ); + lua_pushlightuserdata(L, (void*)wxlObj); + lua_rawset(L, -3); + + lua_pop(L, 2); // pop the object and overridden function table + } + else + { + lua_pop(L, 1); // pop the nil reg table + wxlua_terror(L, "wxLua: The wxLuaDerivedMethods table in the registry is missing!"); + return false; + } + + return true; + } + bool wxlua_hasderivedmethod(lua_State* L, void *pObject, const char *method_name, bool push_method) + { + bool found = false; + + wxlua_pushstring_wxLuaDerivedMethods(L); + lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push table + + if (lua_istable(L, -1)) // else not installed or already removed? Not good in any case. + { + wxLuaObject* wxlObj = NULL; + + lua_pushlightuserdata(L, (void *)pObject); + lua_rawget(L, -2); // pop key, push table or nil + if (lua_istable(L, -1)) + { + // see if there is a method with the same name + lua_pushstring( L, method_name ); + lua_rawget(L, -2); + + if (lua_islightuserdata(L, -1)) + wxlObj = (wxLuaObject*)lua_touserdata( L, -1 ); + + lua_pop(L, 1); // pop the method object or nil + } + + lua_pop(L, 2); // pop registry table and object table or nil + + if (wxlObj != NULL) + { + if (push_method && wxlObj->GetObject()) + found = true; + else if (!push_method) + found = true; + } + } + else + { + lua_pop(L, 1); // pop the nil reg table + wxlua_terror(L, "wxLua: The wxLuaDerivedMethods table in the registry is missing!"); + return false; + } + + return found; + } + bool wxlua_removederivedmethod(lua_State* L, void *pObject) + { + bool found = false; + + wxlua_pushstring_wxLuaDerivedMethods(L); + lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push table + + if (lua_istable(L, -1)) // else not installed or already removed? Not good in any case. + { + lua_pushlightuserdata(L, (void *)pObject); + lua_rawget(L, -2); // pop key, push table or nil + if (lua_istable(L, -1)) + { + found = true; + int t = lua_gettop(L); + lua_pushnil(L); /* first key */ + while (lua_next(L, t) != 0) + { + // uses 'key' (at index -2) and 'value' (at index -1) + //wxPrintf(wxT("%s - %s\n"), lua2wx(lua_tostring(L, -2)).c_str(), lua2wx(lua_typename(L, lua_type(L, -1))).c_str()); + + if (lua_islightuserdata(L, -1)) + { + wxLuaObject* o = (wxLuaObject*)lua_touserdata(L, -1); + delete o; + } + + // removes 'value'; keeps 'key' for next iteration + lua_pop(L, 1); + } + + lua_pop(L, 1); // pop the obj table + lua_pushlightuserdata(L, (void *)pObject); + lua_pushnil(L); + lua_rawset(L, -3); // nil the obj table + lua_pop(L, 1); // pop reg table + } + else + lua_pop(L, 2); // pop the reg table and nil for the obj table + } + else + { + lua_pop(L, 1); // pop the nil reg table + wxlua_terror(L, "wxLua: The wxLuaDerivedMethods table in the registry is missing!"); + return false; + } + + return found; + } + // ---------------------------------------------------------------------------- // wxFindWindowByPointer - find a window by it's pointer *************** *** 2118,2122 **** int wxLuaState::ttag(int stack_idx) const { ! wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); return wxlua_ttag(M_WXLSTATEDATA->m_lua_State, stack_idx); } --- 2267,2271 ---- int wxLuaState::ttag(int stack_idx) const { ! wxCHECK_MSG(Ok(), WXLUA_NOTAG, wxT("Invalid wxLuaState")); return wxlua_ttag(M_WXLSTATEDATA->m_lua_State, stack_idx); } *************** *** 2130,2134 **** int wxLuaState::tnewtag() { ! wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); return wxlua_tnewtag(M_WXLSTATEDATA->m_lua_State); } --- 2279,2283 ---- int wxLuaState::tnewtag() { ! wxCHECK_MSG(Ok(), WXLUA_NOTAG, wxT("Invalid wxLuaState")); return wxlua_tnewtag(M_WXLSTATEDATA->m_lua_State); } *************** *** 2136,2140 **** int wxLuaState::tnewweaktag(bool weak_keys, bool weak_values) { ! wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); return wxlua_tnewweaktag(M_WXLSTATEDATA->m_lua_State, weak_keys, weak_values); } --- 2285,2289 ---- int wxLuaState::tnewweaktag(bool weak_keys, bool weak_values) { ! wxCHECK_MSG(Ok(), WXLUA_NOTAG, wxT("Invalid wxLuaState")); return wxlua_tnewweaktag(M_WXLSTATEDATA->m_lua_State, weak_keys, weak_values); } *************** *** 2188,2192 **** if (wxlua_iswxuserdata(L, stack_idx)) { ! int stack_tag = ttag(stack_idx); if ((GetLuaNULLTag() == stack_tag) || // FIXME, how to check when NULL is valid or not? (GetwxLuaFunctionTag() == stack_tag) || --- 2337,2341 ---- if (wxlua_iswxuserdata(L, stack_idx)) { ! int stack_tag = wxlua_ttag(L, stack_idx); if ((GetLuaNULLTag() == stack_tag) || // FIXME, how to check when NULL is valid or not? (GetwxLuaFunctionTag() == stack_tag) || *************** *** 2559,2616 **** } ! bool wxLuaState::SetDerivedMethod(void *pObject, const char *name, wxLuaObject* wxlObj) { wxCHECK_MSG(Ok() && pObject, false, wxT("Invalid wxLuaState or object to set derived method for.")); lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! wxlua_pushstring_wxLuaDerivedMethods(L); ! lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push table ! ! if (lua_istable(L, -1)) // else not installed or already removed? Not good in any case. ! { ! lua_pushlightuserdata(L, (void *)pObject); ! lua_rawget(L, -2); // pop key, push table or nil ! if (!lua_istable(L, -1)) ! { ! lua_pop(L, 1); // pop nil value ! ! // add new table for this object ! lua_pushlightuserdata(L, (void *)pObject); ! lua_newtable(L); ! lua_rawset(L, -3); ! ! // put the new table back on the top of the stack ! lua_pushlightuserdata(L, (void *)pObject); ! lua_rawget(L, -2); ! } ! ! // see if there already is a method ! lua_pushstring( L, name ); ! lua_rawget(L, -2); ! ! if (lua_islightuserdata(L, -1)) ! { ! // already have a method, delete it before replacing it ! wxLuaObject* o = (wxLuaObject*)lua_touserdata( L, -1 ); ! delete o; ! } ! ! lua_pop(L, 1); // pop the deleted old object, or nil ! ! lua_pushstring( L, name ); ! lua_pushlightuserdata(L, (void*)wxlObj); ! lua_rawset(L, -3); ! ! lua_pop(L, 2); // pop the object and overridden function table ! } ! else ! { ! lua_pop(L, 1); // pop the nil reg table ! terror("wxLua: The wxLuaDerivedMethods table in the registry is missing!"); ! return false; ! } ! ! return true; } --- 2708,2717 ---- } ! bool wxLuaState::SetDerivedMethod(void *pObject, const char *method_name, wxLuaObject* wxlObj) { wxCHECK_MSG(Ok() && pObject, false, wxT("Invalid wxLuaState or object to set derived method for.")); lua_State* L = M_WXLSTATEDATA->m_lua_State; ! return wxlua_setderivedmethod(L, pObject, method_name, wxlObj); } *************** *** 2620,2664 **** lua_State* L = M_WXLSTATEDATA->m_lua_State; ! bool found = false; ! ! wxlua_pushstring_wxLuaDerivedMethods(L); ! lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push table ! ! if (lua_istable(L, -1)) // else not installed or already removed? Not good in any case. ! { ! wxLuaObject* wxlObj = NULL; ! ! lua_pushlightuserdata(L, (void *)pObject); ! lua_rawget(L, -2); // pop key, push table or nil ! if (lua_istable(L, -1)) ! { ! // see if there is a method with the same name ! lua_pushstring( L, method_name ); ! lua_rawget(L, -2); ! ! if (lua_islightuserdata(L, -1)) ! wxlObj = (wxLuaObject*)lua_touserdata( L, -1 ); ! ! lua_pop(L, 1); // pop the method object or nil ! } ! ! lua_pop(L, 2); // pop registry table and object table or nil ! ! if (wxlObj != NULL) ! { ! if (push_method && wxlObj->GetObject()) ! found = true; ! else if (!push_method) ! found = true; ! } ! } ! else ! { ! lua_pop(L, 1); // pop the nil reg table ! terror("wxLua: The wxLuaDerivedMethods table in the registry is missing!"); ! return false; ! } ! ! return found; } --- 2721,2725 ---- lua_State* L = M_WXLSTATEDATA->m_lua_State; ! return wxlua_hasderivedmethod(L, pObject, method_name, push_method); } *************** *** 2668,2717 **** lua_State* L = M_WXLSTATEDATA->m_lua_State; ! bool found = false; ! ! wxlua_pushstring_wxLuaDerivedMethods(L); ! lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push table ! ! if (lua_istable(L, -1)) // else not installed or already removed? Not good in any case. ! { ! lua_pushlightuserdata(L, (void *)pObject); ! lua_rawget(L, -2); // pop key, push table or nil ! if (lua_istable(L, -1)) ! { ! found = true; ! int t = lua_gettop(L); ! lua_pushnil(L); /* first key */ ! while (lua_next(L, t) != 0) ! { ! // uses 'key' (at index -2) and 'value' (at index -1) ! //wxPrintf(wxT("%s - %s\n"), lua2wx(lua_tostring(L, -2)).c_str(), lua2wx(lua_typename(L, lua_type(L, -1))).c_str()); ! ! if (lua_islightuserdata(L, -1)) ! { ! wxLuaObject* o = (wxLuaObject*)lua_touserdata(L, -1); ! delete o; ! } ! ! // removes 'value'; keeps 'key' for next iteration ! lua_pop(L, 1); ! } ! ! lua_pop(L, 1); // pop the obj table ! lua_pushlightuserdata(L, (void *)pObject); ! lua_pushnil(L); ! lua_rawset(L, -3); // nil the obj table ! lua_pop(L, 1); // pop reg table ! } ! else ! lua_pop(L, 2); // pop the reg table and nil for the obj table ! } ! else ! { ! lua_pop(L, 1); // pop the nil reg table ! terror("wxLua: The wxLuaDerivedMethods table in the registry is missing!"); ! return false; ! } ! ! return found; } --- 2729,2733 ---- lua_State* L = M_WXLSTATEDATA->m_lua_State; ! return wxlua_removederivedmethod(L, pObject); } *************** *** 3731,3735 **** //----------------------------------------------------------------------------- ! // This is the code copied directly from lbitlib.c and ever so slightly modified // to allow it to work here. --- 3747,3751 ---- //----------------------------------------------------------------------------- ! // This is the code copied directly from lbitlib.c and ever so slightly modified // to allow it to work here. Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** wxlbind.cpp 13 Jun 2007 04:15:29 -0000 1.74 --- wxlbind.cpp 14 Jun 2007 05:02:48 -0000 1.75 *************** *** 67,73 **** wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! if (wxlua_iswxuserdata(L, 1) && (wxlState.ttag(1) == wxlState.GetwxLuaFunctionTag())) { ! wxLuaFunction *wxlFunction = (wxLuaFunction *)wxlState.ttouserdata(1, true); if (wxlFunction != NULL) delete wxlFunction; --- 67,73 ---- wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! if (wxlua_iswxuserdata(L, 1) && (wxlua_ttag(L, 1) == wxlState.GetwxLuaFunctionTag())) { ! wxLuaFunction *wxlFunction = (wxLuaFunction *)wxlua_ttouserdata(L, 1, true); if (wxlFunction != NULL) delete wxlFunction; *************** *** 81,87 **** wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! if (wxlua_iswxuserdata(L, 1) && (wxlState.ttag(1) == wxlState.GetwxLuaFunctionTag())) { ! wxLuaFunction *wxlFunction = (wxLuaFunction *)wxlState.ttouserdata(1, false); // remove the userdata *this from the stack --- 81,87 ---- wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! if (wxlua_iswxuserdata(L, 1) && (wxlua_ttag(L, 1) == wxlState.GetwxLuaFunctionTag())) { ! wxLuaFunction *wxlFunction = (wxLuaFunction *)wxlua_ttouserdata(L, 1, false); // remove the userdata *this from the stack *************** *** 240,258 **** int LUACALL wxluabind_garbageCollect(lua_State *L) { - wxLuaState wxlState(L); - wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); - wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1)); long key = -1; ! if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxlState.ttag(1) == *wxlClass->class_tag)) { ! key = (long)wxlState.ttouserdata(1, true); wxCHECK_MSG(key != 0, 0, wxT("NULL user data in wxluabind_garbageCollect")); wxlState.RemoveTrackedObject((void*)key, true); ! wxlState.RemoveDerivedMethod((void*)key); } --- 240,258 ---- int LUACALL wxluabind_garbageCollect(lua_State *L) { wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1)); long key = -1; ! if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxlua_ttag(L, 1) == *wxlClass->class_tag)) { ! wxLuaState wxlState(L); ! wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! ! key = (long)wxlua_ttouserdata(L, 1, true); wxCHECK_MSG(key != 0, 0, wxT("NULL user data in wxluabind_garbageCollect")); wxlState.RemoveTrackedObject((void*)key, true); ! wxlua_removederivedmethod(L, (void*)key); } *************** *** 292,298 **** const char *name = NULL; ! if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxlState.ttag(1) == *wxlClass->class_tag)) { ! void *pObject = wxlState.ttouserdata(1); name = lua_tostring(L, 2); // name of the __index method called in lua --- 292,298 ---- const char *name = NULL; ! if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxlua_ttag(L, 1) == *wxlClass->class_tag)) { ! void *pObject = wxlua_ttouserdata(L, 1); name = lua_tostring(L, 2); // name of the __index method called in lua *************** *** 304,308 **** { // if there's a derived method, push it onto the stack to be run ! if (wxlState.HasDerivedMethod(pObject, name, true)) { found = true; --- 304,308 ---- { // if there's a derived method, push it onto the stack to be run ! if (wxlua_hasderivedmethod(L, pObject, name, true)) { found = true; *************** *** 327,331 **** result = 1; wxLuaFunction *wxlFunc = new wxLuaFunction(wxlMethod, wxlClass, pObject); ! wxlState.tpushusertag(wxlFunc, wxlState.GetwxLuaFunctionTag()); } } --- 327,331 ---- result = 1; wxLuaFunction *wxlFunc = new wxLuaFunction(wxlMethod, wxlClass, pObject); ! wxlua_tpushusertag(L, wxlFunc, wxlState.GetwxLuaFunctionTag()); } } *************** *** 382,386 **** bool found = false; ! if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxlState.ttag(1) == *wxlClass->class_tag)) { // See if there is a WXLUAMETHOD_SETPROP in the wxLuaBindClass's wxLuaBindMethods --- 382,386 ---- bool found = false; ! if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxlua_ttag(L, 1) == *wxlClass->class_tag)) { // See if there is a WXLUAMETHOD_SETPROP in the wxLuaBindClass's wxLuaBindMethods *************** *** 413,419 **** if (!found) { ! void *pObject = wxlState.ttouserdata(1); wxLuaObject* wxlObj = new wxLuaObject(wxlState, 3); ! wxlState.SetDerivedMethod(pObject, name, wxlObj); } } --- 413,419 ---- if (!found) { ! void *pObject = wxlua_ttouserdata(L, 1); wxLuaObject* wxlObj = new wxLuaObject(wxlState, 3); ! wxlua_setderivedmethod(L, pObject, name, wxlObj); } } Index: wxlua_bind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlua_bind.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** wxlua_bind.cpp 14 Jun 2007 01:23:19 -0000 1.1 --- wxlua_bind.cpp 14 Jun 2007 05:02:48 -0000 1.2 *************** *** 177,181 **** // int wxluaarg_tag int wxluaarg_tag = wxlua_ttag(L, 1); ! if (wxluaarg_tag == TLUA_NOTAG) { int ltype = lua_type(L, 1); --- 177,181 ---- // int wxluaarg_tag int wxluaarg_tag = wxlua_ttag(L, 1); ! if (wxluaarg_tag == WXLUA_NOTAG) { int ltype = lua_type(L, 1); |