From: John L. <jr...@us...> - 2007-05-31 17:18:59
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv14219/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlstate.cpp Log Message: Huge changes, overloaded functions by default replace wx.wxNull with wx.NULL change WXLUA_VERSION and others with wxLUA_VERSION class member enums are part of class table static class member functions are part of class table %properties are generated on the fly ... and more, see docs/changelog.txt Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -d -r1.97 -r1.98 *** wxlstate.cpp 21 May 2007 01:07:59 -0000 1.97 --- wxlstate.cpp 31 May 2007 17:18:54 -0000 1.98 *************** *** 2176,2180 **** { int stack_tag = ttag(stack_idx); ! if ((M_WXLSTATEDATA->m_wxlStateData->m_wxluatag_wxLuaFunction == stack_tag) || IsDerivedClass(stack_tag, tag)) return true; --- 2176,2181 ---- { int stack_tag = ttag(stack_idx); ! if ((M_WXLSTATEDATA->m_wxlStateData->m_wxluatag_NULL == stack_tag) || // FIXME ! (M_WXLSTATEDATA->m_wxlStateData->m_wxluatag_wxLuaFunction == stack_tag) || IsDerivedClass(stack_tag, tag)) return true; *************** *** 2391,2400 **** WXLUAMETHOD* wxLuaState::GetLuaMethod(const WXLUACLASS *pClass, const char *cpIndex) { ! int i_method, method_count = pClass->num_methods; // find a method in the class, recurse through classes from which this class is derived. for (i_method = 0; i_method < method_count; ++i_method) { WXLUAMETHOD *pMethod = pClass->methods + i_method; ! if (((pMethod->type == LuaMethod) || (pMethod->type == LuaGetProp)) && (strcmp(pMethod->name, cpIndex) == 0)) { --- 2392,2401 ---- WXLUAMETHOD* wxLuaState::GetLuaMethod(const WXLUACLASS *pClass, const char *cpIndex) { ! int i_method, method_count = pClass->methods_n; // find a method in the class, recurse through classes from which this class is derived. for (i_method = 0; i_method < method_count; ++i_method) { WXLUAMETHOD *pMethod = pClass->methods + i_method; ! if (WXLUA_HASBIT(pMethod->type, WXLUAMETHOD_METHOD | WXLUAMETHOD_GETPROP) && (strcmp(pMethod->name, cpIndex) == 0)) { *************** *** 2403,2412 **** } ! // Try Base Class ! wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState")); ! ! const WXLUACLASS* pBaseClass = GetBaseLuaClass(*pClass->class_tag); ! if (pBaseClass) ! return GetLuaMethod(pBaseClass, cpIndex); return NULL; --- 2404,2409 ---- } ! if (pClass->baseclass) ! return GetLuaMethod(pClass->baseclass, cpIndex); return NULL; *************** *** 2417,2421 **** wxCHECK_MSG(pClass, NULL, wxT("Invalid WXLUACLASS in wxLuaState::GetLuaProperty")); ! int i_method, method_count = pClass->num_methods; // find a method in the class, recurse through classes from which this class is derived. for (i_method = 0; i_method < method_count; ++i_method) --- 2414,2418 ---- wxCHECK_MSG(pClass, NULL, wxT("Invalid WXLUACLASS in wxLuaState::GetLuaProperty")); ! int i_method, method_count = pClass->methods_n; // find a method in the class, recurse through classes from which this class is derived. for (i_method = 0; i_method < method_count; ++i_method) *************** *** 2424,2443 **** if (isLuaSetProp) { ! if ((pMethod->type == LuaSetProp) && (strcmp(pMethod->name, cpIndex) == 0)) return pMethod; } else { ! if ((pMethod->type == LuaGetProp) && (strcmp(pMethod->name, cpIndex) == 0)) return pMethod; } } ! // Try Base Class ! wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState")); ! ! const WXLUACLASS* pBaseClass = GetBaseLuaClass(*pClass->class_tag); ! if (pBaseClass) ! return GetLuaProperty(pBaseClass, cpIndex, isLuaSetProp); return NULL; --- 2421,2436 ---- if (isLuaSetProp) { ! if (WXLUA_HASBIT(pMethod->type, WXLUAMETHOD_SETPROP) && (strcmp(pMethod->name, cpIndex) == 0)) return pMethod; } else { ! if (WXLUA_HASBIT(pMethod->type, WXLUAMETHOD_GETPROP) && (strcmp(pMethod->name, cpIndex) == 0)) return pMethod; } } ! if (pClass->baseclass) ! return GetLuaProperty(pClass->baseclass, cpIndex, isLuaSetProp); return NULL; *************** *** 3220,3242 **** } // Redirect lua function call to 1 method from a list of overloaded functions ! int LUACALL wxLuaState::CallOverloadedFunction(struct WXLUAMETHOD* overloadedMethods, int overloadedMethodCount) { ! int i, j, arg; ! int bestMethod = -1; int invalidArg = -1; - int maxargs = -1; - int minargs = -1; // do nothing ! if (!overloadedMethods && (overloadedMethodCount == 0)) return 0; // get number of arguments called from lua int argCount = lua_GetTop(); int lua_argStart = 0; // for methods like pen:SetColour(0,0,0) first lua arg is the wxPen (eg. self) ! if (overloadedMethods[0].type == LuaMethod) { argCount--; --- 3213,3320 ---- } + + wxString wxLuaState::CreateMethodArgTagsMsg(struct WXLUAMETHOD* method) + { + wxCHECK_MSG(method, wxEmptyString, wxT("Invalid method table")); + + wxString fnOverloadList; + int i, arg, funcs_count = method->funcs_n; + WXLUAMETHOD_CFUNC* funcs = method->funcs; + + for (i = 0; i < funcs_count; i++) + { + wxString fnOverload = wxString::Format(wxT("%02d. %s("), (i+1), lua2wx(method->name).c_str()); + + for (arg = 0; arg < funcs[i].maxargs; arg++) + { + // optional args? + if ((funcs[i].minargs < funcs[i].maxargs) && (arg == funcs[i].minargs)) + { + fnOverload += wxT("["); + } + + if (arg > 0) + fnOverload += wxT(", "); + + int tag = (int)*(funcs[i].argtags[arg]); + + if (tag == s_wxluaarg_String) + { + fnOverload += wxT("string"); + } + else if (tag == s_wxluaarg_Boolean) + { + fnOverload += wxT("boolean"); + } + else if (tag == s_wxluaarg_Enumeration) + { + fnOverload += wxT("enum"); + } + else if (tag == s_wxluaarg_Number) + { + fnOverload += wxT("number"); + } + else if (tag == s_wxluaarg_LightUserData) + { + fnOverload += wxT("lightuserdata"); + } + else if (tag == s_wxluaarg_UserData) + { + fnOverload += wxT("userdata"); + } + else if (tag == s_wxluaarg_LuaTable) + { + fnOverload += wxT("luatable"); + } + else if (tag == s_wxluaarg_LuaFunction) + { + fnOverload += wxT("luafunction"); + } + else + { + fnOverload += GetLuaTagName(tag); + } + } + + // close optional args + if (funcs[i].minargs < funcs[i].maxargs) + { + fnOverload += wxT("]"); + } + + fnOverload += wxT(")"); + + fnOverloadList += fnOverload + wxT("\n"); + } + + return fnOverloadList; + } + // Redirect lua function call to 1 method from a list of overloaded functions ! int LUACALL wxLuaState::CallOverloadedFunction(struct WXLUAMETHOD* overloadedMethods) { ! wxCHECK_MSG(overloadedMethods, 0, wxT("Invalid overloaded method table")); ! ! int i, arg; int invalidArg = -1; // do nothing ! if (!overloadedMethods || (overloadedMethods->funcs_n < 1)) return 0; + bool remove_table = wxlua_removetableforcall(GetLuaState(), true); + // get number of arguments called from lua int argCount = lua_GetTop(); int lua_argStart = 0; + if (remove_table) + { + argCount--; + lua_argStart++; + } + // for methods like pen:SetColour(0,0,0) first lua arg is the wxPen (eg. self) ! if (WXLUA_HASBIT(overloadedMethods[0].type, WXLUAMETHOD_METHOD)) { argCount--; *************** *** 3244,3256 **** } // prepare overload function table WXLUAMETHOD** overloadFunctionTable = new WXLUAMETHOD*[overloadedMethodCount]; for (i = 0; i < overloadedMethodCount; i++) { ! if ((maxargs == -1) || (maxargs < overloadedMethods[i].maxargs)) ! maxargs = overloadedMethods[i].maxargs; ! if ((minargs == -1) || (minargs > overloadedMethods[i].minargs)) ! minargs = overloadedMethods[i].minargs; overloadFunctionTable[i] = (overloadedMethods+i); --- 3322,3335 ---- } + #if 0 // prepare overload function table WXLUAMETHOD** overloadFunctionTable = new WXLUAMETHOD*[overloadedMethodCount]; for (i = 0; i < overloadedMethodCount; i++) { ! if ((maxargs == -1) || (maxargs < *overloadedMethods[i].args[1])) ! maxargs = *overloadedMethods[i].args[1]; ! if ((minargs == -1) || (minargs > *overloadedMethods[i].args[0])) ! minargs = *overloadedMethods[i].args[0]; overloadFunctionTable[i] = (overloadedMethods+i); *************** *** 3264,3270 **** for (j = i + 1; j < overloadedMethodCount; j++) { ! if ((overloadFunctionTable[j]->minargs > overloadFunctionTable[i]->minargs) || ! (overloadFunctionTable[j]->minargs == overloadFunctionTable[i]->minargs) && ! (overloadFunctionTable[j]->maxargs > overloadFunctionTable[i]->maxargs)) { // swap order --- 3343,3349 ---- for (j = i + 1; j < overloadedMethodCount; j++) { ! if ((*overloadFunctionTable[j]->args[0] > *overloadFunctionTable[i]->args[0]) || ! (*overloadFunctionTable[j]->args[0] == *overloadFunctionTable[i]->args[0]) && ! (*overloadFunctionTable[j]->args[1] > *overloadFunctionTable[i]->args[1])) { // swap order *************** *** 3276,3389 **** } #endif ! for (i = 0; i < overloadedMethodCount; i++) { ! // does function version handle argCount Arguments? ! if (argCount >= overloadFunctionTable[i]->minargs) { ! bool match = true; ! for (arg = 0; arg < argCount; arg++) { ! // does this method have any more arguments? ! if (!overloadFunctionTable[i]->argtags || !overloadFunctionTable[i]->argtags[arg]) ! { ! match = false; ! break; ! } ! // get argument tag id ! int tag = (int)*(overloadFunctionTable[i]->argtags[arg]); ! int ltype = lua_Type(arg+1+lua_argStart); ! if (tag == s_wxluaarg_String) ! { ! if ((ltype != LUA_TNIL) && (ltype != LUA_TSTRING)) ! { ! match = false; ! break; ! } ! } ! else if (tag == s_wxluaarg_Boolean) ! { ! if ((ltype != LUA_TNIL) && (ltype != LUA_TBOOLEAN)) ! { ! match = false; ! break; ! } ! } ! else if (tag == s_wxluaarg_Enumeration) { ! if (ltype != LUA_TNUMBER) ! { ! match = false; ! break; ! } } ! else if (tag == s_wxluaarg_Number) { ! if ((ltype != LUA_TNIL) && (ltype != LUA_TNUMBER)) ! { ! match = false; ! break; ! } } ! else if (tag == s_wxluaarg_LightUserData) { ! if (!lua_IsLightUserData(arg+1+lua_argStart)) ! { ! match = false; ! break; ! } } ! else if (tag == s_wxluaarg_UserData) { ! if (!lua_IsUserData(arg+1+lua_argStart)) ! { ! match = false; ! break; ! } } ! else if (tag == s_wxluaarg_LuaTable) { ! if (!lua_IsTable(arg+1+lua_argStart)) ! { ! match = false; ! break; ! } } ! else if (tag == s_wxluaarg_LuaFunction) { ! if (!lua_IsFunction(arg+1+lua_argStart)) ! { ! match = false; ! break; ! } } ! else if (!IsUserDataType(arg+1+lua_argStart, tag)) { ! match = false; ! break; } } ! ! if (match) { ! lua_CFunction func = overloadFunctionTable[i]->func; ! ! // cleanup sorted overload function table ! delete []overloadFunctionTable; ! ! // successfully found overloaded function to handle wxLua call ! return (*func)(M_WXLSTATEDATA->m_lua_State); } ! ! if (invalidArg < arg) { ! bestMethod = i; ! invalidArg = arg; } } } lua_Debug ar; lua_GetStack(0, &ar); --- 3355,3488 ---- } #endif + #endif // 0 ! int overloadedMethodCount = overloadedMethods->funcs_n; ! WXLUAMETHOD_CFUNC* overloadFunctionTable = overloadedMethods->funcs; ! ! // only look at the methods that could possibly work ! wxArrayPtrVoid funcArray; ! for (i = 0; i < overloadedMethodCount; ++i) { ! if ((argCount >= overloadFunctionTable[i].minargs) && ! (argCount <= overloadFunctionTable[i].maxargs)) ! funcArray.Add(&overloadFunctionTable[i]); ! } ! ! WXLUAMETHOD_CFUNC* bestFunc = NULL; // store the last function that worked. ! ! // Look at the available functions in parallel, per arg ! for (arg = 0; arg < argCount; arg++) ! { ! if (funcArray.GetCount() == 0u) { ! arg--; ! break; ! } ! ! int ltype = lua_Type(arg+1+lua_argStart); ! ! for (i = 0; i < (int)funcArray.GetCount(); i++) ! { ! WXLUAMETHOD_CFUNC* func = (WXLUAMETHOD_CFUNC*)funcArray[i]; ! bestFunc = func; ! ! // does this method have any more arguments? ! if (!func->argtags || !func->argtags[arg]) { ! // this one won't work, try the next ! funcArray.RemoveAt(i); i--; ! continue; ! } ! // get argument tag id ! int tag = (int)*(func->argtags[arg]); ! //wxPrintf(wxT("ARG '%s' argCount %d arg %d ltype %d wxtype %d func_count %d, f# %d\n"), lua2wx(overloadedMethods->name).c_str(), argCount, arg, ltype, tag, funcArray.GetCount(), i); ! ! if (tag == s_wxluaarg_String) ! { ! if ((ltype != LUA_TNIL) && (ltype != LUA_TSTRING)) { ! funcArray.RemoveAt(i); i--; ! continue; } ! } ! else if (tag == s_wxluaarg_Boolean) ! { ! if ((ltype != LUA_TNIL) && (ltype != LUA_TBOOLEAN)) { ! funcArray.RemoveAt(i); i--; ! continue; } ! } ! else if (tag == s_wxluaarg_Enumeration) ! { ! if (ltype != LUA_TNUMBER) { ! funcArray.RemoveAt(i); i--; ! continue; } ! } ! else if (tag == s_wxluaarg_Number) ! { ! if ((ltype != LUA_TNIL) && (ltype != LUA_TNUMBER)) { ! funcArray.RemoveAt(i); i--; ! continue; } ! } ! else if (tag == s_wxluaarg_LightUserData) ! { ! if (!lua_IsLightUserData(arg+1+lua_argStart)) { ! funcArray.RemoveAt(i); i--; ! continue; } ! } ! else if (tag == s_wxluaarg_UserData) ! { ! if (!lua_IsUserData(arg+1+lua_argStart)) { ! funcArray.RemoveAt(i); i--; ! continue; } ! } ! else if (tag == s_wxluaarg_LuaTable) ! { ! if (!lua_IsTable(arg+1+lua_argStart)) { ! funcArray.RemoveAt(i); i--; ! continue; } } ! else if (tag == s_wxluaarg_LuaFunction) { ! if (!lua_IsFunction(arg+1+lua_argStart)) ! { ! funcArray.RemoveAt(i); i--; ! continue; ! } } ! else if (!IsUserDataType(arg+1+lua_argStart, tag) && ! (tag != M_WXLSTATEDATA->m_wxlStateData->m_wxluatag_NULL)) // FIXME! { ! funcArray.RemoveAt(i); i--; ! continue; } } } + if (funcArray.GetCount() != 0) + { + lua_CFunction func = ((WXLUAMETHOD_CFUNC*)funcArray[0])->func; + + // successfully found overloaded function to handle wxLua call + return (*func)(M_WXLSTATEDATA->m_lua_State); + } + + if (invalidArg < arg) + invalidArg = arg; + + lua_Debug ar; lua_GetStack(0, &ar); *************** *** 3442,3521 **** wxString fnOverloadList = wxT("wxLua Function Overload Table:\n"); ! for (i = 0; i < overloadedMethodCount; i++) ! { ! wxString fnOverload = wxString::Format(wxT("%02d. %s("), (i+1), name.c_str()); ! ! for (arg = 0; arg < overloadFunctionTable[i]->maxargs; arg++) ! { ! // optional args? ! if ((overloadFunctionTable[i]->minargs < overloadFunctionTable[i]->maxargs) && ! (arg == overloadFunctionTable[i]->minargs)) ! { ! fnOverload += wxT("["); ! } ! ! if (arg > 0) ! fnOverload += wxT(", "); ! ! int tag = (int)*(overloadFunctionTable[i]->argtags[arg]); ! ! if (tag == s_wxluaarg_String) ! { ! fnOverload += wxT("string"); ! } ! else if (tag == s_wxluaarg_Boolean) ! { ! fnOverload += wxT("boolean"); ! } ! else if (tag == s_wxluaarg_Enumeration) ! { ! fnOverload += wxT("enum"); ! } ! else if (tag == s_wxluaarg_Number) ! { ! fnOverload += wxT("number"); ! } ! else if (tag == s_wxluaarg_LightUserData) ! { ! fnOverload += wxT("lightuserdata"); ! } ! else if (tag == s_wxluaarg_UserData) ! { ! fnOverload += wxT("userdata"); ! } ! else if (tag == s_wxluaarg_LuaTable) ! { ! fnOverload += wxT("luatable"); ! } ! else if (tag == s_wxluaarg_LuaFunction) ! { ! fnOverload += wxT("luafunction"); ! } ! else ! { ! fnOverload += GetLuaTagName(tag); ! } ! } ! ! // close optional args ! if (overloadFunctionTable[i]->minargs < overloadFunctionTable[i]->maxargs) ! { ! fnOverload += wxT("]"); ! } ! ! fnOverload += wxT(")"); ! ! fnOverloadList += fnOverload + wxT("\n"); ! } ! ! // cleanup sorted overload function table ! delete [] overloadFunctionTable; wxString errmsg; ! if (bestMethod == -1) errmsg = wxString::Format(wxT("wxLua overloaded function %s has invalid argument\n%s"), fnCall.c_str(), fnOverloadList.c_str()); else ! errmsg = wxString::Format(wxT("wxLua overloaded function %s has invalid argument %d on method %02d\n%s"), fnCall.c_str(), (invalidArg+1), (bestMethod+1), fnOverloadList.c_str()); terror(errmsg); --- 3541,3559 ---- wxString fnOverloadList = wxT("wxLua Function Overload Table:\n"); ! fnOverloadList += CreateMethodArgTagsMsg(overloadedMethods); wxString errmsg; ! if (bestFunc == NULL) errmsg = wxString::Format(wxT("wxLua overloaded function %s has invalid argument\n%s"), fnCall.c_str(), fnOverloadList.c_str()); else ! { ! for (i = 0; i < overloadedMethodCount; i++) ! { ! if (&overloadFunctionTable[i] == bestFunc) ! break; ! } ! errmsg = wxString::Format(wxT("wxLua overloaded function %s has invalid argument %d on method %02d\n%s"), fnCall.c_str(), (invalidArg+1), (i+1), fnOverloadList.c_str()); ! } terror(errmsg); Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** wxlbind.cpp 21 May 2007 01:07:59 -0000 1.60 --- wxlbind.cpp 31 May 2007 17:18:54 -0000 1.61 *************** *** 20,23 **** --- 20,25 ---- #include "wxlua/include/wxlstate.h" + #include "wxluadebug/include/wxldebug.h" // for debugging only + #include "wx/listimpl.cpp" WX_DEFINE_LIST(wxLuaBindingList); *************** *** 31,34 **** --- 33,37 ---- wxLuaArgTag s_wxluaargArray_None[1] = {0}; + WXLUADEFINE s_wxluadefineArray_None[1] = {{0, 0}}; int s_wxluaarg_None = 0; *************** *** 51,55 **** // otherwise the colon notation *must* be used. lua_remove(L, 1); // remove the wxLuaFunction userdata from the stack ! return (*m_pMethod->func)(L); } --- 54,58 ---- // otherwise the colon notation *must* be used. lua_remove(L, 1); // remove the wxLuaFunction userdata from the stack ! return (*m_wxlMethod->funcs[0].func)(L); } *************** *** 81,84 **** --- 84,92 ---- { wxLuaFunction *pFunction = (wxLuaFunction *)wxlState.ttouserdata(1, false); + + // remove the userdata *this from the stack + if (pFunction->m_wxlMethod && WXLUA_HASBIT(pFunction->m_wxlMethod->type, WXLUAMETHOD_STATIC)) + lua_remove(L, 1); + return pFunction->CallMethod(L); } *************** *** 251,261 **** int retVal = 0; ! WXLUACLASS *pClass = (WXLUACLASS *)lua_touserdata(L, lua_upvalueindex(1)); //bool tracked = false; long key = -1; ! if ((pClass != NULL) && lua_isuserdata(L, 1) && ! (lua_islightuserdata(L, 1) == 0) && (wxlState.ttag(1) == *pClass->class_tag)) { key = (long)wxlState.ttouserdata(1, true); --- 259,269 ---- int retVal = 0; ! WXLUACLASS *wxlClass = (WXLUACLASS *)lua_touserdata(L, lua_upvalueindex(1)); //bool tracked = false; long key = -1; ! if ((wxlClass != NULL) && lua_isuserdata(L, 1) && ! (lua_islightuserdata(L, 1) == 0) && (wxlState.ttag(1) == *wxlClass->class_tag)) { key = (long)wxlState.ttouserdata(1, true); *************** *** 301,305 **** //wxPrintf(wxT("wxlua_garbageCollect - '%s' tag %d lua %d key %ld tracked %d return value %d\n"), ! // lua2wx(pClass ? pClass->name : "").c_str(), pClass ? *pClass->class_tag : 0, (int)L, key, (int)tracked, retVal); return retVal; --- 309,313 ---- //wxPrintf(wxT("wxlua_garbageCollect - '%s' tag %d lua %d key %ld tracked %d return value %d\n"), ! // lua2wx(wxlClass ? wxlClass->name : "").c_str(), wxlClass ? *wxlClass->class_tag : 0, (int)L, key, (int)tracked, retVal); return retVal; *************** *** 324,327 **** --- 332,340 ---- wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); + // This function is called for the __index metable of the wxLua userdata + // for class instances. The stack contains 1 = userdata, 2 = "FuncName" + // You cannot seem to get the calling convention (. or :) or if it was + // called as a function() or a .member? + // See below, if base_XXX is called then we set this flag so that // the called function knows to call the base class instead of recalling *************** *** 330,338 **** wxlState.SetCallBaseClassFunction(false); ! bool fCallbase = false; ! bool fFound = false; ! int result = 0; ! WXLUACLASS *pClass = (WXLUACLASS *)lua_touserdata(L, lua_upvalueindex(1)); ! const char *cpIndex = "{unknown}"; wxCharBuffer funcName; --- 343,351 ---- wxlState.SetCallBaseClassFunction(false); ! bool callbase = false; ! bool found = false; ! int result = 0; ! WXLUACLASS *wxlClass = (WXLUACLASS *)lua_touserdata(L, lua_upvalueindex(1)); ! const char *name = "{unknown}"; wxCharBuffer funcName; *************** *** 341,398 **** //int init_islightuserdata = lua_islightuserdata(L, 1); //int init_ttag = wxlState.ttag(1); ! //int init_class_tag = pClass ? *pClass->class_tag : -1; ! if ((pClass != NULL) && lua_isuserdata(L, 1) && ! (lua_islightuserdata(L, 1) == 0) && (wxlState.ttag(1) == *pClass->class_tag)) { void *pObject = wxlState.ttouserdata(1); funcName = lua_tostring(L, 2); // make a copy of the string ! cpIndex = funcName.data(); ! fCallbase = (memcmp(cpIndex, CALL_BASECLASS_FUNC, CALL_BASECLASS_FUNC_LEN) == 0); ! if (fCallbase) ! cpIndex += CALL_BASECLASS_FUNC_LEN; // skip past "base_" else { // if there's a derived method, push it onto the stack to be run ! if (wxlState.HasDerivedMethod(pObject, cpIndex, true)) { ! fFound = true; result = 1; } } ! if (!fFound) { ! WXLUAMETHOD *pMethod = wxlState.GetLuaMethod(pClass, cpIndex); ! if (pMethod != NULL) { ! if (pMethod->type == LuaGetProp) { lua_remove(L, 2); // remove the name of the function ! result = (*pMethod->func)(L); ! fFound = true; } else { ! wxLuaFunction *pFunction = new wxLuaFunction(pMethod, pClass, pObject); ! wxlState.tpushusertag(pFunction, wxlState.GetwxLuaFunctionTag()); result = 1; ! fFound = true; } } // This MUST be reset to false in the base class function ! if (fFound && fCallbase) wxlState.SetCallBaseClassFunction(true); } } //if (lua2wx(funcName).Find(wxT("OnBeginDocument")) != -1) ! // wxPrintf(wxT("wxlua_getTableFunc func '%s' pClass %d '%s', userdata %d, lightuserdata %d, ttag %d, class_tag %d lua_State %d wxLuaStateRefData %d call base %d\n"), ! // lua2wx(funcName).c_str(), (long)pClass, pClass ? lua2wx(pClass->name).c_str() : wxT(""), init_isuserdata, init_islightuserdata, init_ttag, init_class_tag, (long)L, (long)wxlState.GetRefData(), (int)wxlState.GetCallBaseClassFunction()); ! if (!fFound) ! wxlState.terror(wxString::Format(_("wxLua: Attempt to call an invalid method '%s'."), lua2wx(cpIndex).c_str())); return result; --- 354,431 ---- //int init_islightuserdata = lua_islightuserdata(L, 1); //int init_ttag = wxlState.ttag(1); ! //int init_class_tag = wxlClass ? *wxlClass->class_tag : -1; ! if ((wxlClass != NULL) && lua_isuserdata(L, 1) && ! (lua_islightuserdata(L, 1) == 0) && (wxlState.ttag(1) == *wxlClass->class_tag)) { void *pObject = wxlState.ttouserdata(1); funcName = lua_tostring(L, 2); // make a copy of the string ! name = funcName.data(); ! callbase = (memcmp(name, CALL_BASECLASS_FUNC, CALL_BASECLASS_FUNC_LEN) == 0); ! if (callbase) ! name += CALL_BASECLASS_FUNC_LEN; // skip past "base_" else { // if there's a derived method, push it onto the stack to be run ! if (wxlState.HasDerivedMethod(pObject, name, true)) { ! found = true; result = 1; } } ! if (!found) { ! WXLUAMETHOD* wxlMethod = wxlState.GetLuaMethod(wxlClass, name); ! if (wxlMethod != NULL) { ! if (WXLUA_HASBIT(wxlMethod->type, WXLUAMETHOD_GETPROP)) { + found = true; lua_remove(L, 2); // remove the name of the function ! result = (*wxlMethod->funcs[0].func)(L); } else { ! found = true; result = 1; ! wxLuaFunction *pFunction = new wxLuaFunction(wxlMethod, wxlClass, pObject); ! wxlState.tpushusertag(pFunction, wxlState.GetwxLuaFunctionTag()); ! } ! } ! ! // Maybe this is an undeclared property? Prepend 'Get' and try again. ! if (!found) ! { ! int len = strlen(name); ! wxCharBuffer buf(len + 4); ! char* str = buf.data(); ! str[0] = 'G'; str[1] = 'e'; str[2] = 't'; ! memcpy(str+3, name, len+1); // include terminating NULL ! ! wxlMethod = wxlState.GetLuaMethod(wxlClass, str); ! if ((wxlMethod != NULL) && (wxlMethod->type == WXLUAMETHOD_METHOD)) ! //wxlMethod->funcs && (wxlMethod->funcs->minargs == 0) && ! //(wxlMethod->funcs->maxargs == 0)) ! { ! found = true; ! lua_remove(L, 2); // remove the name of the function ! result = (*wxlMethod->funcs[0].func)(L); } } // This MUST be reset to false in the base class function ! if (found && callbase) wxlState.SetCallBaseClassFunction(true); } } //if (lua2wx(funcName).Find(wxT("OnBeginDocument")) != -1) ! // wxPrintf(wxT("wxlua_getTableFunc func '%s' wxlClass %d '%s', userdata %d, lightuserdata %d, ttag %d, class_tag %d lua_State %d wxLuaStateRefData %d call base %d\n"), ! // lua2wx(funcName).c_str(), (long)wxlClass, wxlClass ? lua2wx(wxlClass->name).c_str() : wxT(""), init_isuserdata, init_islightuserdata, init_ttag, init_class_tag, (long)L, (long)wxlState.GetRefData(), (int)wxlState.GetCallBaseClassFunction()); ! if (!found) ! wxlState.terror(wxString::Format(_("wxLua: Attempt to call an invalid method '%s'."), lua2wx(name).c_str())); return result; *************** *** 412,432 **** wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! WXLUACLASS *pClass = (WXLUACLASS *)lua_touserdata(L, lua_upvalueindex(1)); ! const char *cpIndex = lua_tostring(L, 2); ! //wxPrintf(wxT("wxlua_setTableFunc '%s'\n"), lua2wx(cpIndex).c_str()); ! if ((pClass != NULL) && lua_isuserdata(L, 1) && (lua_islightuserdata(L, 1) == 0) && ! (wxlState.ttag(1) == *pClass->class_tag)) { ! // See if there is a LuaSetProp in the WXLUACLASS's WXLUAMETHODs ! WXLUAMETHOD *pMethod = wxlState.GetLuaProperty(pClass, cpIndex, true); ! if (pMethod != NULL) { lua_remove(L, 2); ! (*pMethod->func)(L); } ! else { void *pObject = wxlState.ttouserdata(1); --- 445,490 ---- wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! WXLUACLASS *wxlClass = (WXLUACLASS *)lua_touserdata(L, lua_upvalueindex(1)); ! const char *name = lua_tostring(L, 2); ! bool found = false; ! //wxPrintf(wxT("wxlua_setTableFunc '%s'\n"), lua2wx(name).c_str()); ! if ((wxlClass != NULL) && lua_isuserdata(L, 1) && (lua_islightuserdata(L, 1) == 0) && ! (wxlState.ttag(1) == *wxlClass->class_tag)) { ! // See if there is a WXLUAMETHOD_SETPROP in the WXLUACLASS's WXLUAMETHODs ! WXLUAMETHOD *wxlMethod = wxlState.GetLuaProperty(wxlClass, name, true); ! if (wxlMethod != NULL) { + found = true; lua_remove(L, 2); ! (*wxlMethod->funcs[0].func)(L); } ! ! // Maybe this is an undeclared property? Prepend 'Set' and try again. ! if (!found) ! { ! int len = strlen(name); ! wxCharBuffer buf(len + 4); ! char* str = buf.data(); ! str[0] = 'S'; str[1] = 'e'; str[2] = 't'; ! memcpy(str+3, name, len+1); // include terminating NULL ! ! //wxPrintf(wxT("'%s' %d\n"), lua2wx(str).c_str(), lua_gettop(L)); ! //wxLuaCheckStack stk(L, wxT("wxlua_setTableFunc")); ! //stk.DumpStack(); ! ! wxlMethod = wxlState.GetLuaMethod(wxlClass, str); ! if ((wxlMethod != NULL) && (wxlMethod->type == WXLUAMETHOD_METHOD)) ! { ! found = true; ! lua_remove(L, 2); ! (*wxlMethod->funcs[0].func)(L); ! } ! } ! ! if (!found) { void *pObject = wxlState.ttouserdata(1); *************** *** 453,457 **** // see if there already is a method ! lua_pushstring( L, cpIndex ); lua_rawget(L, -2); --- 511,515 ---- // see if there already is a method ! lua_pushstring( L, name ); lua_rawget(L, -2); *************** *** 465,469 **** lua_pop(L, 1); // pop the deleted old object, or nil ! lua_pushstring( L, cpIndex ); lua_pushlightuserdata(L, (void*)wxlObj); lua_rawset(L, -3); --- 523,527 ---- lua_pop(L, 1); // pop the deleted old object, or nil ! lua_pushstring( L, name ); lua_pushlightuserdata(L, (void*)wxlObj); lua_rawset(L, -3); *************** *** 476,479 **** --- 534,549 ---- } + static int wxlua_checkremovetable = 0; + + int wxlua_removetableforcall(lua_State* L, bool only_check) + { + //void* p = (void *)lua_tocfunction(L, lua_upvalueindex(1)); + void* p = (void *)lua_touserdata(L, lua_upvalueindex(1)); + if (!only_check && (p == &wxlua_checkremovetable)) + lua_remove(L, 1); + + return p == &wxlua_checkremovetable; + } + // ---------------------------------------------------------------------------- // Function to compare to events by eventType *************** *** 532,535 **** --- 602,607 ---- lua_rawset(L, LUA_GLOBALSINDEX); } + else + lua_pop(L, 1); lua_pop(L, 1); *************** *** 632,636 **** for (size_t i_class = 0; i_class < m_classCount; ++i_class) { ! WXLUACLASS *pClass = m_classList + i_class; // Create a new tag if registering types, else use tag already set --- 704,708 ---- for (size_t i_class = 0; i_class < m_classCount; ++i_class) { ! WXLUACLASS *wxlClass = m_classList + i_class; // Create a new tag if registering types, else use tag already set *************** *** 638,650 **** { iTag = wxlState.tnewtag(); ! *pClass->class_tag = iTag; } else ! iTag = *pClass->class_tag; // store a lookup table for the class tags to WXLUACLASS structs ! wxlua_tget(L, *pClass->class_tag); lua_pushstring(L, "WXLUACLASS"); ! lua_pushlightuserdata(L, (void *)pClass); lua_rawset(L, -3); // t[name] = tag lua_remove(L, -1); // remove wxLua's registry wxLuaClasses table --- 710,722 ---- { iTag = wxlState.tnewtag(); ! *wxlClass->class_tag = iTag; } else ! iTag = *wxlClass->class_tag; // store a lookup table for the class tags to WXLUACLASS structs ! wxlua_tget(L, *wxlClass->class_tag); lua_pushstring(L, "WXLUACLASS"); ! lua_pushlightuserdata(L, (void *)wxlClass); lua_rawset(L, -3); // t[name] = tag lua_remove(L, -1); // remove wxLua's registry wxLuaClasses table *************** *** 654,659 **** lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the classes table) ! lua_pushstring(L, pClass->name); ! lua_pushlightuserdata(L, (void *)pClass); lua_rawset(L, -3); // t[name] = tag lua_remove(L, -1); // remove wxLua's registry wxLuaClasses table --- 726,731 ---- lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the classes table) ! lua_pushstring(L, wxlClass->name); ! lua_pushlightuserdata(L, (void *)wxlClass); lua_rawset(L, -3); // t[name] = tag lua_remove(L, -1); // remove wxLua's registry wxLuaClasses table *************** *** 662,696 **** for (size_t i_func = 0; i_func < s_funcCount; ++i_func) { ! wxlState.tsettagmethod(iTag, s_funcTable[i_func].name, s_funcTable[i_func].func, (void *)pClass); } ! // install public functions like constructors or global functions ! int i_method, method_count = pClass->num_methods; for (i_method = 0; i_method < method_count; ++i_method) { ! WXLUAMETHOD *pMethod = pClass->methods + i_method; ! if ((pMethod->type == LuaConstructor) || (pMethod->type == LuaGlobal)) { ! #if 0 // C++ class constructors are tables and use the __call metatable to make them "functions" ! // push name of nested table and create the table ! lua_pushstring(L, pMethod->name); ! lua_newtable(L); // add the items to the table as t[first pushed] = second pushed - lua_pushstring(L, "key"); - lua_pushstring(L, "value"); - lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") - lua_pushstring(L, "new"); ! lua_pushcfunction(L, pMethod->func); ! lua_rawset(L, -3); ! // Create the metatable for this table ! //luaL_newmetatable(L, pMethod->func); // we don't need to register it lua_newtable(L); lua_pushstring(L, "__call"); ! lua_pushcfunction(L, pMethod->func); lua_rawset(L, -3); --- 734,794 ---- for (size_t i_func = 0; i_func < s_funcCount; ++i_func) { ! wxlState.tsettagmethod(iTag, s_funcTable[i_func].name, s_funcTable[i_func].func, (void *)wxlClass); } ! ! int i_method, method_count = wxlClass->methods_n; ! ! // install the table for the class ! lua_pushstring(L, wxlClass->name); ! lua_newtable(L); ! ! // Install the member enums for the classname table ! for (int i_enum = 0; i_enum < wxlClass->enums_n; ++i_enum) ! { ! lua_pushstring(L, wxlClass->enums[i_enum].name); ! lua_pushnumber(L, wxlClass->enums[i_enum].value); ! lua_rawset(L, -3); ! } ! ! // Install the static functions for the classname table ! for (int i_static_method = 0; i_static_method < method_count; ++i_static_method) ! { ! if (WXLUA_HASBIT(wxlClass->methods[i_static_method].type, WXLUAMETHOD_STATIC)) ! { ! lua_pushstring(L, wxlClass->methods[i_static_method].name); ! lua_pushcfunction(L, wxlClass->methods[i_static_method].funcs[0].func); ! lua_rawset(L, -3); ! } ! } ! lua_rawset(L, -3); // same as lua_settable(L, tableOffset); ! ! // Install public functions like constructors or global functions for (i_method = 0; i_method < method_count; ++i_method) { ! WXLUAMETHOD *wxlMethod = wxlClass->methods + i_method; ! if (WXLUA_HASBIT(wxlMethod->type, WXLUAMETHOD_CONSTRUCTOR | WXLUAMETHOD_CFUNCTION)) { ! #if 1 // C++ class constructors are tables and use the __call metatable to make them "functions" ! // push name of nested table and create the table or use existing ! lua_pushstring(L, wxlMethod->name); ! if (strcmp(wxlMethod->name, wxlClass->name) != 0) ! lua_newtable(L); ! else ! lua_getfield(L, tableOffset, wxlMethod->name); // add the items to the table as t[first pushed] = second pushed lua_pushstring(L, "new"); ! lua_pushcfunction(L, wxlMethod->funcs[0].func); ! lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") // Create the metatable for this table ! //luaL_newmetatable(L, wxlMethod->func); // we don't need to register it lua_newtable(L); lua_pushstring(L, "__call"); ! //lua_pushcfunction(L, wxlMethod->func); ! lua_pushlightuserdata(L, &wxlua_checkremovetable); // push the method userdata ! lua_pushcclosure(L, wxlMethod->funcs[0].func, 1); // push func with func as upvalue lua_rawset(L, -3); *************** *** 701,713 **** lua_setmetatable(L, -2); ! // add table to the binding table t[pMethod->name] = { this table } lua_rawset(L, -3); // same as lua_settable(L, tableOffset); #elif 0 // C++ constructors are cfunctions, use metatable for access to items. ! lua_pushstring(L, pMethod->name); ! lua_pushcfunction(L, pMethod->func); // Create the metatable for this cfunction ! //luaL_newmetatable(L, pMethod->func); // we don't need to register it lua_newtable(L); --- 799,811 ---- lua_setmetatable(L, -2); ! // add table to the binding table t[wxlMethod->name] = { this table } lua_rawset(L, -3); // same as lua_settable(L, tableOffset); #elif 0 // C++ constructors are cfunctions, use metatable for access to items. ! lua_pushstring(L, wxlMethod->name); ! lua_pushcfunction(L, wxlMethod->func); // Create the metatable for this cfunction ! //luaL_newmetatable(L, wxlMethod->func); // we don't need to register it lua_newtable(L); *************** *** 721,724 **** --- 819,850 ---- lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") + + lua_pushstring(L, "key1"); + lua_pushstring(L, "value1"); + lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") + + + //set the table + lua_rawset(L, -3); + + + // create the t[__call] = { table } + lua_pushstring(L, "__call"); + lua_newtable(L); + + for (size_t i = 0; i < m_functionCount; ++i) + { + if (strcmp(m_functionList[i].name, "wxGetCwd") == 0) + { + wxPrintf(wxT("Adding wxGetCwd '%s' %p\n"), lua2wx(m_functionList[i].name).c_str(), m_functionList[i].func); + + lua_pushstring(L, m_functionList[i].name); + lua_pushcfunction(L, m_functionList[i].func); + lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") + + break; + } + } + //set the table lua_rawset(L, -3); *************** *** 734,740 **** #else // C++ class constructors are cfunctions only ! lua_pushstring(L, pMethod->name); ! lua_pushcfunction(L, pMethod->func); ! lua_rawset(L, tableOffset); #endif } --- 860,866 ---- #else // C++ class constructors are cfunctions only ! lua_pushstring(L, wxlMethod->name); ! lua_pushcfunction(L, wxlMethod->func); ! lua_rawset(L, -3); #endif } *************** *** 747,753 **** for (size_t i_func = 0; i_func < m_functionCount; ++i_func) { ! WXLUAMETHOD *pMethod = m_functionList + i_func; ! lua_pushstring(L, pMethod->name); ! lua_pushcfunction(L, pMethod->func); lua_rawset(L, tableOffset); } --- 873,879 ---- for (size_t i_func = 0; i_func < m_functionCount; ++i_func) { ! WXLUAMETHOD *wxlMethod = m_functionList + i_func; ! lua_pushstring(L, wxlMethod->name); ! lua_pushcfunction(L, wxlMethod->funcs[0].func); lua_rawset(L, tableOffset); } *************** *** 806,812 **** } ! bool wxLuaBinding::SetBaseClass(WXLUACLASS *pClass) { ! if (!pClass->baseclassName) // check if there is a baseclassName at all return false; --- 932,938 ---- } ! bool wxLuaBinding::SetBaseClass(WXLUACLASS *wxlClass) { ! if (!wxlClass->baseclassName) // check if there is a baseclassName at all return false; *************** *** 815,821 **** WXLUACLASS* baseClass = m_classList + n; // potential base class ! if (strcmp(baseClass->name, pClass->baseclassName) == 0) { ! pClass->baseclass = baseClass; return true; } --- 941,947 ---- WXLUACLASS* baseClass = m_classList + n; // potential base class ! if (strcmp(baseClass->name, wxlClass->baseclassName) == 0) { ! wxlClass->baseclass = baseClass; return true; } |