setDirty() vs invalidate()

What’s the difference and when should you use one versus the other?

It was my understanding setDirty() should be used to refresh a control from another thread, and that invalidate() should only be called from GUI thread.

The reason I ask is because I’m seeing different results on Windows vs macOS. It seems that setDirty() doesn’t always cause the control to be redrawn properly in macOS, but it does on Windows. This is using VSTGUI 4.9.

setDirty() is the old way to invalidate a view. It has the problem that it cannot work with overlapped views. In todays world you should not try to invalidate a view from another thread, even if you can safely (without crash) do it with setDirty(), there’s no guarantee that it will work. Are you using setDirty() from another thread, then this is most likely your issue.

Ya, that’s exactly what I’m doing. I’m calling setDirty() from another thread and many of those views/controls are overlapped.

I’m aware that it’s not OK to invalid from another thread. It would be really nice, however, if there was a proper way to invalid a view from another thread. For now I’ve rolled my own method: I set a flag in the view and just before the call to doIdleStuff(), I invalid the view if that flag is set. Seems like this could be easily baked into the existing setDirty() method so that it all happens behind the scenes.

But that’s exactly what setDirty does behind the scenes. You will always have race conditions where your other thread calls setDirty and the main thread is currently iterating over the views to check if they are dirty.
There’s only one solution that works reliable and that is to use a thread safe queue which is not available in VSTGUI.

/** set the view to dirty so that it is redrawn in the next idle. Thread Safe ! */
virtual void setDirty (bool val = true);

I’ve never had a crash calling setDirty() from another thread. Calling invalid () from another thread on the other hand, is a recipe for disaster. Just a heads up then I guess. SetDirty() on Windows reliably causes a view to be updated when called from another thread, but not on macOS / iOS. The only way to reliably get the view to be redrawn is to set a flag and use that flag to call invalid() on the main thread before doIdleStuff();

@Arne_Scheffler you say “setDirty() is the old way to invalidate a view”. I did not know that. How about marking the api deprecated so that when we compile we get a warning?

Arne,

I noticed that simply using my flag to call setDity() from the main thread also causes the view to update properly.

I wonder if the problem is related to the fact that kDirty flag is part of a 32bit variable. Maybe if it was a simply bool, we might have atomic access to it.

…tried this and the issue persists…At any rate I do have a workaround and that’ll have to do I guess.

I don’t know why you see differences on Windows/macOS and/or using your implementation or the setDirty() in the library. My advise is: don’t call into VSTGUI from any other thread than the main thread. If you need to update your UI from another thread than build yourself a thread safe queue where you push your updates into and use a timer on the main thread to pull the changes and then call into VSTGUI. This is how VST3 works and with this change you can even compensate for UI-Latency if required as (again) done by VST3.

@pongasoft : If you use the VST3Editor class then calling setDirty already maps to invalidate(). See vstgui/cview.h at develop · steinbergmedia/vstgui · GitHub

It is on CView not VST3Editor but yes this is what I use. So I guess I am good. Thanks.