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