Invoking a Lua member function from C++ with arg list

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Invoking a Lua member function from C++ with arg list

Sean Barton
Hi.  I'm authoring a system where my lua code registers a callback function to be called from the C++ app after a period of time has elapsed.

I'd like to support passing arguments back into the callback but I can't figure out what to do.

An exmaple:

function MyClass:Foo ()
    ScheduleMemberFunction(self, self.Bar, {1, "second"}, 500)
end

function MyClass:Bar (arg1, arg2)
    print arg1 --> 1
    print arg2 --> 'second'
end


On the C++ side, ScheduleMemberFunction will store the function to be called and the arguments (as a table) to be passed back to Lua...

void ScheduleMemberFunction (object self, object member, object args, int timeMs)
{
    MyLuaCallbackData cb;
    cb.self = self;
    cb.member = member;
    cb.args = args;
    ...
}

And 500 milliseconds later, I invoke the Lua member function (MyClass:Bar) like so ...

void Invoke (MyLuaCallbackData& cb)
{
    cb.member(cb.self, cb.args);
    ...
}

But of course, the "cb.args" luabind object is passed back into MyClass:Bar() as a table, not as seperate variables.

Is there a I can get this to work to handle a variable number of parameters to be handed back to a lua function?
Reply | Threaded
Open this post in threaded view
|

Re: Invoking a Lua member function from C++ with arg list

Evan Wies
Maybe its easiest to just use the Lua stack?  luabind::object makes that easy.  internally, luabind
 probably does something similar.

I haven't tested the following, but it might give you an idea...

void Invoke (MyLuaCallbackData& cb)
{
     // this sample assumes everything has the same lua_State
     // member should probably be a function, and args should probably be a table
     assert( cb.member.state() == cb.self.state() && cb.member.state() == cb.args.state() );

     // push function, then args
     cb.member.push();
     size_t nargs = 0;
     for ( luabind::iterator iter(cb.args), end; iter != end; ++iter )  {
          iter->push();
          ++nargs;
     }

     // we use the "hidden" luabind::pcall since it lets us use the
     // same error calback.  see luabind/src/pcall.cpp.
     // assumes we want no return values.
     int res = luabind::detail::pcall( cb.member.stat(), nargs, 0 );
     assert( res == 0 );
}

Good luck,
-Evan




Sean Barton wrote:

> Hi.  I'm authoring a system where my lua code registers a callback
> function to be called from the C++ app after a period of time has elapsed.
>
> I'd like to support passing arguments back into the callback but I can't
> figure out what to do.
>
> An exmaple:
>
> function MyClass:Foo ()
>     ScheduleMemberFunction(self, self.Bar, {1, "second"}, 500)
> end
>
> function MyClass:Bar (arg1, arg2)
>     print arg1 --> 1
>     print arg2 --> 'second'
> end
>
>
> On the C++ side, ScheduleMemberFunction will store the function to be
> called and the arguments (as a table) to be passed back to Lua...
>
> void ScheduleMemberFunction (object self, object member, object args,
> int timeMs)
> {
>     MyLuaCallbackData cb;
>     cb.self = self;
>     cb.member = member;
>     cb.args = args;
>     ...
> }
>
> And 500 milliseconds later, I invoke the Lua member function
> (MyClass:Bar) like so ...
>
> void Invoke (MyLuaCallbackData& cb)
> {
>     cb.member(cb.self, cb.args);
>     ...
> }
>
> But of course, the "cb.args" luabind object is passed back into
> MyClass:Bar() as a table, not as seperate variables.
>
> Is there a I can get this to work to handle a variable number of
> parameters to be handed back to a lua function?



-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: Re: Invoking a Lua member function from C++ with arg list

Sean Barton
I had to massage it a tiny bit but it works.  Many thanks for pointing me in the right direction.


On 5/30/06, Evan <[hidden email]> wrote:
Maybe its easiest to just use the Lua stack?  luabind::object makes that easy.  internally, luabind
probably does something similar.

I haven't tested the following, but it might give you an idea...

void Invoke (MyLuaCallbackData& cb)
{
     // this sample assumes everything has the same lua_State
     // member should probably be a function, and args should probably be a table
     assert( cb.member.state() == cb.self.state() && cb.member.state () == cb.args.state() );

     // push function, then args
     cb.member.push();
     size_t nargs = 0;
     for ( luabind::iterator iter(cb.args), end; iter != end; ++iter )  {
          iter->push();
          ++nargs;
     }

     // we use the "hidden" luabind::pcall since it lets us use the
     // same error calback.  see luabind/src/pcall.cpp.
     // assumes we want no return values.
     int res = luabind::detail::pcall( cb.member.stat(), nargs, 0 );
     assert( res == 0 );
}

Good luck,
-Evan




Sean Barton wrote:

> Hi.  I'm authoring a system where my lua code registers a callback
> function to be called from the C++ app after a period of time has elapsed.
>
> I'd like to support passing arguments back into the callback but I can't
> figure out what to do.
>
> An exmaple:
>
> function MyClass:Foo ()
>     ScheduleMemberFunction(self, self.Bar, {1, "second"}, 500)
> end
>
> function MyClass:Bar (arg1, arg2)
>     print arg1 --> 1
>     print arg2 --> 'second'
> end
>
>
> On the C++ side, ScheduleMemberFunction will store the function to be
> called and the arguments (as a table) to be passed back to Lua...
>
> void ScheduleMemberFunction (object self, object member, object args,
> int timeMs)
> {
>     MyLuaCallbackData cb;
>     cb.self = self;
>     cb.member = member;
>     cb.args = args;
>     ...
> }
>
> And 500 milliseconds later, I invoke the Lua member function
> (MyClass:Bar) like so ...
>
> void Invoke (MyLuaCallbackData& cb)
> {
>     cb.member(cb.self, cb.args);
>     ...
> }
>
> But of course, the "cb.args" luabind object is passed back into
> MyClass:Bar() as a table, not as seperate variables.
>
> Is there a I can get this to work to handle a variable number of
> parameters to be handed back to a lua function?



-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user