예제 #1
0
/*
* Create a deep userdata
*
*   proxy_ud= deep_userdata( idfunc [, ...] )
*
* Creates a deep userdata entry of the type defined by 'idfunc'.
* Other parameters are passed on to the 'idfunc' "new" invocation.
*
* 'idfunc' must fulfill the following features:
*
*   lightuserdata = idfunc( eDO_new [, ...] )      -- creates a new deep data instance
*   void = idfunc( eDO_delete, lightuserdata )     -- releases a deep data instance
*   tbl = idfunc( eDO_metatable )                  -- gives metatable for userdata proxies
*
* Reference counting and true userdata proxying are taken care of for the
* actual data type.
*
* Types using the deep userdata system (and only those!) can be passed between
* separate Lua states via 'luaG_inter_move()'.
*
* Returns:  'proxy' userdata for accessing the deep data via 'luaG_todeep()'
*/
int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc)
{
	char const* errmsg;
	DEEP_PRELUDE* prelude = DEEP_MALLOC( sizeof(DEEP_PRELUDE));
	if( prelude == NULL)
	{
		return luaL_error( L, "couldn't not allocate deep prelude: out of memory");
	}

	prelude->refcount = 0; // 'push_deep_proxy' will lift it to 1
	prelude->idfunc = idfunc;

	STACK_GROW( L, 1);
	STACK_CHECK( L);
	{
		int oldtop = lua_gettop( L);
		prelude->deep = idfunc( L, eDO_new);
		if( prelude->deep == NULL)
		{
			luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)");
		}

		if( lua_gettop( L) - oldtop != 0)
		{
			luaL_error( L, "Bad idfunc(eDO_new): should not push anything on the stack");
		}
	}
	errmsg = push_deep_proxy( get_universe( L), L, prelude, eLM_LaneBody);  // proxy
	if( errmsg != NULL)
	{
		luaL_error( L, errmsg);
	}
	STACK_END( L, 1);
	return 1;
}
예제 #2
0
/*
* Create a deep userdata
*
*   proxy_ud= deep_userdata( idfunc [, ...] )
*
* Creates a deep userdata entry of the type defined by 'idfunc'.
* Other parameters are passed on to the 'idfunc' "new" invocation.
*
* 'idfunc' must fulfill the following features:
*
*   lightuserdata= idfunc( "new" [, ...] )      -- creates a new deep data instance
*   void= idfunc( "delete", lightuserdata )     -- releases a deep data instance
*   tbl= idfunc( "metatable" )          -- gives metatable for userdata proxies
*
* Reference counting and true userdata proxying are taken care of for the
* actual data type.
*
* Types using the deep userdata system (and only those!) can be passed between
* separate Lua states via 'luaG_inter_move()'.
*
* Returns:  'proxy' userdata for accessing the deep data via 'luaG_todeep()'
*/
int luaG_deep_userdata( lua_State *L ) {
    lua_CFunction idfunc= lua_tocfunction( L,1 );
    int pushed;

    DEEP_PRELUDE *prelude= DEEP_MALLOC( sizeof(DEEP_PRELUDE) );
    ASSERT_L(prelude);

    prelude->refcount= 0;   // 'luaG_push_proxy' will lift it to 1

    STACK_GROW(L,1);
  STACK_CHECK(L)

    // Replace 'idfunc' with "new" in the stack (keep possible other params)
    //
    lua_remove(L,1);
    lua_pushliteral( L, "new" );
    lua_insert(L,1);

    // lightuserdata= idfunc( "new" [, ...] )
    //
    pushed= idfunc(L);

    if ((pushed!=1) || lua_type(L,-1) != LUA_TLIGHTUSERDATA)
        luaL_error( L, "Bad idfunc on \"new\": did not return light userdata" );

    prelude->deep= lua_touserdata(L,-1);
    ASSERT_L(prelude->deep);

    lua_pop(L,1);   // pop deep data

    luaG_push_proxy( L, idfunc, prelude );
        //
        // [-1]: proxy userdata

  STACK_END(L,1)
    return 1;
}