[解決済み] Luaイベントハンドラ
質問
lua には "event handler" が組み込まれているのですか、それとも lib が用意されているのですか?
例えば、"a = 100"のときにイベントが発生するように。
使うのではなく、何か別のものを。
while true do
if a == 100 then
[...]
break;
end
end
単純にスリープをつけるとか。while true do"はほんの一例ですが、これはひどいものです。
解決方法は?
Luaはシングルスレッドで動作するため、チェックはコードで明示的に行う必要があります。
変数が変化したときにすぐにコードを実行することを、ウォッチといいます。
もし、あるコードのセットが毎回実行されるような環境でプログラミングをしている場合 フレーム (ゲームなど)であれば、手動で確認することができます。 例えば
WatchedVariables = {
a = 5,
b = 22,
}
WatchedVariables_cache = {}
for k,v in pairs(WatchedVariables) do
WatchedVariables_cache[k] = v
end
function OnFrame()
print("NEXT FRAME! (possibly 1 second later or something)")
for k,v in pairs(WatchedVariables) do
local v_old = WatchedVariables_cache[k]
if v ~= v_old then
-- this is the "callback"
print(tostring(k).." changed from "..tostring(v_old).." to "..tostring(v))
WatchedVariables_cache[k] = v
end
end
end
function SomeFunctionThatOperatesSomeTime()
print("about to change a, brother!")
WatchedVariables.a = -7
print("a is changed")
end
次のフレームで、コールバックコード(print)が実行されます。
この方法の欠点は、コールバックコードがプリントされないことです。
すぐに
後
WatchedVariables.a
が設定されています。
-7
, つまり: 出力は次のようになります。
about to change a, brother!
a is changed
NEXT FRAME! (possibly 1 second later or something)
a changed from 5 to -7
この望ましくない可能性のある動作を防止するために セッター 関数を使用することができます。
MyObject = {
_private_a = 5,
set_a = function(self, new_value_of_a)
self._private_a = 5
-- callback code
print("a set to "..tostring(new_value_of_a))
end,
get_a = function(self)
return self._private_a
end
}
function SomeFunctionThatOperatesSomeTime()
print("about to change a, brother!")
MyObject:set_a(-7)
print("a is changed")
end
このコードの出力は、コールバックがすぐに実行されることを示しています。
about to change a, brother!
a set to -7
a is changed
これをより快適にするために、Luaでは メタテーブル は、このような動作をプログラマが理解できるようにするものです。 例を挙げます。
MyObject = {
__privates = {
a = 5,
}
}
MyObject_meta = {
__index = function(self, k)
return rawget(self, "__privates")[k]
end,
__newindex = function(self, k, v)
rawget(self, "__privates")[k] = v
-- callback code
print("a set to "..tostring(v))
end,
}
setmetatable(MyObject, MyObject_meta)
function SomeFunctionThatOperatesSomeTime()
print("about to change a, brother!")
MyObject.a = -7
print("a is changed")
end
このコードの出力は、前の例と同じになります。
about to change a, brother!
a set to -7
a is changed
以下は、例のケースでの実装です。
MyObject = {
__privates = {
a = 5,
}
__private_callback = function(self, k, ov, v)
if k == "a" and v == "100" then
print("a is 100!")
end
end
}
MyObject_meta = {
__index = function(self, k)
return rawget(self, "__privates")[k]
end,
__newindex = function(self, k, v)
local privates = rawget(self, "__privates")
local ov = privates[k]
privates[k] = v
rawget(self, "__private_callback")(self, k, ov, v)
end,
}
setmetatable(MyObject, MyObject_meta)
function SomeFunctionThatOperatesSomeTime()
MyObject.a = -7 -- prints nothing
MyObject.a = 100 -- prints "a is 100!"
MyObject.a = 22 -- prints nothing
end
なぜ、変数が
__privates
と
__private_callback
の前にアンダースコアが2つ付いているのは?
一般的なプログラミングでは、アクセスしてはいけないプライベートメンバーの前にアンダースコアを2つ付けるのが慣例となっています。オブジェクト指向の方法論と、JavaやC++などの言語での実装に詳しい人なら、これがどのように
private
と
protected
のキーワードを使用します。
C#言語をご存知の方なら、このように
set_a
/
get_a
であり、metatableの実装はアクセッサに似ている(
set
/
get
).
関連
-
[解決済み] Lua: グローバルな 'mapfinishes' (nil 値) に対して演算を実行しようとした。
-
[解決済み] .luaスクリプトを実行するにはどうしたらいいですか?[クローズド]。
-
[解決済み] Luaスクリプトのメモリ使用量を制限する?
-
[解決済み] Luaでのインクリメント
-
[解決済み] Luaイベントハンドラ
-
[解決済み] 何をするのか? for i=1,select('#',...)
-
グローバルな 'setmetatable' (nil 値) または同様のものを呼び出そうとすると、lua がエラーを報告する。
-
Lua基本関数 type、tonumber、tostring、pcall、print
-
[解決済み] Luaでテーブルが要素を含んでいるかどうかを確認するには?
-
[解決済み] Luaでファイルからデータを読み込む方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Luaスクリプトを終了させるには?
-
[解決済み] Luaでのインクリメント
-
[解決済み] Luaにおけるmath.random()とmath.randomseed()の違いについて
-
[解決済み] LuaでNewLine( \n) alternative?
-
[解決済み] トーチ[cpuType]の文法説明
-
lua が表示される xxx: nil 値 (フィールド 'getn') を呼び出そうとする 解決方法
-
このエラーは、LUA が nil 値(グローバル 'loadstring')を呼び出そうとしたときに発生しました。
-
lua loadlib 関数がグローバルな 'loadlib' (nil 値) を呼び出そうとする
-
[解決済み] <' の近くに予期しない記号がある
-
[解決済み] Luaでファイルからデータを読み込む方法