Program growing in size--split one file into multiple files?

Good day everybody (!)

My App is a one window program. I have a Main.cpp file and a MainComponent.h file, the usual stuff according to the basic Juce Tutorials.

MainComponent is getting bigger and bigger though. From 500 to 2,000 code lines. I figured out how to create ‘different scenes’ based on a single window by way of displaying on-and-off different Components, using paint() along with if, else if… conditionals - and so on. This enables me to keep expanding the code at MainComponent with no trouble. I realized that the system can continue to grow -adding more features- almost endlessly… and using a single window only!

During the last days I reached the 6,000 lines of code mark. My question to you: Is it wise, is it a good idea to continue growing the program this way? At what point is it advisable to think about some form of restructuring, perhaps splitting the file into 2 or more -more manageable- separate files?

Last but not least, how do you split a large MainComponent into two or more files? Is it even possible? I have the feeling that splitting the file into several files is very difficult–since the different sections, like the constructor, paint(), resized(), object declarations, your own routines, etc. are highly interdependent.

Thank you (!)

Yes, once a program starts getting big, it is much better to split it into multiple files. It helps keeps things organized, and also means that you don’t have to recompile the whole thing each time. The standard way of doing this is to put class prototypes in .h files and then function definitions in cpp files. There is a good tutorial on it here. It can cause a lot of headaches to begin with, because you have to deal with circular dependencies on your #includes. But once you get used to it, things will start to run more smoothly than before.

Sourcefiles with this size are usually a strong sign of bad code design.

I have built some more complex applications and plugins and along this, the most complex class template I’ve written in the last couple of months has approx 1000 lines of codes. And this is a rare exception, most of my source files don’t exceed a few hundred lines of code. On the other hand, one of the more complex plugins we released recently contains of about 250 individual source files.

A few thoughts on how to get started with a clean code structure

  • C++ gives you a great concept of classes and inheritance and you should definetively use that as much as possible to split up your code into simpler pieces. Otherwise, whatever you are planing to do will likely never reach a professional level as it gets more and more difficult to maintain.
  • An important rule in programing is “dont repeat yourself”, so every time you find yourself copying a block of code to some repeat it at other location, this is a hint that there is a better and cleaner solution, e.g. put it in a (member) function or create a base class that defines common behaviour used in various subclasses.
  • If you are creating a user interface as I’m assuming from your question you can make great use of the concept of Components owning other Components to create a good hierachy. Each Component then gets its own source file. Instead of enabling/disabling parts of the paint call with big if/else constructs, let a dedicated component handle that part of the painting and switch its visibility on and off.
  • Make sure that you don’t mix e.g. audio processing with GUI code in one source file.
  • Use layout techniques like flexbox and grid (there is a tutorial on that here)

You can also have a look at e.g. how a JUCE application like the Projucer is structured, its source code is completely open

Does this help you a bit?

1 Like

For multiple “scenes”, you should really use a separate Component for each. Then you can simply set them to visible or not (from your Editor, or from a parent Component, depending on how deep your structure is). Each Component should handle only those objects that it controls. For example, your structure might be something like this:

Editor
  MainView
    main view controls
  AlternateView
    alternate view controls
  PrefrencesView
    controls for setting user preferences
  ErrorView
    text views for displaying errors/problems encountered

Here, the Editor would simply set one of those 4 views as visible and the others as invisible whenever you switched between views. (An invisible Component will not paint itself OR any of its child Components.)

As you break your application up into it’s pieces, you could also take the opportunity to see what pieces would be useful in other applications you might write. In which case you can take a little time to ensure that piece is not tightly bound to something, and refactor it to be re-usable. You might also observe places where you have repeated code, and could reduce code by refactoring into something reusable, either through stand alone functions, base classes, etc…

Well, it certainly does [help a bit]. My approach to programming is basic–since I don’t have much knowledge/experience with C++ and OOP–and Juce for that matter.

