LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How do I explicitly invoke an ancestor of a dynamic dispatch VI

Given two classes with dynamic dispatch VIs (LV 2011)

 

Parent

+ m1:string

 

Child

+ m1:string

+ p1:string

 

Where Child inherits from Parent.

 

How do I get Child.p1 (image below) to return the results of Parent.m1? I.e., Child.p1 needs to directly call Parent.m1, and _not_ Child.m1.

 

I've tried what would seem intutive, but it does not do what I expect, even though it looks like it should as it claims it will execute the Parent.m1 VI:

 

Dont Dispatch

 

Attached is a zip of the test case.

 

Thanks!

0 Kudos
Message 1 of 24
(3,385 Views)

The reason your code doesn't work is that the decision which VI to execute is always made at run-time based on the actual object in the wire, not based on the wire type itself. Your upcast simply changes the edit-time type of the wire, but the object is still a child.

 

The more general solution is that you can't and shouldn't - deciding how to do the "m1" operation should be up to m1 and not anyone else. That means that you should call the m1 of the class that's on the wire. Now, if child.m1 wants to call the parent implementation, it can use the call parent implementation node and case out its own code.


___________________
Try to take over the world!
Message 2 of 24
(3,369 Views)

I assume you are using dynamic dispatch vi's

 

Here is a workaround that I have employed

 

Call parent Method.png

 

I use the call parent method in the cluster class variant Palette

 

If you are not using dynamic dispatch, Just wire the parent method directly in, this is not a real problem.

 

#Edit, The False case panel should have been an unbundle element or a method other than the calling one.

 

iTm - Senior Systems Engineer
uses: LABVIEW 2012 SP1 x86 on Windows 7 x64. cFP, cRIO, PXI-RT
Message 3 of 24
(3,348 Views)

The CallParent method calls the parent of the VI that is being overridden. However, I need the Child (e.g., Child.p1) to call another method in Parent (e.g., Parent.m1) which has a been overridden in Child (e.g., Child.m1) without dispatching to Child.m1.

0 Kudos
Message 4 of 24
(3,320 Views)

I agree. The problem I am solving needs a specialization of Parent.m1 (without modifying Parent) that puts additional constraints on the services of m1.

 

In other languages (e.g. Java), I would implement a new Child.m1(N) that overloads Parent.m1() but still calls Parent.m1() to get the services of Parent.m1() (e.g., by calling super()).

 

Unfortunately LV does not support overloading.

What I am looking for is a workaround to this limitation. My first attempt was to implement Child.p1(N) and have it call Parent.m1(), but that didn't work.

0 Kudos
Message 5 of 24
(3,318 Views)

If you don't want to change the API of m1, what you can do is this - add a boolean field to the child class which indicates you want to call the parent. Set that field in child.p1, then call m1, then reset it. Inside child.m1, if the field has been set, then you case out the code and call the parent implementation as shown. Note that if add additional grandchildren which implement m1, they will have to be aware of this behavior if you want them to behave similarly.


___________________
Try to take over the world!
0 Kudos
Message 6 of 24
(3,307 Views)

True, however there is a race condition.

Consider two clients - clientA and clientB - both running in parallel: clientA calls instance.p1 and clientB calls instance.m1. The race condition occurs when instance.p1 (clientA's thread) sets the callParent flag, then clientB's thread calls instance.m1, then clientA's thread calls instance.m1.

0 Kudos
Message 7 of 24
(3,301 Views)

@mflegel wrote:

True, however there is a race condition.

Consider two clients - clientA and clientB - both running in parallel: clientA calls instance.p1 and clientB calls instance.m1. The race condition occurs when instance.p1 (clientA's thread) sets the callParent flag, then clientB's thread calls instance.m1, then clientA's thread calls instance.m1.


This doesn't make any sense (to me, at least). The flag is part of the instance's data, there's no way there would be interference between the two instances. One instance can't write to the other's data.

 

Can you simply modify Parent so that it has a non-dynamic-dispatch method that actually does the work of m1? Then you can call that from Parent.m1, or call it directly  to achieve the behavior you want here.

0 Kudos
Message 8 of 24
(3,278 Views)

The flag is part of the instance data, but there can be interference when the two clients call into the same instance at the same time in their own threads of execution (maybe even running on different cores).

Modification of the Parent is not an option.

 

There's a few constraints I forgot to mention:

  • Each instance encapsulates a single resource, unique resource.
  • The class must support multi-threaded/parallel access to the instance.

To meet these constraints:

  • The VIs are re-entrant, clone sharing.
  • Instance data is encapsulated in refnums (e.g., DVRs)
0 Kudos
Message 9 of 24
(3,275 Views)

If your instances are shared through DVRs, then a single instance can't be accessed at the same time (assuming the object itself is what's in the DVR and not references inside the object) - the DVR mechanism protects you from that and once you use the IPE structure to access a DVR, any other structure which wants it will have to wait until the first structure is done with it before it can proceed. Thus, setting and unsetting the flag inside the IPES should not cause race conditions.

 

Likewise, if you simply split the class wire you created two separate instances and again there is no race condition (although that doesn't seem to be correct behavior in your case).

 

Note that it might be possible to open an explicit VI server reference to parent.m1 and run it with the CBR node, but I have a vague recollection that if you do that LV will still use the DD mechaism to run child.m1. This will probably not happen if you use the Set Ctl Val and Run VI methods, but that workaround is so bad it hurts me just to type it.


___________________
Try to take over the world!
0 Kudos
Message 10 of 24
(3,258 Views)