这个脚本会导致很多闭包吗?如果是,有什么替代方案吗?

我想在 Lua 中实现一个 GUI 消息处理系统,目前它的工作方式如下:

在 c++ 代码中,窗口有窗口过程,就像 Windows API 中一样,我也正在尝试在 Lua 中使用它。

因此,我的窗口携带一个指向表的 luabind::object,例如:

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,

}

表的键是一个 GUI 消息。Ele 是一个窗口句柄,a 是消息,b 和 c 是参数。

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;

是一些示例函数。

它们像这样绑定到对象上:

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);

这一切都在同一个脚本文件中,我只执行它一次(据我所知)当我加载它时。 因此,首先构建表,后来将表绑定到 luabind:::object 上。 然后在 C++ 中调用此对象,如下所示:

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);
        }
    }

因此,每当消息被触发时,都会调用该表并返回一个函数,我想是每次都返回一个函数。 我假设这一点,因为即使我只加载一次脚本文件,当调用 action 对象时,当我在脚本中调试并在那里设置断点时,断点也会被触发。

这是一种处理事物的好方法吗?

原文链接 https://stackoverflow.com/questions/6560127

点赞
stackoverflow用户734069
stackoverflow用户734069

我猜你的问题是每次访问表格是否会_分配_一个新函数。答案是否定的。

请记住:在 Lua 中,普通的函数定义只是未命名函数创建的特例。以下代码是相同的:

function SomeName() end

SomeName = function() end

当 Lua 源文件最初执行时便会创建该函数。就像你使用的表格只会在 Lua 源文件最初执行时创建一次一样。如果你多次执行 Lua 源文件,则会多次创建该表格及其内容。

是的,你的代码会有很多函数。但这有什么问题呢?除非你不断创建函数或执行类似滥用行为,否则就没有所谓的“太多”。Lua 没有 switch 语句,就是因为 Lua 代码通常是这样做的。

简而言之:这在 Lua 中是完全正常的。

2011-07-02 23:29:59
stackoverflow用户383277
stackoverflow用户383277

每次运行构造在“action”中存储表格的代码时,都会创建一个闭包。如果这对你来说是个问题,只需在不可访问的范围内创建本地函数(甚至将它们放在注册表中)并引用它们。例如:

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
2011-07-02 23:32:42