Ernest Galbrun Posted March 16, 2012 Report Share Posted March 16, 2012 (edited) Hello again dear labviewers. I come back to labVIEW after a couple of years doing painful things, and indeed labVIEW is great and fun (IMO). However I am a little bit rusty and I would really appreciate your insight on my project. So here is the thing : I have a class, let's call it class A. Associated with this class is a very fine Xcontrol (whose data is of type 'A') which permits interaction with the user. I have yet another class, that I will henceforth call class B. B has a handful of As in its private data member. For elegance sake, I would appreciate if it could own as many As as the Universe would permit, but practically it won't be more than 5. And I have another XControl for B allowing more sophisticated interraction with the user. And of course this interaction involves using A's xControl in the front panel of B's xControl. Here I have settled for a hard defined maximum number of A's xControl instances. I can't figure out what kind of architecture I should use there. My first attempts were failures, eventually leading to an irrecoverable crash of my project (I think it was due to some kind of circular reference), so I have a nice opportunity to start everything again from scratch. What should/could I put in B's private data member ? an array of As ? an array of references to As ? What should/could I use as my xControls data type ? The natural answer is the same type as the class I wish to assaciate it with, but somehow I wonder if it can work in this case ? And most importantly : How do I connect the As that are instanciated in B's xControl with the As that are owned by B in B's xControl data ? thanks, Ernest Galbrun. Edited March 16, 2012 by Ernest Galbrun Link to comment
Aristos Queue Posted March 16, 2012 Report Share Posted March 16, 2012 (edited) Never break this rule: If an XControl or its member VIs knows about a class in any way shape or form, then that class must not know anything about the XControl except for (optionally) listing the XControl as a friend. You must avoid creating a circle of load dependencies. The easy way to test this is 1) In an empty project, load the XControl. 2) In a second empty project, load the class. 3) Look at the Dependencies section for both projects. If both projects list the other file as a Dependency, then you have a cycle. Do not use the XControl on the panels of the class member VIs. Do not use property nodes of the XControls on the diagrams of the class member VIs. The only thing that your class *might* want to do is add its XControl as a friend and then put some utility VIs in the community scope. Violations of this rule inevitably lead to a crash of LabVIEW. I'm not proud of that fact. Fixing this crash would require us to design XControls completely differently from the ground up, and it just isn't likely to be fixed. Having said that, the crash does enforce the really good design principle of your data type knowing nothing of its display. So there is, I guess, a silver lining to the crash. Now, assuming you follow that rule, > What should/could I put in B's private data member ? an array of As ? an array of references to As ? An array of As seems most appropriate. References? Who taught you about those? Ick! :-) > What should/could I use as my xControls data type ? The natural answer is the same type as the class I wish to assaciate it with, but somehow I wonder if it can work in this case ? The class. Assuming you follow the rules above, it works great. Build the class completely independent of the display, make it work, then build a display that let's users manipulate it. Edited March 16, 2012 by Aristos Queue Link to comment
Ernest Galbrun Posted March 16, 2012 Author Report Share Posted March 16, 2012 (edited) Never break this rule: If an XControl or its member VIs knows about a class in any way shape or form, then that class must not know anything about the XControl except for (optionally) listing the XControl as a friend. You must avoid creating a circle of load dependencies. The easy way to test this is 1) In an empty project, load the XControl. 2) In a second empty project, load the class. 3) Look at the Dependencies section for both projects. If both projects list the other file as a Dependency, then you have a cycle. Do not use the XControl on the panels of the class member VIs. Do not use property nodes of the XControls on the diagrams of the class member VIs. The only thing that your class *might* want to do is add its XControl as a friend and then put some utility VIs in the community scope. Violations of this rule inevitably lead to a crash of LabVIEW. I'm not proud of that fact. Fixing this crash would require us to design XControls completely differently from the ground up, and it just isn't likely to be fixed. Having said that, the crash does enforce the really good design principle of your data type knowing nothing of its display. So there is, I guess, a silver lining to the crash. Now, assuming you follow that rule, > What should/could I put in B's private data member ? an array of As ? an array of references to As ? An array of As seems most appropriate. References? Who taught you about those? Ick! :-) > What should/could I use as my xControls data type ? The natural answer is the same type as the class I wish to assaciate it with, but somehow I wonder if it can work in this case ? The class. Assuming you follow the rules above, it works great. Build the class completely independent of the display, make it work, then build a display that let's users manipulate it. Thanks for the answer! (ans yes, I may have put some kind of references to the xControl's facade control inside my class vis This silver line thing is still a little bit harh though Since I haven't been able to recover anything from my xControl...) I will stick with the classes as data for my xControls, it feels good indeed. However, I still think I must have references to A in B's data member, because I will have instances of A in its xControl (since I want to have A's xControl in B's xControl) ? Edited March 16, 2012 by Ernest Galbrun Link to comment
Ernest Galbrun Posted March 17, 2012 Author Report Share Posted March 17, 2012 Nevermind, got it. In my head. I think. There will be copies though, but who cares ? I don't. Link to comment
Fab Posted July 14, 2012 Report Share Posted July 14, 2012 Is there a simple example out there showing how to have a XControl display for a class that follows all the rules outlined earlier? Thanks, Fab Link to comment
klessm1 Posted May 10, 2013 Report Share Posted May 10, 2013 Posting here because NI forums is down...plus I found this thread which may have something to do with my problem. So what if there is a class that both the XControl calls and the Main class calls? For example, my Xcontrol calls a database class (which calls .net ADO), but that class is also in the dependencies of my main GUI class (which the XControl is also dependency of). I've been dealing with crashes, bad property and method nodes for the last two days am pretty much at that point where I start posting on forums. So my GUI class is in charge of getting data from and updating the display (which includes the XControls). I have the references for the controls I need to control in the class data (which sometimes causes problems when updating the X Control). Most of the time I just get a bad method or property node and can re-select and save. I also have a control (not type def) of the reference that I update with the latest reference of the XControl then I apply it to the class data. Having it as a type def causes way too many problems. I have also tried replacing the XControl strict reference with a regular control and used the "to more specific class", but that didn't work. The references were still called by the GUI class. What I am thinking of doing is removing my main GUI panels from my GUI class (floating VIs), and create a messaging system to another stand alone VI that would contain all the methods and properties I need to access for the X controls (which defeats the purpose of having these nice methods and properties). It is probably going to hurt a little (timewise), so I am looking for some wise guidance. Info: Using 2012 SP1f2 32bit on Win7, Most vi's have separate compiled cache set. Clearing cache before loading (usually have to load XControls first then main gui class). Link to comment
Aristos Queue Posted May 10, 2013 Report Share Posted May 10, 2013 klessm1: Try this... WITHOUT loading the project file... Open just the database class. Does it open without loading the XControl or the Main GUI class? If so, good. If not, bad. If that is good, then try opening just the XControl. Does it load the database class but not the GUI class? If so, good. If not, bad. If both of those are good, then the issue you are experiencing is probably a different issue and you'll need to post to the ni.com forums for an AE to try to help you. If either of those doesn't work, you'll need to restructure your code until both of those are true. And the NI forums are back up now. Link to comment
Mike Le Posted May 10, 2013 Report Share Posted May 10, 2013 I have also tried replacing the XControl strict reference with a regular control and used the "to more specific class", but that didn't work. The references were still called by the GUI class. I've run into a similar problem and this fixed it for me. The trick was that I couldn't just right-click on the preexisting XControl strict reference and convert it to a regular control ref. I had to DELETE the old strict reference and create a brand new regular control reference. Then in my accessors, I used "to more specific class." The reason I had to actually delete the old strict reference was that, for some reason, I was never able to successfully convert the preexisting XControl ref to a generic ref. It would LOOK like a generic ref when I opened the private data ctl file, but it would often BEHAVE as though it were a strict reference to the XControl. Completely deleting the old reference and replacing it with a brand new one worked for me. Not sure if you already did that, but if not, it's worth trying. Link to comment
klessm1 Posted May 11, 2013 Report Share Posted May 11, 2013 Slight restructure worked. I had some weird linkage because of some static vi references. Database class was clean. So my main GUI class is passed to all main screen guis as data from screens is sometimes shared (they are plugin screens for a sub panel). I could of done it diff but that is what I ended up with. Anyway, the GUI screen vis were part of the main GUI class because they use the main GUI class. For each screen I have another class containing the control refs for that GUI. In the init function for the screen class I had a static ref for that screens gui (which was part of the main GUI class). Throw in the fact that the screen guis have the xcontrol on them and the screen classes have the ref, properties,and methods you end up with a bad situation. Like a two day crash fest. So I removed the guis from the main class (don't know if it was required..), and got rid of the static refs from the screen init methods (this was probably the root cause). So now that the main and screen classes don't call each other everything seems to be OK. I left the refs as the xcontrol type (not containing data type) and I don't think I'll change it back as everything is working. Thanks for the inputs. Def will remember the delete ref trick. 1 Link to comment
Mike Le Posted May 11, 2013 Report Share Posted May 11, 2013 Glad to hear your problem's solved, klessm1. The "delete trick" was pretty irritating; I filed a CAR with NI back in November 2012. Hopefully it gets resolved in a future release and other developers can be saved the grief. Link to comment
Aristos Queue Posted May 13, 2013 Report Share Posted May 13, 2013 Sorry to hear about the problems... glad you were able to find a workaround. Link to comment
klessm1 Posted May 13, 2013 Report Share Posted May 13, 2013 I think that maybe a tool to analyze dependency links would be helpful. Not just for this type of issue either. In a couple of our projects I end up saying "why is that class being pulled in"? Many times you end up with a "uses a" relationship with another class (static vi reference, passing a class into another class's method). If you could visually and programatically inspect your class relationship it would be great. I am wondering what Symbio tools would do with the weird setup I had going (we don't use them). A tool like that would be pretty nice for code reviews. Just a simple representation of classes, lvlibs, and xcontrols in your project and some red flags for circular references. If I had some spare time... Link to comment
Fab Posted May 13, 2013 Report Share Posted May 13, 2013 I think that maybe a tool to analyze dependency links would be helpful. Not just for this type of issue either. In a couple of our projects I end up saying "why is that class being pulled in"? Many times you end up with a "uses a" relationship with another class (static vi reference, passing a class into another class's method). If you could visually and programatically inspect your class relationship it would be great. I am wondering what Symbio tools would do with the weird setup I had going (we don't use them). A tool like that would be pretty nice for code reviews. Just a simple representation of classes, lvlibs, and xcontrols in your project and some red flags for circular references. If I had some spare time... I use the Symbio tool to reverse engineer some projects and discover those links. However, for large applications it does not work so well or when there are weird relationships. I don't know if it would have worked with the relationships you had. Link to comment
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now