Приводит ли этот сценарий к множеству замыканий, и если да, то какая альтернатива? - PullRequest
0 голосов
/ 03 июля 2011

Я хочу реализовать систему обработки сообщений с графическим интерфейсом в Lua, в настоящее время она работает следующим образом:

В коде 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,

}

Ключом к таблице является сообщение с графическим интерфейсом.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);
        }
    }

Таким образом, всякий раз, когда запускается сообщение, вызывается таблица, и я думаю, она каждый раз возвращает функцию.Я предполагаю это, потому что, хотя я загружаю файл сценария только один раз, когда я отлаживаю сценарий и устанавливаю точку останова, точка останова срабатывает при вызове объекта действия.

Это хороший способобращаться с вещами?

Ответы [ 2 ]

1 голос
/ 03 июля 2011

Это приводит к созданию замыкания каждый раз, когда вы запускаете тот код, который создает таблицу, которую вы храните в «действии», да. (Я не могу расшифровать ваш вопрос, если он повторялся более одного раза.)

Если это проблема для вас, просто создайте локальные функции где-то в недоступной области (или даже поместите их в реестр) и вместо этого ссылайтесь на них. Например:

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
1 голос
/ 03 июля 2011

Я предполагаю, что ваш вопрос заключается в том, будет ли выделять новую функцию каждый раз, когда вы обращаетесь к таблице. Ответ - нет.

Помните: обычные определения функций в Lua - это просто особые случаи создания безымянных функций. Следующие идентичные:

function SomeName() end

SomeName = function() end

Функция создается при первоначальном выполнении исходного файла Lua. Так же, как таблица, которую вы используете, создается только один раз: когда исходный файл Lua выполняется изначально. Если вы выполнили исходный файл Lua несколько раз, то таблица и ее содержимое будут созданы несколько раз.

Да, в вашем коде будет много функций. Но что с этим не так? Если вы постоянно не создаете функции или не делаете что-то одинаково оскорбительное, не существует такого понятия, как «слишком много». У Lua нет оператора switch точно , потому что Код Lua обычно делает это так.

Короче говоря: это совершенно нормально для Луа.

...