Jump to content


- - - - -

Editing an existing class


16 replies to this topic

#1 mje

    The 500 club

  • Premium Member
  • 634 posts
  • Location:Milford MA USA
  • Version:LabVIEW 2011
  • Since:1997

Posted 14 November 2011 - 07:50 PM

Excuse me while I vent, but I can't be the only one in this situation.

Let's see if this sounds familiar to anyone, as an exercise we'll play a follow along game with how to add a control to an existing class:
  • Open the class' .ctl file.
  • Drop the new control in the private data cluster.
  • Wait...
  • Does LabVIEW recover? If no, kill LabVIEW.exe and start again at step 1.
  • Rename the control so it has a proper name.
  • Wait...
  • Does LabVIEW recover? If no, kill LabVIEW.exe and start again at step 1.
  • Save the .ctl file and move on.
This scenario has become all too familiar on a large project I work on, let's just say there better be a damned good reason for me to change any of those classes (and honestly, it's not that "big", it's just "LabVIEW big", maybe 1600 VIs). But I also have a much smaller project with maybe 18 classes (~250 VIs) and the inheritance hierarchy is at best, three levels deep. And now LabVIEW sees fit freeze indefinitely when I drop a new control on one of my classes.

Don't get me wrong, I love OOP in LabVIEW. Frankly, without OOP I would have relegated the language as a relic of the past and moved on long ago. But I'm getting a little tired of not talking about this dirty little secret. OOP is great, but it's not all sunshine and lollipops, there are some serious gremlins creeping around in there. I've been trying for over an hour to add a DBL to one of my classes and still no luck. Seriously? Come on now.

Mass recompiled my project? Check.
Flush my object cache? Check.

Surely this happens to others?

#2 mje

    The 500 club

  • Premium Member
  • 634 posts
  • Location:Milford MA USA
  • Version:LabVIEW 2011
  • Since:1997

Posted 14 November 2011 - 08:13 PM

For what it's worth, if I add a save operation between step 4 and 5, I can get through adding the control now. It won't get back the previous hour and a half though...

#3 Tim_S

    Extremely Active

  • Members
  • PipPipPipPip
  • 439 posts
  • Location:Michigan
  • Version:LabVIEW 2011
  • Since:1994

Posted 14 November 2011 - 08:23 PM

Yea, I've had similar problems. It's been to where I had to open the "offending" VIs outside of the project, correct the issue and save before I could load the project without Bad Stuff ™ happening.

Tim
Tim

"If this was easy our kids would be doing it." - Coworker

#4 neil

    Very Active

  • Members
  • PipPipPip
  • 209 posts
  • Location:Surrey, UK
  • Version:LabVIEW 2011
  • Since:2004

Posted 15 November 2011 - 12:34 PM

I *really* feel your pain on this.

