Event Handler Order
nicholasjames
Posts: 154
This comes out of some testing I was doing involving this thread, but I discovered something new, so new thread.
Essentially what I was testing was the discovery that NetLinx runs all handlers for an event before checking the wait lists, whereas I had been under the impression that it occurred between each event handler.
In my test code, for each handler, I was calling a WAIT 0 (which expires immediately).
I expected to see this in diagnostics:
But instead saw this:
So when the event comes out of the message queue it's:
CHANNEL 1 ON
- RUN HANDLER 1
-- PLACE WAIT 1 ON WAIT LIST
- RUN HANDLER 2
-- PLACE WAIT 2 ON WAIT LIST
- RUN HANDLER 3
-- PLACE WAIT 3 ON WAIT LIST
CHECK WAIT LIST
- RUN WAIT 1
- RUN WAIT 2
- RUN WAIT 3
NEXT EVENT...
This image (and corresponding tech note) essentially explains that, but I had always thought of each handler as being on the message queue when in fact the message is "CHANNEL 1 ON" and each handler is run as part of that message.
The thing that I found really interesting was when I added a 0 "catch all" wildcard handler:
Since I had placed my wildcard handlers after the explicitly defined ones I assumed event order would also place the wildcard diagnostic text after the explicitly defined ones.
To my surprise I got this:
The Language Reference Guide states "More than one handler can be defined for the same event. In this case, the handlers are executed in the order in which they are defined in the program.", but keep in mind, a wildcard event handler runs before any other explicitly defined handler for that channel regardless of order.
Enjoy!
Essentially what I was testing was the discovery that NetLinx runs all handlers for an event before checking the wait lists, whereas I had been under the impression that it occurred between each event handler.
In my test code, for each handler, I was calling a WAIT 0 (which expires immediately).
// IN MAIN CHANNEL_EVENT[vdvDevice, 1] { ON: { SEND_STRING 0, "'MAIN HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MAIN HANDLER END'"; } } } // IN MODULE 1 CHANNEL_EVENT[vdvDevice, 1] { ON: { SEND_STRING 0, "'MODULE 1 HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MODULE 1 HANDLER END'"; } } } // IN MODULE 2 CHANNEL_EVENT[vdvDevice, 1] { ON: { SEND_STRING 0, "'MODULE 2 HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MODULE 2 HANDLER END'"; } } }
I expected to see this in diagnostics:
MAIN HANDLER START MAIN HANDLER END MODULE 1 HANDLER START MODULE 1 HANDLER END MODULE 2 HANDLER START MODULE 2 HANDLER END
But instead saw this:
MAIN HANDLER START MODULE 1 HANDLER START MODULE 2 HANDLER START MAIN HANDLER END MODULE 1 HANDLER END MODULE 2 HANDLER END
So when the event comes out of the message queue it's:
CHANNEL 1 ON
- RUN HANDLER 1
-- PLACE WAIT 1 ON WAIT LIST
- RUN HANDLER 2
-- PLACE WAIT 2 ON WAIT LIST
- RUN HANDLER 3
-- PLACE WAIT 3 ON WAIT LIST
CHECK WAIT LIST
- RUN WAIT 1
- RUN WAIT 2
- RUN WAIT 3
NEXT EVENT...
This image (and corresponding tech note) essentially explains that, but I had always thought of each handler as being on the message queue when in fact the message is "CHANNEL 1 ON" and each handler is run as part of that message.
The thing that I found really interesting was when I added a 0 "catch all" wildcard handler:
// IN MAIN CHANNEL_EVENT[vdvDevice, 1] { ON: { SEND_STRING 0, "'MAIN HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MAIN HANDLER END'"; } } } CHANNEL_EVENT[vdvDevice, 0] { ON: { SEND_STRING 0, "'MAIN ALL HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MAIN ALL HANDLER END'"; } } } // IN MODULE 1 CHANNEL_EVENT[vdvDevice, 1] { ON: { SEND_STRING 0, "'MODULE 1 HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MODULE 1 HANDLER END'"; } } } CHANNEL_EVENT[vdvDevice, 0] { ON: { SEND_STRING 0, "'MODULE 1 ALL HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MODULE 1 ALL HANDLER END'"; } } } // IN MODULE 2 CHANNEL_EVENT[vdvDevice, 1] { ON: { SEND_STRING 0, "'MODULE 2 HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MODULE 2 HANDLER END'"; } } } CHANNEL_EVENT[vdvDevice, 0] { ON: { SEND_STRING 0, "'MODULE 2 ALL HANDLER START'"; WAIT 0 { SEND_STRING 0, "'MODULE 2 ALL HANDLER END'"; } } }
Since I had placed my wildcard handlers after the explicitly defined ones I assumed event order would also place the wildcard diagnostic text after the explicitly defined ones.
To my surprise I got this:
MAIN ALL HANDLER START MODULE 1 ALL HANDLER START MODULE 2 ALL HANDLER START MAIN HANDLER START MODULE 1 HANDLER START MODULE 2 HANDLER START MAIN ALL HANDLER END MODULE 1 ALL HANDLER END MODULE 2 ALL HANDLER END MAIN HANDLER END MODULE 1 HANDLER END MODULE 2 HANDLER END
The Language Reference Guide states "More than one handler can be defined for the same event. In this case, the handlers are executed in the order in which they are defined in the program.", but keep in mind, a wildcard event handler runs before any other explicitly defined handler for that channel regardless of order.
Enjoy!
0
Comments