You are here

Getting Started with the Actor Framework - Part I

January 26, 2015

The Actor Framework has become the defacto standard tool for developing large, maintainable, and scalable applications in LabVIEW.  For many LabVIEW developers, however, the learning curve associated with the Actor Framework seems like it is much too steep for them to take advantage of its many benefits.  The purpose of this article is to help developers who are familiar with the common design patterns of “procedural” LabVIEW development transition to the Actor Framework.  Hopefully, by the end of this article you will see that the Actor Framework is not quite so different from the patterns you’re already accustomed to using.

 

The Queued Message Handler

As a LabVIEW developer you probably utilize the Queued Message Handler pattern very frequently.  It looks something like this:

If this pattern is foreign to you, I would recommend familiarizing yourself with it before moving forward (Warning: shameless plug ahead - The LabVIEW Style Book is a great resource for this).

In the queued message handler we have a few important properties:

  • A loop with multiple states (Each case in the case structure is a state)
  • A queue of messages that can invoke a state and pass data to that state (the cluster wired to the obtain queue VI is the message.  The string invokes a state because it is wired to the case structure, and the variant can pass data along with the message)
  • A store of data that persists all states (the shift register on the loop which would consist of a cluster of pertinent data)

This pattern provides many advantages.  Data is encapsulated by the loop; no other loops can directly alter its data.  Other loops can interact with the loop via its queue, but this loop gets to define the interface through which that interaction occurs.  For example, this loop could provide a state for modifying a value on its shift register and other loops could invoke that state and pass the new data with the message.  The benefit of this is that this loop has the final say of how that data gets inserted, so it could, for example, reject certain values that are invalid or out of range.  In other words, since the queued message handler owns its data, it can protect it by only exposing what it wants to expose and by defining the rules of how that data is exposed.

There are, however, some disadvantages to this approach.  For one, every time we want to create a queued message handler in our application we need to copy and paste the pattern.  This leaves open the possibility of erroneously breaking the way the QMH works.  It also means that if we want to add a feature to all QMH’s, we must copy and paste that new feature as well.  We also have no way of reusing the QMH’s we have already developed without once again resorting to copying and pasting.  For example, if we developed a Timer QMH and we want to have multiple parallel timers running throughout our application, we would have to duplicate the timer code for each one.

The other primary disadvantage relates to the concept of type safety.  In this pattern, states are invoked via string.  It is easy to imagine a scenario where a mistyped state string could cause unexpected behavior.  In addition to this, the data is passed in as a variant, so it is the QMHs responsibility to convert that variant into the data type it expects.  If the wrong data type is passed in, again unexpected behavior could result.  The real issue here is that these problems are not identifiable until runtime.  In other words, wiring in the wrong data doesn’t produce a broken run arrow.  The application will compile, it just won’t do what you expect.  These types of bugs can be easy to introduce and difficult to track down.

 

The Actor Framework

The Actor Framework serves to solve the issues with the QMH pattern implementation outlined above.  The important point to remember is that the Actor Framework is not a completely new pattern.  It is still a QMH like we’re accustomed to using, it is only the implementation of the pattern that is different.  As we create our first actor we will see how each component of the actor is analogous to the components of the QMH we identified earlier.

 

The completed source code for this tutorial can be found here:

Getting Started with Actor Framework – LabVIEW 2014

Getting Started with Actor Framework – LabVIEW 2013

 

To create a new actor, first create a new class by right clicking My Computer in your LabVIEW project and selecting New > Class

 

Give the class the name “My Actor” when prompted.  You should now have the My Actor.lvclass class in your project.

Next we must add the Actor Framework library to our project.  To do so, right click on My Computer in the project and select Add > File.  Next, browse to your vi.lib folder.  Typically this will be located at C:\Program Files (x86)\National Instruments\LabVIEW 2014\vi.lib.  Note: this tutorial assumes you are using LabVIEW 2014.  If not, that's ok, but be sure you have the latest version of the actor framework, or some of the steps later on will not be accurate. In the vi.lib folder, you should have an “Actor Framework” folder.  Inside the Actor Framework folder you will find the “Actor Framework.lvlib” library file which we want to add.  Select this file and click Add File.  The Actor Framework library should now be added to your project.

Next we must make our “My Actor” class inherit from the Actor Framework.  This transforms our currently blank class into an actor.  In other words, we can inherit the QMH functionality we want from the Actor class, rather than having to write it ourselves.  To do this, first right click My Actor.lvclass and select Properties.  Select the “Inheritance” Category on the left and click Change Inheritance.  Select Actor.lvclass and click Inherit From Selected.  Click OK to close the class properties dialog.

Congratulations, you've made your first actor.  Don't stop to celebrate now though, because we still have to make our actor do something.  For this example we'll have our actor pop up a message to the user.  To do this with a classic QMH we would create a new case in the case structure and name it something like "Display Message".  The AF equivalent of this is to make a new method (read: VI) and name it "Display Message", so that's what we'll do next.

