03-13-2024 05:52 PM
Hi,
I did exactly that. I created two actors and stored the enqueuer of each actor in other Actors private data and launched the actors and send the message with the enqueuers.
This is the launcher which launches two actors A and B. Then Send Write A Enqueuer sends Actor A's Enqueuer to B and vice verse.
Then inside actor core of Actor A i have created a numeric control and in actor B I have created a numeric indicator. Then I created a reference to the numeric indicator in B and then created a control of the reference and then stored that control in the private data of actor B and then created a function to update the numeric control using property node.
Then I created a message for this function and used this message in Actor Core of A to update the value. B's enqueuer is obtained by unbundling the private data of A and there is a numeric control in A and its value is given to the message along with B's enqueuer.
This is actor core of A.
This is actor core of B.
And what I expect is when i change the numeric control in Actor core of A, it automatically changes the numeric indicator in actor core of B. But it is not happening.
So I did this same question as nested actors, where launcher launches A and A launches B, so there was no need to send enqueuer, B's enqueuer was already available in A and I ran the program there and it worked. So with nested actors it worked, but with parallel actors it is not working. Why is this? What am i doing wrong. If the pictures are not good please be free to check the zip file that contains the entire program. Thank you.
03-13-2024 06:54 PM
The issue is that you have blocking code in your actor cores, the user event loops ( and any other blocking code ) will prevent the actor core ( for the actor base class ) from running which prevents any messages from being processed. Typically your actor cores should do very little. Remove all the code from the actor core and instead make an actor method that pops up a window to indicate the state of the actor. A down side of actors is that you have to do extra work to use them with user event loop VIs like in standard labview code.
03-14-2024 02:55 AM
Blocking code is not the problem here. The parent Actor Core will execute in parallel to the UI.
Check the error output of Send Update Numeric Indicator. The enqueuer is invalid.
When you read the enqueuer of Actor B in Actor A's Actor Core, you are reading from the state before it received Actor B's Enqueuer.
Create another message that you can send from AC-A to itself that uses the enqueuer from the current class data for Send Update Numeric Indicator.
03-14-2024 04:06 AM
I did not try to debug your code but here is a simple example I made where a regular VI launches two instances of the same actor that can send messages to each other:
03-14-2024 04:49 AM
Hello @LucianM,
thank you very much but could you release that in LabVIEW 2016. Is it possible? Thank you.
03-14-2024 05:07 AM
Here is the project saved for LV16.
03-14-2024 08:17 AM
@cordm wrote:
Blocking code is not the problem here. The parent Actor Core will execute in parallel to the UI.
Check the error output of Send Update Numeric Indicator. The enqueuer is invalid.
When you read the enqueuer of Actor B in Actor A's Actor Core, you are reading from the state before it received Actor B's Enqueuer.
Create another message that you can send from AC-A to itself that uses the enqueuer from the current class data for Send Update Numeric Indicator.
I was totally wrong, sorry for the bad advice.
03-14-2024 09:17 AM
Thank you. I did exactly what cordm told me to do to and I was able to solve it. Now I have two actors, and I am able use numeric, string and boolean controls in actor a to control numeric, string and boolean indicators in actor b and also vice versa. Thank you very much for helping. But now comes the final part of the program. Earlier I had a stop button in both actors and I stop them individually. Now I need to update the program to stop both actors with either of the stop buttons. That is if I press stop button of Actor A, then both A and B should stop and vice versa. How i tried to do is the same as sending the numeric value. But instead of sending a numeric value, I am trying to send a user event. Pressing stop creates a user event called stop and I send it exactly the same way as I send the numeric value. That is I created a user event control in the private cluster data of both actors and I use that to send the user event. So i press stop in A, the user event is generated and this is then send as a message to actor b and in the user event is executed in the event structure to stop and close the actor. But this is not working. I believe this is due to me not understanding of user events properly. Please check the code and let me know where have I made the mistake. Also for now only stopping from A to B is done. I havent implented B to A, since A to B stopping is not working. Thank you.
03-14-2024 12:01 PM - edited 03-14-2024 12:02 PM
Yes, you should learn a bit more about user events.
The user event refnum is never created, it is just a constant that cannot be used for anything.
That invalid refnum is sent to one actor that just stores it. The actor that receives the user event refnum could generate an event in the sending actor using that refnum. Don't do that. Do not use user events to communicate between actors, use messages.
All you need to do is to send a stop message to the other actor when one actor terminates.
You also need to make sure your helper loop stops.
Look again at what LucianM posted:
- create user event
- register for that event
- call actor core
- generate event after actor core returns (ignoring errors!)
- destroy user event
You can also do that in other VIs:
03-14-2024 01:04 PM - edited 03-14-2024 01:22 PM
So this is the stop core of A. I tried what you told me, overriding prelaunch init and stop core. And it worked. Stopping one, stopped both. Thank you very much