02-03-2021 11:05 AM
Ah, found the Help document that describes this behavior:
https://zone.ni.com/reference/en-XX/help/371361K-01/lvhowto/reg_event_foreach_es/
If you wire the event registration refnum to more than one Event structure, each Event structure handles dynamic events out of the same event queue. This can occur if you branch the event reg refnum out output of a Register For Events function to another Event structure. This causes a race condition, because the first Event structure to handle the event can prevent the other Event structure from receiving the event if it completes the event case before the other Event structure executes.
(Emphasis mine)
If I read this right, it's saying that both COULD get to it, but the event isn't removed from the dequeue when the case STARTS but when the case FINISHES. This means that two loops CAN grab the same event, but might not if one finishes before the other one can catch the event.
02-03-2021 11:11 AM
Interesting, it looks like if they're both waiting for the event they can both get it.... but sometimes only one does.
Still reinforces the concept of having separate registrations per event structure.
02-04-2021 01:47 AM
Thank you for all the answers! Seems that I was not the only one not knowing how this works.
Then another question.
On earlier experiments I used lot of state machines which has while loop with shift registers and case structure.
If I have this kind of structure, would this also require register for every case structure also?
The wrong way presented in the pictures?
Two states which both connected to same register?
If I really need this then it should be like this?
Actor framework is "easy" when you just wait for user inputs like buttons to be pressed. With UI that has lots of components that needs to be enabled/disabled/background color changed etc. according users actions and some measurements, it gets tricky. That kind of state machine would make it easy, but then again dynamic stop event makes life hard if there are lot of states.
02-04-2021 02:50 AM
Dynamic events are new thing to me and I just realized that I'm trying to catch and handle all of them in actor core. But if I run another Vi with while loop and event structure I can caught and handle the dynamic event there?
02-04-2021 03:17 AM
@Waltteri wrote:
Then another question.
On earlier experiments I used lot of state machines which has while loop with shift registers and case structure.
If I have this kind of structure, would this also require register for every case structure also?
Instead of event handlers inside cases of a case structure on State, consider a single event handler, with case structures on State inside that.
So, in words, rather than what you have:
Given State 1
--When Event X happens do Y
Have
When Event X happens
--If in State 1 do Y
This is the way it is more commonly done, I believe. It makes events that apply to many or all states (like your stop event) easy.
02-04-2021 05:11 AM
I created a new vi from static dispatch template.
It has while loop and event structure with three events. Two other events are working but the Stop is not working. When I stop the actor core, this Vi keeps on running.
Any ideas why is that?
02-04-2021 05:25 AM
@Waltteri wrote:
I created a new vi from static dispatch template.
It has while loop and event structure with three events. Two other events are working but the Stop is not working. When I stop the actor core, this Vi keeps on running.
Any ideas why is that?
Are you sure, the events have been unregistered only after your event loop is ended? Maybe the root "race-condition-ish"
02-04-2021 07:31 AM
What is the visibility of the stop event?
I mean if I have nested actors in array and when I send the stop event to all of them, should they all unregister the event that they receive or is it the same event for everyone?
02-04-2021 07:40 AM - edited 02-04-2021 07:44 AM
1.) Where / in which function does your Actor send the Stop event to the helper loop?
2.) When do you unregister the events/ destroy the event ref for the stop event for the helper loop? If you do this immedeatly after firing the stop event it might not be recieved by the event case. If so, sending a different event (which usually works) instead of a stop from the same location withinin your code will also fail.
You might also want to check https://youtu.be/F8DiZrDcres?t=1305
02-04-2021 12:55 PM
@Waltteri wrote:
Thank you for all the answers! Seems that I was not the only one not knowing how this works.
Then another question.
On earlier experiments I used lot of state machines which has while loop with shift registers and case structure.
If I have this kind of structure, would this also require register for every case structure also?
The wrong way presented in the pictures?
Two states which both connected to same register?
If I really need this then it should be like this?
Actor framework is "easy" when you just wait for user inputs like buttons to be pressed. With UI that has lots of components that needs to be enabled/disabled/background color changed etc. according users actions and some measurements, it gets tricky. That kind of state machine would make it easy, but then again dynamic stop event makes life hard if there are lot of states.
Neither of those are good solutions. While I *think* the first method would work, since only one structure is called, it's going to be VERY hard to ensure nothing gets stepped on. The thing with user event queues is that they're not really queues (like you've seen discussed). When you only have one handler, it's fine to think of it that way, but with multiples it's not a good idea. You still have two handlers tied to the same RfE node, and you might one day find that the handler for state 1 still thinks it needs to handle a case even though it was sent when state 2 was active.
Your second method is extra bad, as you will queue up unhandled events while you're in State 2. When you go back to State 1, all of those events will spill out at once.
The right way to do it is to handle state *within* the handler, not externally to it (like drjdpowell said).
Regarding your Stop case not working. This code looks like you might have done something wrong. The fact that you have your Actor coming in AND coming out means you've likely split your Actor wire. Helper loops should read references only. What are you doing with your Actor output?