What I have learned from you now is “don’t do it in one place but rather write down several/many files” each a specific well-defined doing one task/thing.

To implement this approach will be very hard for me–this requires, as you suggest, to learn more about OOP C++…

I guess I need now to concentrate my programming learn experience in C++, not Juce. I think I can say the Juce Tutorials will not help me with this matter–since the examples are all ‘small’ and based on 2 files–the PIP Main.cpp and the MainComponent.h files, am I right?

Is there any good source [book] you would recommend me to read?

Thank you for taking the time to answer (!) Greetings.

Well, what can I say? Your information is very helpful (!) Thank you. As you suggest, this ‘ride’ is going to be very tough for me. The problem is… I will have to figure out lots of things–on my own.

To be sincere I am tired to have to learn alone all the time. Juce provides you with the API but nothing else. The tutorials cover the basics, yes, but for serious programming there is “a lot more” that you need to know.

The whole learning process is quite overwhelming !! at least that is my opinion.

All the best. Greetings from Germany.

Well, yours is an interesting suggestion. To put into practice sounds like… not easy for me to do though. I guess what all you people are telling me is… I need to learn more about OOP C++.

I have the feeling that “Juce knowledge” in this regard is not the crucial thing at this point but C++. After writing down and trying out thousands of lines of C++/Juce code, Juce is more or less covered, not so C++, specially the OOP concepts.

All right, greetings from Germany (!)

Nice to hear that my answer helped at least a bit :wink:

Basically I agree with you here that in order to understand JUCE and its solution to (common) problems it’s really helpful to be able to read the language it is written in (C++) fluently, to have some knowledge on programing best practice patterns (like OOP, MVC etc…) and of course some knowledge on how software works in general (multithreading, etc…)

I learned the most basics about this during about 5 years of studies in various lectures, but I learned the most when trying to build some (JUCE) applications myself. So I think you can learn C++ and programming best practices along with JUCE after having reached a basic level of C++ skills. You’ll face a lot of challenges along the way and researching for best practice solutions to them while you are facing them lets you learn a lot. With all this, I’d recomend you to stay demanding to yourself, e.g. don’t just try to find a solution that works somehow but always try to understand what you are doing and understand why the way you are doing it is the best way possible – at least from your current standpoint or try to find out if there is a better way.

Most likely, if you follow that route, next year you will look at your code from today and you will find a lot of stuff you know better. Maybe you’ll decide to start again as your first approaches turn out to be bad in some way. But it will also be fun to become better at C++, I promise you :wink: I don’t see any real shortcut to learning a lot of stuff, but being aware of that you have to learn a lot in order to reach your goals might also be quite motivating :slight_smile:

Hello cpr2323 (!)

Thank for helping me… a second time, since you supported me before already, not so long ago. Yes, your comments are in line with other experts.

I don’t have the feeling that I am repeating myself when I weigh / analyze different sections of the 6,000+ lines program.

On the other hand, everyone is suggesting me to restructure–creating several individual code files–each specializing in one issue.

New to me is that you are also talking about the ‘developing reusable code’ concept. That is a sound suggestion!

All that I can do is… go back and learn more about C++ - specially the OOP part of it. It will be a long and difficult process, I guess…

Thank you cpr2323, and greetings from Germany

True. More power to you. Learning never stops. C++ and OOP are very challenging things. Lots of patience is required. My eyes get tired :pensive: – time for me to shut-down for a while my PluginPenguin friend.

Actually, what I am trying to do is this–if you have some time, please visit my website

Greetings from Germany

Vento looks like an amazing project!

Don’t lose faith in your abilities. C++ is difficult indeed, but every expert programmer started out as a novice, writing “bad” code. You can learn a lot from studying, but the only way to really get good at it is just to fart around and make mistakes. You’ll spend hours writing something that seems brilliant, but the next next week you’ll realize that it is all wrong and tear the whole thing down. But you don’t need to view this as a failure–in fact it’s quite satisfying to see your code get better and better.

2 Likes