DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Best Practices when handling lots of GUI elements and big data cluster

Hello folks,

 

I wonder what are best practices to handle lots of elements. What I've seen so far and am using until now is the following: Bundle all references from every UI Element in a typed def cluster which I add to the Module Data Cluster. In most cases I have a corresponding item in another cluster which is also part of the Module Data Cluster. In the sub VIs of the MHL when data is updated, I also update the controls / indicators via theire references. It is handy to have all data and references by hand whereever in the program I am. I really like it that way and I didn't need any globals or locals variables until now.

 

 

writeRN.png

 

My concerns:

  • Having two items in the Data Cluster which correspond to the same thing can lead to inconsistencies when updating one but forgetting the other.
  • I've read about the Defer Panel Updates Property but never used it so far. From performance perspective, or any other, should I not write values to property nodes and use them only for settings attributes?
  • After reading this interesting blogpost I found myself questioning, if I'm doing a good job, wiring my Modules Data Cluster down in simple VIs where only a little fraction of the data is needed. Again, from performance perspective it may not be a good idea. But until now I trust in that the compiler is much more efficent than I am, so that is not my main point. But for debugging and understanding a programm I have no clue where my values within the big cluster could have been changed.
  • The frontpanels of my subvi look awfull, because they are way too full

 

1 cluster in - and there a others inputs and outputs on that FP1 cluster in - and there a others inputs and outputs on that FP

 

Until now I've not worked with OOP in Labview. But I guess that could solve my main problems: When I build a Class and put that in the module data cluster, that class is also available everywhere and my FPs would be clean. And with a "Update X" VI (get and setters) which couples writing to the data and updating the FP Element not only inconsistencies are avoiding but also I would be able to search for that VI identifying all places where they are read and written.


Sorry if the question isn't specific to DQMH. Sorry if I answered it to myself while writing. But may be one would even handle it different with different frameworks? I'm not shure. And may be there a way better ways outside. So please let me know how you handle that issues.

 

EDIT: What I saw in an NI Example was to have a "Update Display" case in the MHL where data from the shift register is updating indicators and local variables. I really like the idea of having just one place. How would you do that in a DQMH? Since we should not self enqueue from MHL it would be a private request? Or a simple VI which is dropped where needed?


Proud developer at Hampel Software Engineering where we turn '404 not found' into '200 OK'. Join us on Discord
0 Kudos
Message 1 of 14
(5,877 Views)

Alex, this link might be of interest to you: https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019LXrSAM&l=de-DE

 

We try to avoid sticking the whole Module Data cluster into subVIs, for exactly the reasons you already listed. Strangely, that makes it far easier for me personally to refrain from passing data through VIs and rebundling it to the Module Data cluster when it's not necessary. 

 

Using references definitely moves you from by-value to by-reference country, with all the pros and cons of that. I took it too far myself once (because I tried to be cleverer than I actually was). Another time, I had to maintain software from somebody else who made heavy use of references passed around throughout the application to do stuff, and it was a huge PITA for me to debug and find my way around...

 

Performance-wise, LabVIEW needs to change to the UI thread each time you update a control value by reference. That's slower than other techniques. And if the UI thread is busy...

Property Nodes cause the front panel of a subVI to remain in memory, which can cause unnecessary memory usage.

 

You say that creating classes that handle the VI references and using accessor VIs would make it easier to find all the places that a control is updated. From the UI update perspective, it would be much easier to not use references for value updates and just search for the local variables (if any). Of course, as you say, it would couple the actual value change to the UI update.

 

Regarding the "Update Display" idea, you could read the "Make MHL actions atomic" section of Sam's article on Do's and Don'ts and decide for yourself if that could be an issue in your case, or how best to implement it.

 

All in all, I'm curious as to what other people will answer here.




DSH Pragmatic Software Development Workshops (Fab, Steve, Brian and me)
Release Automation Tools for LabVIEW (CI/CD integration with LabVIEW)
HSE Discord Server (Discuss our free and commercial tools and services)
DQMH® (The Future of Team-Based LabVIEW Development)


Message 2 of 14
(5,855 Views)

Good question.

 

References are fine in this case.

 

Classes could help with clutter. 

 

Defer front panel updates is your friend.

 

To avoid self enqueing create a subvi.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 3 of 14
(5,843 Views)

Hi Alex,

 

Feeding the entire cluster to a subVI is a no no no no! It makes it harder to debug, it makes it harder to create unit tests, it makes your code harder to read and maintain, it might save you a couple of seconds now but it will turn into a lot of pain later.

 

I talk about the clustesaurus Rex in this presentation that I gave at the CLA Summit in Austin in 2016 (starting at minute 15:27):

 

 

