Jump to content

smenjoulet

Members
  • Posts

    126
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by smenjoulet

  1. If so, is there a way to transfer the geneology information from MessageQueue.lvclass to MessageQueue__v1.lvclass? I assume I cannot simply copy the xml from one lvclass file to the other.

    Yes, but it wouldn't help you.

    You have A.lvclass at version 1.0.0.4. You save lots of data. Now you rename the class to B.lvclass.

    You certainly could bump the class version in the file from 1.0.0.0 to 1.0.0.4. And you could cut and paste the mutation history from A.lvclass to B.lvclass. That's great -- you now have a version 4 of B that can load any data that was flattened as B versions 0, 1, 2 or 3. The problem is that all of your data was flattened as *A*. The name of the class and the version number are both part of the flattened data. It has to be because when I flatten data on an A wire, that data might be a child class like ChildOfA.lvclass. When I unflatten data onto an A wire, the data has to declare which class it represents.

    So, yes, you could preserve all the mutation instructions of your previous class on the new class, but it doesn't make any of your data accessible. To be able to unflatten old data, you have to be a new version of the same class and "same class" means same name.

    So admittedly this is the end of the day and I haven't given it too much thought, but would it be possible in future version of LV to decouple the Class Name from the .lvclass file name on disk?

    Would that allow us to avoid this issue with renaming a class? I'm willing to bet that in most cases (as Dave points out) we're just needing the *file* renamed and not the actual CLASS itself. If you actually needed to rename the CLASS, then it works as it does now and wipes the mutation history.

    Any problems that could engender?

    -Scott

    Nice presentation by the way! thumbup1.gif

  2. OMG! Look at that nesting!

    Good luck with this project wink.gif

    Yea, and that's just the nesting you can see! And this is one VI out of hundreds.

    The original developer recently had to make some changes (I'm not gonna touch it; it's like a house of cards- remove one VI and the thing implodes) and we did a code review of the changes. One of the people in the review who doesn't know LabVIEW said, "Ow! That hurts my eyes!" Tell me about it. I've gone home with headaches after looking at this code.

  3. Hit the clean up button, I dare you.

    Well you threw down the gauntlet, so I had to pick it up! Cleanup handled it pretty well, it took maybe 10 seconds. I can't say it's any more usable; in fact I'd say it's worse. Same code now spread out over 5-10x the real estate. Some messes you just can't clean up...

    I feel for you, Scott! That looks like all the projects I inherited when I started working here. I can very well understand why everyone else in my group now hate LabVIEW and refuse to use it.

    Thanks Crystal.

    If you want to play hunt the white block ....... this is the program I inherited a couple of months ago.

    That's pretty bad too. Where do these people come from???

  4. I remember that something changed with the licensing of Matlab script nodes with 2009 but I can't remember the details.

    I think you're confusing this with the licensing for MathScript, which had a script node similar to the MATLAB node. MathScript used to be included with a LabVIEW Pro license (and maybe LabVIEW Full, don't remember). It is now a separately paid for license in addition to LabVIEW.

    The MATLAB node (to my knowledge) does not have any special licensing requirments from the LabVIEW side. Of course, you do need a MATLAB license to be able to use it.

    -Scott

  5. For what you posted, you don't need to use the Locate File VI and you're using the Extract VI incorrectly. FYI, the Extract VI uses the Locate File VI in its implementation.

    See the attached for how to do what you want and have it work correctly.

    post-415-127006594788_thumb.png

    -Scott

  6. Try these on for size!

    post-415-127005216553_thumb.png throwpc.gif

    post-415-127005224263_thumb.png

    That little white block on that last one is my 1920x1200 monitor. frusty.gif I'd need about nine of them side by side to see the whole thing.

    At least I don't have to refactor, but try and understand and document that! If it were up to me, it would be rewritten from scratch. That may happen yet at some point.

  7. I don't know whether to ask this here or on the other thread, but are there any drawbacks about using Variant Attributes on real-time targets? Besides memory... And on that note, is there a better way of getting the number of the elements in the Variant than producing names/values arrays just to get the length?

    Miha

    Can't answer the RT part of the question.

    For your second question though, you could store the size of the table in the variant itself as it is not used for anything else in this scenario. Just remember to update the count whenever you add or remove a key/value pair.

    -Scott

  8. I still don't see any way anyone is actually paying for SP1. If you are, can you tell us how that happened?

    While I'm not in this situation, I can envision a rare one. Both Jeff Phillips and I posted this scenario in our previous posts:

    1) Buy LabVIEW 8.6 in October 2008 (get one year of SSP)

    2) Get all 8.6 bug and maintenance releases.

    3) Under SSP, you upgrade to LV2009 when NI releases it in August 2009.

    4) You do not renew SSP in October 2009

    5) You still get the 2009f2 and f3 fixes, but not SP1 as your SSP has expired

    At that point you are not required to "pay" for SP1 if you don't feel you need, but you also can't install it. But if you do you need it, you would need to "pay" for it by renewing the SSP on your license. The cost for that varies by how long your license has been inactive.

    Whether you interpret that as actually paying for SP1 or paying to renew your SSP (and getting SP1 as one of the benefits) is up to the indivdual. Like I said, I think that situation would be pretty rare.

    -Scott

  9. Stop writing crappy code, NI. Fix it before you ship it.

    As Chris and others have noted, I think that is an unfair characterization. I think this born more out of anger at the SP1 terms than of the general bugginess of 2009. It is my anecdotal experience that the quality of NI software has generally improved over the years. There have been hiccups here and there, but I find LabVIEW, etc. more stable than in the earlier years.

    What could possibly motivate NI to charge us money to fix their bugs? angry.gif

    Agreed. I'm on the SSP plan, but I think it stinks to charge for bug fixes.

    Let me preface my following comments by saying that I don't agree with NI's verbiage on SP1 nor am I trying to defened them. I am just trying view it from the opposite side to understand the motivation. Let the flames fly.

    On the requirement of an active SSP for using SP1:

    Stop for a moment. I think it affects relativley few LabVIEW users. If it does happen to affect you, that is little consolation. But you might need to adjust your "upgrade" practices. Let me explain:

    1) If you purchased 2009, then you have 1 year SSP built-in. No charge for bug fixes.

    2) If you buy the upgrade to 2009 from an earler version, ditto above.

    3) If you have an active SSP (per SP1 terms) there is no charge.

    4) If you are not using 2009, you're not affected.

    The only users it would affect are those that had an existing SSP (ealier LV version, Dev Suite or VLA) and let it expire between the release of LV2009 and the release of SP1, but they used that SSP to upgrade to 2009 before the expiration. If you are upgrading to a new version, you might want to question the practice of letting SSP expire. Everyone else should be covered. Like I said at the beginning, I don't agree with terms, but if affects few users and those it does affect had a choice.

    On the motivation of NI to adopt these terms:

    I think it comes down to users getting up to two years of SSP for the price of one. Take the following example:

    I purchase LV8.6 in Oct 2008. I get my 1 year of SSP. I get the 8.6.1 maintenance release. NI releases LV2009 in August 2009. I upgrade to LV2009 in September. I let my SSP expire in October 2009. I get 2009f2 and f3 fixes. NI releases LV2009 SP1 to active SSP users only. I am "locked out" of the additional bug fixes by not keeping SSP active. But if NI let me have access to SP1, I'd be getting a year and a half of SSP (minus the priority phone support). That could extend close to 2 years if they have additional fixes come out.

    I'm not defending these terms, just offering up this viewpoint for you to chew on and spit out as you wish. If you disagree with NI, make your voice and case known.

    [EDIT] Jeff Phillips has made some additional eloquent arguments from the NI side above.

    Besides, if you seriously think that NI's code has had a negative impact on your business, then give your local FSE a call and they might be able to help you. NI isn't a faceless corporation, and they're not out to screw you with bad product.

    I second that 100%. If you have a good a DSM/FSE then work with them. Have the above discussions with them and raise the issue. I've usually found them willing to do whatever is reasonable to help out.

    -Scott

    • Like 1
  10. Eric, Ben,

    The issue in this case is not with VI snippets, but how they are attached and/or displayed in forums or web pages. Often the image is just a placholder for the real image file. The placeholder image doesn't contain any of the VI code for the snippet feature to work. When you drag it, you get the circle with line through it (operation not allowed).

    When you find these cases, right click on the image and select "Save Target as..." (not "Save Picture as...") to save it to you computer. Then drag the resulting image file to your LabVIEW VI and the snippet should work fine.

    I was able to get all the snippets you referenced into LabVIEW, though some searched for missing VIs or typedefs that aren't saved in the snippet.

    -Scott

  11. Mike,

    Here's the non-OO implementation.

    Norm,

    I was not trying to imply that the OO design should not be used going forward in any substantial project. I was making the point that to understand the concept, especially for a LVUG presentation as Mike is doing, I think it is easier to start from a non-OO base, especially when you have limited time.

    I agree that once you get the concept, moving to the OO approach should be the goal.

    and is a work of genius! worshippy.gif

    I don't know 'bout genius , but it was fun. Thanks for the props!

    -Scott

    LVx Example.zip

  12. I have this folder on my PC. No idea if it works, but I think it's what you want.

    It does work although I think it deserves a better example. This was Norm Kirchner's OO implementation. My original implementation (circa 2004/2005, ~LabVIEW 7.x) was not OO as native LVOOP did not exist in LabVIEW at the time and I have never used Endevo GOOP. I think it might be better to start with a non-OO example and then work up to OO as appropriate. I'll see if I can dig one up or put a simple one together.

    Mike,

    Norm and I were going to put a similar presentation together for NI Week one year, but it never made it off the ground. I'd be happy to collaborate on part of it with you. Just send me a PM if interested.

    -Scott

  13. And another quick question about queues, if I tell something to enqueue as fast as possible (0 timeout) and my dequeing code can't possibly keep up, what happens to the data? Is it destroyed or lost somehow? Or does the code behave like a lossy enqueue rather than a normal one?

    Regards

    Alex

    You don't need to specify a 0 timeout if you want to enqueue something as fast as possible. If there is room in the queue, it will be put on it.

    If you are using an unbounded queue, then theoretically the function will happily enqueue items until you run out of memory no matter what timeout value you specify.

    If you have a bounded queue (as in your example) and it is full, then the enqueue function will wait until the timeout expires or space becomes available. If the timeout happens first, no enqueue takes place. You will not get an error from the function, but you can check the 'timeout' output to see if a timeout occurred.

    -Scott

  14. The difference is in what data is being sent with the user event. Your example puts a parent object in a user event typed with a child object. I'm restricting myself to putting a child object on a user event typed with a parent object.

    I debated with myself on whether it was worth it to reply or not and lost. I stand by my comment that "there is no difference", as I believe (correct me if I'm wrong) you missed the point of my statement. Of course there is a difference in what data was actually sent in our examples, but that isn't what I was referring to.

    I think the key is in the invisible link between the Generate User Event prim and the event structure. Notice the for loop in your example. The Generate User Event prim *thinks* both queues are typed with the parent object, so it doesn't object to sending a parent object down them. The data type in the event structure is defined by the wire sent into the Reg Event prim at design time, so at runtime the parent object is automatically cast as a child, which is can't fully support.

    Yep. Now looking at your example, notice the "Generate User Event prim *thinks* the queue is typed with the parent object". Sure, there is a difference in data being sent. I explicity chose to send a parent object, while you say you are restricting yourself to sending a child object. It doen't change the fact that both examples are the same in that a child event refnum has been cast to a parent. Yours was explicit with a type cast. Mine was implicit with the refnum coercion "bug" in 2009. But the result is the same.

    In my example there's a coercion dot on the Generate prim, indicating the child object is being upcast to the parent, which is perfectly legal. The silent typecast at the event structure is simply casting the child object from a parent back into the child--also legal. Putting the wrong child class or a parent object does cause problems, so I've tried structuring the framework to prevent the event producer from doing that.

    Again, no disagreement in principle, but I could have sent a child object and I would have the coercion dot as well and it all would work fine. That would defeat the point of the experiment.

    In your example, you could also send a parent object (consciously or accidentally) and you wan't get any coercion. You'll end up sending parent data to a child object. It will 1) wire up correctly 2) compile 3) run and 4) CRASH... probably hard!

    If you look back at the rest of my statement, I say: But if you're careful to ensure that you don't send the wrong data, I'm betting it works fine.

    That's what you're doing. Being as careful as you can with the structuring of your framework to ensure that doesn't happen.

    Conclusion-

    Technique: SAME

    Data: DIFFERENT

    I'll split the pot with you, how about that...

    If you can, I'd strongly suggest you take the jump into OOP. I have yet to meet anyone who has really learned OOP decide that the 'old' way is better. (Aside from specific high performance applications where c or assembly are needed.)

    Ditto that!

    -Scott

  15. My initial guess would have been a silent shutdown or lockup since that's what happens to me 96% of the time. But since Norm jogged my memory on the dynamic dispatching error I think he's probably right. I'm running into that error more frequently these days... (The error text is, "This dynamic subVI cannot execute because the needed member VI cannot be found.")

    Well, depending on the circumstances, you're both right. And also partly wrong. It's all a matter of perspective.

    I identified and tried the following four cases:

    1) Dynamic dispatch where all members are available.

    2) Dynamic dispatch where just the child method was available

    3) Static dispatch that does nothing

    4) Static dispatch that passes out data

    All were tested with the parent data being dumped on a child wire:

    1) Functions normally, maybe to the chagrin of AQ. Parent and child VI's dispatched appropriately depending on the type

    2) Gives the "This dynamic subVI cannot execute because the needed member VI cannot be found" error.

    3) Does essentially nothing. No errors. No crash.

    4) Ahh... well the devil he no like this case. As a fine a lady as Miss LabVIEW is, well she try tado da dance on that high wire and she trip and fall flat on her face. And a big flaming pit open in the ground and she be dragged straight to hades.

    Seeing that bug in '09 has me a bit concerned that what I'm doing may be violating the rules of 8.6. I think I'm okay, but it never hurts to check... Is there anything wrong with typecasting a child class user event into a parent class user event, aside from the fact that it's possible for the event producer to send the wrong EventData child class along with the event?

    As expected you cand perform tha same cast in 2009. Strictly speaking, I am betting AQ will call this a "hole" that needs to be covered as I don't see that it is any different than what I tried above. So from that perspective I'd say that it is bad. But if you're careful to ensure that you don't send the wrong data, I'm betting it works fine.

    So I think we're all in agreement that having parent data on a child wire or control is BAD. But instead of not allowing these typecasts or polymorphisms and causing broken wires, I wonder if there isn't a compromise. I would think that even though a child basd user event (or queue, etc) refnum has been cast to a parent type, LabVIEW would still be able to check the true type and throw an error from the primitive at runtime. This would allow this type of technique to operate and still provide type safety at runtime.

    Admittedly, I haven't tried to think through all the implications of that, but hey, that's what Stephen get paid for... smile.gif

    -Scott

  16. OH NO. This is VERY BAD. That's going to have to be fixed in LV2010. That's a severe bug and I had no idea it existed until today.

    So I have to ask: Why did you ignore it when I posted similar examples using USER events (see previous posts)? Is it because you don't see the same issue with user event references?

    I can see why this is BAD for other references (queues, etc), but I'm really trying to dissect whether it is the same for user events. Unlike queues, where it was quite easy to get a child control that contained parent data, I am having more difficulty doing this with user events. When you have an array of class user event refs used in an event structre, the event data is of parent type, so I can't see in that scenario how you'd get parent data on a child wire or control. Maybe I'm missing it, but the attached image appears to be a valid operation and it does work properly.

    post-415-126393062171_thumb.png

    If you see other issues, I could use the clarification. I have other thoughts, but I'll hold them for now.

    -Scott

    I can see why this is BAD for other references (queues, etc), but I'm really trying to dissect whether it is the same for user events. Unlike queues, where it was quite easy to get a child control that contained parent data, I am having more difficulty doing this with user events. When you have an array of class user event refs used in an event structre, the event data is of parent type, so I can't see in that scenario how you'd get parent data on a child wire or control. Maybe I'm missing it, but the attached image appears to be a valid operation and it does work properly.

    Just answered my own question... I don't know if it's possible to get the "parent data on child" violation with a single event structure, but it's easily doable with two. Occurred to me right after my post.

    post-415-126393128096_thumb.png

  17. What happens when you try to wire a parent class user event and child class user event to the same output node in a case block?

    It depends on how you wire it up. You can get a class conflict error on the parent event wire or you can get it to wire up correctly. It has to do with how you wire through the cases. If you wire the parent event through the FALSE case and the child event through TRUE, it will wire ok. If you do the opposite, you get a class conflict error on the parent event wire.

    post-415-12638330524_thumb.png

    I don't know what NI calls it, but I call it the master case rule. I don't know if my understanding is completely correct, but it seems that case structures (and probably others as well) have a "master" case that governs the type of a wire coming out of the case structure if other conversion/casting rules fail. The master case is normally the first one listed (FALSE, 0) when you drop the structure, but you can rearrange or relabel it after the fact.

    -Scott

  18. To allow clients to do arbitrary operations on arbitrary data from arbitrary events, I think you have to expose all the data elements to them, which in turn means the user event structure has to give them a strongly typed EventData subclass at design time. This of course requires the module expose unique events rather than a single generic event. I can do that... so far so good. The inconvenience arises while developing the source code to enable this functionality. Since user events are not polymorphic it is very difficult to operate on the them in sub vis or case statements. This forces me to create and maintain a lot of duplicate code; I have to recreate any common user event processes (Create, RaiseEvent, Destroy, etc.) for each user event the module exposes. Hopefully this image helps explain the problem I'm trying to address.

    hammer, but there are lots of things laying around that don't look like nails. I'm trying to fill out the rest of my tool belt.

    Heh... sometimes I wonder. This path is covered with jagged rocks and prickly thornbushes. I don't think many have travelled this way. wink.gif

    Is LV2009 at all an option for you. Based on the image below, it seems to get you farther down the rocky path. It seems that it supports some level of polymorphism on class-based user events where 8.x doesn't. I was hoping AQ would shed some light on this based on his previous comment of never supporting polymorphism of user event wires. I can understand that comment when applied to types that are completely different (say string and int), but when the types are part of a class hierarchy and follow certain constraints, LV2009 appears to contradict his statement.

    -Scott

    post-415-126359876975_thumb.png

×
×
  • Create New...

Important Information

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