开发者

Does this script result in many, many closures, and if yes, whats an alternative?

I want to implement a GUI message handling system in Lua, currently it works开发者_JS百科 like this:

In the c++ code, windows have window procedures, like they have in the Windows API, and I am trying to lean on this in Lua as well.

So my windows carry a luabind::object that points to a table like

local action = {
  [on_uimsg.MOUSEMOVE] = function (ele, a,b,c)return on_mousemove(b,c) end,
  [on_uimsg.MOUSEDOWN] = function (ele, a,b,c) return on_mousedown(ele,b) end,
  [on_uimsg.LEAVE] = function (ele, a,b,c) return on_mouseleave(b,c) end,

}

The key to the table is a GUI message. Ele is a handle to a window, a is the message again, b and c are parameters.

local function on_mousemove(b,c)
ConsoleOut2("mousemove %i %i",b,c);
return 0;
end;

local function on_command(b,c)
ConsoleOut2("mousecmd %i %i",b,c);
return 1;
end;

Are some example functions.

They get bound to the object like this:

parms.pos_x = 620;
parms.pos_y = 300;
parms.width = 100;
parms.height = 100;
parms.parent = DESKTOP;
parms.name = "Test";
parms.skin = "Default_outline";
parms.class = "BasicStaticText";
local window = hud:addWindow(parms,action); 

This is all in the same script file, which only gets (to my knowledge) executed once, when I load it. So at first the table gets constructed, then later on the table gets bound to a luabind:::object . This object then gets called in c++ like this:

if (luabind::type(o)==LUA_TFUNCTION)
    {
        luabind::call_function<int>(o,handle,a,b,c);
    }
    else if (luabind::type(o)==LUA_TTABLE)
    {
        luabind::object call = o[a];

        if (luabind::type(call)==LUA_TFUNCTION)
        {
        luabind::call_function<int>(call,handle,a,b,c);
        }
    }

So whenever an message is fired, the table gets called and it returns a function every time, I guess. I am assuming this, because even though I only load the script file once, when I debug the script and put a breakpoint there, the breakpoint gets hit when the action object is called.

Is that a good way of handling things?


I assume your question is whether this will allocate a new function every time you access the table. The answer is no.

Remember: normal function definitions in Lua are just special-cases of unnamed function creation. The following are identical:

function SomeName() end

SomeName = function() end

The function is created when the Lua source file is originally executed. Just as the table you use is created only once: when the Lua source file is originally executed. If you executed the Lua source file multiple times, then the table and its contents would be created multiple times.

Yes, your code will have a lot of functions in it. But what's wrong with that? Unless you are constantly creating functions or doing something equally abusive, there's no such thing as "too many". Lua doesn't have the switch statement precisely because Lua code typically does things this way.

In short: this is entirely normal for Lua.


It results in the creation of a closure every time you run that code that constructs the table you're storing in 'action', yes. (I couldn't decipher from your question if that was running more than once.)

If this is a problem for you, just create local functions somewhere in a scope that is inaccessible (or even put them in the registry) and reference them instead. For example:

local createActionTable;
do
  local function onMouseMove(ele, a,b,c)return on_mousemove(b,c) end
  local function onMouseDown(ele, a,b,c) return on_mousedown(ele,b) end
  local function onMouseLeave(ele, a,b,c) return on_mouseleave(b,c) end

  function createActionTable()
    local action = {
      [on_uimsg.MOUSEMOVE] = onMouseMove,
      [on_uimsg.MOUSEDOWN] = onMouseDown,
      [on_uimsg.LEAVE] = onMouseLeave,
    }

    return action
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