LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Maintaining LVOOP type in a non-dynamic dispatch VI of another class

First thing to clear up: I am NOT looking for multiple dynamic dispatch inputs (I think).

 

When I refer to Object type I mean the Wire type, not the ACTUAL object type.

 

I also apologise if I mix up "Class" with "Object" in this text.  I hope what I'm trying to say is understood anyway.

 

I have the following VI Setup.

 

I have a communication class (A) with Dynamic Dispatch VIs to allow the base VIs to be overridden for specific communication cases (A1,A2..).

 

I also have different communication packet classes(B1, B2...), all derived from a base class (B).

 

I want to allow the Objects of Class A and its children to be able to accept an object of class B (or its children).  The only methods being called on the B Object within the A* classes are present in the Base Class B. 

 

So far so good.

 

Problem is that when I define a child communication packet Class (with a custom data out with pre-formatted data for example) and I input an object of this class to an A* Object (Connected to inputs of static type B), the output is downcast to Base class B when output.

 

B B1 Class coercion.PNG

 

I think I understand why this is happening.  The inputs and outputs for my communications packet class of the Dynamic dispatch VI (Class A) are static and of type B.  Thus any B1, B2... will be cast to B.  After each and every call to process my communications packet I have to use the new "Preserve Run-Time Class" primitive to re-cast the object to the correct class.

 

The strange part is that calling the VIs used from Base Class B with an Object of class B1 does NOT cast the object type to B even though the object input is defined as static.  In other words, if I take the CONTENTS of the Sub-VI coloured Green above the problem goes away.  The fact that the functionality is wrapped in a different class seems to be preventing the object type retention.

 

The coercion seems to be taking place at the Static input of the VI coloured green above.  All of the VIs called within this VI maintain the real object type (no downcasting).

 

Does this have to be?  Is there no way to allow the REAL object type to propagate on the wire in such a scheme so that I can avoid having to re-cast the object?

 

In other words, why the coercion at the input to the green VI above?

 

Shane.

Message Edited by Intaris on 09-02-2009 05:52 AM
Message Edited by Intaris on 09-02-2009 05:53 AM
Message Edited by Intaris on 09-02-2009 05:55 AM
0 Kudos
Message 1 of 15
(4,351 Views)

Nobody?

 

Am I delusional about wanting to be able to do this....?

 

Shane

0 Kudos
Message 2 of 15
(4,319 Views)

Intaris wrote:

First thing to clear up: I am NOT looking for multiple dynamic dispatch inputs (I think).

 

...

So far so good.

 

Problem is that when I define a child communication packet Class (with a custom data out with pre-formatted data for example) and I input an object of this class to an A* Object (Connected to inputs of static type B), the output is downcast to Base class B when output.

 

B B1 Class coercion.PNG

 

I think I understand why this is happening.  The inputs and outputs for my communications packet class of the Dynamic dispatch VI (Class A) are static and of type B.  Thus any B1, B2... will be cast to B.  After each and every call to process my communications packet I have to use the new "Preserve Run-Time Class" primitive to re-cast the object to the correct class.

 

The strange part is that calling the VIs used from Base Class B with an Object of class B1 does NOT cast the object type to B even though the object input is defined as static.  In other words, if I take the CONTENTS of the Sub-VI coloured Green above the problem goes away.  The fact that the functionality is wrapped in a different class seems to be preventing the object type retention.

 

The coercion seems to be taking place at the Static input of the VI coloured green above.  All of the VIs called within this VI maintain the real object type (no downcasting).

 

Does this have to be?  Is there no way to allow the REAL object type to propagate on the wire in such a scheme so that I can avoid having to re-cast the object?

 

In other words, why the coercion at the input to the green VI above?

 

Shane.


Hi Shane,

 

Could you post a zip that illustrates this situation?

 

I threw together this

 

Child_Class.png 

 

to experiment and this shows that passing the parent class to the terminal does not show the coercion dot while the other two child classes do show a coercion.

 

So it sounds like Multiple Dynamic Dispatch is what you are asking for. This would require nine VI to handle all of the variations if that was even allowed.

 

If it sounds like I am catching part of what you are throwing, then please help me get on the same base as you with more words and an example. I only read the update notes fast but I wonder if the new "friends" settings will let us appraoch this differently, like making the comm class the dynamic terminal and then use methods to store the class in one of three classes stuffed in ..... blah blah blah.

 

Just trying to help,

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 3 of 15
(4,304 Views)

