Speaking from a Bug:
Found in the internal demo players have a task to follow the logic Npc hung up.
telnet to connect the device to the problem, things began to engage in
This follows the logic is driven by a Timer. The Timer will start when the main character is created. Initially not considered a problem Timer itself. Suspect there are various places on the return flow situation
Dynamic get rid of a few functions are not implemented to Description Timer callback not called to. Suspect Timer itself
Timer output of the state, found to be running = true. I feel very surprised. Also read Timer in other fields found to have a handle. Output of view the next, found a removed = true.
Here wonder, explanation is abnormally removed the realization began to see the Timer:
Timer.lua create a Timer process is as follows:
1. Timer.New()
Create a table yuan, the underlying field initialization. Running = false ...
2. Timer.Start ()
1) Create a Handle from UpdateBeat
By calling UpdateBeat: CreateListener, incoming Timer.Update and Timer function return value itself Handle, its role is a list of Node.
代码: self.handle = UpdateBeat:CreateListener(self.Update, self)
2) Sign in to UpdateBeat:
That is, the handler as a node linked list into a list UpdateBeat's.
代码: UpdateBeat:AddListener(self.handle)
3). At this time, the Timer class initialization process is complete. Timer.Update follow-up waiting to be called up. You can see the main content is in fact UpdateBeat years.
4) To understand the invocation Handle management and Timer.Update we must think UpdateBeat code
5). UpdateBeat is defined in the event.lua
We can see a _event metatable
6) concerns the contents _event:
#1 _event.CreateListener(func, obj)
That is above 1 function) in the call, func here is Timer.Update, obj is the Timer itself.
Here judged self.keepSafe, i.e. 5) defined in the second parameter of true UpdateBeat so here self.keepSafe = true.
You can see the case keepSafe of, func and obj is wrapped into a xfunctor where this xfunctor read, is a xpcall package. That is keepSafe the event is executed with xpcall way when func actual call. Wrong, then returns throwing the wrong information.
Followed by several other fields, including cached package the value of the field xpcall function Timer.Update . Implement two pointers (_prev, _next) doubly linked list of needs, and we have to check bug concern removed = to true . Can see at the beginning of Timer.Start application Handle, this is the true state of removed.
#2_event.AddListener
After creating the Handle, the interface is registered by AddListener linked list can be seen here judge the effect of this field is self.lock lock self.list. That avoid when operating list, there are other logic to change this list.
The lock field is set when performing an Update to true after the completion of the implementation of a change in the process lock false is true, if there are other AddListener behavior, will conduct the Add to cache a temporary list:.. Self. opList in, rather than self.list
This list cache Add operation that is function () self.list:... After pushnode (handle) end and then wait to perform an Update, the Add the cache operations are performed again (RemoveListener empathy)
#3 _event.__call
This function is performed when the calling operation _event. Below UpdateBeat ()
__call function first locked lock = true. Then use the iterator generator ilist traverse the list list. This list is our AddListener Operating Storage doubly linked list of Timer. (ilist see detailed explanation below)
. Each iteration of i shall be a handle, f is xpcall packaging Timer.Update function and then calls the function f, the result of a successful return xpcall identity:. Flag, error msg If an error occurs, the error is thrown with LuaException and calls. _list.remove, removing the Node from the list, and unlock: lock = false
(There is a problem, if one of Timer wrong, then unlocked, really stuffed behind Timer Timer come in, are we going to bomb ?? seek to explain.)
If all normal circumstances, would be to cache the Add / RemoveListener of operations performed again at the end.
ilist list.lua iterator can see, the iterative returns generated depending on the nature of the for statement Lua three values: Iterated Function (list.next), a steady state (i.e. the _list), control variables (useless ). then a constant state variable and control parameters for the iterative function to call, and then the obtained return value assigned to the key for loop, value (<var-list>)
So iterative function list.next. This function requires only a constant state (first time list, in fact, the head node, followed by each node) can, because directly accessible through next next. When the next is when the first node, loop end.
for circular definition:
for <var-list> in <exp-list> do
list.lua: