|
I wasn't enough clear so I'm going to start from the beginning. Here is what I want to do : register classes with their attributes, properties and functions. I have a reflexivity system so no problème do dynamcly create the tables. Here's what I do (I'm not really sure for all the step. I don't think I really get the whole thing of how works the metatables). So, when I want to register a class, I call this function : void gnScriptEngine::RegisterMetaType(gnMetaType const& a_rMetaType) { gnMetaClass const& rMetaClass = a_rMetaType.GetMetaClass(); //Get the class gnPrintA oPrint; gnSzA szClassName = gnStrConvert(rMetaClass.GetName().Sz(), oPrint); //Get the class name // MetaTable = {} luaL_newmetatable(m_pState, szClassName); //Create the main metatable of the classe int iMetaTable = lua_gettop(m_pState); // MetaTable.__index = MethodTable lua_pushliteral(m_pState, "__index"); // MetaTable "__index" lua_pushvalue(m_pState, iMetaTable); // MetaTable "__index" MetaTable lua_settable(m_pState, iMetaTable); // MetaTable // MetaTable.__gc = gc_account lua_pushliteral(m_pState, "__gc"); // MetaTable "__gc" lua_pushcfunction(m_pState, GarbageCollecting); // MetaTable "__gc" GarbageCollecting lua_settable(m_pState, iMetaTable); // MetaTable // MetaTable.__tostring = ToString lua_pushliteral(m_pState, "__tostring"); // MetaTable "__tostring" lua_pushcfunction(m_pState, ToString); // MetaTable "__tostring" ToString lua_settable(m_pState, iMetaTable); // MetaTable gnMetaFieldVector vMetaFields; rMetaClass.GetAllMetaFields(vMetaFields); //Get all the attributes of the class GN_FOREACH_IT_CONST(gnMetaFieldVector, vMetaFields, it) // == for each { gnIMetaField const& rMetaField = **it; gnPrintA oPrint; gnSzA szFieldName = gnStrConvert(rMetaField.GetName().Sz(), oPrint); //Get the name of the attribute //Push the name of the field (the key in the iMetaTable) lua_pushstring(m_pState, szFieldName); //push the name onto the stack //Create a new closure for each field gnPseudoField* pPseudoField = (gnPseudoField*)lua_newuserdata(m_pState, sizeof(gnPseudoField)); //create a new userdata from the pseudoField containing the attribute and its type gnAssertBase(pPseudoField != NULL, 0x4AA40200, "Allocation of new user data failed"); pPseudoField->m_rMetaField = rMetaField; pPseudoField->m_oMetaType = rMetaField.GetValueType(); lua_pushcfunction(m_pState, DispatchField); //push the function DispatchField onto the stack (this function do a get or a set depending of the stack) lua_settable(m_pState, iMetaTable); //affecte it to the metatable } vMetaFields.Clear(); //clear the list gnMetaMethodVector vMetaMethods; rMetaClass.GetAllMetaMethods(vMetaMethods); //get all the methods of the class GN_FOREACH_IT_CONST(gnMetaMethodVector, vMetaMethods, it) // == for each { gnIMetaMethod const& rMetaMethod = gnMetaClass::GetMetaMethod(it); get the method gnPrintA oPrint; gnSzA szMethodName = gnStrConvert(rMetaMethod.GetName().Sz(), oPrint); //get the name of the method lua_pushstring(m_pState, szMethodName); //push the name onto the stack // Create a new closure for each method (with the gnMetaMethod in it) gnPseudoMethod* pPseudoMethod = (gnPseudoMethod*)lua_newuserdata(m_pState, sizeof(gnPseudoMethod)); //create a new userdata from pseudoMethod containing the method gnAssertBase(pPseudoMethod != NULL, 0x64E80200, "Allocation of new user data failed"); pPseudoMethod->m_rMetaMethod = rMetaMethod; lua_pushcclosure(m_pState, DispatchMethod, 1); //push the function DispatchMethod onto the stack (this function call the method) // Affect the entry in the iMetaTable, and pop key and value lua_settable(m_pState, iMetaTable); } vMetaMethods.Clear(); // Drop MetaTable lua_pop(m_pState, 1); // Constructor gnBoxedMetaType* pBoxedMetaType = (gnBoxedMetaType*)lua_newuserdata(m_pState, sizeof(gnBoxedMetaType)); gnAssertBase(pBoxedMetaType != NULL, 0x58500200, "Allocation of new user data failed"); pBoxedMetaType->m_oMetaType = a_rMetaType; lua_pushcclosure(m_pState, New, 1); lua_setglobal(m_pState, szClassName); Finish ! So, all work but not the myObject.myAttribute. When I try to call "myObject.myAttribute, the DispatchField method is nerver called :( |