0

我想在 Lua 中实现一个 GUI 消息处理系统,目前它的工作原理是这样的:

在 c++ 代码中,windows 有窗口过程,就像它们在 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);
        }
    }

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

这是处理事情的好方法吗?

4

2 回答 2

1

我假设您的问题是这是否会在您每次访问表时分配一个新函数。答案是不。

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

function SomeName() end

SomeName = function() end

该函数是在 Lua 源文件最初执行时创建的。就像您使用的表只创建一次:当 Lua 源文件最初执行时。如果您多次执行 Lua 源文件,则该表及其内容将被创建多次。

是的,您的代码中将包含很多功能。但这有什么问题呢?除非你不断地创建函数或做同样滥用的事情,否则没有“太多”这样的事情。Lua 没有该switch语句正是因为Lua 代码通常以这种方式执行操作。

简而言之:这对于 Lua 来说是完全正常的。

于 2011-07-02T23:29:59.753 回答
1

每次运行构建存储在“操作”中的表的代码时,都会创建一个闭包,是的。(如果不止一次运行,我无法解读您的问题。)

如果这对您来说是个问题,只需在无法访问的范围内的某处创建本地函数(甚至将它们放在注册表中)并引用它们。例如:

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-02T23:32:42.273 回答