From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

JKI State Machine Objects

cancel
Showing results for 
Search instead for 
Did you mean: 

SMO Dependencies

Hi,

I have been using the JKI SMO for the past 5 days and overall I really like it. This is the first framework I try to use and for someone like me who used to spawn asynchronous processes using the basic Labview functions, having a framework handling all the heavy work feels like a relief.

I especially like the possibility to define dependencies but I couldnt find any clear documentation about how to add dependencies to an existing SMO. So far I managed to add static dependencies to SMOs created with the "Instrument" template by just putting an instance of the dependency in the type def "dependencies" but I'm struggling to add a dependencies to SMO created with other templates (the UI SMO template for instance). I keep running into errors like:

"Error 116: Flattened String To Variant in SMO.lvclass:CastArrayDependenciesToClusterOrClass.vi->UI - actuator display.lvclass:Get static dependencies.vi->UI - actuator display.lvclass:Process.vi:5310001->SMO.lvclass:LaunchProcess.vi:3770002->SMO.lvclass:LaunchProcess.vi.ACBRProxyCaller.88500295"

Is there a extensive documentation somewhere about dependencies management in the SMO framework?

Also, correct me if I'm wrong, but it seems that a dependency will always be launched as a clone.  Yet, in my application, all the SMOs need to log - on the same file - what they are doing. To do so, I thought I would create another SMO - called "SMO_logging" - and define a unique instance of "SMO Logging" as a dependency of all the other SMO so they can all have access to the API of "SMO Logging". SMO loggin would then be a shared ressource. I think it is refered as the singleton pattern. Is it an intended use case for the SMO framework? How could I implement that?

I hope my questions make sense

Regards,

peper

Message 1 of 5
(9,298 Views)

There is not much documentation on the Launch Dependency method out there. It's mostly been released because it was used in this webinar, and I wanted to release the code publicly.

To answer your question, you can have a single instance being used as a dependency to multiple subsystems. The Launch Dependency method will create a new instance only if you pass a type (uninitialized object). In the use case of a logger that needs to be reused, you should create (and optionnaly start) your logger object before injecting it into another SMO as a dependency. You can then use the created logger and add it to as many SMOs you want and still run a single instance.

When an SMO is in unknown state (references invalid), the act of Launching Dependency will first create a new instance of the object. It will then take ownership of the object's lifetime and become responsible for stopping it and disposing of its reference. (Composition)

When a SMO has already been created or started, the Launch Dependency primitive will add the object through "composition" if it is an object that does not have an owner. In that case, it would claim ownership and simply skip the "create-start" steps accordingly. If the object has already been claimed by another SMO, then it would be added as an "aggregation", meaning it would not manage its lifetime, but simply have access to its reference. When stopping, it will not stop and destroy the reference.

Here's a quick video of the difference with launching dependencies that have already been created and those that have not.

The first run shows that two loggers are created. The second run shows how to reuse the reference to a single logger.

http://www.screencast.com/t/WWYmEkZUC75

GCentral ChampionCLA
0 Kudos
Message 2 of 5
(9,079 Views)

Ok, thanks for the clarification!

I'll be on holliday for the next two weeks but I'll try to implement my logger when I get back and let you know how it goes.

Regards,

peper

0 Kudos
Message 3 of 5
(9,079 Views)

Hi,

 

I still have some questions regarding dependencies.

 

I'm trying to implement the pattern described in the video. The idea is that I have a "data repo", implemented with a DVR, and multiple SMOs that will modify and read the DVR.

 

When one of the SMO modifies the DVR, it needs to tell all the other SMOs that the DVR has been modified so they can update their front panel to reflect the new data.

 

Hence I created a "Repo SMO" - which holds the DVR of the data repo - and implements one public event called "Repo was updated". I want all SMOs to listen to the "Repo was updated" event and have access to the DVR.

 

What is the best way to do that?

 

Here is what I tried to do: I defined the "Repo SMO" as a dynamic dependency (like in the video) of all the SMOs that need to have access to the repo. In the picture bellow you'll see that all the static dependencies of my main SMO have the "Repo SMO" as dynamic dependency.SMO Dependencies dynamic.png

 

Now, I have a few questions:

1) How do I acces a dynamically defined dependency from inside the SMO.

2) Is there an event triggerd when a dynamic dependency is added to a SMO?

3) What is the difference between a simple dependency and a shared ressource?

 

Regards,

 

peper

 

0 Kudos
Message 4 of 5
(8,487 Views)

Hi peper, 

I missed your post from last year... I'm sure it is too late for a reply but here it is in case others are stumbling on this post and are looking for the same answers.

 

1- There are a few methods in the Protected palette to list the dependencies. To access a dynamic dependency, the easiest is to use "FindDependency(byKey).vi" for which you feed the dependency's name. You'll need to cast to a more specific SMO class as needed.

2- There is a protected event triggered when a dependency is added. Your process (and more specific processes, if you override your class) can register for this event and react accordingly.

3- A shared resource is a dependency that can be used bu other subsystems. A simple dependency means that the owner does not share it with others. A shared resource's lifetime (create-start-stop-destroy) can only be managed by the owner of the resource (i.e the SMO that launched it in the first place). All the other SMOs that have the shared resource in their array of dependencies will be able to access its public API, but not control its lifetime. If you are familiar with UML representation, a simple dependency is a solid diamond and a shared resource is an empty diamond (except for the 1st caller for which it is a solid diamond)

 

GCentralChampionCLA
0 Kudos
Message 5 of 5
(6,084 Views)