lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


You will find samples of doing this right in other people's code and at least one message included links. Read their code. We've given enough hints by now, the rest is for you to figure out. This is also the only way to really learn something well. Imitate, adopt and then teach others.
- asko

On 18.10.2009, at 22.18, Jiří Prymus <jiri.prymus@gmail.com> wrote:

Yes, I know what do you think but this static approach, in  my case
will be better use dynamic algorithm.
But meantime I don't know how to do that.

I want to create algorithm where I can use something like this:

-- lua script--
cv=require('luacv')

function on_trackbar1(pos)
.... some update event stuff..
end

function on_trackbar2(pos)
...another update event stuff for another trackbar widget
end

cv.cvCreateTrackbar(name1,wndname1,edge1,100,"on_trackbar1")
cv.cvCreateTrackbar(name2,wndname2,edge2,100,"on_trackbar2")
-- end of lua --

And that is problem with my current implementation because stack
information and funcname will be rewritten
by second calling of cvCreateTrackbar(....) and C callback function
of first TrackBar will call lua callback function of second TrackBar.

Little confusing, isn't it? :)

With regards,
Jiri Prymus


2009/10/18 GrayFace <sergroj@mail.ru>:
Instead of 1 you can also have 10 or 100 or 1000 callbacks, but a limited
number of them.
Like,
void mycallback(int pos, int funcid)
{
    luaL_unref(...);
    lua_rawgeti(state, -1, funcid);
    lua_pushnumber(state,pos);
    lua_call(state,1,0);
    lua_pop(state, 1);
}

void mycallback_1(int pos) { mycallback(pos, 1); }
...
void mycallback_100(int pos) { mycallback(pos, 100); }





----- Original Message ----- From: Jiří Prymus
To: Lua list
Sent: Sunday, October 18, 2009 9:25 PM
Subject: Re: Conversion Lua function to C function


Hi,

thanks for great idea.
But I have problem with lua_State *  in my_callback fuction, because
it has only "int pos " as argument .
It's defined like :
typedef void (CV_CDECL *CvTrackbarCallback)(int pos);

And only way to pass stack to callback function is in global variable,
but this isn't so good technique as I hoped.

But yes sample code like this works.

....
lua_State *state;
char funcname[100];

void mycallback(int pos)
{
    lua_pushstring(state,funcname);
    lua_gettable(state,LUA_GLOBALSINDEX);
    lua_pushnumber(state,pos);
    lua_call(state,1,0);
}

static int luacv_cvCreateTrackbar(lua_State *L)
{
 const char *trackbar_name=luaL_checkstring(L,1);
 const char *window_name=luaL_checkstring(L,2);
 int value=luaL_checkint(L,3);
 int count=luaL_checkint(L,4);

 sprintf(funcname,"%s",luaL_checkstring(L,5));
 lua_pushstring(L,funcname);
 lua_gettable(L,LUA_GLOBALSINDEX);
 if (lua_isfunction(L,-1))
 {
    sprintf(funcname,"%s",luaL_checkstring(L,-1));
    state=lua_newthread(L);
  }
else
  luaL_error(L,"luacv.cvCreateTrackbar(string trackbar_name,string
window_name,int value,int count, name of 'void func(int pos))'");

cvCreateTrackbar(trackbar_name,window_name,&value,count,mycallback);
return 0;
}
....

if  state and funcname are global variables, then it works. But this
way is limited to only one Trackbar widget per script.

Unfortunately I can't use lua_State  in mycallback as you wrote with
gpointer, because
cvCreateTrackbar function is platform depended. Depends on GUI you
use, including WinAPI.


With regards,
Jiri Prymus

2009/10/18 Francesco Abbate <francesco.bbt@gmail.com>:

Hi,
I think you can do it cleanly. When you use gtk_signal_connect you
should pass lua_State * as a gpointer func_data. As a callback
function you should use a simple C function that you define in your
code, lets call it 'my_callback'.

Then in my_callback you will have access the lua_State * through the
func_data gpointer (you need just a cast). The you need to use
Lua_State to put the Lua function you want in the Lua stack. The
function could be in the Environment, or in the registry or in the
global namespace of even it could already be in the stack. Then you
push the arguments of the Lua functions in the Lua stack and you use
lua_call or lua_pcall.

Anyway, to use this schema the condition is that the GTK main event
loop run from a C function that was called from Lua. So the schema
could be:
- gtk_signal_connect will be used with some C functions callback that
you prepare on your source code. These functions will look for
particular Lua function and call them
with lua_call
- a Lua function is called to run the GTK main loop, some Lua
functions have been
prepared in advance in the Environment or in the Lua stack to be
used as callbacks

So we can summarize the call sequence like that:
Lua main code => GTK main loop (C code called from Lua, a Lua stack
will be available) => a C callback is called by GTK main loop (we
still have access to the same Lua stack available for GTK main loop)
=> a lua function is called.

So we have closed the sequence Lua => C code => Lua.

Of course it will be important to clean the stack before the C
callback terminates.

I hope this is clear and pertinent with your problem.

Regards,
Francesco

2009/10/17 Jiří Prymus <jiri.prymus@gmail.com>

So if I understand that, I can't wrapper cvCreateTrackBar function
without re-implementing it in my wrapper, because i'm not able to get
proper Callback function pointer from lua and pass it to opencv
library as a C function pointer.

But it leads to the bypassing original library function and that isn't
too great.

And using hacks isn't proper for me, because it's part of my Bachelor
thesis and I want clear code.

Thanks for help.

With regards,
Jiri Prymus

2009/10/17 Wesley Smith <wesley.hoke@gmail.com>:
I've got a system that allows me to set Lua functions as callback
actions from GtkMenuItems. You can find he code here:

// generic interface:

http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/src/LuaAVMenu.cpp
471: int MenuItem :: action(lua_State *L)


// gtk callback system:

http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/linux/LuaAVMenuLinux.cpp
93: void MenuBarImpl :: dispatch(MenuItem *mi)
419: void MenuItem :: implEnableAction()


wes