Advertisement

Call lua function from c++ (not global function)

Started by March 17, 2011 08:54 AM
6 comments, last by jblue 13 years, 8 months ago
Hi,
I wound like to provide my program with "class" ability. And the lua class can receive "event" from program.

Following example, My program random to rob money in account. How can I call "Account:Robbed" in my c++ code?
(ResisterEvent is provide from c++)


Code in lua.



Account = {};
Account.__index = Account;

function Account.Create( balance )
local acnt = {}; -- our new object
setmetatable( acnt,Account ); -- make Account handle lookup
acnt.balance = balance; -- initialize our object
return acnt;
end

function Account:Withdraw( amount )
self.balance = self.balance - amount
end

function Account:Robbed( amount )
self.balance = self.balance - amount
end

-- create and use an Account
acc = Account.Create( 1000 )
acc:Withdraw( 100 )

ResisterEvent( acc.Robbed );


In pseudo-code:

lua_getglobal("Account")


lua_getfield(""Robbed")

lua_pushtable(<Account object>)

lua_pushnumber(<argument 'amount'>)


lua_call(-3);

<pop any return values>

lua_pop(2) // pop "Account" global

Advertisement
Try this:


lua_getglobal(L, "acc"); // Get the table instance
lua_getfield(L, -1, "Robbed"); // Get the function
lua_pushinteger(L, 123); // pass amount parameter value
lua_pcall(L, 1, 0, 0); // Call the Lua function
[size="2"]I like the Walrus best.
Hi Vectorian,

My goal is that any user can write his own lua?so in my program I'll never know "Account".

And what <Account object> means? can you explain more.

Just like the addon system of World of Warcraft. Any one can write his own lua.
two things he can do are...
1. call global function we support
2. receive event from AP

I already done step 1. The Step 2 also ok if receive function is global.

function OnTimer( time )
--
end


But in this case, user can not write his own module if he want to handle the event automatic.



In pseudo-code:

lua_getglobal("Account")


lua_getfield(""Robbed")

lua_pushtable(<Account object>)

lua_pushnumber(<argument 'amount'>)


lua_call(-3);

<pop any return values>

lua_pop(2) // pop "Account" global


Hi owl,

It just an example, I assume in my program I'll never know the name.

Try this:


lua_getglobal(L, "acc"); // Get the table instance
lua_getfield(L, -1, "Robbed"); // Get the function
lua_pushinteger(L, 123); // pass amount parameter value
lua_pcall(L, 1, 0, 0); // Call the Lua function


Hi owl,

It just an example, I assume in my program I'll never know the name.
[quote name='owl' timestamp='1300354523' post='4786923']
Try this:


lua_getglobal(L, "acc"); // Get the table instance
lua_getfield(L, -1, "Robbed"); // Get the function
lua_pushinteger(L, 123); // pass amount parameter value
lua_pcall(L, 1, 0, 0); // Call the Lua function


[/quote]


Then you pass it in the RegisterEvent as a string and you'll know.

[size="2"]I like the Walrus best.
Advertisement
Hi owl,

I know what you want to tell me.

But my requirement is

lua


CTestModule = {};
CTestModule.__index = CTestModule;

function CTestModule.OnEvent( balance )
print( "1234" );
end

function OnEvent( balance )
print( "4567" );
end

RegisterEvent( "CTestModule", "OnEvent" );



in c++


lua_getfield( pState, LUA_GLOBALSINDEX, "OnEvent" );
lua_call( pState, 0, 0 );

lua_getglobal( pState, "CTestModule" );
lua_getfield( pState, LUA_GLOBALSINDEX, "OnEvent" );
lua_call( pState, 0, 0 );


my screen print "4567" twice, But I need "1234" & "4567"



Then you pass it in the RegisterEvent as a string and you'll know.


You could take a look at "A Dynamic and Flexible Event System for Script-Driven Games" from Lua Gems. It approaches the problem you have with an elegant design for registering and firing events.

This topic is closed to new replies.

Advertisement