Lua's syntax is very flexible. Using Its retriable and metamethod can simulate the features of many languages.
In C #, we use the event as follows:
Xxx. Click + = New System. eventhandler (xxx_click );
Private VoidXxx_click (ObjectSender, eventargs E)
{
/**/
}
To achieve the same effect in Lua and support event multicast mechanism, the key is to rewrite metamethod _ call so that not only functions can be called, but also tables can be called.
The main idea is to use a table to save several response functions for event registration, and then use the table as the function to call it. After rewriting _ call, implement traversal and execution of the Registration Method in the table when calling the table.
It needs to be executed on lua5.0 or lua.net, and Lua 5.1 is slightly changed.
-- Test. Lua
Do
--Event prototype object. All events are generated by this prototype.
Event ={}
Function Event : New ()
Local Event = {}
Setretriable ( Event , Self)
-- Overwrite _ index Logic
Self. _ Index = Self
-- Overwrite _ call logic
Self. _ call = Self. Call
Return Event
End
--Event registration: registers the response method to the event.
--@ Source: the object to which the response method belongs
--@ FUNC: Response Method
Function Event: Add (source, func)
Table. insert (self, {source, func })
End
-- Internal method. The default _ call logic is rewritten. When an event is triggered, the response method registered in the event is cyclically executed.
-- @ Table: when an object is called, it is passed in.
-- @: Call Parameters
Function Event . Call (table ,)
For _, Item In Ipairs (table) Do
-- Item [ 1 ] Is source, item [ 2 ] Is the func response method.
-- Lua 5 . 1. You can directly use it without using unpack (ARG ).
Item [ 2 ] (Item [ 1 ], Unpack (ARG ))
End
End
------------------The following are test cases:-----------------------
--Create a window object and register the Click Event of the button
Window={
Name= "Simonw's window",
}
function window: Init ()
-- register an event, self is window, object source.
button. clickevent: add (self, self. button_onclick)
end
-- event response method, sender is the passed Button Object
function window: button_onclick (sender)
Print (sender. name .. " click on " .. self. name)
end
-- Create a button object, event with clickevent
button = {< br> name = " A button " ,
-- Create an event
clickevent = event : New (),
}
-- click the button
function button: Click ()
Print ( ' click begin ')
-- trigger an event, self is the sender parameter
self. clickevent (Self)
Print ( ' click end ')
end
--Execute from here
Window: Init ()
Button: Click ()
--[[
Execution result:
>Dofile'Test. lua'
Click begin
A button clickOnSimonw'S window
ClickEnd
]
End