In a previous thread, the creation of timers on linux was discussed and solved with a patch to the linux RunLoop implementation.
I made a request to the REAPER devs and they apparently implemented (or improved?) the new runloop in v7.17: VST3: support IPluginFactory3::setHostContext with IRunLoop support on Linux
.
Originally, I faced two issues with the RunLoop on Linux Reaper:
-
The DataExchange iMessage fallback did not work (transmit) on linux with reaper.
This has apparently been resolved with v7.17. -
Timer::stop()
issued by the vstgui4 animator when closing the editor window leads to
vst3sdk/vstgui4/vstgui/lib/platform/linux/x11timer.cpp:38: Assertion 'runLoop' failed. Timer only works of run loop was set
This issue has not been resolved and I’m now not so sure any more the reaper devs can do anything about it on their side, since I can observe the timer working through the Animator and DataExchange, which must mean the RunLoop is working as expected?
It’s confusing to me since Timer::start()
and Timer::stop()
use identical code for retrieving the RunLoop, yet it only fails in Timer::stop()
:
auto runLoop = RunLoop::get ();
vstgui_assert (runLoop, "Timer only works of run loop was set");
Also, since VST3PluginTestHost is win/mac only, what’s the recommended testing procedure on linux?
To facilitate easier testing, here is my animator-based TimerTester view (does not draw anything):
TimerTest.h
#ifndef TimerTest_H
#define TimerTest_H
#include "vstgui/vstgui.h"
namespace VSTGUI {
class TimerTest : public CView, public Animation::IAnimationTarget
{
public:
TimerTest(const CRect& size);
bool attached(CView* parent) override;
bool removed(CView* parent) override;
void setViewSize(const CRect& rect, bool invalid) override;
void parentSizeChanged() override;
//void setVisible(bool state) override;
//void invalidRect(const CRect& rect) override;
protected:
virtual void animationStart(CView* view, IdStringPtr name) override;
virtual void animationTick(CView* view, IdStringPtr name, float pos) override;
virtual void animationFinished(CView* view, IdStringPtr name, bool wasCanceled) override;
float zRotation;
};
}
#endif //TimerTest_H
TimerTest.cpp
#include "TimerTest.h"
namespace VSTGUI {
TimerTest::TimerTest(const CRect& size) : CView(size) {
zRotation = 0.f;
}
bool TimerTest::attached(CView* parent)
{
if (!CView::attached(parent))
{
return false;
}
addAnimation("zR", this, new Animation::RepeatTimingFunction(new Animation::LinearTimingFunction(8000), -1, false));
return true;
}
bool TimerTest::removed(CView* parent)
{
return true;
}
void TimerTest::setViewSize(const CRect& rect, bool invalid)
{
CView::setViewSize(rect, invalid);
}
void TimerTest::parentSizeChanged()
{
CView::parentSizeChanged();
}
void TimerTest::animationStart(CView* view, IdStringPtr name) {}
void TimerTest::animationTick(CView* view, IdStringPtr name, float pos)
{
if (strcmp(name, "zR") == 0)
zRotation = pos * 360.f;
}
void TimerTest::animationFinished(CView* view, IdStringPtr name, bool wasCanceled) {}
}
Adding removeAllAnimations();
to removed()
does not change anything.
TimerTestFactory.cpp
#include "vstgui/vstgui.h"
#include "vstgui/vstgui_uidescription.h"
#include "vstgui/uidescription/detail/uiviewcreatorattributes.h"
#include "TimerTest.h"
#define TimerTest_default_w 200
#define TimerTest_default_h 200
namespace VSTGUI {
class TimerTestFactory : public ViewCreatorAdapter
{
public:
TimerTestFactory()
{
// register in view factory
UIViewFactory::registerViewCreator(*this);
}
IdStringPtr getViewName() const override
{
// provide display name
return "TimerTest";
}
IdStringPtr getBaseViewName() const override
{
// provide parent class
return UIViewCreator::kCView;
}
CView* create(const UIAttributes& attributes, const IUIDescription* description) const override
{
// set default size
CRect size(CPoint(45, 45), CPoint(TimerTest_default_w, TimerTest_default_h));
// return new instance
return new TimerTest(size);
}
};
// create a static factory instance so that it registers itself with the view factory
TimerTestFactory __gRegisterTimerTestFactory;
} // namespace VSTGUI
Removing the assertion in Timer::stop ()
makes it fail on a different assertion:
/vst3sdk/vstgui4/vstgui/lib/cview.cpp:250: Assertion 'isAttached () == false' failed. View is still attached
even with removeAllAnimations();
in removed()
.
Please help me solve this issue.
Tested with SDK 3.7.12 (to build the plugin) and reaper versions up to 7.19 dev0802.
If I can test/provide anything else, let me know!