From 1ba85518fceadc0884971385b69d7d57ff633aca Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 13 Feb 2015 11:36:41 -0800 Subject: [PATCH 1/2] fix for playSound called from same thread --- .../src/AudioScriptingInterface.cpp | 39 +++++++++---------- .../src/AudioScriptingInterface.h | 3 -- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/libraries/script-engine/src/AudioScriptingInterface.cpp b/libraries/script-engine/src/AudioScriptingInterface.cpp index 32b9eb23e2..387852fe00 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.cpp +++ b/libraries/script-engine/src/AudioScriptingInterface.cpp @@ -31,44 +31,41 @@ AudioScriptingInterface::AudioScriptingInterface() : } ScriptAudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions& injectorOptions) { - AudioInjector* injector = NULL; - QMetaObject::invokeMethod(this, "invokedPlaySound", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(AudioInjector*, injector), - Q_ARG(Sound*, sound), Q_ARG(const AudioInjectorOptions&, injectorOptions)); - if (injector) { - return new ScriptAudioInjector(injector); - } else { - return NULL; + if (QThread::currentThread() != thread()) { + ScriptAudioInjector* injector = NULL; + + QMetaObject::invokeMethod(this, "playSound", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(ScriptAudioInjector*, injector), + Q_ARG(Sound*, sound), Q_ARG(const AudioInjectorOptions&, injectorOptions)); + return injector; } -} - -AudioInjector* AudioScriptingInterface::invokedPlaySound(Sound* sound, const AudioInjectorOptions& injectorOptions) { + if (sound) { // stereo option isn't set from script, this comes from sound metadata or filename AudioInjectorOptions optionsCopy = injectorOptions; optionsCopy.stereo = sound->isStereo(); - + QThread* injectorThread = new QThread(); injectorThread->setObjectName("Audio Injector Thread"); - + AudioInjector* injector = new AudioInjector(sound, optionsCopy); injector->setLocalAudioInterface(_localAudioInterface); - + injector->moveToThread(injectorThread); - + // start injecting when the injector thread starts connect(injectorThread, &QThread::started, injector, &AudioInjector::injectAudio); - + // connect the right slots and signals for AudioInjector and thread cleanup connect(injector, &AudioInjector::destroyed, injectorThread, &QThread::quit); connect(injectorThread, &QThread::finished, injectorThread, &QThread::deleteLater); - + injectorThread->start(); - - return injector; - + + return new ScriptAudioInjector(injector); + } else { qDebug() << "AudioScriptingInterface::playSound called with null Sound object."; return NULL; } -} +} \ No newline at end of file diff --git a/libraries/script-engine/src/AudioScriptingInterface.h b/libraries/script-engine/src/AudioScriptingInterface.h index ed52d951ad..b74c520670 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.h +++ b/libraries/script-engine/src/AudioScriptingInterface.h @@ -32,9 +32,6 @@ protected: signals: void mutedByMixer(); void environmentMuted(); - -private slots: - AudioInjector* invokedPlaySound(Sound* sound, const AudioInjectorOptions& injectorOptions); private: AudioScriptingInterface(); From 28430d928a7cfa1f44bc8f935292aa11ec38124c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 13 Feb 2015 11:52:51 -0800 Subject: [PATCH 2/2] use direct connection to ensure injector is stopped --- libraries/script-engine/src/ScriptAudioInjector.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptAudioInjector.cpp b/libraries/script-engine/src/ScriptAudioInjector.cpp index beb056468f..7bdf78be63 100644 --- a/libraries/script-engine/src/ScriptAudioInjector.cpp +++ b/libraries/script-engine/src/ScriptAudioInjector.cpp @@ -13,7 +13,9 @@ QScriptValue injectorToScriptValue(QScriptEngine* engine, ScriptAudioInjector* const& in) { // when the script goes down we want to cleanup the injector - QObject::connect(engine, &QScriptEngine::destroyed, in, &ScriptAudioInjector::stopInjectorImmediately); + + QObject::connect(engine, &QScriptEngine::destroyed, in, &ScriptAudioInjector::stopInjectorImmediately, + Qt::DirectConnection); return engine->newQObject(in, QScriptEngine::ScriptOwnership); } @@ -36,5 +38,6 @@ ScriptAudioInjector::~ScriptAudioInjector() { } void ScriptAudioInjector::stopInjectorImmediately() { + qDebug() << "ScriptAudioInjector::stopInjectorImmediately called to stop audio injector immediately."; _injector->stopAndDeleteLater(); }