0

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

これはすべて同じスクリプト ファイル内にあり、(私の知る限り) ロード時に 1 回だけ実行されます。したがって、最初にテーブルが構築され、後でテーブルが にバインドされます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);
        }
    }

したがって、メッセージが発生するたびにテーブルが呼び出され、毎回関数が返されると思います。スクリプト ファイルを 1 回だけロードしても、スクリプトをデバッグしてそこにブレークポイントを配置すると、アクション オブジェクトが呼び出されたときにブレークポイントがヒットするため、これを想定しています。

それは物事を処理する良い方法ですか?

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 に答える