I’ve found out that the workability of the OnIdle() function heavily depends on the implementation of the VST host. Sometimes OnIdle() is not called at all. Everything works with the exception of the OnIdle().
I also tried to make my own timer as follows:
mUITimer = iplug::Timer::Create([this](iplug::Timer& t) {
//my code here
}, 30);
Unfortunately this code is host-dependent too. If I load the VST plug-in in the host’s constuctor and open the plug-in’s UI later, the Timer doesn’t work. Everything works with the exception of the Timer.
Is there a recommended method to implement an OnTimer() function that doesn’t depend on the host’s quirks?
I think I understand the reason of the problem. IPlug2 uses the SetTimer() function to create its own timer (line 233 at IGraphicsWind.cpp). The SetTimer() function succeeds, Windows creates a timer, WM_TIMER messages are put into the thread’s message queue, but the WM_TIMER messages are never delivered because the host’s constructor thread never runs GetMessage/DispatchMessage. This is not a problem because I start the plug-in in the invisible mode, so I don’t need the OnIdle() function in that mode.
The problem begins when I open the plug-in’s UI in host’s UI thread. The plug-in is fully functional, but the host’s UI thread cannot dispatch WM_TIMER for a window created on constructor’s thread and my peak meter doesn’t work.
I tried to create a timer in my custom thread and use it instead of the OnIdle() function. This method solves the original problem, but creates an additional thread synchronization problem, so I abandoned it.
I eventually solved this problem on the host side, but I’m still wondering if there’s a recommended way to make the plug-in timer independent of the host implementation.