Regarding the MHL case for Update Display, DQMH 1.0 had that case, and we finally got rid of it on DQMH 4.0. In the DQMH 4.0 Release Notes we added the following:

 

"Modified the template VIs to not have the Update Display status and instead call the Status updated broadcast. –> This is to follow one of our own Best Practices of calling atomic operations directly instead of enqueuing several operations because we cannot guarantee that nothing else is enqueued in between."

 

Also, we were noticing that the status updates on the tester sometimes were not in the right order because the code would have to wait until it would get to the Update Display case. Having a single MHL case to update all your indicators is a necessity when you have too much information on the front panel and you start to have performance issues, at that point, you can have a single state where you update the front panel and you add the defer updates there. My experience is that there is a lot of things you can do before needing that, starting from making your code more modular and only displaying what the end user really cares about that moment. 

 

I know that you might have heard at some point in your training to avoid local variables, but avoid doesn't mean to never use them! Like the link, Joerg sent you pointed out, local variables are more efficient. The guidelines I give LabVIEW programmers are:

 

  1. First, try to get a wire to update your data
  2. If that doesn't work (and you couldn't use a shift register either), then use a local variable
  3. If that doesn't work, then look into using a property node

I hope this helps.

 

Regards,

Fab

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
Message 4 of 14
(5,824 Views)

One more thing.

 

Check if your indicators really have to be in a cluster if you are only modifying certain elements at a time. Are you clustering for aesthetic purposes (you can use other things instead) or are you clustering because all elements in the cluster really belong together.

 

If it is the second option and you must keep them as part of the cluster, then like Sam said, references are fine.

 

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 5 of 14
(5,816 Views)

One more... this might be the last one 😉

 

Also, check if you could benefit from using subpanels, you could load the DQMH Main.vi in the top-level VI and that might reduce the number of GUI updates you have to do.

 

http://zone.ni.com/reference/en-XX/help/371361R-01/lvhowto/loading_panel_in_subpanel/

 

 

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 6 of 14
(5,815 Views)

"starting from making your code more modular and only displaying what the end user really cares about that moment."

 

Also perhaps you are trying to do too much in one module?

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
Message 7 of 14
(5,814 Views)

Hi Alex, hi Fab,

 

to put panels into a sub panel of a main panel i use MGI Panel Manager with DQMH Panels 

 

vipm://mgi_lib_mgi_panel_manager_dqmh_panels?repo_url=http://ftp.ni.com/evaluation/labview/lvtn/vipm

 

With this MGI Panels i can separate my module doing the stuff from the UI and i can put separate chunks of specific UI-Tasks into separate modules easily.

 

regards

Thomas

Message 8 of 14
(5,789 Views)

Regarding the question wether to use locals or other techniques, I would like to complement:

Its the question of if there is the need to transport data between loops, where the loops are placed and how much data has to be transmitted:

1. Transport data between states within one loop via wires (and shiftregs or feedbacknodes) only!

2. Transport data via locals between two or more loops, that are placed on one single blockdiagram - if you need a quick solution

3. Transport small amount of data between loops in different blockdiagrams e.g. via 1-element-queue by making use of "lossy enqueue" and "preview queue" - if it´s just actual data to be processed

4. Big amount of data: Use data value reference to exchange large amount of data between Modules/loops

5. Use references and propertynodes only in the case that there is a FP-element in a userinterface, that you want to process in a subVI via reference  ...

 

0 Kudos
Message 9 of 14
(5,774 Views)

I am going to add a couple of caveats

 


@Andreas_Pfichner wrote:

Regarding the question wether to use locals or other techniques, I would like to complement:

Its the question of if there is the need to transport data between loops, where the loops are placed and how much data has to be transmitted:

1. Transport data between states within one loop via wires (and shiftregs or feedbacknodes) only!


There are exceptions for things like the status indicator, where I want the end user rather see immediately the status change on the front panel as soon as it changes. I know I could put it outside of the case structure and hook it to the wire coming into the shift register, but that means I have to put a message in each MHL case an that would still require a couple of local variables to show different points within the case. So I would replace the "only" with "Most of the time".

 


@Andreas_Pfichner wrote:

5. Use references and propertynodes only in the case that there is a FP-element in a userinterface, that you want to process in a subVI via reference  ...


The specific case of the Value property node only uses it if the terminal is already having other properties modified. For example, you might be setting the x,y scales on a graph via property nodes, it is ok to expand the property node to also update the value there.

 

And stay away as much as possible from the Value(signaling) property node. Try to find other ways that are more traceable first, like user events. There might still be cases for its use, but they should be extremely rare. I have used them as "macros" to automate the clicking of different buttons the end user would normally do, but it was after thinking very hard about the consequences of my actions 😉

 

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 10 of 14
(5,770 Views)