From: John L. <jr...@us...> - 2009-05-14 05:06:31
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv9404/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlstate.cpp wxlua_bind.cpp Log Message: Allow multiple inheritance in the bindings. Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.179 retrieving revision 1.180 diff -C2 -d -r1.179 -r1.180 *** wxlstate.cpp 24 Mar 2009 04:15:32 -0000 1.179 --- wxlstate.cpp 14 May 2009 05:06:21 -0000 1.180 *************** *** 1191,1194 **** --- 1191,1225 ---- // ---------------------------------------------------------------------------- + static int wxluaT_isderivedtype_recurser(const wxLuaBindClass *wxlClass, int base_wxl_type, int levels) + { + if (wxlClass != NULL) + { + if (*wxlClass->wxluatype == base_wxl_type) + return levels; + else if (wxlClass->baseclassNames != NULL) // check baseclass by baseclass + { + for (size_t i = 0; wxlClass->baseclassNames[i]; ++i) + { + // Note: base class may be NULL if lib/module containing it is not loaded + wxLuaBindClass* baseClass = wxlClass->baseBindClasses[i]; + + if (baseClass != NULL) + { + if (*baseClass->wxluatype == base_wxl_type) + return levels; + else + { + int ret = wxluaT_isderivedtype_recurser(baseClass, base_wxl_type, levels+1); + if (ret > -1) + return ret; + } + } + } + } + } + + return -1; // wxluatype is not derived from base_wxluatype + } + int LUACALL wxluaT_isderivedtype(lua_State* L, int wxl_type, int base_wxl_type) { *************** *** 1202,1217 **** const wxLuaBindClass *wxlClass = wxluaT_getclass(L, wxl_type); - int levels = 1; - - while (wxlClass != NULL) // check baseclass by baseclass - { - if (wxlClass->baseclass && (*wxlClass->baseclass->wxluatype == base_wxl_type)) - return levels; ! wxlClass = wxlClass->baseclass; ! ++levels; ! } ! ! return -1; // wxluatype is not derived from base_wxluatype } --- 1233,1238 ---- const wxLuaBindClass *wxlClass = wxluaT_getclass(L, wxl_type); ! return wxluaT_isderivedtype_recurser(wxlClass, base_wxl_type, 1); } *************** *** 1222,1237 **** return -1; ! const wxLuaBindClass* c = wxlClass; ! int levels = 0; ! while (c != NULL) ! { ! if (c->wxluatype == base_wxlClass->wxluatype) // comparing pointers ! return levels; ! ! c = c->baseclass; ! ++levels; ! } ! return -1; // wxlClass is not derived from wxlBaseClass } --- 1243,1251 ---- return -1; ! // These two types are the same ! if (wxlClass->wxluatype == base_wxlClass->wxluatype) // comparing pointers ! return 0; ! return wxluaT_isderivedtype_recurser(wxlClass, *base_wxlClass->wxluatype, 1); } Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.121 retrieving revision 1.122 diff -C2 -d -r1.121 -r1.122 *** wxlbind.cpp 8 Dec 2008 05:17:11 -0000 1.121 --- wxlbind.cpp 14 May 2009 05:06:21 -0000 1.122 *************** *** 1433,1436 **** --- 1433,1455 ---- // static + const wxLuaBindClass* wxLuaBinding::FindBindClass(const char* className) + { + wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst(); + + while (node) + { + wxLuaBinding* binding = node->GetData(); + const wxLuaBindClass* wxlClass = binding->GetBindClass(className); + + if (wxlClass) + return wxlClass; + + node = node->GetNext(); + } + + return NULL; + } + + // static const wxLuaBindClass* wxLuaBinding::FindBindClass(int wxluatype) { *************** *** 1549,1554 **** wxLuaBindMethodArrayCompareFnGet); ! if ((wxlMethod == NULL) && search_baseclasses && wxlClass->baseclass) ! return GetClassMethod(wxlClass->baseclass, methodName, method_type, search_baseclasses); #else --- 1568,1580 ---- wxLuaBindMethodArrayCompareFnGet); ! if ((wxlMethod == NULL) && search_baseclasses && wxlClass->baseclassNames) ! { ! for (size_t i = 0; wxlClass->baseclassNames[i]; ++i) ! { ! wxlMethod = GetClassMethod(wxlClass->baseBindClasses[i], methodName, method_type, search_baseclasses); ! if (wxlMethod != NULL) ! return wxlMethod; ! } ! } #else *************** *** 1577,1580 **** --- 1603,1642 ---- // -------------------------------------------------------------------------- + static void wxLuaBinding_RecurseBaseMethods(wxLuaBindClass* wxlClass, wxLuaBindMethod* wxlMethod, bool force_update) + { + // iterate through the base classes to find if this function is + // an overload, but only if we haven't checked already. + if (force_update || !WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_CHECKED_OVERLOAD|WXLUAMETHOD_DELETE)) + { + wxLuaBindMethod *parentMethod = wxlMethod; + + // Use the baseclassNames to check for terminating NULL + for (size_t i = 0; wxlClass->baseclassNames && wxlClass->baseclassNames[i]; ++i) + { + // Note that these may be NULL if the lib/module containing them wasn't loaded + wxLuaBindClass *baseClass = wxlClass->baseBindClasses[i]; + if (baseClass != NULL) + { + parentMethod->method_type |= WXLUAMETHOD_CHECKED_OVERLOAD; // have checked parent + + wxLuaBindMethod* baseMethod = wxLuaBinding::GetClassMethod(baseClass, wxlMethod->name, WXLUAMETHOD_SEARCH_MASK, false); + if (baseMethod) + { + // don't link to base class delete functions + if (!WXLUA_HASBIT(baseMethod->method_type, WXLUAMETHOD_DELETE)) + { + parentMethod->basemethod = baseMethod; + parentMethod = baseMethod; + } + + // we have already checked the base classes below this + if (!WXLUA_HASBIT(baseMethod->method_type, WXLUAMETHOD_CHECKED_OVERLOAD)) + wxLuaBinding_RecurseBaseMethods(baseClass, parentMethod, force_update); + } + } + } + } + } + // static void wxLuaBinding::InitAllBindings(bool force_update) *************** *** 1592,1596 **** } ! // setup base class wxLua types node = sm_bindingList.GetFirst(); while (node) --- 1654,1658 ---- } ! // set the base class wxLuaBindClass* using the base class names of the parent wxLuaBindClass node = sm_bindingList.GetFirst(); while (node) *************** *** 1602,1620 **** for (i = 0; i < class_count; ++i, ++wxlClass) { ! if (wxlClass->baseclassName) // does it have a name { ! wxLuaBindingList::compatibility_iterator basenode = sm_bindingList.GetFirst(); ! while (basenode) { ! wxLuaBinding* basebinding = basenode->GetData(); ! ! wxLuaBindClass* wxlBaseClass = (wxLuaBindClass*)basebinding->GetBindClass(wxlClass->baseclassName); if (wxlBaseClass) ! { ! wxlClass->baseclass = wxlBaseClass; ! break; ! } ! ! basenode = basenode->GetNext(); } } --- 1664,1675 ---- for (i = 0; i < class_count; ++i, ++wxlClass) { ! if (wxlClass->baseclassNames) // does it have any base classes at all? { ! // find the base class using their names in the bindings ! for (size_t j = 0; wxlClass->baseclassNames[j]; ++j) { ! wxLuaBindClass* wxlBaseClass = (wxLuaBindClass*)wxLuaBinding::FindBindClass(wxlClass->baseclassNames[j]); if (wxlBaseClass) ! wxlClass->baseBindClasses[j] = wxlBaseClass; } } *************** *** 1635,1639 **** for (i = 0; i < class_count; ++i, ++wxlClass) { ! if (wxlClass->baseclass) // does it have a base class at all? { wxLuaBindMethod *wxlMethod = wxlClass->wxluamethods; --- 1690,1694 ---- for (i = 0; i < class_count; ++i, ++wxlClass) { ! if (wxlClass->baseclassNames) // does it have any base classes at all? { wxLuaBindMethod *wxlMethod = wxlClass->wxluamethods; *************** *** 1642,1674 **** for (j = 0; j < method_count; ++j, ++wxlMethod) { ! // iterate through the base classes to find if this function is ! // an overload, but only if we haven't checked already. ! if (!WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_CHECKED_OVERLOAD|WXLUAMETHOD_DELETE)) ! { ! wxLuaBindClass *baseClass = wxlClass->baseclass; ! wxLuaBindMethod *parentMethod = wxlMethod; ! ! while (baseClass) ! { ! parentMethod->method_type |= WXLUAMETHOD_CHECKED_OVERLOAD; // have checked this ! ! wxLuaBindMethod* baseMethod = wxLuaBinding::GetClassMethod(baseClass, wxlMethod->name, WXLUAMETHOD_SEARCH_MASK, false); ! if (baseMethod) ! { ! // don't link to base class delete functions ! if (!WXLUA_HASBIT(baseMethod->method_type, WXLUAMETHOD_DELETE)) ! { ! parentMethod->basemethod = baseMethod; ! parentMethod = baseMethod; ! } ! ! // we have already checked the base classes below this ! if (WXLUA_HASBIT(baseMethod->method_type, WXLUAMETHOD_CHECKED_OVERLOAD)) ! break; ! } ! ! baseClass = baseClass->baseclass; ! } ! } } } --- 1697,1701 ---- for (j = 0; j < method_count; ++j, ++wxlMethod) { ! wxLuaBinding_RecurseBaseMethods(wxlClass, wxlMethod, force_update); } } Index: wxlua_bind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlua_bind.cpp,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** wxlua_bind.cpp 26 Mar 2008 05:01:33 -0000 1.30 --- wxlua_bind.cpp 14 May 2009 05:06:21 -0000 1.31 *************** *** 576,596 **** return 1; } ! else if (strcmp(idx_str, "baseclassName") == 0) { ! lua_pushstring(L, wxlClass->baseclassName); ! return 1; } ! else if (strcmp(idx_str, "baseclass") == 0) { ! if (wxlClass->baseclass) { ! const void **ptr = (const void **)lua_newuserdata(L, sizeof(void *)); ! *ptr = wxlClass->baseclass; ! lua_newtable(L); ! lua_pushstring(L, "__index"); ! lua_pushlightuserdata(L, wxlBinding); ! lua_pushcclosure(L, wxluabind_wxLuaBindClass__index, 1); // push func with tag as upvalue ! lua_rawset(L, -3); ! lua_setmetatable(L, -2); return 1; --- 576,619 ---- return 1; } ! else if (strcmp(idx_str, "baseclassNames") == 0) { ! if (wxlClass->baseclassNames) ! { ! lua_newtable(L); ! for (size_t i = 0; wxlClass->baseclassNames[i]; ++i) ! { ! lua_pushstring(L, wxlClass->baseclassNames[i]); ! lua_rawseti(L, -2, i + 1); ! } ! return 1; ! } ! ! return 0; } ! else if (strcmp(idx_str, "baseBindClasses") == 0) { ! if (wxlClass->baseBindClasses) { ! lua_newtable(L); ! for (size_t i = 0; wxlClass->baseclassNames[i]; ++i) // use names to check for terminating NULL ! { ! if (wxlClass->baseBindClasses[i] == NULL) // may be NULL if not loaded ! { ! lua_pushnil(L); ! } ! else ! { ! const void **ptr = (const void **)lua_newuserdata(L, sizeof(void *)); ! *ptr = wxlClass->baseBindClasses[i]; ! lua_newtable(L); ! lua_pushstring(L, "__index"); ! lua_pushlightuserdata(L, wxlBinding); ! lua_pushcclosure(L, wxluabind_wxLuaBindClass__index, 1); // push func with tag as upvalue ! lua_rawset(L, -3); ! lua_setmetatable(L, -2); ! } ! ! lua_rawseti(L, -2, i + 1); ! } return 1; *************** *** 805,808 **** --- 828,850 ---- lua_rawset(L, -3); + lua_pushstring(L, "wxLuaBindClass"); + const wxLuaBindClass* wxlClass = wxlBinding->GetBindClass(*wxlEvent->wxluatype); + if (wxlClass == NULL) + { + lua_pushnil(L); + } + else + { + const void **ptr = (const void **)lua_newuserdata(L, sizeof(void *)); + *ptr = wxlClass; + lua_newtable(L); + lua_pushstring(L, "__index"); + lua_pushlightuserdata(L, wxlBinding); + lua_pushcclosure(L, wxluabind_wxLuaBindClass__index, 1); // push func with tag as upvalue + lua_rawset(L, -3); + lua_setmetatable(L, -2); + } + lua_rawset(L, -3); + lua_rawseti(L, -2, idx + 1); } *************** *** 835,838 **** --- 877,899 ---- lua_rawset(L, -3); + lua_pushstring(L, "wxLuaBindClass"); + const wxLuaBindClass* wxlClass = wxlBinding->GetBindClass(*wxlObject->wxluatype); + if (wxlClass == NULL) + { + lua_pushnil(L); + } + else + { + const void **ptr = (const void **)lua_newuserdata(L, sizeof(void *)); + *ptr = wxlClass; + lua_newtable(L); + lua_pushstring(L, "__index"); + lua_pushlightuserdata(L, wxlBinding); + lua_pushcclosure(L, wxluabind_wxLuaBindClass__index, 1); // push func with tag as upvalue + lua_rawset(L, -3); + lua_setmetatable(L, -2); + } + lua_rawset(L, -3); + lua_rawseti(L, -2, idx + 1); } *************** *** 1049,1055 **** if (!wxlua_iswxluatype(l_type, WXLUA_TUSERDATA)) wxlua_argerror(L, 1, wxT("a 'userdata'")); ! void* o = wxlua_touserdata(L, 1, false); ! if (wxluaO_isgcobject(L, o)) { --- 1110,1116 ---- if (!wxlua_iswxluatype(l_type, WXLUA_TUSERDATA)) wxlua_argerror(L, 1, wxT("a 'userdata'")); ! void* o = wxlua_touserdata(L, 1, false); ! if (wxluaO_isgcobject(L, o)) { *************** *** 1140,1149 **** // --------------------------------------------------------------------------- wxLuaBindClass* wxLuaGetClassList_wxlua(size_t &count) { static wxLuaBindClass classList[] = { ! { "wxLuaObject", wxLuaObject_methods, wxLuaObject_methodCount, CLASSINFO(wxLuaObject), &wxluatype_wxLuaObject, "wxObject", NULL ,g_wxluanumberArray_None, 0, }, ! { "wxLuaState", wxLuaState_methods, wxLuaState_methodCount, CLASSINFO(wxLuaState), &wxluatype_wxLuaState, "wxObject", NULL ,g_wxluanumberArray_None, 0, }, { 0, 0, 0, 0, 0, 0, 0 }, --- 1201,1220 ---- // --------------------------------------------------------------------------- + static const char* wxluaclassname_wxLuaObject = "wxLuaObject"; + static const char* wxluaclassname_wxLuaState = "wxLuaState"; + static const char* wxluaclassname_wxObject = "wxObject"; + + static const char* wxluabaseclassnames_wxLuaObject[] = { wxluaclassname_wxObject, NULL }; + static wxLuaBindClass* wxluabaseclassbinds_wxLuaObject[] = { NULL }; + static const char* wxluabaseclassnames_wxLuaState[] = { wxluaclassname_wxObject, NULL }; + static wxLuaBindClass* wxluabaseclassbinds_wxLuaState[] = { NULL }; + + wxLuaBindClass* wxLuaGetClassList_wxlua(size_t &count) { static wxLuaBindClass classList[] = { ! { wxluaclassname_wxLuaObject, wxLuaObject_methods, wxLuaObject_methodCount, CLASSINFO(wxLuaObject), &wxluatype_wxLuaObject, wxluabaseclassnames_wxLuaObject, wxluabaseclassbinds_wxLuaObject, g_wxluanumberArray_None, 0, }, ! { wxluaclassname_wxLuaState, wxLuaState_methods, wxLuaState_methodCount, CLASSINFO(wxLuaState), &wxluatype_wxLuaState, wxluabaseclassnames_wxLuaState, wxluabaseclassbinds_wxLuaState, g_wxluanumberArray_None, 0, }, { 0, 0, 0, 0, 0, 0, 0 }, |