Lua Event Handler

Does lua have an “event handler” or does it have lib available for this?

So, an example, when "a = 100" event occurs.

Something else, not usage:

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

Or just add a dream to it. "While true do" is just an example, but its scary.

+5
source share
2 answers

Lua runs on a single thread, so any check must be explicitly performed by your code.

The act of executing code immediately after changing a variable is known as "lookup."

If you program in an environment where a set of codes for each frame is started (for example, a game), you can check it manually. For instance:

 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 

After the next frame, a callback code (print) will be executed. The disadvantage of this approach is that the callback code does not print immediately after WatchedVariables.a set to -7 , that is: the output will be:

 about to change a, brother! a is changed NEXT FRAME! (possibly 1 second later or something) a changed from 5 to -7 

To prevent this potentially unwanted behavior, you can use the setter function, for example:

 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 

The result of this code shows that the callback is immediate:

 about to change a, brother! a set to -7 a is changed 

To make this more comfortable, Lua provides metatables that make this behavior transparent to the programmer. Example:

 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 

The result of this code will be the same as in the previous example:

 about to change a, brother! a set to -7 a is changed 

Here is an implementation for an example of your example:

 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 

Why are the __privates and __private_callback variables prefixed with two underscores? Matching the prefix of private members that should not be addressed in typical programming situations with two underscores. If you are familiar with the object-oriented methodology and its implementation in languages ​​such as Java and C ++, you will understand how they look like the private and protected keywords.

If you are familiar with C #, you can see how the set_a / get_a and metatable implementers look like accessors ( set / get ).

+16
source

tried the code in lua 5.3.5, the output is not output. The code also generates an error in line 5 when using the last code. Error in question

 __privates = { a = 5, } 

whereas the code was supposed to be

 __privates = { a = 5 }, 
0
source

Source: https://habr.com/ru/post/1383549/


All Articles