Deprecation and JUCE; and also font width

I guess my rough view is

  • Upgrading from 8.0.1 to 8.0.2 should be 15 minutes
  • Upgrading from 8.0.7 to 8.1.0 should be 2 hours
  • Upgrading from 7.0.12 to 8.1.0 should be a day or two

The problem is the first gets blown up when string width gets deprecated with no way out and no backout between versions.

I agree with your synopsis, but would love it if the version strategy could make my sort of ‘internal clock’ more like ‘the lived experience’!

1 Like

And to add to macro based deprecations here’s an idea

add macros like JUCE_DEPRECATE_IN_080100 and a flag JUCE_DEPRECATE_LIKE_080100 and JUCE_MAXIMAL_DEPRECATION

#if JUCE_VERSION >= 0x080100 || JUCE_DEPRECATE_LIKE_080100 || JUCE_MAXIMAL_DEPRECATION
#define JUCE_DEPRECATE_IN_080100(x) x
#else
#define JUCE_DEPRECATE_IN_080100(x)
#endif

then for string width you would do

    JUCE_DEPRECATE_IN_080100([[deprecated use glyph thing]])
    float getStringWidth()

and merge that in 8.0.x

then

  1. Those of us who want to always be ahead of game can do CI runs with JUCE_MAXIMAL_DEPRECATION on
  2. We can get an idea of where upgrades will hit us early and
  3. You can still add depreciation ‘as you go’ just phase it in bit by bit across versions
  4. We can stage in fixes slowly since you can get the ‘new’ thing in the code base for a while before the ‘old’ thing goes.

that sort of seems like it would have made this a much easier change.

Just a suggestion of course! But thought it was worth expanding on that idea

1 Like

Just one more thing on this for when you expand the comment on the function

int x = font.getStringWidth("foo");

if you replace this with

int x = juce::GlyphArrangement::getStringWidth(f, "foo");

you get an implicit cast from float to int which truncates.

And then you get

Screenshot 2024-09-28 at 11.44.18 AM

so the correct fix is to go to getStringWidthInt

Right… see how the JUCE devs updated the Slider code…

        void getContentSize (int& w, int& h) override
        {
            w = GlyphArrangement::getStringWidthInt (font, text) + 18;
            h = (int) (font.getHeight() * 1.6f);
        }

Rail

I think many people have missed this detail, but Font{FontOptions{}} is NOT a direct replacement for Font{}. For backwards compatibility you would need to use Font{FontOptions{}.withMetricsKind (TypefaceMetricsKind::legacy)}. If you use an empty FontOptions object you are implicitly specifying TypefaceMetricsKind::portable.

If we had just changed this default, the font size may have changed on some platforms and not others, which could be a subtle bug for a lot of our users. If we kept the old behaviour but didn’t deprecate the constructors the chances are users would continue constructing fonts in what we believe is the wrong way and could cause considerable pain for them further down the line. We did also have this change up on a public JUCE 8 branch for quite some time (~2 months I think), unfortunately I don’t think any issues were raised until it made it to master.

I dunno it’s not that bad and you get some good new features! Emojis in patch names has been missing in surge since we abandoned vstgui and folks are happy they are back.

For me to upgrade surge shortcircuit and a few of our other tools from 7-802 took me maybe a day or so. The tricky things were

  1. Sharing 7/8 hence the macros
  2. Moving our docker build image from u18 to u20
  3. Finding new stuff deprecated at the 801/802 boundary (hence this thread)
  4. Understanding the intent of the changes so I could code properly. For instance a font is now much more clumsy than a font option for a value at rest.

But I do agree with your (implicit) feedback that deprecating features can be more expensive on the user base than it is on the library team. I hope some of the suggestions for staging deprecation we offered here could make future workflows a bit more predictable and granular - especially since the compilers make deprecation “all or nothing” right now.

2 Likes