The big list of JUCE tips and tricks (from n00b to pro)

I found this blog post I started years ago when first learning JUCE. I kept procrastinating publishing it. I figure others can help fix / add missing things, so here it is:

Most of the tips target beginners. But there’s some advanced things in there too.

Anything look sus? What else should I add?

15 Likes

Few things I would add:

  • Sometimes in order to debug, you need to log things to a file. spdlog is a nice library for that. Or the JUCE FileLogger class.
  • Pluginval is your friend. Run it regularly or better, add it to your CI pipeline
  • Regularly run pluginval and your plugin both built with ASAN to catch potential memory related crashes.
  • Statically link the Windows runtime to save trouble
  • Be careful with dependencies between your processor and your editor. Use Async messaging such as ValueTreePropertyChanged. Don’t use lambda functions owned by the Editor that might be called the Processor!
  • Use clang-format and forget about manual formatting
  • For accessibility, avoid using juce::Graphics::drawText and use Labels instead. Your visually impaired users will thank you.
7 Likes

I missed that one, thanks for that hint

1 Like

Ooooh, this one is good, thank you.

1 Like

I’ll put this one in too, only recently ran into this!

1 Like

This is a good one!

use VBlankAttachment instead of the timer to ensure your component is repainted on the very next frame.

2 Likes

For the AU not appearing another good tip is to set your version number to 0 for debug builds and your plugin will be auto scanned every time.

7 Likes

Probably need one about AUv3 and needing to build and run the .app, not the .appex

2 Likes

Yes please. I’ve never done this, what’s the short story?

:exploding_head: added!

Oh and an absolute classic.

Don’t call setBufferedToImage() on a component that has children!! Instead make a sibling component that does the drawing and call setBufferedToImage() on that component instead.

2 Likes

From memory the first time you try to build/run AUv3 the best solution is to enable the stand alone target and AUv3 target then build both and run the stand alone first. That should install the AUv3 and with any luck it should show up in Logic :crossed_fingers:

1 Like

It’s been a long time since I check this was indeed working but I got it from Apple support many years ago, I assume it still applies, when I do it I don’t notice myself needing to run the kill command much so I think it still works, but I could be kidding myself.

1 Like

Is this to avoid also caching the children? So if you want the children to still update, you need to move the “expensive parent painting” elsewhere? Or am I missing something else…

No there’s an edge case that means every time a child repaints, the parent will be forced to repaint its image even if that image hasn’t changed. If you have exactly the same thing but with a sibling rather than a parent the image won’t be invalidated, so when it’s made to repaint it can use the cached image.

Ah wow, I don’t think I knew that. I’m assuming it’s considered an “unresolvable bug” for Reasons, otherwise it would eventually be fixed?

Thanks Anthony!!

I assume you mean a child, as in a sibling of the children?

Sibling to the component that has setBufferedToImage (true);

// instead of:
setBufferedToImage (true);
addAndMakeVisible (foreground);

// do this:
background.setBufferedToImage (true);
addAndMakeVisible (background);
addAndMakeVisible (foreground);
4 Likes

I tried it recently and it didn’t work for me (could be something on my end). However, bumping the version does still work.

1 Like

Regarding including the build type as a compile definition, the correct way to do this for multi-config generators is:

target_compile_definitions(YourPlugin PRIVATE "BUILD_CONFIG=$<CONFIG>")
1 Like