Bitwig workarounds for VST
This commit is contained in:
parent
a002b994f4
commit
d763ebde83
7 changed files with 241 additions and 142 deletions
|
|
@ -4,6 +4,8 @@ set (VSTPLUGIN_BUNDLE_NAME "${PROJECT_NAME}.vst3")
|
||||||
set (VST3SDK_BASEDIR "${CMAKE_CURRENT_SOURCE_DIR}/external/VST_SDK/VST3_SDK")
|
set (VST3SDK_BASEDIR "${CMAKE_CURRENT_SOURCE_DIR}/external/VST_SDK/VST3_SDK")
|
||||||
set (VST3SDK_ARCHIVE "vst-sdk_3.6.14_build-24_2019-11-29.zip")
|
set (VST3SDK_ARCHIVE "vst-sdk_3.6.14_build-24_2019-11-29.zip")
|
||||||
|
|
||||||
|
file (MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external")
|
||||||
|
|
||||||
if (NOT EXISTS "${VST3SDK_BASEDIR}")
|
if (NOT EXISTS "${VST3SDK_BASEDIR}")
|
||||||
message (STATUS "VST3 SDK is not found, downloading")
|
message (STATUS "VST3 SDK is not found, downloading")
|
||||||
|
|
||||||
|
|
@ -41,7 +43,8 @@ add_library(${VSTPLUGIN_PRJ_NAME} MODULE
|
||||||
SfizzVstEditor.cpp
|
SfizzVstEditor.cpp
|
||||||
SfizzVstState.cpp
|
SfizzVstState.cpp
|
||||||
GUIComponents.cpp
|
GUIComponents.cpp
|
||||||
VstPluginFactory.cpp)
|
VstPluginFactory.cpp
|
||||||
|
X11RunLoop.cpp)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(${VSTPLUGIN_PRJ_NAME} PRIVATE vst3.def)
|
target_sources(${VSTPLUGIN_PRJ_NAME} PRIVATE vst3.def)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#include "SfizzVstState.h"
|
#include "SfizzVstState.h"
|
||||||
#include "GUIComponents.h"
|
#include "GUIComponents.h"
|
||||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||||
#include "x11runloop.h"
|
#include "X11RunLoop.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace VSTGUI;
|
using namespace VSTGUI;
|
||||||
|
|
@ -39,7 +39,9 @@ bool PLUGIN_API SfizzVstEditor::open(void* parent, const VSTGUI::PlatformType& p
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||||
X11::FrameConfig x11config;
|
X11::FrameConfig x11config;
|
||||||
x11config.runLoop = VSTGUI::owned(new RunLoop(plugFrame));
|
if (!_runLoop)
|
||||||
|
_runLoop = new RunLoop(plugFrame);
|
||||||
|
x11config.runLoop = _runLoop;
|
||||||
config = &x11config;
|
config = &x11config;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -58,8 +60,13 @@ void PLUGIN_API SfizzVstEditor::close()
|
||||||
{
|
{
|
||||||
CFrame *frame = this->frame;
|
CFrame *frame = this->frame;
|
||||||
if (frame) {
|
if (frame) {
|
||||||
frame->forget();
|
frame->removeAll();
|
||||||
this->frame = nullptr;
|
if (frame->getNbReference() != 1)
|
||||||
|
frame->forget ();
|
||||||
|
else {
|
||||||
|
frame->close();
|
||||||
|
this->frame = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,6 +143,30 @@ void SfizzVstEditor::controlEndEdit(CControl* ctl)
|
||||||
enterOrLeaveEdit(ctl, false);
|
enterOrLeaveEdit(ctl, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMessageResult SfizzVstEditor::notify(CBaseObject* sender, const char* message)
|
||||||
|
{
|
||||||
|
CMessageResult result = VSTGUIEditor::notify(sender, message);
|
||||||
|
|
||||||
|
if (result != kMessageNotified)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||||
|
if (message == CVSTGUITimer::kMsgTimer) {
|
||||||
|
SharedPointer<VSTGUI::RunLoop> runLoop = RunLoop::get();
|
||||||
|
if (runLoop) {
|
||||||
|
// note(jpc) I don't find a reliable way to check if the host
|
||||||
|
// notifier of X11 events is working. If there is, remove this and
|
||||||
|
// avoid polluting Linux hosts which implement the loop correctly.
|
||||||
|
runLoop->processSomeEvents();
|
||||||
|
|
||||||
|
runLoop->cleanupDeadHandlers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void SfizzVstEditor::onStateChanged()
|
void SfizzVstEditor::onStateChanged()
|
||||||
{
|
{
|
||||||
updateStateDisplay();
|
updateStateDisplay();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "SfizzVstController.h"
|
#include "SfizzVstController.h"
|
||||||
#include "public.sdk/source/vst/vstguieditor.h"
|
#include "public.sdk/source/vst/vstguieditor.h"
|
||||||
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||||
|
namespace VSTGUI { class RunLoop; }
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace Steinberg;
|
using namespace Steinberg;
|
||||||
using namespace VSTGUI;
|
using namespace VSTGUI;
|
||||||
|
|
@ -30,6 +33,9 @@ public:
|
||||||
void controlBeginEdit(CControl* ctl) override;
|
void controlBeginEdit(CControl* ctl) override;
|
||||||
void controlEndEdit(CControl* ctl) override;
|
void controlEndEdit(CControl* ctl) override;
|
||||||
|
|
||||||
|
// VSTGUIEditor
|
||||||
|
CMessageResult notify(CBaseObject* sender, const char* message) override;
|
||||||
|
|
||||||
// SfizzVstController::StateListener
|
// SfizzVstController::StateListener
|
||||||
void onStateChanged() override;
|
void onStateChanged() override;
|
||||||
|
|
||||||
|
|
@ -75,4 +81,8 @@ private:
|
||||||
CSliderBase *_numVoicesSlider = nullptr;
|
CSliderBase *_numVoicesSlider = nullptr;
|
||||||
CSliderBase *_oversamplingSlider = nullptr;
|
CSliderBase *_oversamplingSlider = nullptr;
|
||||||
CSliderBase *_preloadSizeSlider = nullptr;
|
CSliderBase *_preloadSizeSlider = nullptr;
|
||||||
|
|
||||||
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||||
|
SharedPointer<RunLoop> _runLoop;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
||||||
145
vst/X11RunLoop.cpp
Normal file
145
vst/X11RunLoop.cpp
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||||
|
#include "X11RunLoop.h"
|
||||||
|
#include "vstgui/lib/platform/linux/x11platform.h"
|
||||||
|
#include "base/source/fobject.h"
|
||||||
|
|
||||||
|
namespace VSTGUI {
|
||||||
|
|
||||||
|
RunLoop::RunLoop(Steinberg::FUnknown* runLoop)
|
||||||
|
: runLoop(runLoop)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RunLoop::~RunLoop() {}
|
||||||
|
|
||||||
|
SharedPointer<RunLoop> RunLoop::get()
|
||||||
|
{
|
||||||
|
return X11::RunLoop::get().cast<VSTGUI::RunLoop>();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RunLoop::EventHandler final : Steinberg::Linux::IEventHandler, public Steinberg::FObject {
|
||||||
|
X11::IEventHandler* handler { nullptr };
|
||||||
|
bool alive { false };
|
||||||
|
|
||||||
|
void PLUGIN_API onFDIsSet(Steinberg::Linux::FileDescriptor) override
|
||||||
|
{
|
||||||
|
if (alive && handler)
|
||||||
|
handler->onEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
DELEGATE_REFCOUNT(Steinberg::FObject)
|
||||||
|
DEFINE_INTERFACES
|
||||||
|
DEF_INTERFACE(Steinberg::Linux::IEventHandler)
|
||||||
|
END_DEFINE_INTERFACES(Steinberg::FObject)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RunLoop::TimerHandler final : Steinberg::Linux::ITimerHandler, public Steinberg::FObject {
|
||||||
|
X11::ITimerHandler* handler { nullptr };
|
||||||
|
bool alive { false };
|
||||||
|
|
||||||
|
void PLUGIN_API onTimer() override
|
||||||
|
{
|
||||||
|
if (alive && handler)
|
||||||
|
handler->onTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
DELEGATE_REFCOUNT(Steinberg::FObject)
|
||||||
|
DEFINE_INTERFACES
|
||||||
|
DEF_INTERFACE(Steinberg::Linux::ITimerHandler)
|
||||||
|
END_DEFINE_INTERFACES(Steinberg::FObject)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void RunLoop::processSomeEvents()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < eventHandlers.size(); ++i) {
|
||||||
|
const auto& eh = eventHandlers[i];
|
||||||
|
if (eh->alive && eh->handler) {
|
||||||
|
eh->handler->onEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunLoop::cleanupDeadHandlers()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < eventHandlers.size(); ++i) {
|
||||||
|
const auto& eh = eventHandlers[i];
|
||||||
|
if (!eh->alive) {
|
||||||
|
runLoop->unregisterEventHandler(eh);
|
||||||
|
eventHandlers.erase(eventHandlers.begin() + i--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < timerHandlers.size(); ++i) {
|
||||||
|
const auto& th = timerHandlers[i];
|
||||||
|
if (!th->alive) {
|
||||||
|
runLoop->unregisterTimer(th);
|
||||||
|
timerHandlers.erase(timerHandlers.begin() + i--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RunLoop::registerEventHandler(int fd, X11::IEventHandler* handler)
|
||||||
|
{
|
||||||
|
if (!runLoop)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto smtgHandler = Steinberg::owned(new EventHandler());
|
||||||
|
smtgHandler->handler = handler;
|
||||||
|
smtgHandler->alive = true;
|
||||||
|
if (runLoop->registerEventHandler(smtgHandler, fd) == Steinberg::kResultTrue) {
|
||||||
|
eventHandlers.push_back(smtgHandler);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RunLoop::unregisterEventHandler(X11::IEventHandler* handler)
|
||||||
|
{
|
||||||
|
if (!runLoop)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < eventHandlers.size(); ++i) {
|
||||||
|
const auto& eh = eventHandlers[i];
|
||||||
|
if (eh->alive && eh->handler == handler) {
|
||||||
|
eh->alive = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RunLoop::registerTimer(uint64_t interval, X11::ITimerHandler* handler)
|
||||||
|
{
|
||||||
|
if (!runLoop)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto smtgHandler = Steinberg::owned(new TimerHandler());
|
||||||
|
smtgHandler->handler = handler;
|
||||||
|
smtgHandler->alive = true;
|
||||||
|
if (runLoop->registerTimer(smtgHandler, interval) == Steinberg::kResultTrue) {
|
||||||
|
timerHandlers.push_back(smtgHandler);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RunLoop::unregisterTimer(X11::ITimerHandler* handler)
|
||||||
|
{
|
||||||
|
if (!runLoop)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < timerHandlers.size(); ++i) {
|
||||||
|
const auto& th = timerHandlers[i];
|
||||||
|
if (th->alive && th->handler == handler) {
|
||||||
|
th->alive = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace VSTGUI
|
||||||
|
|
||||||
|
#endif
|
||||||
47
vst/X11RunLoop.h
Normal file
47
vst/X11RunLoop.h
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
/*
|
||||||
|
This is a modified version the X11 run loop from vst3editor.cpp.
|
||||||
|
|
||||||
|
This version is edited to add more safeguards to protect against host bugs.
|
||||||
|
It also permits to call event processing externally in case the host has a
|
||||||
|
defective X11 event loop notifier.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||||
|
#include "vstgui/lib/platform/linux/x11frame.h"
|
||||||
|
#include "pluginterfaces/gui/iplugview.h"
|
||||||
|
|
||||||
|
namespace VSTGUI {
|
||||||
|
|
||||||
|
class RunLoop final : public X11::IRunLoop, public AtomicReferenceCounted {
|
||||||
|
public:
|
||||||
|
explicit RunLoop(Steinberg::FUnknown* runLoop);
|
||||||
|
~RunLoop();
|
||||||
|
|
||||||
|
static SharedPointer<RunLoop> get();
|
||||||
|
|
||||||
|
void processSomeEvents();
|
||||||
|
void cleanupDeadHandlers();
|
||||||
|
|
||||||
|
// X11::IRunLoop
|
||||||
|
bool registerEventHandler(int fd, X11::IEventHandler* handler);
|
||||||
|
bool unregisterEventHandler(X11::IEventHandler* handler);
|
||||||
|
bool registerTimer(uint64_t interval, X11::ITimerHandler* handler);
|
||||||
|
bool unregisterTimer(X11::ITimerHandler* handler);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct EventHandler;
|
||||||
|
struct TimerHandler;
|
||||||
|
|
||||||
|
private:
|
||||||
|
using EventHandlers = std::vector<Steinberg::IPtr<EventHandler>>;
|
||||||
|
using TimerHandlers = std::vector<Steinberg::IPtr<TimerHandler>>;
|
||||||
|
EventHandlers eventHandlers;
|
||||||
|
TimerHandlers timerHandlers;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Linux::IRunLoop> runLoop;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace VSTGUI
|
||||||
|
|
||||||
|
#endif
|
||||||
27
vst/external/steinberg/LICENSE
vendored
27
vst/external/steinberg/LICENSE
vendored
|
|
@ -1,27 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// VSTGUI LICENSE
|
|
||||||
// (c) 2018, Steinberg Media Technologies, All Rights Reserved
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
// are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from this
|
|
||||||
// software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
||||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
||||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
110
vst/external/steinberg/src/x11runloop.h
vendored
110
vst/external/steinberg/src/x11runloop.h
vendored
|
|
@ -1,110 +0,0 @@
|
||||||
#include "vstgui/lib/platform/linux/x11frame.h"
|
|
||||||
#include "pluginterfaces/gui/iplugview.h"
|
|
||||||
#include "base/source/fstring.h"
|
|
||||||
|
|
||||||
namespace VSTGUI {
|
|
||||||
|
|
||||||
// Map Steinberg Vst Interface to VSTGUI Interface
|
|
||||||
class RunLoop : public X11::IRunLoop, public AtomicReferenceCounted
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct EventHandler : Steinberg::Linux::IEventHandler, public Steinberg::FObject
|
|
||||||
{
|
|
||||||
X11::IEventHandler* handler {nullptr};
|
|
||||||
|
|
||||||
void PLUGIN_API onFDIsSet (Steinberg::Linux::FileDescriptor) override
|
|
||||||
{
|
|
||||||
if (handler)
|
|
||||||
handler->onEvent ();
|
|
||||||
}
|
|
||||||
DELEGATE_REFCOUNT (Steinberg::FObject)
|
|
||||||
DEFINE_INTERFACES
|
|
||||||
DEF_INTERFACE (Steinberg::Linux::IEventHandler)
|
|
||||||
END_DEFINE_INTERFACES (Steinberg::FObject)
|
|
||||||
};
|
|
||||||
struct TimerHandler : Steinberg::Linux::ITimerHandler, public Steinberg::FObject
|
|
||||||
{
|
|
||||||
X11::ITimerHandler* handler {nullptr};
|
|
||||||
|
|
||||||
void PLUGIN_API onTimer () final
|
|
||||||
{
|
|
||||||
if (handler)
|
|
||||||
handler->onTimer ();
|
|
||||||
}
|
|
||||||
DELEGATE_REFCOUNT (Steinberg::FObject)
|
|
||||||
DEFINE_INTERFACES
|
|
||||||
DEF_INTERFACE (Steinberg::Linux::ITimerHandler)
|
|
||||||
END_DEFINE_INTERFACES (Steinberg::FObject)
|
|
||||||
};
|
|
||||||
|
|
||||||
bool registerEventHandler (int fd, X11::IEventHandler* handler) final
|
|
||||||
{
|
|
||||||
if(!runLoop)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto smtgHandler = Steinberg::owned (new EventHandler ());
|
|
||||||
smtgHandler->handler = handler;
|
|
||||||
if (runLoop->registerEventHandler (smtgHandler, fd) == Steinberg::kResultTrue)
|
|
||||||
{
|
|
||||||
eventHandlers.push_back (smtgHandler);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool unregisterEventHandler (X11::IEventHandler* handler) final
|
|
||||||
{
|
|
||||||
if(!runLoop)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (auto it = eventHandlers.begin (), end = eventHandlers.end (); it != end; ++it)
|
|
||||||
{
|
|
||||||
if ((*it)->handler == handler)
|
|
||||||
{
|
|
||||||
runLoop->unregisterEventHandler ((*it));
|
|
||||||
eventHandlers.erase (it);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool registerTimer (uint64_t interval, X11::ITimerHandler* handler) final
|
|
||||||
{
|
|
||||||
if(!runLoop)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto smtgHandler = Steinberg::owned (new TimerHandler ());
|
|
||||||
smtgHandler->handler = handler;
|
|
||||||
if (runLoop->registerTimer (smtgHandler, interval) == Steinberg::kResultTrue)
|
|
||||||
{
|
|
||||||
timerHandlers.push_back (smtgHandler);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool unregisterTimer (X11::ITimerHandler* handler) final
|
|
||||||
{
|
|
||||||
if(!runLoop)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (auto it = timerHandlers.begin (), end = timerHandlers.end (); it != end; ++it)
|
|
||||||
{
|
|
||||||
if ((*it)->handler == handler)
|
|
||||||
{
|
|
||||||
runLoop->unregisterTimer ((*it));
|
|
||||||
timerHandlers.erase (it);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RunLoop (Steinberg::FUnknown* runLoop) : runLoop (runLoop) {}
|
|
||||||
private:
|
|
||||||
using EventHandlers = std::vector<Steinberg::IPtr<EventHandler>>;
|
|
||||||
using TimerHandlers = std::vector<Steinberg::IPtr<TimerHandler>>;
|
|
||||||
EventHandlers eventHandlers;
|
|
||||||
TimerHandlers timerHandlers;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Linux::IRunLoop> runLoop;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
Loading…
Add table
Reference in a new issue