01-26-2018 01:41 PM
Hi All,
I have a fairly interesting problem that I am looking for ideas or direction from others who may have been here before. I recently inherited several med/large sized applications (3000-4000 vis each) that I will be maintaining and upgrading with new features. The applications all currently work, however there are several major problems with them that will continue to get worse if they are not addressed. First, there is a lot of shared code between the applications, but the shared code isn't actually shared code on disk - Project 1 uses class A, and Project 2 also uses class A, however they both have their own, totally separate copy of class A. So, if I find a bug or need to add a feature to class A, I need to make that change in both the Project 1 and Project 2 copies.
This is obviously a problem, so I have started moving this shared code to a shared directory, however, this leads to the next big problem - the application components are all very highly coupled. Parent classes are tied to children, classes are tied to random, non packaged Vis, classes that have nothing to do with each other are dependent on each other and so on. This of course makes moving files around quite a pain. I do plan on fixing the coupling, however I would like to not have to make the same code changes twice - hence why I planned on moving the code to a shared directory first, then decoupling.
A couple of hours into this en-devour and I am thinking that I am unfortunately I am going to have to decouple first, then try and move to a shared code base. So far, LabVIEW has crashed probably 15 times, including lots of weird fatal errors (issues related to OMUDClassLinker.cpp) I had never seen before. I have considered writing some code to help with this task, but I am not sure how much it would help.. Has anyone ever done something similar? Any advice or direction I should take?
01-26-2018 01:59 PM
Along these lines, does anyone know how to disable the 'Load Warning Summary' popup?
01-26-2018 02:19 PM
I feel your pain. While this may not be an answer you want to hear but have you considered basically a ground up redesign of the applications. Start with the class definitions, UI, communication methods and so on. As you flush out the higher level details you can start to pull actual code from the existing code base in while refactoring and improving at the same time. This may be extra work up front but I think it would pay off in the long run.
01-26-2018 02:47 PM
I have, and in the past that would have been my initial thought - however I learned the lesson described in the link below the hard way on another recent project where I rewrote an application that could have been refactored. It inevitably took much longer than expected, many of the 'Why on earth did they do that?' questions were answered as I rewrote myself, etc.
One big problem is that while the current applications have some major design flaws, they do work, and are deployed to customers around the world. Rewriting from the ground up (even if I used pieces of the old code) would require a ton of extra validation, and would likely take close to a year to do in parallel with the feature adds/bug fixes to the old application. Plus, I think refactoring code is a good skill set to have, so I think it will be a great exercise in my growth as a developer.
https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/
01-26-2018 02:59 PM
Understood. Though I would suggest that your validation effort will/should be the same as if you did a complete re-write. You are making significant changes to the code and therefore the system should be fully re-tested. You can break the testing up according to the classes but in the end you will probably need a full revalidation of the complete system.
01-26-2018 03:24 PM - edited 01-26-2018 03:26 PM
Agreed, although with this approach I can do releases incrementally - refactor one component then test and so on, which does somewhat reduce the risks associated with making changes to the code. As you can imagine, all tests are currently done manually - any type of unit tests are practically impossible due to the code inter-dependencies.
01-26-2018 06:32 PM
Have you done much with VI scripting?
I'm sure there's not one magic script that you can write to fix everything, but it can give pointers on where to start. For instance:
You can use "<vi.lib>\SourceControl\support\SCCSup Compare Two VIs.vi" to compare VIs in project 1 with VIs in project 2 to give you a rapid summary of the differences (or not) between them.
You can load VIs by reference and use a "Get VI dependencies" invoke node on every VI in the project, and then interpret that information in various ways to eliminate circular dependencies and the like.
It sounds like some of the classes are the biggest headache. I'd start there to see if you can get one class at a time to behave properly (i.e. no dependencies on child classes and can be used with both projects without recoding).
02-08-2018 01:04 PM
Ive done decent amount with VI scripting, however I found that because of the size and amount of circular dependencies in the code, trying to do anything through scripting is incredibly slow and/or just crashes LabVIEW.
Related question - does anyone know how to disable the 'Add to Project and Update Dependencies' and 'LabVIEW:Failed to load..' Popups?