mje Posted September 2, 2010 Report Share Posted September 2, 2010 I'm a little confused as to why this is. If you could take a quick look at the code below: 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): Is someone able to explain why the behavior is as it is? I've never stumbled across this problem before... Quote Link to comment
crelf Posted September 2, 2010 Report Share Posted September 2, 2010 It's complaning that there's no unadulterated path between the object input and the object output, which you need for dynamic dispatch methods. In the non-broken exaple you have the same object type wired to the object in and out, but in the broken one you don't. Quote Link to comment
Aristos Queue Posted September 2, 2010 Report Share Posted September 2, 2010 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: 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. Quote Link to comment
Aristos Queue Posted September 2, 2010 Report Share Posted September 2, 2010 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. Quote Link to comment
mje Posted September 2, 2010 Author Report Share Posted September 2, 2010 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!): 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. Quote Link to comment
crelf Posted September 2, 2010 Report Share Posted September 2, 2010 For the record (with properly named terminals!): There you go! That's much better Quote Link to comment
mje Posted September 2, 2010 Author Report Share Posted September 2, 2010 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: 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... Quote Link to comment
Aristos Queue Posted September 2, 2010 Report Share Posted September 2, 2010 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. Quote Link to comment
mje Posted September 2, 2010 Author Report Share Posted September 2, 2010 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: 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 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.