From: John L. <jr...@us...> - 2008-01-25 23:51:00
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv1159/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlstate.cpp wxlua_bind.cpp Log Message: - Removed the wxLuaBinding::PreRegister() and PostRegister() functions and made RegisterBinding() virtual Note: wxLuaBinding::RegisterBinding() now leaves the Lua table that the binding objects were installed into on the stack. You must pop it. * The rules.lua for genwxbind.lua now uses wxLuaBinding_class_declaration and wxLuaBinding_class_implementation to replace wxLuaBinding_preregister and wxLuaBinding_postregister. You may now add whatever you like to the class declaration and implementation source code. Updated to Lua 5.1.3 official Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.166 retrieving revision 1.167 diff -C2 -d -r1.166 -r1.167 *** wxlstate.cpp 24 Jan 2008 00:18:18 -0000 1.166 --- wxlstate.cpp 25 Jan 2008 23:50:53 -0000 1.167 *************** *** 2377,2381 **** // register our NULL type ! wxluatype_NULL = wxluaT_newmetatable(L, wxluatype_NULL); // now register bindings --- 2377,2382 ---- // register our NULL type ! //wxluatype_NULL = wxluaT_newmetatable(L, wxluatype_NULL); ! wxLuaBinding::InstallClassMetatable(L, &wxLuaBindClass_NULL); // now register bindings *************** *** 2770,2776 **** wxLuaBinding::InitAllBindings(); // only runs the first time through ! binding->RegisterBinding(*this); ! return true; } --- 2771,2778 ---- wxLuaBinding::InitAllBindings(); // only runs the first time through ! bool ret = binding->RegisterBinding(*this); ! if (ret) lua_Pop(1); ! return ret; } *************** *** 2786,2789 **** --- 2788,2793 ---- wxLuaBinding* binding = node->GetData(); binding->RegisterBinding(*this); + lua_Pop(1); // pop the Lua table the binding was installed into + node = node->GetNext(); } Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.118 retrieving revision 1.119 diff -C2 -d -r1.118 -r1.119 *** wxlbind.cpp 24 Jan 2008 00:18:17 -0000 1.118 --- wxlbind.cpp 25 Jan 2008 23:50:53 -0000 1.119 *************** *** 47,50 **** --- 47,53 ---- int wxluatype_NULL = WXLUA_TNULL; + wxLuaBindClass wxLuaBindClass_NULL = + { "NULL", NULL, 0, NULL, &wxluatype_NULL, NULL, NULL, g_wxluanumberArray_None, 0, }; + static int wxluatype_dummy = WXLUA_TUNKNOWN; int* p_wxluatype_wxEvent = &wxluatype_dummy; *************** *** 542,546 **** wxString name = wxluaT_typename(L, wxl_type); if (!name.IsEmpty()) ! str += wxString::Format(wxT(" [%s(%p, %d)]"), name.c_str(), wxlua_touserdata(L, 1, false), wxl_type); } else --- 545,556 ---- wxString name = wxluaT_typename(L, wxl_type); if (!name.IsEmpty()) ! { ! // GCC prints '(' for NULL %p for some reason. ! void* p = wxlua_touserdata(L, 1, false); ! if (p) ! str += wxString::Format(wxT(" [%s(%p, %d)]"), name.c_str(), p, wxl_type); ! else ! str += wxString::Format(wxT(" [%s(0x0, %d)]"), name.c_str(), wxl_type); ! } } else *************** *** 942,946 **** wxLuaBindingList wxLuaBinding::sm_bindingList; bool wxLuaBinding::sm_bindingList_initialized = false; ! int wxLuaBinding::sm_wxluatype_max = WXLUA_T_MAX; wxLuaBinding::wxLuaBinding() --- 952,956 ---- wxLuaBindingList wxLuaBinding::sm_bindingList; bool wxLuaBinding::sm_bindingList_initialized = false; ! int wxLuaBinding::sm_wxluatype_max = WXLUA_TNULL; // highest wxLua type initially wxLuaBinding::wxLuaBinding() *************** *** 1024,1030 **** } - // leave the table on the stack, it's the one we'll populate - int bind_table_idx = lua_gettop(L); - // Find a registered binding with the same namespace, if any, // and share the table with that of the previously loaded binding --- 1034,1037 ---- *************** *** 1069,1100 **** lua_pop(L, 1); // pop table - // Call the binding functions - PreRegister(wxlState, bind_table_idx); // register all our classes etc. in the wxLua table ! DoRegisterBinding(wxlState, bind_table_idx); ! PostRegister(wxlState, bind_table_idx); ! ! lua_pop(L, 1); // pop the table created above return true; } ! void wxLuaBinding::DoRegisterBinding(const wxLuaState& wxlState, int bind_table_idx) { - // Replace the metatable functions for the classes we push into Lua - static const luaL_reg s_funcTable[] = - { - {"__gc", wxlua_wxLuaBindClass__gc }, - {"__index", wxlua_wxLuaBindClass__index }, - {"__newindex", wxlua_wxLuaBindClass__newindex }, - {"__tostring", wxlua_wxLuaBindClass__tostring } - }; - static const size_t s_funcCount = sizeof(s_funcTable)/sizeof(s_funcTable[0]); - wxCHECK_RET(wxlState.Ok(), wxT("Invalid wxLuaState")); lua_State *L = wxlState.GetLuaState(); size_t n; - int wxl_type = WXLUA_TUNKNOWN; // install the classes, functions and methods, creating new wxLua types --- 1076,1091 ---- lua_pop(L, 1); // pop table // register all our classes etc. in the wxLua table ! DoRegisterBinding(wxlState); return true; } ! void wxLuaBinding::DoRegisterBinding(const wxLuaState& wxlState) const { wxCHECK_RET(wxlState.Ok(), wxT("Invalid wxLuaState")); lua_State *L = wxlState.GetLuaState(); size_t n; // install the classes, functions and methods, creating new wxLua types *************** *** 1103,1265 **** for (n = 0; n < m_classCount; ++n, ++wxlClass) { ! // ------------------------------------------------------------------ ! // Add to the lookup table for "class name" to wxLuaBindClass struct ! lua_pushlightuserdata(L, &wxlua_lreg_classes_key); ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the classes table) ! lua_pushstring(L, wxlClass->name); // push key ! lua_pushlightuserdata(L, (void *)wxlClass); // push value ! lua_rawset(L, -3); // set t[key] = value, pops key and value ! lua_pop(L, 1); // pop wxlua_lreg_classes_key table ! ! // ------------------------------------------------------------------ ! // Create a new metatable for this class with a numerical wxLua type index ! ! wxl_type = *wxlClass->wxluatype; ! ! // we may be reregistering this binding, get the old metatable, we'll rewrite it ! if (!wxluaT_getmetatable(L, wxl_type)) ! wxluaT_newmetatable(L, wxl_type); // create metatable, is on top of stack ! ! // store a lookup in the class metatable to the wxLuaBindClass struct ! lua_pushlightuserdata(L, &wxlua_metatable_wxluabindclass_key); // push key ! lua_pushlightuserdata(L, (void *)wxlClass); // push value ! lua_rawset(L, -3); // set t[key] = value, pops key and value ! ! // set the functions for the class in the metatable ! for (size_t i_func = 0; i_func < s_funcCount; ++i_func) ! { ! lua_pushstring(L, s_funcTable[i_func].name); // push method name ! lua_pushlightuserdata(L, (void *)wxlClass); // push the userdata ! lua_pushcclosure(L, s_funcTable[i_func].func, 1); // push func with wxlClass as upvalue ! lua_rawset(L, -3); // t["method_name"] = closure of func and upvalues ! } ! ! lua_pop(L, 1); // pop metatable from wxluaT_newmetatable() ! ! // ------------------------------------------------------------------ ! // Create and install the table for the class ! ! lua_pushstring(L, wxlClass->name); // push key ! lua_newtable(L); // push value, the table we use as the class ! ! // 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); ! } ! ! int method_count = wxlClass->wxluamethods_n; ! ! // Install the static functions for the classname table ! wxLuaBindMethod *wxlMethod = wxlClass->wxluamethods; ! for (int i_static_method = 0; i_static_method < method_count; ++i_static_method, ++wxlMethod) ! { ! // we will handle the WXLUAMETHOD_GET/SETPROP|WXLUAMETHOD_STATIC using __index and __newindex ! if (((wxlMethod->method_type & (WXLUAMETHOD_METHOD|WXLUAMETHOD_STATIC)) == (WXLUAMETHOD_METHOD|WXLUAMETHOD_STATIC)) && ! (wxlMethod->wxluacfuncs_n > 0)) ! { ! lua_pushstring(L, wxlMethod->name); ! lua_pushlightuserdata(L, wxlMethod); ! if (wxlMethod->wxluacfuncs_n > 1) ! lua_pushcclosure(L, wxlua_callOverloadedFunction, 1); ! else ! lua_pushcclosure(L, wxlMethod->wxluacfuncs[0].lua_cfunc, 1); ! ! lua_rawset(L, -3); ! } ! } ! ! // Create a metatable for the "class" table ! lua_newtable(L); ! lua_pushlstring(L, "__index", 7); ! lua_pushlightuserdata(L, wxlClass); ! lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__index, 1); ! lua_rawset(L, -3); ! ! lua_pushlstring(L, "__newindex", 10); ! lua_pushlightuserdata(L, wxlClass); ! lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__newindex, 1); ! lua_rawset(L, -3); ! ! //lua_pushstring(L, "__metatable"); ! //lua_pushstring(L, "Metatable is not accessible"); ! //lua_rawset(L, -3); ! lua_setmetatable(L, -2); // pops the metatable ! ! // Finalize the class table since we may not have a constructor ! // or have multiple constructors. ! lua_rawset(L, -3); // set t[key] = value, pops key and value ! ! // ------------------------------------------------------------------ ! // Install public functions like constructors or global functions ! wxlMethod = wxlClass->wxluamethods; ! for (int i_method = 0; i_method < method_count; ++i_method, ++wxlMethod) ! { ! if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_CONSTRUCTOR | WXLUAMETHOD_CFUNCTION) && wxlMethod->wxluacfuncs_n) ! { ! #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 ! // we do it this way since we can have multiple constructors (renamed) ! // that are of the same class and so they share the same wxLua type. ! lua_pushstring(L, wxlMethod->name); ! ! if (strcmp(wxlMethod->name, wxlClass->name) != 0) ! lua_newtable(L); ! else ! lua_getfield(L, bind_table_idx, wxlMethod->name); ! ! // add the items to the table as t[first pushed] = second pushed ! lua_pushlstring(L, "new", 3); ! lua_pushlightuserdata(L, wxlMethod); ! lua_pushcclosure(L, wxlua_callOverloadedFunction, 1); ! lua_rawset(L, -3); ! ! // Add __call to the metatable for this table ! bool has_meta = (lua_getmetatable(L, -1) != 0); ! if (!has_meta) lua_newtable(L); ! ! lua_pushlstring(L, "__call", 6); ! lua_pushlightuserdata(L, wxlMethod); ! lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__call, 1); ! lua_rawset(L, -3); ! ! //lua_pushstring(L, "__metatable"); ! //lua_pushstring(L, "Metatable is not accessible"); ! //lua_rawset(L, -3); ! ! if (!has_meta) ! lua_setmetatable(L, -2); ! else ! lua_pop(L, 1); ! ! // add table to the binding table t[wxlMethod->name] = { this table } ! lua_rawset(L, -3); // set t[key] = value, pops key and value ! ! #elif 0 // C++ constructors are userdata, use metatable for access to items. ! ! // This almost works, but we need to add __call to the metatable which means ! // that if you append () to any instance of this class you call the constructor. ! ! lua_pushstring(L, wxlMethod->name); ! ! const void **ptr = (const void **)lua_newuserdata(L, sizeof(void *)); ! *ptr = wxlClass; ! ! wxluaR_getref(L, iTag); ! lua_setmetatable(L, -2); ! ! lua_rawset(L, -3); ! ! #else // C++ class constructors are cfunctions only ! ! lua_pushstring(L, wxlMethod->name); ! lua_pushcfunction(L, wxlMethod->wxluacfuncs); ! lua_rawset(L, -3); ! #endif ! } ! } } --- 1094,1099 ---- for (n = 0; n < m_classCount; ++n, ++wxlClass) { ! InstallClassMetatable(L, wxlClass); ! InstallClass(L, wxlClass); } *************** *** 1316,1319 **** --- 1150,1313 ---- } + /* static */ + bool wxLuaBinding::InstallClassMetatable(lua_State* L, const wxLuaBindClass* wxlClass) + { + // Replace the metatable functions for the classes we push into Lua + static const luaL_reg s_funcTable[] = + { + {"__gc", wxlua_wxLuaBindClass__gc }, + {"__index", wxlua_wxLuaBindClass__index }, + {"__newindex", wxlua_wxLuaBindClass__newindex }, + {"__tostring", wxlua_wxLuaBindClass__tostring } + }; + static const size_t s_funcCount = sizeof(s_funcTable)/sizeof(s_funcTable[0]); + + // ------------------------------------------------------------------ + // Add to the lookup table for "class name" to wxLuaBindClass struct + lua_pushlightuserdata(L, &wxlua_lreg_classes_key); + lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the classes table) + lua_pushstring(L, wxlClass->name); // push key + lua_pushlightuserdata(L, (void *)wxlClass); // push value + lua_rawset(L, -3); // set t[key] = value, pops key and value + lua_pop(L, 1); // pop wxlua_lreg_classes_key table + + // ------------------------------------------------------------------ + // Create a new metatable for this class with a numerical wxLua type index + + int wxl_type = *wxlClass->wxluatype; + + // we may be reregistering this binding, get the old metatable, we'll rewrite it + if (!wxluaT_getmetatable(L, wxl_type)) + wxluaT_newmetatable(L, wxl_type); // create metatable, is on top of stack + + // store a lookup in the class metatable to the wxLuaBindClass struct + lua_pushlightuserdata(L, &wxlua_metatable_wxluabindclass_key); // push key + lua_pushlightuserdata(L, (void *)wxlClass); // push value + lua_rawset(L, -3); // set t[key] = value, pops key and value + + // set the functions for the class in the metatable + for (size_t i_func = 0; i_func < s_funcCount; ++i_func) + { + lua_pushstring(L, s_funcTable[i_func].name); // push method name + lua_pushlightuserdata(L, (void *)wxlClass); // push the userdata + lua_pushcclosure(L, s_funcTable[i_func].func, 1); // push func with wxlClass as upvalue + lua_rawset(L, -3); // t["method_name"] = closure of func and upvalues + } + + lua_pop(L, 1); // pop metatable from wxluaT_newmetatable() + + return true; + } + + /* static */ + bool wxLuaBinding::InstallClass(lua_State* L, const wxLuaBindClass* wxlClass) + { + // ------------------------------------------------------------------ + // Create and install the table for the class + + lua_pushstring(L, wxlClass->name); // push key + lua_newtable(L); // push value, the table we use as the class + + // 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); + } + + int method_count = wxlClass->wxluamethods_n; + + // Install the static functions for the classname table + wxLuaBindMethod *wxlMethod = wxlClass->wxluamethods; + for (int i_static_method = 0; i_static_method < method_count; ++i_static_method, ++wxlMethod) + { + // we will handle the WXLUAMETHOD_GET/SETPROP|WXLUAMETHOD_STATIC using __index and __newindex + if (((wxlMethod->method_type & (WXLUAMETHOD_METHOD|WXLUAMETHOD_STATIC)) == (WXLUAMETHOD_METHOD|WXLUAMETHOD_STATIC)) && + (wxlMethod->wxluacfuncs_n > 0)) + { + lua_pushstring(L, wxlMethod->name); + lua_pushlightuserdata(L, wxlMethod); + if (wxlMethod->wxluacfuncs_n > 1) + lua_pushcclosure(L, wxlua_callOverloadedFunction, 1); + else + lua_pushcclosure(L, wxlMethod->wxluacfuncs[0].lua_cfunc, 1); + + lua_rawset(L, -3); + } + } + + // Create a metatable for the "class" table + lua_newtable(L); + lua_pushlstring(L, "__index", 7); + lua_pushlightuserdata(L, (void*)wxlClass); + lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__index, 1); + lua_rawset(L, -3); + + lua_pushlstring(L, "__newindex", 10); + lua_pushlightuserdata(L, (void*)wxlClass); + lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__newindex, 1); + lua_rawset(L, -3); + + //lua_pushstring(L, "__metatable"); + //lua_pushstring(L, "Metatable is not accessible"); + //lua_rawset(L, -3); + lua_setmetatable(L, -2); // pops the metatable + + // Finalize the class table since we may not have a constructor + // or have multiple constructors. + lua_rawset(L, -3); // set t[key] = value, pops key and value + + // ------------------------------------------------------------------ + // Install public functions like constructors or global functions + wxlMethod = wxlClass->wxluamethods; + for (int i_method = 0; i_method < method_count; ++i_method, ++wxlMethod) + { + if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_CONSTRUCTOR | WXLUAMETHOD_CFUNCTION) && wxlMethod->wxluacfuncs_n) + { + // push name of nested table and create the table or use existing + // we do it this way since we can have multiple constructors (renamed) + // that are of the same class and so they share the same wxLua type. + lua_pushstring(L, wxlMethod->name); + + if (strcmp(wxlMethod->name, wxlClass->name) != 0) + lua_newtable(L); + else + lua_getfield(L, -2, wxlMethod->name); + + // add the items to the table as t[first pushed] = second pushed + lua_pushlstring(L, "new", 3); + lua_pushlightuserdata(L, wxlMethod); + lua_pushcclosure(L, wxlua_callOverloadedFunction, 1); + lua_rawset(L, -3); + + // Add __call to the metatable for this table + bool has_meta = (lua_getmetatable(L, -1) != 0); + if (!has_meta) lua_newtable(L); + + lua_pushlstring(L, "__call", 6); + lua_pushlightuserdata(L, wxlMethod); + lua_pushcclosure(L, wxlua_wxLuaBindMethod_table__call, 1); + lua_rawset(L, -3); + + //lua_pushstring(L, "__metatable"); + //lua_pushstring(L, "Metatable is not accessible"); + //lua_rawset(L, -3); + + if (!has_meta) + lua_setmetatable(L, -2); + else + lua_pop(L, 1); + + // add table to the binding table t[wxlMethod->name] = { this table } + lua_rawset(L, -3); // set t[key] = value, pops key and value + } + } + + return true; + } + + // --------------------------------------------------------------------------- + const wxLuaBindEvent* wxLuaBinding::GetBindEvent(wxEventType eventType_) const { Index: wxlua_bind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlua_bind.cpp,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** wxlua_bind.cpp 24 Jan 2008 00:18:18 -0000 1.22 --- wxlua_bind.cpp 25 Jan 2008 23:50:54 -0000 1.23 *************** *** 969,985 **** } ! void wxLuaBinding_wxlua::PreRegister(const wxLuaState& , int ) ! { ! } ! void wxLuaBinding_wxlua::PostRegister(const wxLuaState& wxlState, int luaTable) { ! wxCHECK_RET(wxlState.Ok(), wxT("Invalid wxLuaState")); lua_State* L = wxlState.GetLuaState(); lua_pushlstring(L, "NULL", 4); wxluaT_pushuserdatatype(L, NULL, wxluatype_NULL, true, true); ! lua_rawset(L, luaTable); // set t["NULL"] = userdata(NULL) w/ NULL tag } // --------------------------------------------------------------------------- --- 969,986 ---- } ! bool wxLuaBinding_wxlua::RegisterBinding(const wxLuaState& wxlState) { ! bool ret = wxLuaBinding::RegisterBinding(wxlState); ! lua_State* L = wxlState.GetLuaState(); lua_pushlstring(L, "NULL", 4); wxluaT_pushuserdatatype(L, NULL, wxluatype_NULL, true, true); ! lua_rawset(L, -3); // set t["NULL"] = userdata(NULL) w/ NULL tag ! ! return ret; } + // --------------------------------------------------------------------------- |