lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

I'm trying to wrap C++ object.
Currently, I can call C++ constructors, destructors and methods on object but I can't call attributes in lua like : myObject.myAttribute (can't call the get or the set)

Here's my code :

gnMetaClass const& rMetaClass = a_rMetaType.GetMetaClass();

    gnPrintA oPrint;
    gnSzA szClassName = gnStrConvert(rMetaClass.GetName().Sz(), oPrint);

    // MetaTable = {}
    luaL_newmetatable(m_pState, szClassName);                // MetaTable
    int iMetaTable = lua_gettop(m_pState);

    // 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

    // MetaTable.__index = MethodTable
    lua_pushliteral(m_pState, "__index");                    // MetaTable "__index"
    lua_pushvalue(m_pState, iMetaTable);                    // MetaTable "__index" MetaTable
    lua_settable(m_pState, iMetaTable);                        // MetaTable

    gnMetaFieldVector vMetaFields;
    rMetaClass.GetAllMetaFields(vMetaFields);

    GN_FOREACH_IT_CONST(gnMetaFieldVector, vMetaFields, it)
    {
        gnIMetaField const& rMetaField = **it;
       
        gnPrintA oPrint;
        gnSzA szFieldName = gnStrConvert(rMetaField.GetName().Sz(), oPrint);

        //Push the name of the field (the key in the iMetaTable)
        lua_pushstring(m_pState, szFieldName);
       
        //Create a new closure for each field
        gnPseudoField* pPseudoField = (gnPseudoField*)lua_newuserdata(m_pState, sizeof(gnPseudoField));
        gnAssertBase(pPseudoField != NULL, 0x4AA40200, "Allocation of new user data failed");
        pPseudoField->m_rMetaField = rMetaField;            // MetaTable szMethodName rMetaMethod
       
        //gnIMetaMethod const& rMetaMethod = gnMetaClass::GetMetaAttribute::G(it);


        //        // MetaTable szMethodName Dispatch
        //lua_pushlightuserdata(m_pState, (void*)pPseudoField);
        lua_pushcclosure(m_pState, DispatchField, 1);   
        // Affect the entry in the iMetaTable, and pop key and value
        lua_settable(m_pState, iMetaTable);                    // MetaTable
    }

    vMetaFields.Clear();


    // Drop MetaTable
    //lua_pop(m_pState, 1);

    //lua_newtable(m_pState);
    //iMetaTable = lua_gettop(m_pState);
    //iMetaTable = lua_gettop(m_pState);
    // Fill method table with methods from class T
    gnMetaMethodVector vMetaMethods;

    rMetaClass.GetAllMetaMethods(vMetaMethods);
    GN_FOREACH_IT_CONST(gnMetaMethodVector, vMetaMethods, it)
    {
        gnIMetaMethod const& rMetaMethod = gnMetaClass::GetMetaMethod(it);

        gnPrintA oPrint;
        gnSzA szMethodName = gnStrConvert(rMetaMethod.GetName().Sz(), oPrint);

        // Push the name of the method (ie the key in the iMetaTable)
        lua_pushstring(m_pState, szMethodName);                // MetaTable szMethodName

        // Create a new closure for each method (with the gnMetaMethod in it)
        gnPseudoMethod* pPseudoMethod = (gnPseudoMethod*)lua_newuserdata(m_pState, sizeof(gnPseudoMethod));
        gnAssertBase(pPseudoMethod != NULL, 0x64E80200, "Allocation of new user data failed");
        pPseudoMethod->m_rMetaMethod = rMetaMethod;            // MetaTable szMethodName rMetaMethod
        lua_pushcclosure(m_pState, DispatchMethod, 1);            // MetaTable szMethodName Dispatch
       
        // Affect the entry in the iMetaTable, and pop key and value
        lua_settable(m_pState, iMetaTable);                    // MetaTable
    }

    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);

Does anyone could help me ?

Thanks,

Tim