VBlankAttachment - check for isShowing()?

Not sure if this would be considered a bug or a feature, right now I’m having to add an isShowing() check in my VBlankAttachments due to doing a large amount of processing work in them, and there’s a high probability they won’t be visible, so it’s nice to be able to skip that work.

I’m curious why VBlankAttachment doesn’t already check for isShowing() for it’s constructor component? Are there use cases where it would ever be useful to do the work when it’s not showing?

Would it be possible to just not call onVBlank() when isShowing() is false to be a bit cleaner? I can abstract it away, but I really can’t currently see a reason why this functionality isn’t already in there?

1 Like

This is interesting and something I think about every time I work with VBlank stuff.

In another thread, I mention setting the callback to nullptr on component visibility change. This is bit cumbersome for an app with dozens of components (most working with animation), but this still makes the most sense to me, if only to avoid dozens of isShowing calls running at 60fps…

1 Like

If that’s the case, since vBlankAttachment is itself a componentlistener, it could just stop calling onVblank whenever componentVisibilityChanged is called in those cases.

This is, however, for items within separate tabs or not currently visible (but still showing) within a very large scrollable area (12000x12000), which means many of the items will still be running when they don’t really need to be.

For now I’ve just wrapped this up with a simple wrapper, it’s not pretty and I’m not happy having to run that many checks each vsync, maybe this is a bit of a unique case, but I guess for those that want it, I’m using:

    class VSyncItem
	{
	public:
		VSyncItem(juce::Component* component) : vblank(component, [&, component]
			{
				if (component && onVSync)
				{
					if (component->isShowing())
						onVSync();
				}
			})
		{
		}

		std::function<void()> onVSync = nullptr;
	private:
		VBlankAttachment vblank;
		JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VSyncItem)
	};
1 Like

Huh! I like the idea of it calling add/removeVBlankListener on componentVisibilityChanged. Maybe @attila has thoughts…

Maybe another alternative is to roll our own attachment class that inherits from ComponentPeer::VBlankListener

2 Likes

The problem with componentVisibilityChanged is, that it only reacts to the setVisible flag. It doesn’t react to the visibility of the parent or being on the desktop or minimised at all.
The isShowing checks the parent too, but is therefore a more expensive method

1 Like

It would be great to get a ComponentListener callback and/or a virtual method on Component specifically for when the isShowing() condition has changed.

We use isShowing() quite a lot, especially for accessibility, but in order to use it safely you need to override visibilityChanged() and parentHierarchyChanged() every time.
E.g. grabKeyboardFocus() asserts on isShowing(), so if you want a component to grab keyboard focus as soon as it becomes visible on the screen, you need to override both methods.

7 Likes