0

オブジェクト指向の lua (メタテーブルの設定) についてかなり読んだことがあり、継承を備えたシステムを構築しました。

私の問題は、いくつかの変数が互いに漏れているように見えることです。関数と呼ばれるwindow:click(x, y)関数を呼び出すと、関数は問題なく呼び出されます。この関数の役割は、すべてのコンポーネントにクリックを通知することです。それは何をしている

for number, component in pairs(self.components) do
    component.focus = false
    component:click(x, y, msg)
end

self.componentsウィンドウのすべてのコンポーネントが含まれています

component.lua というクラスを持っているすべてのコンポーネントの基本クラスとして機能するために、このファイルは components というテーブルを作成し、それにcreate()メソッドを追加します (通常の OO lua のすべてを実行します)。この基本クラスにはすべてのメソッドが含まれ、変数を含むすべてのコンポーネントで必要な変数component:click(x, y)が呼び出されます。

for key, callback in pairs(self.clickCallback) do
    callback()
end
return

clickCallbackテーブルには、コンポーネントが通知されたときに呼び出される関数が含まれています。component.lua 内で初期化されます

ここから、新しいコンポーネント (テキストボックス、ボタン、ラベルなど) のメタテーブルを設定するだけで、このクラスを他のクラスに継承します。これらのコンポーネントはself.components、ウィンドウ内のテーブルに追加されるものです。

問題は、これらの各コンポーネントに独自の clickCallback テーブルが必要なことです。私はセッターを介して書いていますcomponent.lua

function component:addClickHandler(handler)
    table.insert(self.clickCallback, handler)
end

しかし、click(x,y)あるコンポーネントを呼び出すと、別のボタンであろうとラベルであろうと、すべての clickHandlers が呼び出されます。

上記のように、focusこれと呼ばれるパラメーターを設定していますが、同じ問題が発生しているようです.1つのコンポーネントに設定すると(各コンポーネントをループしているのがわかります)、すべてに設定されます(したがって、4つのコンポーネントがある場合)フォーカスは各コンポーネントで 4 回リセットされます)

lua がこれを行うのはなぜですか? また、それを修正するにはどうすればよいですか?

4

1 に答える 1

2

まず、問題を示す完全に機能する例を投稿しただけでは、小さなスニペットから何が起こっているのかを理解しようとするのがはるかに困難になります。

self.components には、ウィンドウのすべてのコンポーネントが含まれています

これはおそらくあなたの問題です。繰り返しますが、メソッドを示していないため、これは推測ですがcreate、コンストラクターがインスタンスclickCallbackごとにメンバーを初期化していない場合は、クラス自体でテーブルを使用します。

問題を示す例を次に示します。

component = {}
component.__index = component

component.clickCallback = {}

function component.create()
  return setmetatable({}, component)
end

function component:addClickHandler(handler)
  table.insert(self.clickCallback, handler)
end

function component:click(x,y)
  for _,callback in pairs(self.clickCallback) do
      callback(x,y)
  end
end

a = component.create()
b = component.create()

a:addClickHandler(function(x,y) print("a", x, y) end)
b:addClickHandler(function(x,y) print("b", x, y) end)

a:click(10,20)
b:click(11,22)

あなたが説明した症状を示す出力は次のとおりです。

a       10      20
b       10      20
a       11      22
b       11      22

つまり、 を呼び出すと、 anda:clickのハンドラが呼び出されます。これは、テーブルがクラス自体にあり、そのクラスのすべてのインスタンスで共有されているためです。各インスタンスに独自のハンドラー テーブルがあることを確認する修正:abclickCallback

component = {}
component.__index = component

function component.create()
  return setmetatable({ clickCallback = {}}, component)
end

function component:addClickHandler(handler)
  table.insert(self.clickCallback, handler)
end

function component:click(x,y)
  for _,callback in pairs(self.clickCallback) do
      callback(x,y)
  end
end

a = component.create()
b = component.create()

a:addClickHandler(function(x,y) print("a", x, y) end)
b:addClickHandler(function(x,y) print("b", x, y) end)

a:click(10,20)
b:click(11,22)

出力:

a       10      20
b       11      22
于 2012-07-15T04:18:17.370 に答える