lua是否有一个“事件处理程序”内置或它有一个lib可用来做到这一点?Lua事件处理程序
因此,举个例子,当“a = 100”事件发生时。
别的东西,而不是使用:
while true do
if a == 100 then
[...]
break;
end
end
还是简单地增加睡眠吧。 “虽然真的做”只是一个例子,但它是一个可怕的例子。
lua是否有一个“事件处理程序”内置或它有一个lib可用来做到这一点?Lua事件处理程序
因此,举个例子,当“a = 100”事件发生时。
别的东西,而不是使用:
while true do
if a == 100 then
[...]
break;
end
end
还是简单地增加睡眠吧。 “虽然真的做”只是一个例子,但它是一个可怕的例子。
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
为了防止这种潜在的不希望的行为,一个设定器函数可用于,例如:
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
前缀有两个下划线?约定以私有成员为前缀,在典型编程情况下不应使用两个下划线进行访问。如果您熟悉面向对象的方法,并且在Java和C++等语言中实现它,您将会了解它与private
和protected
关键字的相似之处。
如果你熟悉C#语言,你可能会看到set_a
/get_a
和元表如何实现类似于存取(set
/get
)。
好吧。基本上检查一个值,如果它满足一个事件被调用的要求。只是不要以“ifs”的方式来做,或者像上面的“while true do”那样做,因为它不适合。例如,可以在任何时候满足要求,而不是我可以调用if语句的特定部分或时间。我希望能解释一下。 – luacoder