Last medium size project I had this exact same problem. In the end the only solution I found that worked was to delete the offending class and re-create it, including all member VIs :-(

Not sure if this has gotten any better in 2011 though.

#5 crelf

    I'm a LAVA, not a fighter.

  • V I Engineering, Inc.
  • 5,535 posts
  • Version:LabVIEW 2011
  • Since:1993

Posted 15 November 2011 - 02:49 PM

Your intial post isn't clear on whether you are working on the class in the project explorer, or just opening the ctl somehow on disk? Is it the lvclass or a ctl that's used by the lvclass?
Posted Image

#6 mje

    The 500 club

  • Premium Member
  • 634 posts
  • Location:Milford MA USA
  • Version:LabVIEW 2011
  • Since:1997

Posted 15 November 2011 - 03:01 PM

It's the ctl that defines the private data cluster of the lvclass. Granted there is no actual ctl file, but it appears as so in the project explorer. I probably should have best described it as an item in the project explorer.

Editing the class outside of the larger project often works, but that's really avoiding the issue. For starters if the lvclass is part of a library, the entire library must be loaded to edit the class. Often when this issue creeps up, the class can't be removed from the library either, for if you try to do so, LabVIEW gets horribly confused.

I did manage to get all the functionality I needed added to the class. However I still can't delete legacy elements. Last night I left LabVIEW for 14 hours, and when I came back in the morning it was still chugging away after I tried deleting a DBL from the private data cluster. Oh well, I guess I can live with orphaned data. It's inelegant, but at least the functionality I need is there.

#7 Tim_S

    Extremely Active

  • Members
  • PipPipPipPip
  • 439 posts
  • Location:Michigan
  • Version:LabVIEW 2011
  • Since:1994

Posted 15 November 2011 - 03:12 PM

You may have luck by opening just the class and editing it by itself (no project open). Having as little as possible open seems to help LabVIEW not get into some infinite loop.

Tim
Tim

"If this was easy our kids would be doing it." - Coworker

#8 Daklu

    Learning LabFu Daily

  • Premium Member
  • 1,493 posts
  • Location:Seattle
  • Version:LabVIEW 2010
  • Since:2006

Posted 15 November 2011 - 04:34 PM

I have found removing the mutation history resolves all sorts of LVOOP ills. It doesn't always work, but sometimes it does--often enough that it's usually the first thing I try.
Certified LabVIEW Architect
Good software is an investment. Bad software is an expense. Choose wisely.

Dak's First Law of Problem Solving: If the solution looks simple, I don't know enough about the problem.

There are two secrets to success:
Secret #1 - Never tell everything you know.

#9 mje

    The 500 club

  • Premium Member
  • 634 posts
  • Location:Milford MA USA
  • Version:LabVIEW 2011
  • Since:1997

Posted 18 November 2011 - 03:04 PM

*
POPULAR

Well, I've tracked this down to an issue being brought on to using classes within a LabVIEW library. The two kinds of libraries (.lvlib and .lvclass) just plain do not work together.

My little project's classes became plain uneditable, they were contained in an lvlib. In a fit of frustration, I dragged the entire lvlib hierarchy out of the library scope, and magically everything just works as intended. This is a shame, for lvlibs offered a lot of control and namespacing which really helps with code reuse. Please to any at NI who are reading this thread, fix this.

Well, it's a good thing I got this working. I'm literally down to the last hours, about to be gone for two weeks and this code has to work by end of day. Meanwhile, I just lost two hours trying to add a simple primitive to one of my classes.

Since there's no way I'm going to drop my use of .lvclass objects, I'm done with lvlibs for now.

#10 SteveChandler

    Very Active

  • Members
  • PipPipPip
  • 157 posts
  • Version:LabVIEW 2010
  • Since:2000

Posted 17 January 2012 - 11:31 PM

View Postmje, on 15 November 2011 - 03:01 PM, said:

For starters if the lvclass is part of a library, the entire library must be loaded to edit the class.

Usually learning something new leaves me feeling all warm and happy. In this case, not so much! :angry:
Steven Chandler
Certified LabVIEW Developer

#11 Aristos Queue

    LV R&D: I write C++/# so you don't have to.

  • Premium Member
  • 2,324 posts
  • Location:Austin, TX
  • Version:LabVIEW 2011
  • Since:2000

Posted 18 January 2012 - 05:00 AM

I believe you. Really. I just don't see these crashes myself.

I probably develop more classes than most people on this list, whether it be apps on my own, quick demos for people who ask for them, or testing for CARs. I *don't* typically have the problems you're discussing when editing the private data control or renaming classes. Just today, I had a hierarchy four levels deep in which I had classes in one library. I moved some of those classes to another library, renamed them, moved them on disk and then deleted fields from the private data control and had no problems, before, during or after the operations. I do this on both my Windows machine at work and my Mac at home.

If you have a situation where this happens, I need you to file CARs. Even though I'm not working on them myself any more (see thread in LAVA Lounge from last week), I still care about the quality. My team has done a huge amount to stabilize LV classes over the years. We will do more if you bring it to our attention. This is especially true for those of you who use source code control and can provide before and after images of the classes if they become corrupted.

#12 SteveChandler

    Very Active

  • Members
  • PipPipPip
  • 157 posts
  • Version:LabVIEW 2010
  • Since:2000

Posted 24 January 2012 - 09:19 PM

I have not had any serious problems since upgrading to LV2011. 2010 would crash on me when doing anything with a lot of classes.

But what I did not realize is that if I use a class in a library then all classes get loaded into memory. I have some libraries with a lot of classes in them and now have to think about breaking things up somewhat. Again, it has not proven to be an issue yet but I want to be proactive. I have a development system with lots of horsepower and ram but the applications get deployed on systems with fewer resources. I use the factory pattern to load a preconfigured child class of an abstract parent because I didn't want to load all of the classes. But the parent and children are all in the same library so I guess that defeats the purpose. From a library standpoint it makes sense (to me) to include all those classes in the same library.

Do you have any specific guidelines on what goes into a library as far as class hierarchies go?

Is there any way this could change? Could it be possible to load pieces of a library without loading the rest? I ask because maybe it is something for the idea exchange. I don't want to post it yet because I don't know if it is a good idea or if it is even doable.
Steven Chandler
Certified LabVIEW Developer

#13 drjdpowell

    Extremely Active

  • Premium Member
  • 305 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 24 January 2012 - 09:42 PM

View PostSteveChandler, on 24 January 2012 - 09:19 PM, said:

But what I did not realize is that if I use a class in a library then all classes get loaded into memory. I have some libraries with a lot of classes in them and now have to think about breaking things up somewhat. Again, it has not proven to be an issue yet but I want to be proactive.

I went through something similar about a month ago. Most of my classes are not in Libraries now, which is not really what I would prefer, but it is necessary if I want to only load necessary software (every so often I open a new project, open a fresh VI, and drop a single object into it and see how much loads up under “Dependancies”). It’s more than just Libraries; any VI in a class that refers to another class acts as a “linker”, causing that other class to fully load in memory. It just takes a few linkers to get a sort of “domino effect” as class after class loads up.

#14 mje

    The 500 club

  • Premium Member
  • 634 posts
  • Location:Milford MA USA
  • Version:LabVIEW 2011
  • Since:1997

Posted 24 January 2012 - 10:14 PM

View PostSteveChandler, on 24 January 2012 - 09:19 PM, said:

Could it be possible to load pieces of a library without loading the rest? I ask because maybe it is something for the idea exchange. I don't want to post it yet because I don't know if it is a good idea or if it is even doable.


I doubt it is possible. As soon as something is a member of a library, loading that item will force the library to be read so that item scope (among other things) can be determined. But when you load a library, LabVIEW must make sure that the library isn't broken, which demands that every item get loaded to verify status.

As DrJD implied, I think this effect propagates for linked libraries too. Break a VI that is part of a dynamic dispatch for example, you'll notice every method of every class in the hierarchy becomes broken until the single VI is fixed, never mind any other VIs that use these classes, and their libraries, ad nauseam...

#15 drjdpowell

    Extremely Active

  • Premium Member
  • 305 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 25 January 2012 - 10:51 AM

What I’d like to see is for a LVLib to not automatically load its contained LVClasses until and unless something else in memory refers to that class. In other words, have LVClasses follow the same loading rule as regular VIs in libraries. That would allow me to organize classes in libraries without issue. It would be nice if LVClass libraries could load piece-by-peice, but that is less important and probably not doable.

— James

#16 Aristos Queue

    LV R&D: I write C++/# so you don't have to.

  • Premium Member
  • 2,324 posts
  • Location:Austin, TX
  • Version:LabVIEW 2011
  • Since:2000

Posted 25 January 2012 - 04:34 PM

View PostSteveChandler, on 24 January 2012 - 09:19 PM, said:

Do you have any specific guidelines on what goes into a library as far as class hierarchies go?
I discussed this issue a bit in the Actor Framework documentation. My personal policy is that "a library should contain intimately connected pieces that are almost always needed together for operations". In other words, your plug-ins and dynamically loaded content should not be in the same library as your core framework. In the case of the Actors, we've been making libraries that contain the actor and all messages that can be sent to that actor on the theory that each message represents a call to one method of the public API, and the public API is always expected to exist on a class.

View Postmje, on 24 January 2012 - 10:14 PM, said:

I doubt it is possible. As soon as something is a member of a library, loading that item will force the library to be read so that item scope (among other things) can be determined. But when you load a library, LabVIEW must make sure that the library isn't broken, which demands that every item get loaded to verify status.
Only classes load all their member VIs. Regular libraries do not. Regular libraries do not care if VIs in them are broken as far as the functionality of other VIs is concerned. They do load all their member libraries, which, by the transitive property of "things that load things", means that a library having a class will load all the member VIs of that class.

Classes can relax this rule in the runtime environement, which we do when you deploy a class to RT, but we never found a satisfactory user experience in the dev environement without having all the members in memory. One weirdness was changing the name of a VI causing VIs of child classes to load or unload, and the unload case was especially weird if you got a Save Changes dialog -- no one expected Save As on one VI to cause a Save Changes dialog on a bunch of other VIs. There were multiple other weirdnesses. Eventually we decided that loading everything in a class is mostly ok since classes are generaly bundles of tightly related functionality such that if you need one part of the class, you mostly need the entire class. Mostly. As long as we could strip out unused methods when going to RT where memory is particularly tight, the tradeoffs seemed worth it.

View Postdrjdpowell, on 25 January 2012 - 10:51 AM, said:

What I’d like to see is for a LVLib to not automatically load its contained LVClasses until and unless something else in memory refers to that class. In other words, have LVClasses follow the same loading rule as regular VIs in libraries. That would allow me to organize classes in libraries without issue. It would be nice if LVClass libraries could load piece-by-peice, but that is less important and probably not doable.

Yes. I'd like this too. I hope they make something like this.

Ooo... that felt good... hoping something improves and not having to feel guilty that I'm not actively improving it... probably not a habit I should get into since I do expect to go back to direct LV development someday... ;-)

#17 kugr

    Very Active

  • Premium Member
  • 72 posts
  • Location:NJ
  • Version:LabVIEW 2011
  • Since:2009

Posted 22 February 2012 - 02:30 PM

I have had similar problems to mje's with altering a Private Data Cluster and having LabVIEW peg the CPU for longer than I wanted to wait (overnite once). Yesterday, I had another situation and wanted to share my work around.

Yesterday I wanted to start a new empty project and load my libraries one at a time to see what the dependencies had exploded to. I had an existing working project with all of the libraries. My project is heavily OOP with a hierarchy of up to 6 derived classes. Well, on the second library added to the project, LabVIEW2011 was trying to resolve something. I was about to hunker down for a long evening of disecting lvlib files but then I though about separating compiled code in my working project. I saved and closed the working project. Then I created a new one and added the two libraries. On the second one the dependent libraries came in fast with no problems.

I will have to look at the cross dependencies between libraries, but at least I loaded a fresh project and got to go home for the night.