Jump to content

To More Specific Class loses run-time type info?


Recommended Posts

I'm a little confused as to why this is. If you could take a quick look at the code below:

post-11742-039795400 1283441105_thumb.pn

The method is an override for a base class method. I need to get information from my class data, so I cast the object to the proper class. Note the cast will ALWAYS be valid (otherwise the dynamic dispatch will not invoke the method). I understand that the primitive can't have knowledge of this, but why does the prim lose the run-type type info? I can't use the output to wire up my Call Parent Method because it generates an error (as expected given the prim's behavior):

post-11742-055641000 1283441559_thumb.pn

Is someone able to explain why the behavior is as it is? I've never stumbled across this problem before...

Link to comment
Note the cast will ALWAYS be valid (otherwise the dynamic dispatch will not invoke the method).
The node might produce an error. When it produces an error, the output object is not the same type as the input object -- it is a default value of the type wired to the center terminal. Your output FPTerminal is marked as "Dynamic Dispatch Output". That means that the data from Dynamic Dispatch Input may pass through any nodes that modify value, but not through any nodes that modify type. This node can modify type.

If you are 100% certain that the downcast will always succeed (because of other logic in the rest of your code ensures this), use the "Preserve Run-Time Class" primitive. Like this:

post-5877-070891200 1283444465_thumb.png

You must wire the center terminal directly from the Dynamic Dispatch Input terminal for this to work so that the node has the original type of the class to work with. If you're not 100% certain the downcast will succeed, run your error cluster wire through the Preserve Run-Time Class prim -- that will tell you when the object couldn't maintain the contract.

Link to comment

2nd alternative: Change the output FPTerminal to just be "Recommended" instead of "Dynamic Dispatch Output (Recommended)". A dynamic dispatch VI does not *have* to have a dynamic dispatch output to match its dyn dispatch input. Making that change would free you of the requirement of maintaining object type across the diagram.

WAY MORE IMPORTANT: When I replied before, I was concentrating on the syntax of your diagram and I offered a work around. Now I'm looking at the semantics of your diagram and I'm seeing an issue. Pump is a class. View is a child of Pump. This VI is Pump.lvclass:MessageLoopStopped.vi. Why isn't all of this code on View's override of this VI? In other words, you should create an override VI of this VI on the View class. Whenever the object is a View object, you would dispatch to that version. That eliminates the To More Specific node entirely. Currently, you've got all the children of Pump that do not have their own overrides calling into this VI and they will all return an error because they are not View objects.

Do the overriding properly and your issues with the dynamic dispatch propagation vanish entirely.

Link to comment

Well, that was foolish of me.

First to clarify:

Now I'm looking at the semantics of your diagram and I'm seeing an issue. Pump is a class. View is a child of Pump. This VI is Pump.lvclass:MessageLoopStopped.vi. Why isn't all of this code on View's override of this VI? In other words, you should create an override VI of this VI on the View class.

Actually I did, if you look at the title bar that's exactly what the VI is. Pardon the names on the terminal labels, but I hadn't gotten around to changing them yet (the override script does not apply the new name). So to clarify, the terminals *are* View.lvclass objects, they just are labeled as "Pump".

Now the weird part is when I created the override and connected View methods, I *swear* I got a broken wire. So without thinking I inserted the cast. That was dumb on my part. Should have immediately clued in to the fact that something was wrong. I was also having problems in which the override was never being called, even with the "functional" version I showed. Still not sure what happened there, I'm trying to figure it out.

For now, ignore the mad man, I'm trying to reproduce the behavior...

Well I give up. I have no idea what was going through my mind.

For the record (with properly named terminals!):

post-11742-034472500 1283450522_thumb.pn

I swear that when I first coded the VI the wire to the first method broke when I wired it up. I'm not crazy. Honest.

Sheesh, this VI should have taken five minutes to code and it took nearly an hour (had a meeting in between some of my posts).

Sigh...I need a vacation.

Link to comment

There's still something funky going on with that class though. I think some of the info in the lvclass file is corrupt or something?

Look what happens when I try to create an override:

post-11742-081743300 1283458172_thumb.pn

What's the problem you ask? The methods in the red boxes are not dynamic, yet the script picks them up for some reason and puts them in the box. Also the previously mentioned bit how the terminals aren't getting properly renamed when I override a method in the class.

Even weirder is the dialog appears normal if I try to do an override of a class further down the inheritance chain. For now I'm ignoring the behavior, I hope it doesn't come back to bite me in the behind...

Link to comment

That is... weird. Try changing the conpane of one of those VIs -- change the input terminal to Dynamic Dispatch Input, save it, then change it back and save it again. See if that gets it out of the list.

(the override script does not apply the new name)
No, it doesn't. That's deliberate, although possibly wrong in retrospect. It's a philosophy question -- what does the label even mean on these terminals? Is it the name of the parameter? If so, it should be the same on all the overrides. The fact that it happens to default to the same as the name of the original parent class notwithstanding. If it is the name of the class, well, for one thing, it is redundant, but it also would mean it should change with each level of inheritance.

Honestly, in retrospect, I think the default names should have been something like "dispatch in" and "dispatch out", but I know a lot of people wouldn't like that for various reasons.

Link to comment

Good idea, but nope, the methods still list in the override dialog. Code is attached.

To reproduce the behavior, just right click on View.lvclass, select New > VI for Override ...

The View class inherits from MessagePump, which defines the offending methods. Some of the offending methods are even privately scoped, all of them reside with property definition folders:

post-11742-052807400 1283469271_thumb.pn

Note that if you then go further down the inheritance chain, and try to implement an override on ContainerView, the methods are no longer listed.

The project is for LV2010: LabVIEW.Messaging.2.0-r494.zip

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.