>> On Thu, Feb 16, 2012 at 12:06 PM, Mike Richards <mrichard...@gmx.com>
>>>
>>> function test() is declared in the current scope, and globally as
>>> filterform.test
>>>
>>> After fiddling around for a bit, it looks like wx.wxEvtHandler:Connect
>>> saves upvalues, but not the current function environment (scope), which was
>>> set in the call to module(...)

Mike you're right, I was wrong in my first reply. The environment is
not saved and the global table is always set as the environment of the
Lua event callback function. I haven't thought about this for awhile,
but I can't think of any reason not to save it right now, however that
code dates from over 5 years ago so I don't remember if it was tried
it and it didn't work or what...

Here's what's actually done before your Lua event handler function is
called, where m_luafunc_ref is the reference to the Lua callback
function that's put on the stack.

http://wxlua.svn.sourceforge.net/viewvc/wxlua/trunk/wxLua/modules/wxlua/src/wxlcallb.cpp?revision=36&view=markup

191     if (wxlState.wxluaR_GetRef(m_luafunc_ref, &wxlua_lreg_refs_key))
192     {
193         wxlState.lua_PushValue(LUA_GLOBALSINDEX);
194         if (wxlState.lua_SetFenv(-2) != 0)
195         {
196             // Don't track the wxEvent since we don't own it and tracking it
197             // causes clashes in the object registry table since many can be
198             // created and deleted and the mem address is resused by C++.
199             wxlState.wxluaT_PushUserDataType(event, event_wxl_type, false);
200             wxlState.LuaPCall(1, 0); // one input no returns


>>> When the event function is called, the function environment is reset to
>>> the global scope, so if you want to reference things you declared in the
>>> module scope in the event callback, you have a couple of options:
>>> 1. Declare everything as local, which to me is just good practice.
>>> 2. Use a fully qualified name (e.g. filterform.test())
>>> 3. Wrap all your calls to wx.wxEvtHandler:Connect like this:
>>>
>>> function Connect(evthandler, id, func)
>>>     local environment = getfenv(1)
>>>     evthandler:Connect(id,
>>>         function(event)
>>>             setfenv(1, environment)
>>>             func(event)
>>>         end
>>>     )
>>> end
>>>
>>> [...]
>>>
>>> local button = wx.Button([...])
>>> Connect(button, wx.wxEVT_COMMAND_BUTTON_CLICKED, function(event) end)
>>>
>>> John -- It seems like wx.wxEvtHandler:Connect should do this anyways . .
>>> . that is, save the current function environment, and then apply it before
>>> calling the callback.

I'll have to check a little bit more into 5.2 since get/setfenv are
gone, but it looks like all you do is get/set the _ENV variable to get
the same behavior. For the callback function, we'd set it as an
upvalue to the callback function.

http://www.corsix.org/content/look-lua-52-work3

If it's really that simple then yes, we can save the environment and
not worry about breaking anything in 5.2, though under the hood it
will be implemented differently. If I'm wrong and it can't be made to
work in 5.2, then it should be left as is.


I'm thinking a little out loud here... the pros of the global +
upvalues (current state) is that you always get the same environment
so there's no surprises, which is also a downside when you're in a
module since you're not in what you thought was the global table. The
downside of saving the environment of each Connect() callback is an
extra reference to a Lua table.

I'll look into it.

Regards,
    John

------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
wxlua-users mailing list
wxlua-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wxlua-users

Reply via email to