Ben, there's a slight difference apparent between our two versions.

 

My version accepts the Class B as an input to a VI and outputs it again in the same VI.  It simply "uses" the object to do something.

 

Your version seems to store the object internally within the Object A which is a slightly different case.

 

In my version I have an unbroken line of Wires for my Object of Class B1 from input to output within the VI causing the coercion.  I don't see why the IDE doesn't realise that this is the case and retain the class on the wire.....

 

I'll post an example tomorrow.

 

Shane.

0 Kudos
Message 4 of 15
(4,298 Views)

I definitely see why you would want such type propogation, but I'm trying to understand how it would work. For example - If you have two inputs of the same type connected to the same output (let's say by using a select primitive), which one determines the type? What happens if there's a constant in there? etc.

 

In DD it's easy to do this, because you explicitly tell the VI you want the two terminals to be "connected". Maybe we need a "propogate LVOOP type" option for VI I/O. Of course, then you would need some way of pairing specific terminals, since you want more than one.


___________________
Try to take over the world!
Message 5 of 15
(4,292 Views)

tst wrote:

I definitely see why you would want such type propogation, but I'm trying to understand how it would work. For example - If you have two inputs of the same type connected to the same output (let's say by using a select primitive), which one determines the type? What happens if there's a constant in there? etc.

 

In DD it's easy to do this, because you explicitly tell the VI you want the two terminals to be "connected". Maybe we need a "propogate LVOOP type" option for VI I/O. Of course, then you would need some way of pairing specific terminals, since you want more than one.


 

...or if we could twist this inside out so that the wired-thru terminals were DD.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 6 of 15
(4,290 Views)

Tst,

 

What's annoying me is that exactly this type of propagation IS working in certain circumstances (without DD) and I don't understand why it works there and not in this example.

 

Like I said, I'll post code tomorrow.  Maybe then the difference in behaviour will be clear.

 

Shane.

Message 7 of 15
(4,286 Views)

Ben,

 

twisting it around like that means that the VI has to be e member of Class B right?

 

This isn't what I want.

 

Shane.

0 Kudos
Message 8 of 15
(4,285 Views)

I think I may have just grasped the issue....

 

When I have a definite unbroken connection between input and output, the wire type is propagated.

 

Once a DD VI gets involved (where the determining class type is not of the B family), it's actually not possible to know the configuration of the wire connections until run-time so I would assume the compiler is playing it safe and automatically down-casting.

 

Even though the DD VI I am calling has an unbroken connection from input to output (which propagates the object type just fine outside of the DD VI), the compiler cannot know for sure that I won't load a Class which is unknown at compile time which does NOT have an unbroken wire and which may otherwise cause problems or even insert a "true" B class object on the wire.... Because the inputs and outputs for Class B are not DD, the type at the output can be different from the input.

 

If I'm right, changing the DD VI to a static VI (no DD inputs at all) should fix the problem.  This is do-able because it's essentially a fixed function.  I can live without the ability to override it in child classes.

 

I'll see how it goes tomorrow.

 

Shane.

0 Kudos
Message 9 of 15
(4,268 Views)

Yup, that's the problem (I say problem, but it's kind of a logical requirement I think).

 

I changed the member VI to a static VI and the object propagation worked a treat.  No longer required to use the "preserve run-time class" primitive any more.

 

Unfortunately I spoke too soon saying I could make this VI static in my framework.  I need at least PARTS of it to be overridden so I'll have to do a bit of refactoring, but I reckon it's possible.

 

To Ben (brave Knight) and Tst

 

Thanks for being there for me to bounce my ideas off you guys.

 

Sometimes I hate not having another LV programmer to discuss these things with (as in non-virtually).  -Sob-

 

So bottom line is that if the Compiler is sure there's an unbroken line from input to output, the obejct type WILL propagate, even if the declared input type is a parent of the actual object type.  This is cool.

 

Bringing in Dynamic Dispatch (with the Dynamic Dispatch class being one other than B) into the equation removes this certainty (nobody knows what kinds of crazy classes could be loaded at run-time) and so the conditions for propagation are no longer given.

 

It's perfectly logical when you think about it.  A lot.  And look at the moon at the right angle.  On thursdays.  After a few beers......   :smileyvery-happy:

 

Thanks again

 

Shane.

Message Edited by Intaris on 09-03-2009 02:34 PM
0 Kudos
Message 10 of 15
(4,263 Views)