Exemplo n.º 1
0
void lualoom_pushnative_userdata(lua_State *L, Type *type, int nativeIdx)
{
    nativeIdx = lua_absindex(L, nativeIdx);

    lmAssert(lua_isuserdata(L, nativeIdx), "Internal Error: userdata expected in lsr_instancewrapnative");

    if (type->isNativeManaged())
    {
        lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMANAGEDNATIVESCRIPT);
        lua_pushvalue(L, nativeIdx);
        lua_gettable(L, -2);
        lmAssert(lua_istable(L, -1), "Internal Error: Unable to get managed native for return value");
        lua_remove(L, -2); // remove managed table
        return;
    }

    nativeIdx = lua_absindex(L, nativeIdx);

    lua_newtable(L);
    int instanceIdx = lua_gettop(L);

    lsr_getclasstable(L, type);
    lua_rawseti(L, instanceIdx, LSINDEXCLASS);

    lua_pushlightuserdata(L, type);
    lua_rawseti(L, instanceIdx, LSINDEXTYPE);

    lua_pushvalue(L, nativeIdx);
    lua_rawseti(L, instanceIdx, LSINDEXNATIVE);

    // set meta table
    luaL_getmetatable(L, LSINSTANCE);
    lua_setmetatable(L, instanceIdx);
}
Exemplo n.º 2
0
void LSLuaState::getClassTable(Type *type)
{
    lsr_getclasstable(L, type);
}
Exemplo n.º 3
0
void lualoom_downcastnativeinstance(lua_State *L, int instanceIdx, Type *fromType, Type *toType)
{
    // ensure that we match
    lmAssert(fromType->isNativeManaged() == toType->isNativeManaged(), "lualoom_downcastnativeinstance - managed/non-managed downcast mixmatch from type %s to type %s", fromType->getFullName().c_str(), toType->getFullName().c_str());
    lmAssert(fromType != toType, "lualoom_downcastnativeinstance - downcasting identical type %s to type %s", fromType->getFullName().c_str(), toType->getFullName().c_str());
    lmAssert(toType->isDerivedFrom(fromType), "lualoom_downcastnativeinstance - downcasting unrelated type %s to type %s", fromType->getFullName().c_str(), toType->getFullName().c_str());
    lmAssert(!toType->isInterface() && !fromType->isInterface(), "lualoom_downcastnativeinstance - downcasting interface type in cast type %s to type %s", fromType->getFullName().c_str(), toType->getFullName().c_str());

    int top = lua_gettop(L);

    NativeTypeBase *nativeType = NativeInterface::getNativeType(toType);

    // replace the class table with the downcast table
    lsr_getclasstable(L, toType);
    lua_rawseti(L, instanceIdx, LSINDEXCLASS);

    // replace the type
    lua_pushlightuserdata(L, toType);
    lua_rawseti(L, instanceIdx, LSINDEXTYPE);

    // get the current user data
    lua_rawgeti(L, instanceIdx, LSINDEXNATIVE);

    bool managed = fromType->isNativeManaged();

    if (managed)
    {
        // if we're managed we need to clear original userdata
        // from managed -> script table
        lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMANAGEDNATIVESCRIPT);
        lua_pushvalue(L, -2);
        lua_pushnil(L);
        lua_rawset(L, -3);
        lua_pop(L, 1);
    }

    Detail::UserdataPtr *ud = (Detail::UserdataPtr *)lua_topointer(L, -1);

    // create a new userdata of the "to" type given the native pointer
    lualoom_newnativeuserdata(L, nativeType, ud->getPointer());

    // ensure that we created the proper type
    Detail::UserdataPtr *nud = (Detail::UserdataPtr *)lua_topointer(L, -1);
    lmAssert(nud->m_nativeType == nativeType, "lualoom_downcastnativeinstance - native type mismatch on new user data");

    int uIdx = lua_gettop(L);

    // replace userdata
    lua_pushvalue(L, -1);
    lua_rawseti(L, instanceIdx, LSINDEXNATIVE);

    if (managed)
    {
        // if we're managed, need to update the managed tables

        // store (void*) entry to native bridge user data
        lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMANAGEDUSERDATA);
        lua_pushlightuserdata(L, ud->getPointer());
        lua_pushvalue(L, uIdx);
        lua_settable(L, -3);
        lua_pop(L, 1);

        // store userdata -> script table
        lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMANAGEDNATIVESCRIPT);
        lua_pushvalue(L, uIdx);
        lua_pushvalue(L, instanceIdx);
        lua_settable(L, -3);
        lua_pop(L, 1);

        // we need to call the instance initializers for all types in the downcast
        // from the downcast type up to the from (which would have already been initialized)
        lualoom_callscriptinstanceinitializerchain_internal(L, toType, instanceIdx, fromType);
    }

    lua_settop(L, top);
}