Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/23/2009 in all areas

  1. Daklu, the style of my writing below is fairly terse and occassionally EMPHATIC. I've done this to emphasize key points that I think you've missed in How Things Work. Some customers in the past have felt I'm insulting them writing this way, but it is the only way I know through the limited text medium to highlight the key points. My only other option is to post just the key bits and leave out a lot of the exposition, but that doesn't seem to be as helpful when communicating. So, please, don't think I'm calling you dumb or being disdainful. I'm trying to teach. The problem is that you're almost right. Customers who are completely off-base are easier to teach because they need the whole lesson. Here, I'm just trying to call out key points, but presenting them in their full context to make sure it's clear what fits where. Throughout the post, refer to the graphic at the end of the post as it may clarify what I'm talking about. Dalku wrote: No. If there is, that's a bug that needs to be reported to NI ASAP. Think about what you just asked for... ignore the DVR part for a moment. You just asked for a PARENT object to invoke a CHILD class method. That cannot ever happen. You cannot pass a parent object directly to a function that takes a child object. The parent object in question IS NOT a child -- the parent object does not have the child's private data, nor does it have all the methods that may have been defined on the child class. For this reason, LV will break the wire if you try to wire a parent wire to a child terminal -- the wire is broken because there are zero situations in which this can successfully execute. You CAN pass a child object to a parent terminal. That is because a child IS an instance of the parent -- it has all the necessary data and methods defined to act as a parent object. What you can do is take a child wire, up cast it to a parent wire and make a Parent DVR out of that. Alternatively, you could take a child wire, make a Child DVR wire, and then upcast that to a Parent DVR wire... these two processes produce the idenitical result: a parent DVR that contains child data. Upcast and downcast DO NOT create new objects EXCEPT when they return an error. The point of a cast is to say, "I have an existing object. Please check that it is this type and approve it to go downstream if it passes this test." You use this only when you need to do something for a specific type of object and you do not have the ability to edit the parent and child classes in order to add the appropriate dynamic dispatch VIs to both. Preserve Run-time Class (PRTC) is the same thing. "Allow this object to pass downstream if it passes this test, otherwise create a new object that does pass the test." The test in this case is "Does the object in have the same TYPE AT RUN TIME as the OBJECT (not the wire) on the target object input?" If the left object is the same or a child class of the center object then there is no error. You will ALMOST NEVER WIRE PRTC WITH A CONSTANT FOR THE CENTER TERMINAL. I would say "never" because I can't think of any useful cases, but maybe someone has something out there. If you are wiring the center terminal of PRTC with a constant, something is wrong in your code. You use the PRTC to assert that the left object, which comes from some mystical source, is the right type to fulfill run-time type requirements of dynamic dispatch VIs, automatic downcast static VIs, and the Lock/Unlock of Data Value References. In all three of these cases, there is some input (either the input FPTerm or the left side of the Inplace Elt Struct) that must be passed across to the output (either the output FPTerm or the right side of the Inplace Elt Struct) WITHOUT PASSING THROUGH ANY FUNCTION THAT CHANGES THE OBJECT'S TYPE. You're free to change the object's value, but not its type. Sometimes you pass the object to functions where LV cannot prove that the type is maintained. Easy example -- pass the object into a Global VI and then read the Global VI. You'd never do this, of course, but it demonstrates the problem. LV cannot know that the object you read from the global is the same object you wrote in -- some other VI elsewhere might have written to the global in parallel. But you, as the programmer, know that there are no other writes to the global VI, so you use the PRTC to assert "this is going to be the right object type." You wire the original input (as described above) to the center terminal, and the output of the global to the left terminal, and pass the result to the original output terminal (as described above). Does that make sense?
    3 points
  2. If you follow me on Twitter, you probably already know that I own the "metric system" lunchbox mentioned in this list of the worst lunchboxes ever. The article, however, only shows the front of the lunch box. There's 5 more sides to the Exciting World of Metrics. So I thought I'd post the other faces of the lunch box here. Note: This was not a lunchbox I originally owned as a child. I bought it in a kitschy retro-70s-&-80s-crap store in downtown Portland a few years ago. Back in my elementary school years, I rolled with a sweet Return of the Jedi lunchbox, and then later on an even more awesome Dragon's Lair lunchbox.
    1 point
  3. Interesting question! If you put code inside the TimeOut case, you are screwed. There are many different approaches here, but the easiest one I use is by using a state machine like this: If the TimeOutCounter is zero, I wait for 1000ms before going to the TimeOut case, else a 0 or 1 ms is wired to the TimeOut on the Event Structure, so it goes directly to the TimeOut case if no other events are in the queue. Event2.vi //Mikael
    1 point
  4. Hi I can’t help you much there. The design I’m looking into is to have the class-data (attributes) as a TypeDef belonging to the class and then put it into the Data Value Reference (DVR) wire. That then goes into the lvclass private data. A update method could then look like this. By using this method the dynamic dispatching will work as usually without having to put an In Place Element Structure around all abstract methods. Cheers, Mikael
    1 point
  5. Hi Daklu I have been playing with LVOOP and DVR also! It is very cool stuff. I had a look at your post as it is very interesting. I think removing the references to investigate the problem may help to solve the issue. Below is what I have come up with. Parent cannot downcast to Child as Parent cannot run extended Child methods (Child can always run all Parent Methods) so you get a broken run arrow and that makes sense, any other casting will generate a run time error (see attached png top). When you use the Preserve Run Time Class function I don't think you are getting a new parent, I think you are getting a new child: When the error occurs, all data on the wire is lost and a new child is created. You can then do what you like with the child (see attached png middle). I think the references may be hiding all this in the example you posted as you can have a parent reference pointing to a child object (see attached png bottom). Therefore I do not think it is a bug either way? Would you agree or am I totally off!
    1 point
×
×
  • Create New...

Important Information

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