lua-users home
lua-l archive

RE: Another userdata question

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


damn I am more confused on this than I thought I was :(
 
I have progressed maybe from the last post in that I have pushed my userdata instance ptr onto the stack (I used pushlightuserdata to get the fulluserdata address onto the stack)
 
but then the next line from the example is
 
 // then call the "action" method on the button object
 lua_getfield(L, -1, "action");
This only makes sense if the last thing we pushed onto the stack was a table. In my example I have just pushed a userdata address, clearly not the same thing. So what the heck was that table its looking up "action" from ?
 
I am obviously misunderstanding something here. I wish this was better documented in the official Lua docs
 
Thanks again 
 
From: spammealot1@live.co.uk
To: lua-l@lists.lua.org
Subject: RE: Another userdata question
Date: 2013年11月14日 01:24:36 +0000
Hello 
 
Thanks for the replies, the tricky bit I am stuck on is illustrated with these 2 lines from the quoted example
 
 // and the registry to store the Lua object (this time a Lua table).
 lua_State * L = GetWindowLongPtr(hwnd, GWLP_USERDATA);
 lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)hwnd);
In my example when the instance of the userdata was created I kept a copy of the pointer to the userdata instance on the C side. So instead of the above example where it gets the object ptr from the registry and pushes it onto the stack I was thinking I just push my stashed ptr with something like a pushUserdata() API function.
 
Only snag with my idea is no such function exists :( So how do I get my instance ptr back on the stack so that I can see if it has got an associated action function defined in the Lua code ?
 
Maybe I should stash it in and retrieve it from the Registry anyway ?
 
Thanks for any further tips. For info, I am using Lua 5.1 
 
Regards Geoff
 
Date: 2013年11月13日 21:32:10 +0800
From: pengzhicheng1986@gmail.com
To: lua-l@lists.lua.org
Subject: Re: Another userdata question
 
 
 
 
 
 于 2013年11月13日 4:48, Geoff Smith 写道:
 
 
 
 I am really hoping someone could help me with this
 question please as I am totally stuck on it for now.
 
 I am trying to implement a userdata via the C API, to give me
 this type of functionality
 
 btn1 = graphics.newButton(x,y,width,ht, "pressMe")
 btn1:setText("Different Text")
 btn1:setFont("Arial")
 
 That's OK I think I have got that figured out and largely
 working, but the next thing I want to do is call a user defined
 Lua action function on the button instance. For example
 
 In Lua
 
 function btn1:action(someArbitrayParamBackFromC)
 print("ouch someone just poked btn1")
 end
 
 How can I call that Lua button instance function from C when I
 have detected the key is pressed ?
 
 I have done something vaguely similar in the past when I have
 created a custom timer on the Lua side, but the difference was I
 had a timer create function in Lua such as 
 
 myNewTimer = createTimer( period, luaFunctionCallback)
 
 So I was passed the callback function into the C code which
 meant I could stash it away in the registry and then when the
 timer elapsed on the C side, I did this
 
 // push function indexed by registryRef from the registry back
 onto the stack
 // the lua callback function in this case
 lua_rawgeti(local_L, LUA_REGISTRYINDEX, registryRef);
 /* the first function argument is the timerID */ 
 lua_pushinteger(local_L, myTimerID); 
 /* call the function with 1 argument, return 0 result */ 
 pcallResult = lua_pcall(local_L,1,0,0); // pops 2 params from
 stack
 
 I am guessing the solution is somewhat similar but cant figure
 it out.
 
 Many thanks for any assistance
 
 Geoff
 
 
 
 
 
 You are right. The solution is similar.
 
 In your Timer example, you retrieved the callback Lua function which
 was passed to the C side
 when the timer was created. While in your button press example, you
 should retrieve the button
 object first, then call the specified method on that object.
 
 Thus said, I assumed you had used some method (e.g.
 GetWindowLongPtr) to associate the
 button object (from Lua) with the *native* button object of the
 underlying GUI system.
 
 Following is an imaginary example to illustrate this idea to bind
 Lua to Win32 message system.
 Just as an illustration, can't claim the correctness.
----------------------------------------------------------------------------------
 
 [inside the window procedure of the button]
 [...]
 
 case WM_LBUTTONUP:
 // first retrive the associated object of the Lua side.
 // the following is just an demo method using GWLP_USERDATA to
 store L
 // and the registry to store the Lua object (this time a Lua
 table).
 lua_State * L = GetWindowLongPtr(hwnd, GWLP_USERDATA);
 lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)hwnd);
 
 // then call the "action" method on the button object
 lua_getfield(L, -1, "action");
 
 // do some check
 if (!lua_isnil(L, -1)) {
 // push the self parameter
 lua_pushvalue(L, -2);
 lua_pcall(L, 1, 1, 0);
 // check the callback return value and do some processing
 [...]
 }
 case WM_XXXX:
 [...]
-------------------------------------------------------------------------------------
 
 
 		 	 		 		 	 		 

AltStyle によって変換されたページ (->オリジナル) /