[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: calling fcuntion from other lua context
- From: Mario <www.derfordfahrer@...>
- Date: Mon, 05 Sep 2005 20:13:56 +0200
Thanks Jeffrey for your code snippet. I will give it a try! But i have
expected this would be a feature of LUA to call functions/mehtods in an
other LUA context. I'm a bit surprised...is that really the only way?
>> Date: Thu, 01 Sep 2005 08:18:21 +0200
>> From: Mario <www.derfordfahrer@gmx.de>
>> Subject: calling fcuntion from other lua context
>> To: lua@bazar2.conectiva.com.br
>> Message-ID: <43169D2D.7000806@gmx.de>
>> Content-Type: text/plain; charset=us-ascii
>>
>> Hi all!
>>
>> I have some c++ objects, all with their own lua context. How is it
>> possible to call a lua function from one lua context to an another one?
>> For example:
>>
>>
>> script 1:
>> function CObject:OnLogic( )
>>
>> local a = wmanager:getEntityByName( "NewObject" );
>> a:some_function( )
>>
>> end
>>
>>
>> script 2:
>> function CObject:OnLogic( )
>> -- do nothing
>> end
>>
>> function CObject:some_function( )
>> io.write("Hi there!\n")
>> end
>>
>> I'm getting the error message "attempt to call method `some_function' (a
>> nil value)"?
>>
>> Thank you in advance!
>> Greetings Mario
>
>
>
> Today I was just "solving" the same problem myself. It is really
> complicated and not easy to do imho. Here is a snippet of code that I
> made which does it although it has a limitation in that you can only
> pass and return arguments that are bool, string, number or nil...
> although the code could be exanded to do more. Some of the code
> contains stuff my personal library I called bindlua, but I think it
> might at least give you something you can work with.
>
> int lua_state_to_state_func_call(lua_State* L)
> {
> lua_State* LO = static_cast<lua_State*>(lua_touserdata(L,
> upvalueindex<1>::VAL));
> const char* func = lua_tostring(L, upvalueindex<2>::VAL);
>
> const int LO_origTop = lua_gettop(LO);
> lua_pushstring(LO, func);
> lua_gettable(LO, LUA_GLOBALSINDEX);
> // the func to call is now on top of LO
> // Now put the args on LO, they r current in L
>
> bool error = false;
> const int args = lua_gettop(L);
> for(int i = 1; i <= args; ++i)
> {
> if(lua_type(L, i) == LUA_TSTRING)
> {
> const char* s = lua_tostring(L, i);
> lua_pushstring(LO, s);
> }
> else if(lua_type(L, i) == LUA_TNUMBER)
> {
> lua_Number n = lua_tonumber(L, i);
> lua_pushnumber(LO, n);
> }
> else
> {
> std::ostringstream oss;
> oss << "state to state func call does not support arg (" << i << ")
> type: " << lua_typename(L, lua_type(L, i));
> lua_warning(L, oss.str());
> error = true;
> }
> }
>
> if(error)
> {
> lua_settop(LO, LO_origTop);
> return 0;
> }
>
> try
> {
> lua_pcall(LO, args, LUA_MULTRET, 0);
> const int results = lua_gettop(LO) - LO_origTop;
> for(int i = LO_origTop + 1; i <= lua_gettop(LO); ++i)
> {
> if(lua_type(LO, i) == LUA_TSTRING)
> {
> const char* s = lua_tostring(LO, i);
> lua_pushstring(L, s);
> }
> else if(lua_type(LO, i) == LUA_TNUMBER)
> {
> lua_Number n = lua_tonumber(LO, i);
> lua_pushnumber(L, n);
> }
> else
> {
> std::ostringstream oss;
> oss << "state to state func call does not support ret val type: " <<
> lua_typename(LO, lua_type(LO, i));
> lua_warning(LO, oss.str());
> return 0;
> }
> }
>
> lua_settop(LO, LO_origTop);
> return results;
> }
> catch(bindlua_exception& e)
> {
> lua_warning(L, e.what());
> }
> }
>
> // Here pScr is an object which olds the state of the "other object"
> // L is the state that is calling a function in the other ob
> // ie: x = ob.SomeFunc(1,2,3);
> // ob is a userdata holding pScr, and through some code of my bindlua
> library you eventually get to this
> // unhanded_get code, which makes a dispatch to the
> state_to_state_func_call above
> template<>
> int unhandled_get(const Interface::ScriptPtr& pScr, const std::string&
> key, lua_State* L)
> {
> bindlua::lua_state LB = pScr->GetState();
> lua_getglobal(LB, key);
> if(lua_isnil(LB, -1))
> {
> lua_pop(LB, 1);
> return 0;
> }
> if(lua_type(LB, -1) == LUA_TFUNCTION)
> {
> lua_pushlightuserdata(L, LB.get());
> lua_pushstring(L, key);
> lua_pushcclosure(L, lua_state_to_state_func_call, 2);
> return 1;
> }
> if(lua_type(LB, -1) == LUA_TSTRING)
> {
> std::string s = lua_tostring(LB, -1);
> lua_pushstring(L, s);
> return 1;
> }
> std::ostringstream oss;
> oss << "unsupported type in script to script transfer, type: " <<
> lua_typename(LB.get(), lua_type(LB.get(), -1));
> lua_warning(L, oss.str());
> return 0;
> }
>
>
>