Just a quick note about this video: In this video, I'm assuming you already know your way around Actor Framework, I'm also assuming you know why we use abstract messages to send data from a nested actor to a calling actor. Hence why I don't explain why we should be using abstract/interface messages. If you're unsure about Actor Framework/have no idea what I'm on about, check out my Actor Framework tutorial series: th-cam.com/video/2k3ZDwJolbA/w-d-xo.html Regarding why we should be using abstract messages (and now interface messages), I explain that in my abstract message video (link below). But the quick answer is to reduce dependencies between the nested actor and the calling actor. The nested actor shouldn't know who the calling actor is. If we used standard messages, the nested and calling actors would be tightly coupled, which would mean you couldn't use the nested actor in another project without the calling actor. th-cam.com/video/eTaufgA7Lkc/w-d-xo.html Also, one thing I forget to mention, with the interface messages, ANY ACTOR that inherits from the interface can receive the messages - No extra work required! WOO! 😁
I don't know if its me, but I am finding that if a Calling actor chooses not to implement an interface defined message handling VI i.e. it does not want to know about something the nested-actor is periodically telling it, the framework can't handle it and errors are produced. Are interfaces optional to a caller or MUST the caller inherit and implement them?
@@stephencole9377 Hi Stephen, an interface is a contract that demands all overrides are implmented. The calling actor should implement (inherit from) the interface defining the messages - and then you will see you get a broken run arrow until all methods are implmented. Until then you will get run-time errors. I hope this makes sense.
Brilliants series. Really has clarified the AF pattern for me. And what is best is that it is quick and gives you just enough clues to get you thinking and trying stuff for yourself. I don't know how many times I have replayed these lessons picking up with eventual understanding a point being mentioned. Great piece of work which I hope is never taken down.
Yes, this is great and I can't wait to see more from you and interfaces. I am watching this now for the 5th time and I slowly start to get my head into this.
I'm glad you're finding it helpful. I would recommend downloading the code and having a play around yourself. It's one of those things where once it 'clicks' it will make total sense :)
Hi Tom, thanks a lot for this video (and all the other ones) I have a question regarding your comment: "Also, one thing I forget to mention, with the interface messages, ANY ACTOR that inherits from the interface can receive the messages - No extra work required! WOO! 😁" I have an arborescence of calling and nested actors and I would like to send a message from a nester actor (level 4) to the "caller of its caller" (level 2 or even 1). How do I recover those enqueuers? Or is just not possible and I would have to send this message to its caller and then it will have to pass it along? - But then all my nested actors would have to inherit from the interface message I would like to send to the "root"? I hope my question is not too confusing. In any case I do appreciate your help. And by the way, I enjoyed the GLA summit, thanks.
Hi Tom, Thank you for all your great videos on AF. I didn't know much about AF before watching your video series, and I really enjoyed watching all of them. Videos are well made, easy to follow , and very useful. I will highly recommend to anyone new to AF of watching your videos. Thanks again! I will check your other tutorial series for sure.
Hey Tom, I have a fundamental question, what techniques do you use to store and share large data sets between several Actors? Global variables, FGV, or DVR? For example, I have a measurement machine with a UI actor, which handles the basic framework tasks and I have several process actors that need to read and write to the data pool, which then will be saved to file. Could you give me any advice? Cheers
When using AF, I try not to mix-up data transfer mechanisms. When using a framework you should try to follow the rules (i.e send messages up and down the actor tree hierarchy). That being said... I'm sharing global data by using variant attributes wrapped in a DVR. Using a variant attributes as a CVT I believe is the fastest way of setting and getting data. I have a separate PPL that handles all of the reading/writing to the CVT and can save/read from file, in the PPL I also have wrappers for every read and write operation. This technique works for me and is very effective. However, global variables are also a valid form of tag communication - but I would always wrap the sets/gets in VIs and make the 'Set' VIs private. FGVs are also fine, but a Global Variable achieves the same thing and it's quicker to implement. Globals are good to use, but only if you're responsible with them ;)
Hi Tom, thanks for the explanation, it is not quite obvious where to look for the scripting tool for creating messages using the interfaces. I have a question though regarding your overall architecture. In your system, the Business logic actor is the Root Actor, and redirects the data from one its nested actors to the other. Is there any advantage of not making a UI a Root Actor. That way if you need to reuse Business Logic Actor in a larger application, you can simply "disconnect" it from the UI and reconnect into the appropriate caller. I naively think that since the only data transfer direction for the Business Logic Actor is up, this won't change in the larger application, by simply creating a new interface for the the interaction with new caller. It could be a different way of thinking, however, I saw the approach similar to yours (GUI not being the root actor) in other large applications so there must be a good reason for this. Thanks.
You are doing the LabVIEW world such a huge favor! Thanks again. Question - Is this what should be used when a nested actor is to tell the caller to shutdown?
Hey Colin, Yep. To stop a calling actor you can use the 'Send normal stop message' function (that just sends a stop message). However, remember, by default, if your calling actor stops, the nested actors are going to stop too. If you don't want this to happen, you can use a FALSE constant for "Auto-Stop (T)" when launching the nested actor. N.b. Well done on making it through all the videos, it's been quite satisfying seeing your comments filter through the playlist throughout the week!
@@TomsLabVIEWAdventure Oh right, and I suppose it's even easier to read enquerer from caller and send normal stop with out even using the interface message. Everything is still sinking, I will definitely re-watch several times. This channel is my goto for all things LabVIEW now! Cheers.
Tom, you are a lifesaver!! Is there any way for you to attach note to your Abstract Messages video referring to the new interface capabilities of LV2020? Thanks.
Another great video, Tom. I know you're a user of plugins and PPL's, how would that be implemented using interfaces for the abstracted messages? I attempted this by creating a Abstract Messaging interface library, and building that into a PPL. Then added that PPL to the test project. After creating the required overrides I ended up with a broken wire when connecting the Caller Enqueuer ref to the Send.vi from the PPL.
Hi Josh, I use PPLs a lot with other frameworks, but I haven't had much of a need with AF (yet). I'll give it ago over the next week or so and get back to you. I "know" why you're getting that behaviour but, until I try it myself and come up with a good build process, I don't want to share potentially inaccurate information.
Hey Tom, great video again. I have a question about abstract message you might be able to help me with? In my project the business logic actor launches multiple nested actors of the same class type. What would you recommend is the best way for the business logic actor to know which nested actor is sending the abstract message to it? My current approach is that the nested actor sends its own Enqeuerer as part of the message and the Business Logic actor compares this to the stored array of nested Enqeuerers. Would using interfaces make this easier?
Hey Jack, I'm glad you liked it :) Unfortunately, I don't have a super clean solution. I've always done what you've suggested. I treat the enqueuer as a UID for every actor. In my calling actor, I'll use a pair of arrays, one with names and one with enqueuers. In this instance I wouldn't use a map as we're regularly going from enqueuer -> name and name -> enqueuer. 'Would using interfaces make this easier?' Yes, in the sense that interfaces are easier to use and easier to extend than abstract messages.
Hello Tom, thank you for making all these nice videos. I practise the interface messages idea on the Video 9 - Abstract Messages. When I drag the Nested Actor class over to the new project, the interface class will become dependencies of the new project. Does it sound correct?
Hi Qian, That's absolutely correct :) Having the interface part of the dependencies is okay as the interface is defining the behaviours. However, we don't want the calling actor in the dependencies.
@@TomsLabVIEWAdventure Thank you for the fast response. It is good to get it correctly. I have been watching your video several times, as I am struggle a bit to understand the concept. I think that I am finnaly there. :) Thank you again.
Hi Tom, Thanks for all your videos!!! I simply wanted to know, Whether 'Encoder Logic.lvlib' gets loaded into dependencies when having 'Linear Encoder .lvlib' in seperate new project ?
Hi Karthikeyan, The Encoder Logic Library (/interface) will be brought into memory with Linear Encoder, as Linear Encoder is dependant on the interface. However, that's okay because the thing we want to avoid is the nested actor being dependant on the calling actor - which it isn't :)
Hi Tom, Thanks for all your tutorial about Actor Framework. When I use your code, I can't run it because of a broken dependency, it misses SAS_AFTester_Enqueuer Manager.lvclass. Is it a VI package to download ?
Hi Aurélien, The SAS AF Tester is a tool by Sam Taggart, I think if you google 'Sam Taggart AF Tester' you should be able to find it. Sorry, I'm not on my PC so I can't get a link for you right now
Thanks a lot for this video! I'm just wondering - in case of ordinary abstract messages, it is possible to handle by one caller multiple different children of abstract messages. In other words - caller could implement different handling of same parent message from its callers. But how to achieve it with interfaces? Because actor could implement interface just "once", override one method. How to handle the situation, when single caller needs to deal with multiple messages from different nested actors? For each nested actor - to have separate interface?
Hi Ivan, If I understand your question correctly, you're asking "Can a calling actor handle the same message differently depending on the nested actor which sent it?". If the calling actor is performing different tasks depending on the nested actor, then I would argue they should be separate messages. That's not to say you should have separate interfaces for each message. For example, you could have a "UI Interface" that specifies the messages: Open Panel, Show Menu Bar, Minimise etc, because all those messages are cohesive to 'UI Stuff', I would use the same interface to specify all those messages. However, if your messages aren't cohesive, then I would create separate interfaces. Does that help? or have I missed the point of your question? Cheers, Tom
@@TomsLabVIEWAdventure Hello Tom, thanks a lot for your answer! Let me, please, describe my use case a little bit different. Imagine, that I have caller actor, and nested actor. Nester actor - is some buffer. It buffers data based on setting, and then it should send data to caller, and caller saves data to correspondent database. And, there are launched 2 instances of buffer actor - one is fast buffer, second is slow buffer. So, in case of abstract messages, I would do the following. Buffer actor would create abstract message for caller. Then caller would have two methods: WriteSlowBuffer, WriteFastBuffer. And these methods would have messages-children of abstract message. Then, I would launch each instance of buffer actor, and set correspondent message (for WriteFastBuffer or for WriteSlowBuffer) to each of them. So when they send data to caller, data will be processed in proper method. And now, it's time to change it to interface. So, if interface will have just one method "Save data" - then caller actor could implement just that one method. But then, this method should have selector where to save data - to slow, or fast database. If interface will have 2 methods - "Save fast data", "Save slow data" - then, when buffer actor will be launched twice, it has to have some selector set, based on which either "Send Save fast data msg" or "Send Save slow data msg" will be executed. But caller will override each of methods, so caller already does not need that selector. Which approach, by your opinion, would be the best in such cases please? Thank you very much in advance, Sincerely, Ivan.
Ahhh okay, I fully understand now! So the quick answer is 'no'. However, I think this is a very interesting point you have raised. I don't think I've used that style of design pattern before, but I like it. I think this is a really good use-case of when to still use Abstract Messages. However, for everything else, I would use interfaces. Here's a quick example I created that demos the different approaches (annoyingly I published it on the wrong GitHub account!): github.com/TomsLabVIEWExtensions/AbstractOrInterface
Are you referring to updating message VIs if the interface methods change their connector panes? If so, you can update messages by right-clicking the message class and click 'Rescript message'
Just a quick note about this video:
In this video, I'm assuming you already know your way around Actor Framework, I'm also assuming you know why we use abstract messages to send data from a nested actor to a calling actor. Hence why I don't explain why we should be using abstract/interface messages.
If you're unsure about Actor Framework/have no idea what I'm on about, check out my Actor Framework tutorial series: th-cam.com/video/2k3ZDwJolbA/w-d-xo.html
Regarding why we should be using abstract messages (and now interface messages), I explain that in my abstract message video (link below). But the quick answer is to reduce dependencies between the nested actor and the calling actor. The nested actor shouldn't know who the calling actor is. If we used standard messages, the nested and calling actors would be tightly coupled, which would mean you couldn't use the nested actor in another project without the calling actor.
th-cam.com/video/eTaufgA7Lkc/w-d-xo.html
Also, one thing I forget to mention, with the interface messages, ANY ACTOR that inherits from the interface can receive the messages - No extra work required! WOO! 😁
I don't know if its me, but I am finding that if a Calling actor chooses not to implement an interface defined message handling VI i.e. it does not want to know about something the nested-actor is periodically telling it, the framework can't handle it and errors are produced. Are interfaces optional to a caller or MUST the caller inherit and implement them?
@@stephencole9377 Hi Stephen, an interface is a contract that demands all overrides are implmented. The calling actor should implement (inherit from) the interface defining the messages - and then you will see you get a broken run arrow until all methods are implmented. Until then you will get run-time errors.
I hope this makes sense.
Brilliants series. Really has clarified the AF pattern for me. And what is best is that it is quick and gives you just enough clues to get you thinking and trying stuff for yourself. I don't know how many times I have replayed these lessons picking up with eventual understanding a point being mentioned. Great piece of work which I hope is never taken down.
Yes, this is great and I can't wait to see more from you and interfaces. I am watching this now for the 5th time and I slowly start to get my head into this.
I'm glad you're finding it helpful. I would recommend downloading the code and having a play around yourself. It's one of those things where once it 'clicks' it will make total sense :)
Hi Tom, thanks a lot for this video (and all the other ones) I have a question regarding your comment: "Also, one thing I forget to mention, with the interface messages, ANY ACTOR that inherits from the interface can receive the messages - No extra work required! WOO! 😁"
I have an arborescence of calling and nested actors and I would like to send a message from a nester actor (level 4) to the "caller of its caller" (level 2 or even 1). How do I recover those enqueuers?
Or is just not possible and I would have to send this message to its caller and then it will have to pass it along? - But then all my nested actors would have to inherit from the interface message I would like to send to the "root"?
I hope my question is not too confusing.
In any case I do appreciate your help. And by the way, I enjoyed the GLA summit, thanks.
Thanks Tom. Your videos are by far the best learning resource I've found for labview so far. Always well explained with good, clear examples.
Hi Tom,
Thank you for all your great videos on AF. I didn't know much about AF before watching your video series, and I really enjoyed watching all of them. Videos are well made, easy to follow , and very useful. I will highly recommend to anyone new to AF of watching your videos. Thanks again! I will check your other tutorial series for sure.
Love learning new techniques from you. Keep up the Great Work!
Amazing video Tom. Thanks!
Hey Tom, I have a fundamental question, what techniques do you use to store and share large data sets between several Actors? Global variables, FGV, or DVR? For example, I have a measurement machine with a UI actor, which handles the basic framework tasks and I have several process actors that need to read and write to the data pool, which then will be saved to file. Could you give me any advice? Cheers
When using AF, I try not to mix-up data transfer mechanisms. When using a framework you should try to follow the rules (i.e send messages up and down the actor tree hierarchy). That being said... I'm sharing global data by using variant attributes wrapped in a DVR. Using a variant attributes as a CVT I believe is the fastest way of setting and getting data. I have a separate PPL that handles all of the reading/writing to the CVT and can save/read from file, in the PPL I also have wrappers for every read and write operation.
This technique works for me and is very effective. However, global variables are also a valid form of tag communication - but I would always wrap the sets/gets in VIs and make the 'Set' VIs private. FGVs are also fine, but a Global Variable achieves the same thing and it's quicker to implement. Globals are good to use, but only if you're responsible with them ;)
Hi Tom, thanks for the explanation, it is not quite obvious where to look for the scripting tool for creating messages using the interfaces. I have a question though regarding your overall architecture. In your system, the Business logic actor is the Root Actor, and redirects the data from one its nested actors to the other. Is there any advantage of not making a UI a Root Actor. That way if you need to reuse Business Logic Actor in a larger application, you can simply "disconnect" it from the UI and reconnect into the appropriate caller. I naively think that since the only data transfer direction for the Business Logic Actor is up, this won't change in the larger application, by simply creating a new interface for the the interaction with new caller. It could be a different way of thinking, however, I saw the approach similar to yours (GUI not being the root actor) in other large applications so there must be a good reason for this. Thanks.
You are doing the LabVIEW world such a huge favor! Thanks again. Question - Is this what should be used when a nested actor is to tell the caller to shutdown?
Hey Colin, Yep. To stop a calling actor you can use the 'Send normal stop message' function (that just sends a stop message). However, remember, by default, if your calling actor stops, the nested actors are going to stop too. If you don't want this to happen, you can use a FALSE constant for "Auto-Stop (T)" when launching the nested actor.
N.b. Well done on making it through all the videos, it's been quite satisfying seeing your comments filter through the playlist throughout the week!
@@TomsLabVIEWAdventure Oh right, and I suppose it's even easier to read enquerer from caller and send normal stop with out even using the interface message. Everything is still sinking, I will definitely re-watch several times. This channel is my goto for all things LabVIEW now! Cheers.
Tom, you are a lifesaver!! Is there any way for you to attach note to your Abstract Messages video referring to the new interface capabilities of LV2020? Thanks.
Great shout, I'll do that now 👍
Another great video, Tom. I know you're a user of plugins and PPL's, how would that be implemented using interfaces for the abstracted messages? I attempted this by creating a Abstract Messaging interface library, and building that into a PPL. Then added that PPL to the test project. After creating the required overrides I ended up with a broken wire when connecting the Caller Enqueuer ref to the Send.vi from the PPL.
Hi Josh,
I use PPLs a lot with other frameworks, but I haven't had much of a need with AF (yet). I'll give it ago over the next week or so and get back to you. I "know" why you're getting that behaviour but, until I try it myself and come up with a good build process, I don't want to share potentially inaccurate information.
Hey Tom, great video again. I have a question about abstract message you might be able to help me with? In my project the business logic actor launches multiple nested actors of the same class type. What would you recommend is the best way for the business logic actor to know which nested actor is sending the abstract message to it? My current approach is that the nested actor sends its own Enqeuerer as part of the message and the Business Logic actor compares this to the stored array of nested Enqeuerers. Would using interfaces make this easier?
Hey Jack, I'm glad you liked it :)
Unfortunately, I don't have a super clean solution. I've always done what you've suggested. I treat the enqueuer as a UID for every actor. In my calling actor, I'll use a pair of arrays, one with names and one with enqueuers. In this instance I wouldn't use a map as we're regularly going from enqueuer -> name and name -> enqueuer.
'Would using interfaces make this easier?' Yes, in the sense that interfaces are easier to use and easier to extend than abstract messages.
@@TomsLabVIEWAdventure thanks for clarifying Tom. I will use interfaces once we move to lv2020. Looking forward to the next video 👍
Hello Tom, thank you for making all these nice videos. I practise the interface messages idea on the Video 9 - Abstract Messages. When I drag the Nested Actor class over to the new project, the interface class will become dependencies of the new project. Does it sound correct?
Hi Qian,
That's absolutely correct :)
Having the interface part of the dependencies is okay as the interface is defining the behaviours. However, we don't want the calling actor in the dependencies.
@@TomsLabVIEWAdventure Thank you for the fast response. It is good to get it correctly. I have been watching your video several times, as I am struggle a bit to understand the concept. I think that I am finnaly there. :) Thank you again.
Hi Tom,
Thanks for all your videos!!!
I simply wanted to know, Whether 'Encoder Logic.lvlib' gets loaded into dependencies when having 'Linear Encoder .lvlib' in seperate new project ?
Hi Karthikeyan,
The Encoder Logic Library (/interface) will be brought into memory with Linear Encoder, as Linear Encoder is dependant on the interface. However, that's okay because the thing we want to avoid is the nested actor being dependant on the calling actor - which it isn't :)
Hi, Tom:
I have a question.
After downloading your project, There is no SAS library or folder.
Where can I find it?
Thanks
Hello, sorry I should have made a link to it.
You can download the SAS tester here: www.sasworkshops.com/af-tester/
@@TomsLabVIEWAdventure this link is dead now. Any other way we can get this files to run the code? Thank you very much!
Hi Tom,
Thanks for all your tutorial about Actor Framework. When I use your code, I can't run it because of a broken dependency, it misses SAS_AFTester_Enqueuer Manager.lvclass. Is it a VI package to download ?
Hi Aurélien,
The SAS AF Tester is a tool by Sam Taggart, I think if you google 'Sam Taggart AF Tester' you should be able to find it. Sorry, I'm not on my PC so I can't get a link for you right now
@@TomsLabVIEWAdventure Thank you, I succeed to find it here www.sasworkshops.com/af-tester/
Now I can run your code ;)
Thanks a lot for this video! I'm just wondering - in case of ordinary abstract messages, it is possible to handle by one caller multiple different children of abstract messages. In other words - caller could implement different handling of same parent message from its callers. But how to achieve it with interfaces? Because actor could implement interface just "once", override one method. How to handle the situation, when single caller needs to deal with multiple messages from different nested actors? For each nested actor - to have separate interface?
Hi Ivan,
If I understand your question correctly, you're asking "Can a calling actor handle the same message differently depending on the nested actor which sent it?".
If the calling actor is performing different tasks depending on the nested actor, then I would argue they should be separate messages. That's not to say you should have separate interfaces for each message. For example, you could have a "UI Interface" that specifies the messages: Open Panel, Show Menu Bar, Minimise etc, because all those messages are cohesive to 'UI Stuff', I would use the same interface to specify all those messages. However, if your messages aren't cohesive, then I would create separate interfaces.
Does that help? or have I missed the point of your question?
Cheers,
Tom
@@TomsLabVIEWAdventure Hello Tom,
thanks a lot for your answer!
Let me, please, describe my use case a little bit different.
Imagine, that I have caller actor, and nested actor. Nester actor - is some buffer. It buffers data based on setting, and then it should send data to caller, and caller saves data to correspondent database. And, there are launched 2 instances of buffer actor - one is fast buffer, second is slow buffer.
So, in case of abstract messages, I would do the following. Buffer actor would create abstract message for caller. Then caller would have two methods: WriteSlowBuffer, WriteFastBuffer. And these methods would have messages-children of abstract message.
Then, I would launch each instance of buffer actor, and set correspondent message (for WriteFastBuffer or for WriteSlowBuffer) to each of them.
So when they send data to caller, data will be processed in proper method.
And now, it's time to change it to interface. So, if interface will have just one method "Save data" - then caller actor could implement just that one method. But then, this method should have selector where to save data - to slow, or fast database. If interface will have 2 methods - "Save fast data", "Save slow data" - then, when buffer actor will be launched twice, it has to have some selector set, based on which either "Send Save fast data msg" or "Send Save slow data msg" will be executed. But caller will override each of methods, so caller already does not need that selector.
Which approach, by your opinion, would be the best in such cases please?
Thank you very much in advance,
Sincerely, Ivan.
Ahhh okay, I fully understand now!
So the quick answer is 'no'.
However, I think this is a very interesting point you have raised. I don't think I've used that style of design pattern before, but I like it. I think this is a really good use-case of when to still use Abstract Messages. However, for everything else, I would use interfaces.
Here's a quick example I created that demos the different approaches (annoyingly I published it on the wrong GitHub account!): github.com/TomsLabVIEWExtensions/AbstractOrInterface
Please more about Interfaces
thanks for your video and it's useful!
Is there a good way to update a interface .vi after it is created?
Are you referring to updating message VIs if the interface methods change their connector panes? If so, you can update messages by right-clicking the message class and click 'Rescript message'
very useful,thank you
Love it!