gpt4 book ai didi

Lua 事件处理程序

转载 作者:行者123 更新时间:2023-12-04 13:17:25 30 4
gpt4 key购买 nike

lua 是否有一个“事件处理程序”内置或者它有一个可用的库来做到这一点?

因此,例如,当“a = 100”时发生事件。

别的东西,而不是使用:

while true do
if a == 100 then
[...]
break;
end
end

或者只是给它添加一个 sleep 。 “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

在下一帧,回调代码(打印)将被执行。
这种方法的缺点是不打印回调代码 立即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

为了防止这种潜在的不良行为,可以使用 setter 函数,例如:
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前缀有两个下划线?在典型的编程情况下,不应使用两个下划线为不应访问的私有(private)成员添加前缀是惯例。如果您熟悉面向对象的方法及其在 Java 和 C++ 等语言中的实现,您将了解它与 private 的相似之处。和 protected关键字。

如果您熟悉 C# 语言,您可能会看到 set_a/ get_a和元表实现类似于访问器( set/ get )。

关于Lua 事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8305248/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com