In your project, right click on My Actor.lvclass and select New > VI from Static Dispatch Template.  This will auto-generate a new method.  Edit the method's block diagram to look like below, and save it as Display Message.vi.

Great, now our actor can greet the outside world.  But how do we call this functionality?  In the QMH world we would enqueue a cluster with a string and a variant where the string is "Display Message".  In the AF, rather than sending a cluster, we send a Message Class.  Creating all of these message classes can become tedious, but luckily there is a tool that ships with the actor framework that makes it very easy.

In your project window, go to Tools > Actor Framework Message Maker.  In the window that opens, select Display Message and click Build Selected.  This will create a new Message Class that can be sent to our actor to invoke the Display Message method.  Your project tree should now look like this:

Ok, we're almost done.  The last step is to launch the actor and to send it the message.  To do this create a new VI by right clicking My Computer and selecting New > VI.  Save the VI as Launcher.vi.  Modify the block diagram to look like this:

You can get the My Actor.lvclass class constant by dragging My Actor.lvclass from your project into the block diagram.  The Send Display Message VI can also be found in your project in the Display Message Msg.lvclass we created earlier.  The Launch Root Actor VI and the Send Normal Stop VI can be found in the Actor Framework pallete which is in the Data Communication pallete.

If you are using an earlier version of LabVIEW or the Actor Framework, you may not have a "Launch Root Actor.vi".  If so, you will need to construct your launcher using  "Launch Actor.vi" as shown below:

 

That's it, you're done!  If you run Launcher.vi you should see your actor's pop-up message.  At this point you may wish to organize your project a bit and place your actor in a library and create a virtual folder for its messages as shown here:

This will help you keep track of all of your classes as your project grows.

In future blog entries we will build some more complex actor-based applications to show the additional features of the AF.

 

Realted Links

Getting Started with the Actor Framework - Part II

Category:

Comments

Correct me if I'm wrong because I couldn't try this in my PC as I don't have actor framework installed.

You mean, hereby we use "Send Display Message.vi" which correctly triggers the "Display Message" in my MyActor class, so mistyped state string is avoided. And you mean, we should use the input terminal of "Send Display Message.vi" which is already teypdef (string in this case), so datatype is secured now . Thus this framework give top level successful compilation to normal QMH without our attention. Is that only advantage of actor framework? Are there many other? Does any other development platform supports this actor framework like (C#/Java etc.)?

Hello I am new to the Actor Framework. I like this introduction, I came here after finding only "Read this first" (https://decibel.ni.com/content/docs/DOC-17193) from NI, which seems to stop at LV2012. But I am using LV2014 for this.

I was surprised to find that the way to create a VI to send a message is to create a class. A class seems to me to be bigger than what you would want for a simple task like this. In a large project I would expect to end up with hundreds of classes just to send messages around. Is that the intent?

Thanks
Keith

There are several advantages to using the actor framework.  You touched on one of them here, which is the compile time type safety that it provides.  Another main advantage is that your actors and messages are classes, and are therefore extensible.  If you need to create a new actor which is similar to an existing one, you can use inheritance to avoid code duplication.

Sorry about that.  This is because you are using an older version of the Actor Framework.  You are probably not using LabVIEW 2014.  I will be updating the blog to show how to do this in LabVIEW 2013 and prior as well.

Hi Keith,

You are correct that in the Actor Framework requires a class to be created for each message.  In some cases the overhead associated with these message classes may not be acceptable, but my experience has been that the benefits often outweigh the costs.  The extensibility and type safety that classes provide is very powerful.  Having hundreds of message classes is a real possibility in a medium to large size project.  Luckily the message maker script can make the messages for you, so it's not too burdensome to create new messages.

The Actor Framework is a part of LabVIEW since LV 2012. Extensive getting started documentation can be found by creating the Actor Framework template project (File >> Create Project... >> Actor Framework) and looking at the HTML files provided with the new project.

I added a note to this effect to the top of the READ THIS FIRST page.

Regarding the large number of classes:
"In a large project I would expect to end up with hundreds of classes just to send messages around. Is that the intent?"

Yes. A well-designed OO project will have many classes, some of them very small.

If you cannot find Launch Root Actor VI then you must be using LV 2013 or earlier.
The two functions Launch Root Actor VI and Launch Nested Actor VI were introduced in LV 2014 and deprecated Launch Actor VI. This change made teaching the Actor Framework to new users MUCH easier and removed a lot of the getting-started headaches.

So, I am using LV2014 and tried following your instructions, when I go to tool>>actor framework message maker... the GUI comes up, however the Display Message method is greyed out. After reading some help files from NI it claims that the message has already been created. I didn't use your template project and did everything from scratch on my own (obviously the template project you have provided already has a message created for My Actor Class.

Where did I go wrong?

Hi rsmrostov,

Sorry to hear you're having trouble creating the message.  You are definitely on the right track with your debugging, the message maker will indeed grey out the methods which already have messages created.  My best guess is that you may have the example files downloaded in a nearby directory and the message maker is finding the message class from the example files.  Try removing the example files and see if that fixes the issue.  Alternatively, changing the name of the method should also work.