Don't use blocking connections on the main thread

This commit is contained in:
Brad Davis 2017-06-29 17:00:27 -07:00
parent b22daa9a6f
commit b52dd7b822
45 changed files with 377 additions and 178 deletions

View file

@ -16,6 +16,7 @@
#include <QThread>
#include <QTimer>
#include <shared/QtHelpers.h>
#include <AccountManager.h>
#include <AddressManager.h>
#include <Assignment.h>
@ -141,7 +142,7 @@ void AssignmentClient::stopAssignmentClient() {
QThread* currentAssignmentThread = _currentAssignment->thread();
// ask the current assignment to stop
QMetaObject::invokeMethod(_currentAssignment, "stop", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(_currentAssignment, "stop");
// ask the current assignment to delete itself on its thread
_currentAssignment->deleteLater();

View file

@ -13,6 +13,7 @@
#include <QThread>
#include <glm/gtx/transform.hpp>
#include <shared/QtHelpers.h>
#include <GLMHelpers.h>
#include <AnimUtil.h>
#include "ScriptableAvatar.h"
@ -49,7 +50,7 @@ void ScriptableAvatar::stopAnimation() {
AnimationDetails ScriptableAvatar::getAnimationDetails() {
if (QThread::currentThread() != thread()) {
AnimationDetails result;
QMetaObject::invokeMethod(this, "getAnimationDetails", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "getAnimationDetails",
Q_RETURN_ARG(AnimationDetails, result));
return result;
}

View file

@ -48,6 +48,7 @@
#include <gl/QOpenGLContextWrapper.h>
#include <shared/QtHelpers.h>
#include <shared/GlobalAppProperties.h>
#include <StatTracker.h>
#include <Trace.h>
@ -1208,15 +1209,26 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// Make sure we don't time out during slow operations at startup
updateHeartbeat();
int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now
connect(&_settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
connect(&_settingsThread, SIGNAL(started()), &_settingsTimer, SLOT(start()));
connect(&_settingsThread, SIGNAL(finished()), &_settingsTimer, SLOT(stop()));
_settingsTimer.moveToThread(&_settingsThread);
_settingsTimer.setSingleShot(false);
_settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL); // 10s, Qt::CoarseTimer acceptable
_settingsThread.setPriority(QThread::LowestPriority);
_settingsThread.start();
QTimer* settingsTimer = new QTimer();
moveToNewNamedThread(settingsTimer, "Settings Thread", [this, settingsTimer]{
connect(qApp, &Application::beforeAboutToQuit, [this, settingsTimer]{
// Disconnect the signal from the save settings
QObject::disconnect(settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
// Stop the settings timer
settingsTimer->stop();
// Delete it (this will trigger the thread destruction
settingsTimer->deleteLater();
// Mark the settings thread as finished, so we know we can safely save in the main application
// shutdown code
_settingsGuard.trigger();
});
int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now
settingsTimer->setSingleShot(false);
settingsTimer->setInterval(SAVE_SETTINGS_INTERVAL); // 10s, Qt::CoarseTimer acceptable
QObject::connect(settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
}, QThread::LowestPriority);
if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) {
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); // So that camera doesn't auto-switch to third person.
@ -1644,7 +1656,7 @@ QString Application::getUserAgent() {
if (QThread::currentThread() != thread()) {
QString userAgent;
QMetaObject::invokeMethod(this, "getUserAgent", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, userAgent));
hifi::qt::blockingInvokeMethod(this, "getUserAgent", Q_RETURN_ARG(QString, userAgent));
return userAgent;
}
@ -1802,11 +1814,13 @@ void Application::cleanupBeforeQuit() {
locationUpdateTimer.stop();
identityPacketTimer.stop();
pingTimer.stop();
QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection);
// save state
_settingsThread.quit();
saveSettings();
// Wait for the settings thread to shut down, and save the settings one last time when it's safe
if (_settingsGuard.wait()) {
// save state
saveSettings();
}
_window->saveGeometry();
// Destroy third party processes after scripts have finished using them.
@ -1830,8 +1844,7 @@ void Application::cleanupBeforeQuit() {
// FIXME: something else is holding a reference to AudioClient,
// so it must be explicitly synchronously stopped here
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(),
"cleanupBeforeQuit", Qt::BlockingQueuedConnection);
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "cleanupBeforeQuit", Qt::BlockingQueuedConnection);
// destroy Audio so it and its threads have a chance to go down safely
// this must happen after QML, as there are unexplained audio crashes originating in qtwebengine

View file

@ -25,6 +25,7 @@
#include <QtWidgets/QApplication>
#include <QtWidgets/QUndoStack>
#include <ThreadHelpers.h>
#include <AbstractScriptingServicesInterface.h>
#include <AbstractViewStateInterface.h>
#include <EntityEditPacketSender.h>
@ -596,8 +597,7 @@ private:
bool _notifiedPacketVersionMismatchThisDomain;
QThread _settingsThread;
QTimer _settingsTimer;
ConditionalGuard _settingsGuard;
GLCanvas* _glWidget{ nullptr };

View file

@ -25,6 +25,7 @@
#endif
#include <shared/QtHelpers.h>
#include <AvatarData.h>
#include <PerfStat.h>
#include <RegisteredMetaTypes.h>
@ -482,7 +483,7 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersection(const PickRay&
const QScriptValue& avatarIdsToDiscard) {
RayToAvatarIntersectionResult result;
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(const_cast<AvatarManager*>(this), "findRayIntersection", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarManager*>(this), "findRayIntersection",
Q_RETURN_ARG(RayToAvatarIntersectionResult, result),
Q_ARG(const PickRay&, ray),
Q_ARG(const QScriptValue&, avatarIdsToInclude),

View file

@ -21,6 +21,7 @@
#include <QtCore/QTimer>
#include <shared/QtHelpers.h>
#include <scripting/HMDScriptingInterface.h>
#include <AccountManager.h>
#include <AddressManager.h>
@ -897,7 +898,7 @@ void MyAvatar::restoreAnimation() {
QStringList MyAvatar::getAnimationRoles() {
if (QThread::currentThread() != thread()) {
QStringList result;
QMetaObject::invokeMethod(this, "getAnimationRoles", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QStringList, result));
hifi::qt::blockingInvokeMethod(this, "getAnimationRoles", Q_RETURN_ARG(QStringList, result));
return result;
}
return _skeletonModel->getRig().getAnimationRoles();
@ -1368,7 +1369,7 @@ void MyAvatar::resetFullAvatarURL() {
void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "useFullAvatarURL", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "useFullAvatarURL",
Q_ARG(const QUrl&, fullAvatarURL),
Q_ARG(const QString&, modelName));
return;
@ -1394,7 +1395,7 @@ void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelN
void MyAvatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "setAttachmentData", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "setAttachmentData",
Q_ARG(const QVector<AttachmentData>, attachmentData));
return;
}
@ -2358,7 +2359,7 @@ bool MyAvatar::safeLanding(const glm::vec3& position) {
if (QThread::currentThread() != thread()) {
bool result;
QMetaObject::invokeMethod(this, "safeLanding", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result), Q_ARG(const glm::vec3&, position));
hifi::qt::blockingInvokeMethod(this, "safeLanding", Q_RETURN_ARG(bool, result), Q_ARG(const glm::vec3&, position));
return result;
}
glm::vec3 better;

View file

@ -11,6 +11,8 @@
#include "Audio.h"
#include <shared/QtHelpers.h>
#include "Application.h"
#include "AudioClient.h"
#include "ui/AvatarInputs.h"
@ -49,27 +51,22 @@ float Audio::loudnessToLevel(float loudness) {
Audio::Audio() : _devices(_contextIsHMD) {
auto client = DependencyManager::get<AudioClient>().data();
connect(client, &AudioClient::muteToggled, this, &Audio::onMutedChanged);
connect(client, &AudioClient::noiseReductionChanged, this, &Audio::onNoiseReductionChanged);
connect(client, &AudioClient::inputLoudnessChanged, this, &Audio::onInputLoudnessChanged);
connect(client, &AudioClient::inputVolumeChanged, this, &Audio::onInputVolumeChanged);
connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged);
connect(&_devices._inputs, &AudioDeviceList::deviceChanged, this, &Audio::onInputChanged);
enableNoiseReduction(enableNoiseReductionSetting.get());
}
void Audio::setMuted(bool isMuted) {
if (_isMuted != isMuted) {
auto client = DependencyManager::get<AudioClient>().data();
QMetaObject::invokeMethod(client, "toggleMute", Qt::BlockingQueuedConnection);
_isMuted = isMuted;
emit mutedChanged(_isMuted);
QMetaObject::invokeMethod(client, "toggleMute");
}
}
void Audio::onMutedChanged() {
auto client = DependencyManager::get<AudioClient>().data();
bool isMuted;
QMetaObject::invokeMethod(client, "isMuted", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, isMuted));
bool isMuted = DependencyManager::get<AudioClient>()->isMuted();
if (_isMuted != isMuted) {
_isMuted = isMuted;
emit mutedChanged(_isMuted);
@ -79,11 +76,16 @@ void Audio::onMutedChanged() {
void Audio::enableNoiseReduction(bool enable) {
if (_enableNoiseReduction != enable) {
auto client = DependencyManager::get<AudioClient>().data();
QMetaObject::invokeMethod(client, "setNoiseReduction", Qt::BlockingQueuedConnection, Q_ARG(bool, enable));
QMetaObject::invokeMethod(client, "setNoiseReduction", Q_ARG(bool, enable));
enableNoiseReductionSetting.set(enable);
_enableNoiseReduction = enable;
emit noiseReductionChanged(enable);
}
}
void Audio::onNoiseReductionChanged() {
bool noiseReductionEnabled = DependencyManager::get<AudioClient>()->isNoiseReductionEnabled();
if (_enableNoiseReduction != noiseReductionEnabled) {
_enableNoiseReduction = noiseReductionEnabled;
emit noiseReductionChanged(_enableNoiseReduction);
}
}
@ -93,19 +95,11 @@ void Audio::setInputVolume(float volume) {
if (_inputVolume != volume) {
auto client = DependencyManager::get<AudioClient>().data();
QMetaObject::invokeMethod(client, "setInputVolume", Qt::BlockingQueuedConnection, Q_ARG(float, volume));
_inputVolume = volume;
emit inputVolumeChanged(_inputVolume);
QMetaObject::invokeMethod(client, "setInputVolume", Q_ARG(float, volume));
}
}
// different audio input devices may have different volumes
void Audio::onInputChanged() {
auto client = DependencyManager::get<AudioClient>().data();
float volume;
QMetaObject::invokeMethod(client, "getInputVolume", Qt::BlockingQueuedConnection, Q_RETURN_ARG(float, volume));
void Audio::onInputVolumeChanged(float volume) {
if (_inputVolume != volume) {
_inputVolume = volume;
emit inputVolumeChanged(_inputVolume);

View file

@ -62,9 +62,12 @@ signals:
void contextChanged(const QString& context);
public slots:
void onMutedChanged();
void onContextChanged();
void onInputChanged();
private slots:
void onMutedChanged();
void onNoiseReductionChanged();
void onInputVolumeChanged(float volume);
void onInputLoudnessChanged(float loudness);
protected:

View file

@ -11,6 +11,8 @@
#include <map>
#include <shared/QtHelpers.h>
#include "AudioDevices.h"
#include "Application.h"
@ -71,22 +73,14 @@ bool AudioDeviceList::setData(const QModelIndex& index, const QVariant& value, i
bool AudioDeviceList::setDevice(int row, bool fromUser) {
bool success = false;
auto& device = _devices[row];
_userSelection = fromUser;
// skip if already selected
if (!device.selected) {
auto client = DependencyManager::get<AudioClient>();
QMetaObject::invokeMethod(client.data(), "switchAudioDevice", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, success),
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
Q_ARG(QAudio::Mode, _mode),
Q_ARG(const QAudioDeviceInfo&, device.info));
if (success) {
device.selected = true;
if (fromUser) {
emit deviceSelected(device.info, _selectedDevice);
}
emit deviceChanged(device.info);
}
}
emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0));
@ -135,12 +129,12 @@ void AudioDeviceList::resetDevice(bool contextIsHMD, const QString& device) {
}
void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device) {
auto oldDevice = _selectedDevice;
_selectedDevice = device;
QModelIndex index;
for (auto i = 0; i < _devices.size(); ++i) {
AudioDevice& device = _devices[i];
if (device.selected && device.info != _selectedDevice) {
device.selected = false;
} else if (device.info == _selectedDevice) {
@ -149,6 +143,11 @@ void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device) {
}
}
if (_userSelection) {
_userSelection = false;
emit deviceSelected(_selectedDevice, oldDevice);
}
emit deviceChanged(_selectedDevice);
emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0));
}

View file

@ -58,7 +58,7 @@ private:
static QHash<int, QByteArray> _roles;
static Qt::ItemFlags _flags;
bool _userSelection { false };
QAudio::Mode _mode;
QAudioDeviceInfo _selectedDevice;
QList<AudioDevice> _devices;

View file

@ -8,9 +8,12 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "Application.h"
#include "ClipboardScriptingInterface.h"
#include <shared/QtHelpers.h>
#include "Application.h"
ClipboardScriptingInterface::ClipboardScriptingInterface() {
}
@ -24,7 +27,7 @@ float ClipboardScriptingInterface::getClipboardContentsLargestDimension() {
bool ClipboardScriptingInterface::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs) {
bool retVal;
QMetaObject::invokeMethod(qApp, "exportEntities", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(qApp, "exportEntities",
Q_RETURN_ARG(bool, retVal),
Q_ARG(const QString&, filename),
Q_ARG(const QVector<EntityItemID>&, entityIDs));
@ -33,7 +36,7 @@ bool ClipboardScriptingInterface::exportEntities(const QString& filename, const
bool ClipboardScriptingInterface::exportEntities(const QString& filename, float x, float y, float z, float s) {
bool retVal;
QMetaObject::invokeMethod(qApp, "exportEntities", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(qApp, "exportEntities",
Q_RETURN_ARG(bool, retVal),
Q_ARG(const QString&, filename),
Q_ARG(float, x),
@ -45,7 +48,7 @@ bool ClipboardScriptingInterface::exportEntities(const QString& filename, float
bool ClipboardScriptingInterface::importEntities(const QString& filename) {
bool retVal;
QMetaObject::invokeMethod(qApp, "importEntities", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(qApp, "importEntities",
Q_RETURN_ARG(bool, retVal),
Q_ARG(const QString&, filename));
return retVal;
@ -53,7 +56,7 @@ bool ClipboardScriptingInterface::importEntities(const QString& filename) {
QVector<EntityItemID> ClipboardScriptingInterface::pasteEntities(glm::vec3 position) {
QVector<EntityItemID> retVal;
QMetaObject::invokeMethod(qApp, "pasteEntities", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(qApp, "pasteEntities",
Q_RETURN_ARG(QVector<EntityItemID>, retVal),
Q_ARG(float, position.x),
Q_ARG(float, position.y),

View file

@ -13,6 +13,10 @@
#include <QObject>
#include <glm/glm.hpp>
#include <EntityItemID.h>
/**jsdoc
* @namespace Clipboard
*/

View file

@ -14,6 +14,7 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include <shared/QtHelpers.h>
#include <MenuItemProperties.h>
#include "Menu.h"
@ -43,7 +44,7 @@ bool MenuScriptingInterface::menuExists(const QString& menu) {
return Menu::getInstance()->menuExists(menu);
}
bool result;
QMetaObject::invokeMethod(Menu::getInstance(), "menuExists", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(Menu::getInstance(), "menuExists",
Q_RETURN_ARG(bool, result),
Q_ARG(const QString&, menu));
return result;
@ -86,7 +87,7 @@ bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString&
return Menu::getInstance()->menuItemExists(menu, menuitem);
}
bool result;
QMetaObject::invokeMethod(Menu::getInstance(), "menuItemExists", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(Menu::getInstance(), "menuItemExists",
Q_RETURN_ARG(bool, result),
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem));
@ -114,7 +115,7 @@ bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
return Menu::getInstance()->isOptionChecked(menuOption);
}
bool result;
QMetaObject::invokeMethod(Menu::getInstance(), "isOptionChecked", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(Menu::getInstance(), "isOptionChecked",
Q_RETURN_ARG(bool, result),
Q_ARG(const QString&, menuOption));
return result;
@ -131,7 +132,7 @@ bool MenuScriptingInterface::isMenuEnabled(const QString& menuOption) {
return Menu::getInstance()->isOptionChecked(menuOption);
}
bool result;
QMetaObject::invokeMethod(Menu::getInstance(), "isMenuEnabled", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(Menu::getInstance(), "isMenuEnabled",
Q_RETURN_ARG(bool, result),
Q_ARG(const QString&, menuOption));
return result;
@ -157,7 +158,7 @@ bool MenuScriptingInterface::isInfoViewVisible(const QString& path) {
}
bool result;
QMetaObject::invokeMethod(Menu::getInstance(), "isInfoViewVisible", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(Menu::getInstance(), "isInfoViewVisible",
Q_RETURN_ARG(bool, result), Q_ARG(const QString&, path));
return result;
}

View file

@ -9,11 +9,14 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "WindowScriptingInterface.h"
#include <QClipboard>
#include <QtCore/QDir>
#include <QMessageBox>
#include <QScriptValue>
#include <shared/QtHelpers.h>
#include <SettingHandle.h>
#include <display-plugins/CompositorHelper.h>
@ -24,8 +27,6 @@
#include "Menu.h"
#include "OffscreenUi.h"
#include "WindowScriptingInterface.h"
static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
static const QString LAST_BROWSE_LOCATION_SETTING = "LastBrowseLocation";
static const QString LAST_BROWSE_ASSETS_LOCATION_SETTING = "LastBrowseAssetsLocation";
@ -316,7 +317,7 @@ bool WindowScriptingInterface::isPhysicsEnabled() {
int WindowScriptingInterface::openMessageBox(QString title, QString text, int buttons, int defaultButton) {
if (QThread::currentThread() != thread()) {
int result;
QMetaObject::invokeMethod(this, "openMessageBox", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "openMessageBox",
Q_RETURN_ARG(int, result),
Q_ARG(QString, title),
Q_ARG(QString, text),

View file

@ -18,6 +18,8 @@
#include <QtScript/QScriptValue>
#include <QtWidgets/QMessageBox>
#include <DependencyManager.h>
class CustomPromptResult {
public:
QVariant value;

View file

@ -15,6 +15,7 @@
#include <QScrollBar>
#include <QtConcurrent/QtConcurrentRun>
#include <shared/QtHelpers.h>
#include <ScriptEngines.h>
#include <PathUtils.h>
@ -115,7 +116,7 @@ void JSConsole::executeCommand(const QString& command) {
QScriptValue JSConsole::executeCommandInWatcher(const QString& command) {
QScriptValue result;
QMetaObject::invokeMethod(_scriptEngine, "evaluate", Qt::ConnectionType::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(_scriptEngine, "evaluate",
Q_RETURN_ARG(QScriptValue, result),
Q_ARG(const QString&, command),
Q_ARG(const QString&, _consoleFileName));

View file

@ -9,15 +9,18 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "AnimationCache.h"
#include <QRunnable>
#include <QThreadPool>
#include "AnimationCache.h"
#include "AnimationLogging.h"
#include <shared/QtHelpers.h>
#include <Trace.h>
#include <StatTracker.h>
#include <Profile.h>
#include "AnimationLogging.h"
int animationPointerMetaTypeId = qRegisterMetaType<AnimationPointer>();
AnimationCache::AnimationCache(QObject* parent) :
@ -31,7 +34,7 @@ AnimationCache::AnimationCache(QObject* parent) :
AnimationPointer AnimationCache::getAnimation(const QUrl& url) {
if (QThread::currentThread() != thread()) {
AnimationPointer result;
QMetaObject::invokeMethod(this, "getAnimation", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "getAnimation",
Q_RETURN_ARG(AnimationPointer, result), Q_ARG(const QUrl&, url));
return result;
}
@ -97,7 +100,7 @@ bool Animation::isLoaded() const {
QStringList Animation::getJointNames() const {
if (QThread::currentThread() != thread()) {
QStringList result;
QMetaObject::invokeMethod(const_cast<Animation*>(this), "getJointNames", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<Animation*>(this), "getJointNames",
Q_RETURN_ARG(QStringList, result));
return result;
}
@ -111,7 +114,7 @@ QStringList Animation::getJointNames() const {
QVector<FBXAnimationFrame> Animation::getFrames() const {
if (QThread::currentThread() != thread()) {
QVector<FBXAnimationFrame> result;
QMetaObject::invokeMethod(const_cast<Animation*>(this), "getFrames", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<Animation*>(this), "getFrames",
Q_RETURN_ARG(QVector<FBXAnimationFrame>, result));
return result;
}

View file

@ -1335,6 +1335,14 @@ void AudioClient::toggleMute() {
emit muteToggled();
}
void AudioClient::setNoiseReduction(bool enable) {
if (_isNoiseGateEnabled != enable) {
_isNoiseGateEnabled = enable;
emit noiseReductionChanged();
}
}
void AudioClient::setIsStereoInput(bool isStereoInput) {
if (isStereoInput != _isStereoInput) {
_isStereoInput = isStereoInput;
@ -1446,6 +1454,8 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceIn
_audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this);
_numInputCallbackBytes = calculateNumberOfInputCallbackBytes(_inputFormat);
_audioInput->setBufferSize(_numInputCallbackBytes);
// different audio input devices may have different volumes
emit inputVolumeChanged(_audioInput->volume());
// how do we want to handle input working, but output not working?
int numFrameSamples = calculateNumberOfFrameSamples(_numInputCallbackBytes);
@ -1703,7 +1713,7 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) {
// produce an oriented angle about the y-axis
glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2));
float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward"
float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward"
return (direction.x < 0.0f) ? -angle : angle;
} else {
@ -1847,3 +1857,10 @@ void AudioClient::setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 sca
void AudioClient::startThread() {
moveToNewNamedThread(this, "Audio Thread", [this] { start(); });
}
void AudioClient::setInputVolume(float volume) {
if (_audioInput && volume != _audioInput->volume()) {
_audioInput->setVolume(volume);
emit inputVolumeChanged(_audioInput->volume());
}
}

View file

@ -180,7 +180,8 @@ public slots:
virtual void setIsStereoInput(bool stereo) override;
void setNoiseReduction(bool isNoiseGateEnabled) { _isNoiseGateEnabled = isNoiseGateEnabled; }
void setNoiseReduction(bool isNoiseGateEnabled);
bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; }
void toggleLocalEcho() { _shouldEchoLocally = !_shouldEchoLocally; }
void toggleServerEcho() { _shouldEchoToServer = !_shouldEchoToServer; }
@ -197,7 +198,7 @@ public slots:
bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName);
float getInputVolume() const { return (_audioInput) ? (float)_audioInput->volume() : 0.0f; }
void setInputVolume(float volume) { if (_audioInput) _audioInput->setVolume(volume); }
void setInputVolume(float volume);
void setReverb(bool reverb);
void setReverbOptions(const AudioEffectOptions* options);
@ -207,7 +208,9 @@ public slots:
void saveSettings();
signals:
bool muteToggled();
void inputVolumeChanged(float volume);
void muteToggled();
void noiseReductionChanged();
void mutedByMixer();
void inputReceived(const QByteArray& inputSamples);
void inputLoudnessChanged(float loudness);

View file

@ -9,10 +9,13 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <qthread.h>
#include "SoundCache.h"
#include <QtCore/QThread>
#include <shared/QtHelpers.h>
#include "AudioLogging.h"
#include "SoundCache.h"
static const int SOUNDS_LOADING_PRIORITY { -7 }; // Make sure sounds load after the low rez texture mips
@ -29,7 +32,7 @@ SoundCache::SoundCache(QObject* parent) :
SharedSoundPointer SoundCache::getSound(const QUrl& url) {
if (QThread::currentThread() != thread()) {
SharedSoundPointer result;
QMetaObject::invokeMethod(this, "getSound", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "getSound",
Q_RETURN_ARG(SharedSoundPointer, result), Q_ARG(const QUrl&, url));
return result;
}

View file

@ -15,6 +15,7 @@
#include <glm/gtx/transform.hpp>
#include <glm/gtx/vector_query.hpp>
#include <shared/QtHelpers.h>
#include <DeferredLightingEffect.h>
#include <EntityTreeRenderer.h>
#include <NodeList.h>
@ -1010,7 +1011,7 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
int Avatar::getJointIndex(const QString& name) const {
if (QThread::currentThread() != thread()) {
int result;
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "getJointIndex", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<Avatar*>(this), "getJointIndex",
Q_RETURN_ARG(int, result), Q_ARG(const QString&, name));
return result;
}
@ -1024,7 +1025,7 @@ int Avatar::getJointIndex(const QString& name) const {
QStringList Avatar::getJointNames() const {
if (QThread::currentThread() != thread()) {
QStringList result;
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "getJointNames", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<Avatar*>(this), "getJointNames",
Q_RETURN_ARG(QStringList, result));
return result;
}
@ -1034,7 +1035,7 @@ QStringList Avatar::getJointNames() const {
glm::vec3 Avatar::getJointPosition(int index) const {
if (QThread::currentThread() != thread()) {
glm::vec3 position;
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "getJointPosition", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<Avatar*>(this), "getJointPosition",
Q_RETURN_ARG(glm::vec3, position), Q_ARG(const int, index));
return position;
}
@ -1046,7 +1047,7 @@ glm::vec3 Avatar::getJointPosition(int index) const {
glm::vec3 Avatar::getJointPosition(const QString& name) const {
if (QThread::currentThread() != thread()) {
glm::vec3 position;
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "getJointPosition", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<Avatar*>(this), "getJointPosition",
Q_RETURN_ARG(glm::vec3, position), Q_ARG(const QString&, name));
return position;
}
@ -1105,7 +1106,7 @@ static std::shared_ptr<Model> allocateAttachmentModel(bool isSoft, const Rig& ri
void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "setAttachmentData", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "setAttachmentData",
Q_ARG(const QVector<AttachmentData>, attachmentData));
return;
}

View file

@ -25,6 +25,7 @@
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <shared/QtHelpers.h>
#include <QVariantGLM.h>
#include <Transform.h>
#include <NetworkAccessManager.h>
@ -1227,7 +1228,7 @@ bool AvatarData::isJointDataValid(int index) const {
}
if (QThread::currentThread() != thread()) {
bool result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "isJointDataValid", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "isJointDataValid",
Q_RETURN_ARG(bool, result), Q_ARG(int, index));
return result;
}
@ -1240,7 +1241,7 @@ glm::quat AvatarData::getJointRotation(int index) const {
}
if (QThread::currentThread() != thread()) {
glm::quat result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getJointRotation", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getJointRotation",
Q_RETURN_ARG(glm::quat, result), Q_ARG(int, index));
return result;
}
@ -1255,7 +1256,7 @@ glm::vec3 AvatarData::getJointTranslation(int index) const {
}
if (QThread::currentThread() != thread()) {
glm::vec3 result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getJointTranslation", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getJointTranslation",
Q_RETURN_ARG(glm::vec3, result), Q_ARG(int, index));
return result;
}
@ -1266,7 +1267,7 @@ glm::vec3 AvatarData::getJointTranslation(int index) const {
glm::vec3 AvatarData::getJointTranslation(const QString& name) const {
if (QThread::currentThread() != thread()) {
glm::vec3 result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getJointTranslation", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getJointTranslation",
Q_RETURN_ARG(glm::vec3, result), Q_ARG(const QString&, name));
return result;
}
@ -1344,7 +1345,7 @@ void AvatarData::clearJointData(const QString& name) {
bool AvatarData::isJointDataValid(const QString& name) const {
if (QThread::currentThread() != thread()) {
bool result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "isJointDataValid", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "isJointDataValid",
Q_RETURN_ARG(bool, result), Q_ARG(const QString&, name));
return result;
}
@ -1354,7 +1355,7 @@ bool AvatarData::isJointDataValid(const QString& name) const {
glm::quat AvatarData::getJointRotation(const QString& name) const {
if (QThread::currentThread() != thread()) {
glm::quat result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getJointRotation", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getJointRotation",
Q_RETURN_ARG(glm::quat, result), Q_ARG(const QString&, name));
return result;
}
@ -1364,8 +1365,7 @@ glm::quat AvatarData::getJointRotation(const QString& name) const {
QVector<glm::quat> AvatarData::getJointRotations() const {
if (QThread::currentThread() != thread()) {
QVector<glm::quat> result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this),
"getJointRotations", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getJointRotations",
Q_RETURN_ARG(QVector<glm::quat>, result));
return result;
}
@ -1380,8 +1380,7 @@ QVector<glm::quat> AvatarData::getJointRotations() const {
void AvatarData::setJointRotations(QVector<glm::quat> jointRotations) {
if (QThread::currentThread() != thread()) {
QVector<glm::quat> result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this),
"setJointRotations", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "setJointRotations",
Q_ARG(QVector<glm::quat>, jointRotations));
}
QWriteLocker writeLock(&_jointDataLock);
@ -1398,8 +1397,7 @@ void AvatarData::setJointRotations(QVector<glm::quat> jointRotations) {
QVector<glm::vec3> AvatarData::getJointTranslations() const {
if (QThread::currentThread() != thread()) {
QVector<glm::vec3> result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this),
"getJointTranslations", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getJointTranslations",
Q_RETURN_ARG(QVector<glm::vec3>, result));
return result;
}
@ -1414,8 +1412,7 @@ QVector<glm::vec3> AvatarData::getJointTranslations() const {
void AvatarData::setJointTranslations(QVector<glm::vec3> jointTranslations) {
if (QThread::currentThread() != thread()) {
QVector<glm::quat> result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this),
"setJointTranslations", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "setJointTranslations",
Q_ARG(QVector<glm::vec3>, jointTranslations));
}
QWriteLocker writeLock(&_jointDataLock);
@ -1616,7 +1613,7 @@ void AvatarData::setDisplayName(const QString& displayName) {
QVector<AttachmentData> AvatarData::getAttachmentData() const {
if (QThread::currentThread() != thread()) {
QVector<AttachmentData> result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getAttachmentData", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getAttachmentData",
Q_RETURN_ARG(QVector<AttachmentData>, result));
return result;
}
@ -2339,7 +2336,7 @@ void AvatarData::clearAvatarEntity(const QUuid& entityID) {
AvatarEntityMap AvatarData::getAvatarEntityData() const {
AvatarEntityMap result;
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getAvatarEntityData", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getAvatarEntityData",
Q_RETURN_ARG(AvatarEntityMap, result));
return result;
}
@ -2380,7 +2377,7 @@ void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) {
AvatarEntityIDs AvatarData::getAndClearRecentlyDetachedIDs() {
AvatarEntityIDs result;
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getAndClearRecentlyDetachedIDs", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<AvatarData*>(this), "getAndClearRecentlyDetachedIDs",
Q_RETURN_ARG(AvatarEntityIDs, result));
return result;
}

View file

@ -11,14 +11,16 @@
#include <memory>
#include <math.h>
#include <glm/gtc/type_ptr.hpp>
#include <QtCore/QTimer>
#include <QtCore/QThread>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <glm/gtc/type_ptr.hpp>
#include <QtGui/QWindow>
#include <QQuickWindow>
#include <shared/QtHelpers.h>
#include <ui/Menu.h>
#include <NumericalConstants.h>
#include <DependencyManager.h>
@ -289,7 +291,7 @@ glm::vec2 CompositorHelper::getReticleMaximumPosition() const {
void CompositorHelper::sendFakeMouseEvent() {
if (qApp->thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "sendFakeMouseEvent", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "sendFakeMouseEvent");
return;
}

View file

@ -17,6 +17,7 @@
#include <QScriptSyntaxCheckResult>
#include <QThreadPool>
#include <shared/QtHelpers.h>
#include <ColorUtils.h>
#include <AbstractScriptingServicesInterface.h>
#include <AbstractViewStateInterface.h>
@ -380,7 +381,7 @@ ModelPointer EntityTreeRenderer::allocateModel(const QString& url, float loading
// Only create and delete models on the thread that owns the EntityTreeRenderer
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "allocateModel", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "allocateModel",
Q_RETURN_ARG(ModelPointer, model),
Q_ARG(const QString&, url));
@ -397,7 +398,7 @@ ModelPointer EntityTreeRenderer::allocateModel(const QString& url, float loading
ModelPointer EntityTreeRenderer::updateModel(ModelPointer model, const QString& newUrl) {
// Only create and delete models on the thread that owns the EntityTreeRenderer
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "updateModel", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "updateModel",
Q_RETURN_ARG(ModelPointer, model),
Q_ARG(ModelPointer, model),
Q_ARG(const QString&, newUrl));

View file

@ -9,19 +9,20 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "EntityScriptingInterface.h"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include "EntityScriptingInterface.h"
#include <QFutureWatcher>
#include <QtConcurrent/QtConcurrentRun>
#include "EntityItemID.h"
#include <shared/QtHelpers.h>
#include <VariantMapToScriptValue.h>
#include <SharedUtil.h>
#include <SpatialParentFinder.h>
#include "EntityItemID.h"
#include "EntitiesLogging.h"
#include "EntityDynamicFactoryInterface.h"
#include "EntityDynamicInterface.h"
@ -1488,7 +1489,7 @@ int EntityScriptingInterface::getJointIndex(const QUuid& entityID, const QString
return -1;
}
int result;
QMetaObject::invokeMethod(_entityTree.get(), "getJointIndex", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(_entityTree.get(), "getJointIndex",
Q_RETURN_ARG(int, result), Q_ARG(QUuid, entityID), Q_ARG(QString, name));
return result;
}
@ -1498,7 +1499,7 @@ QStringList EntityScriptingInterface::getJointNames(const QUuid& entityID) {
return QStringList();
}
QStringList result;
QMetaObject::invokeMethod(_entityTree.get(), "getJointNames", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(_entityTree.get(), "getJointNames",
Q_RETURN_ARG(QStringList, result), Q_ARG(QUuid, entityID));
return result;
}

View file

@ -20,6 +20,7 @@
#include <QtNetwork/QHostInfo>
#include <QtNetwork/QNetworkInterface>
#include <shared/QtHelpers.h>
#include <ThreadHelpers.h>
#include <LogHandler.h>
#include <UUID.h>
@ -232,7 +233,7 @@ void NodeList::processICEPingPacket(QSharedPointer<ReceivedMessage> message) {
void NodeList::reset() {
if (thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "reset", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "reset");
return;
}

View file

@ -9,22 +9,24 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ResourceCache.h"
#include <cfloat>
#include <cmath>
#include <assert.h>
#include <QThread>
#include <QTimer>
#include <SharedUtil.h>
#include <assert.h>
#include <shared/QtHelpers.h>
#include <Trace.h>
#include <Profile.h>
#include "NetworkAccessManager.h"
#include "NetworkLogging.h"
#include "NodeList.h"
#include "ResourceCache.h"
#include <Trace.h>
#include <Profile.h>
#define clamp(x, min, max) (((x) < (min)) ? (min) :\
(((x) > (max)) ? (max) :\
@ -178,7 +180,7 @@ ScriptableResource* ResourceCache::prefetch(const QUrl& url, void* extra) {
if (QThread::currentThread() != thread()) {
// Must be called in thread to ensure getResource returns a valid pointer
QMetaObject::invokeMethod(this, "prefetch", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "prefetch",
Q_RETURN_ARG(ScriptableResource*, result),
Q_ARG(QUrl, url), Q_ARG(void*, extra));
return result;
@ -301,7 +303,7 @@ QVariantList ResourceCache::getResourceList() {
QVariantList list;
if (QThread::currentThread() != thread()) {
// NOTE: invokeMethod does not allow a const QObject*
QMetaObject::invokeMethod(this, "getResourceList", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "getResourceList",
Q_RETURN_ARG(QVariantList, list));
} else {
auto resources = _resources.uniqueKeys();

View file

@ -17,6 +17,7 @@
#include <QtCore/QThread>
#include <shared/QtHelpers.h>
#include <LogHandler.h>
#include "../NetworkLogging.h"
@ -276,7 +277,7 @@ Connection* Socket::findOrCreateConnection(const HifiSockAddr& sockAddr) {
void Socket::clearConnections() {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "clearConnections", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "clearConnections");
return;
}

View file

@ -11,6 +11,8 @@
#include <QThread>
#include <shared/QtHelpers.h>
#include "DisplayPlugin.h"
#include "InputPlugin.h"
#include "PluginManager.h"
@ -21,7 +23,7 @@ InputConfiguration::InputConfiguration() {
QStringList InputConfiguration::inputPlugins() {
if (QThread::currentThread() != thread()) {
QStringList result;
QMetaObject::invokeMethod(this, "inputPlugins", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "inputPlugins",
Q_RETURN_ARG(QStringList, result));
return result;
}
@ -42,7 +44,7 @@ QStringList InputConfiguration::inputPlugins() {
QStringList InputConfiguration::activeInputPlugins() {
if (QThread::currentThread() != thread()) {
QStringList result;
QMetaObject::invokeMethod(this, "activeInputPlugins", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "activeInputPlugins",
Q_RETURN_ARG(QStringList, result));
return result;
}
@ -64,7 +66,7 @@ QStringList InputConfiguration::activeInputPlugins() {
QString InputConfiguration::configurationLayout(QString pluginName) {
if (QThread::currentThread() != thread()) {
QString result;
QMetaObject::invokeMethod(this, "configurationLayout", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "configurationLayout",
Q_RETURN_ARG(QString, result),
Q_ARG(QString, pluginName));
return result;
@ -81,7 +83,7 @@ QString InputConfiguration::configurationLayout(QString pluginName) {
void InputConfiguration::setConfigurationSettings(QJsonObject configurationSettings, QString pluginName) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "setConfigurationSettings", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "setConfigurationSettings",
Q_ARG(QJsonObject, configurationSettings),
Q_ARG(QString, pluginName));
return;
@ -97,7 +99,7 @@ void InputConfiguration::setConfigurationSettings(QJsonObject configurationSetti
QJsonObject InputConfiguration::configurationSettings(QString pluginName) {
if (QThread::currentThread() != thread()) {
QJsonObject result;
QMetaObject::invokeMethod(this, "configurationSettings", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "configurationSettings",
Q_RETURN_ARG(QJsonObject, result),
Q_ARG(QString, pluginName));
return result;
@ -113,7 +115,7 @@ QJsonObject InputConfiguration::configurationSettings(QString pluginName) {
void InputConfiguration::calibratePlugin(QString pluginName) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "calibratePlugin", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "calibratePlugin");
return;
}
@ -128,7 +130,7 @@ void InputConfiguration::calibratePlugin(QString pluginName) {
bool InputConfiguration::uncalibratePlugin(QString pluginName) {
if (QThread::currentThread() != thread()) {
bool result;
QMetaObject::invokeMethod(this, "uncalibratePlugin", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "uncalibratePlugin",
Q_ARG(bool, result));
return result;
}

View file

@ -8,6 +8,8 @@
#include <QThread>
#include <shared/QtHelpers.h>
#include "ClipCache.h"
#include "impl/PointerClip.h"
#include "Logging.h"
@ -37,7 +39,7 @@ ClipCache::ClipCache(QObject* parent) :
NetworkClipLoaderPointer ClipCache::getClipLoader(const QUrl& url) {
if (QThread::currentThread() != thread()) {
NetworkClipLoaderPointer result;
QMetaObject::invokeMethod(this, "getClipLoader", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "getClipLoader",
Q_RETURN_ARG(NetworkClipLoaderPointer, result), Q_ARG(const QUrl&, url));
return result;
}

View file

@ -18,6 +18,7 @@
#include <glm/gtx/transform.hpp>
#include <glm/gtx/norm.hpp>
#include <shared/QtHelpers.h>
#include <GeometryUtil.h>
#include <PathUtils.h>
#include <PerfStat.h>
@ -870,7 +871,7 @@ bool Model::getRelativeDefaultJointTranslation(int jointIndex, glm::vec3& transl
QStringList Model::getJointNames() const {
if (QThread::currentThread() != thread()) {
QStringList result;
QMetaObject::invokeMethod(const_cast<Model*>(this), "getJointNames", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(const_cast<Model*>(this), "getJointNames",
Q_RETURN_ARG(QStringList, result));
return result;
}

View file

@ -10,9 +10,12 @@
//
#include "Config.h"
#include "Task.h"
#include <QtCore/QThread>
#include <shared/QtHelpers.h>
#include "Task.h"
using namespace task;
void JobConfig::setPresetList(const QJsonObject& object) {
@ -58,7 +61,7 @@ void TaskConfig::transferChildrenConfigs(QConfigPointer source) {
void TaskConfig::refresh() {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "refresh", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "refresh");
return;
}

View file

@ -13,6 +13,8 @@
#include <QVector3D>
#include <shared/QtHelpers.h>
#include "ScriptAudioInjector.h"
#include "ScriptEngineLogging.h"
@ -32,7 +34,7 @@ ScriptAudioInjector* AudioScriptingInterface::playSound(SharedSoundPointer sound
if (QThread::currentThread() != thread()) {
ScriptAudioInjector* injector = NULL;
QMetaObject::invokeMethod(this, "playSound", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "playSound",
Q_RETURN_ARG(ScriptAudioInjector*, injector),
Q_ARG(SharedSoundPointer, sound),
Q_ARG(const AudioInjectorOptions&, injectorOptions));

View file

@ -14,6 +14,7 @@
#include <QtScript/QScriptValue>
#include <QtWidgets/QFileDialog>
#include <shared/QtHelpers.h>
#include <AssetClient.h>
#include <AssetUpload.h>
#include <BuildInfo.h>
@ -98,7 +99,7 @@ void RecordingScriptingInterface::loadRecording(const QString& url, QScriptValue
void RecordingScriptingInterface::startPlaying() {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "startPlaying", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "startPlaying");
return;
}
@ -115,7 +116,7 @@ void RecordingScriptingInterface::setPlayerAudioOffset(float audioOffset) {
void RecordingScriptingInterface::setPlayerTime(float time) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "setPlayerTime", Qt::BlockingQueuedConnection, Q_ARG(float, time));
hifi::qt::blockingInvokeMethod(this, "setPlayerTime", Q_ARG(float, time));
return;
}
_player->seek(time);
@ -147,7 +148,7 @@ void RecordingScriptingInterface::setPlayerUseSkeletonModel(bool useSkeletonMode
void RecordingScriptingInterface::pausePlayer() {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "pausePlayer", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "pausePlayer");
return;
}
_player->pause();
@ -155,7 +156,7 @@ void RecordingScriptingInterface::pausePlayer() {
void RecordingScriptingInterface::stopPlaying() {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "stopPlaying", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "stopPlaying");
return;
}
_player->stop();
@ -176,7 +177,7 @@ void RecordingScriptingInterface::startRecording() {
}
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "startRecording", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "startRecording");
return;
}
@ -199,7 +200,7 @@ QString RecordingScriptingInterface::getDefaultRecordingSaveDirectory() {
void RecordingScriptingInterface::saveRecording(const QString& filename) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "saveRecording", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "saveRecording",
Q_ARG(QString, filename));
return;
}
@ -220,7 +221,7 @@ bool RecordingScriptingInterface::saveRecordingToAsset(QScriptValue getClipAtpUr
if (QThread::currentThread() != thread()) {
bool result;
QMetaObject::invokeMethod(this, "saveRecordingToAsset", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "saveRecordingToAsset",
Q_RETURN_ARG(bool, result),
Q_ARG(QScriptValue, getClipAtpUrl));
return result;
@ -257,7 +258,7 @@ bool RecordingScriptingInterface::saveRecordingToAsset(QScriptValue getClipAtpUr
void RecordingScriptingInterface::loadLastRecording() {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "loadLastRecording", Qt::BlockingQueuedConnection);
hifi::qt::blockingInvokeMethod(this, "loadLastRecording");
return;
}

View file

@ -36,6 +36,7 @@
#include <QtScriptTools/QScriptEngineDebugger>
#include <shared/QtHelpers.h>
#include <AudioConstants.h>
#include <AudioEffectOptions.h>
#include <AvatarData.h>
@ -436,12 +437,12 @@ void ScriptEngine::loadURL(const QUrl& scriptURL, bool reload) {
_fileNameString = url.toString();
_isReloading = reload;
// Check that script has a supported file extension
// Check that script has a supported file extension
if (!hasValidScriptSuffix(_fileNameString)) {
scriptErrorMessage("File extension of file: " + _fileNameString + " is not a currently supported script type");
emit errorLoadingScript(_fileNameString);
return;
}
}
const auto maxRetries = 0; // for consistency with previous scriptCache->getScript() behavior
auto scriptCache = DependencyManager::get<ScriptCache>();
@ -964,7 +965,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi
qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::evaluate() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
"sourceCode:" << sourceCode << " fileName:" << fileName << "lineNumber:" << lineNumber;
#endif
QMetaObject::invokeMethod(this, "evaluate", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "evaluate",
Q_RETURN_ARG(QScriptValue, result),
Q_ARG(const QString&, sourceCode),
Q_ARG(const QString&, fileName),

View file

@ -12,6 +12,7 @@
#include <QtWidgets/QApplication>
#include <shared/QtHelpers.h>
#include <SettingHandle.h>
#include <UserActivityLogger.h>
#include <PathUtils.h>
@ -452,7 +453,7 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL
bool activateMainWindow, bool reload) {
if (thread() != QThread::currentThread()) {
ScriptEngine* result { nullptr };
QMetaObject::invokeMethod(this, "loadScript", Qt::BlockingQueuedConnection, Q_RETURN_ARG(ScriptEngine*, result),
hifi::qt::blockingInvokeMethod(this, "loadScript", Q_RETURN_ARG(ScriptEngine*, result),
Q_ARG(QUrl, scriptFilename),
Q_ARG(bool, isUserLoaded),
Q_ARG(bool, loadScriptFromEditor),

View file

@ -16,6 +16,7 @@
#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
#include <QtCore/QWaitCondition>
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QThread>
@ -34,4 +35,25 @@ void withLock(QMutex& lock, F function) {
void moveToNewNamedThread(QObject* object, const QString& name, std::function<void()> startCallback, QThread::Priority priority = QThread::InheritPriority);
void moveToNewNamedThread(QObject* object, const QString& name, QThread::Priority priority = QThread::InheritPriority);
class ConditionalGuard {
public:
void trigger() {
QMutexLocker locker(&_mutex);
_triggered = true;
_condition.wakeAll();
}
bool wait(unsigned long time = ULONG_MAX) {
QMutexLocker locker(&_mutex);
if (!_triggered) {
_condition.wait(&_mutex, time);
}
return _triggered;
}
private:
QMutex _mutex;
QWaitCondition _condition;
bool _triggered { false };
};
#endif

View file

@ -0,0 +1,57 @@
//
// Created by Bradley Austin Davis on 2015/11/09
// Copyright 2013-2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "QtHelpers.h"
#include <QtCore/QThread>
#include <QtCore/QCoreApplication>
#include <QtCore/QLoggingCategory>
Q_LOGGING_CATEGORY(thread_safety, "hifi.thread_safety")
namespace hifi { namespace qt {
bool blockingInvokeMethod(
QObject *obj, const char *member,
QGenericReturnArgument ret,
QGenericArgument val0,
QGenericArgument val1,
QGenericArgument val2,
QGenericArgument val3,
QGenericArgument val4,
QGenericArgument val5,
QGenericArgument val6,
QGenericArgument val7,
QGenericArgument val8,
QGenericArgument val9) {
if (QThread::currentThread() == qApp->thread()) {
qCWarning(thread_safety, "BlockingQueuedConnection invoked on main thread!");
}
return QMetaObject::invokeMethod(obj, member,
Qt::BlockingQueuedConnection, ret, val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
bool blockingInvokeMethod(
QObject *obj, const char *member,
QGenericArgument val0,
QGenericArgument val1,
QGenericArgument val2,
QGenericArgument val3,
QGenericArgument val4,
QGenericArgument val5,
QGenericArgument val6,
QGenericArgument val7,
QGenericArgument val8,
QGenericArgument val9) {
qCWarning(thread_safety, "BlockingQueuedConnection invoked without return value!");
return blockingInvokeMethod(obj, member, QGenericReturnArgument(), val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
} }

View file

@ -0,0 +1,47 @@
//
// Created by Bradley Austin Davis on 2017/06/29
// Copyright 2013-2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#pragma once
#ifndef hifi_Shared_QtHelpers_h
#define hifi_Shared_QtHelpers_h
#include <QtCore/QObject>
namespace hifi { namespace qt {
bool blockingInvokeMethod(
QObject *obj, const char *member,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument());
bool blockingInvokeMethod(
QObject *obj, const char *member,
QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument());
} }
#endif

View file

@ -15,6 +15,7 @@
#include <QtQuick/QQuickWindow>
#include <QtQml/QtQml>
#include <shared/QtHelpers.h>
#include <gl/GLHelpers.h>
#include <AbstractUriHandler.h>
@ -249,7 +250,7 @@ int OffscreenUi::waitForMessageBoxResult(QQuickItem* messageBox) {
QMessageBox::StandardButton OffscreenUi::messageBox(Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
if (QThread::currentThread() != thread()) {
QMessageBox::StandardButton result = QMessageBox::StandardButton::NoButton;
QMetaObject::invokeMethod(this, "messageBox", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "messageBox",
Q_RETURN_ARG(QMessageBox::StandardButton, result),
Q_ARG(Icon, icon),
Q_ARG(QString, title),
@ -351,7 +352,7 @@ QVariant OffscreenUi::getCustomInfo(const Icon icon, const QString& title, const
QVariant OffscreenUi::inputDialog(const Icon icon, const QString& title, const QString& label, const QVariant& current) {
if (QThread::currentThread() != thread()) {
QVariant result;
QMetaObject::invokeMethod(this, "inputDialog", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "inputDialog",
Q_RETURN_ARG(QVariant, result),
Q_ARG(Icon, icon),
Q_ARG(QString, title),
@ -366,7 +367,7 @@ QVariant OffscreenUi::inputDialog(const Icon icon, const QString& title, const Q
QVariant OffscreenUi::customInputDialog(const Icon icon, const QString& title, const QVariantMap& config) {
if (QThread::currentThread() != thread()) {
QVariant result;
QMetaObject::invokeMethod(this, "customInputDialog", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "customInputDialog",
Q_RETURN_ARG(QVariant, result),
Q_ARG(Icon, icon),
Q_ARG(QString, title),
@ -640,7 +641,7 @@ QString OffscreenUi::fileDialog(const QVariantMap& properties) {
QString OffscreenUi::fileOpenDialog(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) {
if (QThread::currentThread() != thread()) {
QString result;
QMetaObject::invokeMethod(this, "fileOpenDialog", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "fileOpenDialog",
Q_RETURN_ARG(QString, result),
Q_ARG(QString, caption),
Q_ARG(QString, dir),
@ -662,7 +663,7 @@ QString OffscreenUi::fileOpenDialog(const QString& caption, const QString& dir,
QString OffscreenUi::fileSaveDialog(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) {
if (QThread::currentThread() != thread()) {
QString result;
QMetaObject::invokeMethod(this, "fileSaveDialog", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "fileSaveDialog",
Q_RETURN_ARG(QString, result),
Q_ARG(QString, caption),
Q_ARG(QString, dir),
@ -686,7 +687,7 @@ QString OffscreenUi::fileSaveDialog(const QString& caption, const QString& dir,
QString OffscreenUi::existingDirectoryDialog(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) {
if (QThread::currentThread() != thread()) {
QString result;
QMetaObject::invokeMethod(this, "existingDirectoryDialog", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "existingDirectoryDialog",
Q_RETURN_ARG(QString, result),
Q_ARG(QString, caption),
Q_ARG(QString, dir),
@ -773,7 +774,7 @@ QString OffscreenUi::assetOpenDialog(const QString& caption, const QString& dir,
// ATP equivalent of fileOpenDialog().
if (QThread::currentThread() != thread()) {
QString result;
QMetaObject::invokeMethod(this, "assetOpenDialog", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "assetOpenDialog",
Q_RETURN_ARG(QString, result),
Q_ARG(QString, caption),
Q_ARG(QString, dir),

View file

@ -13,12 +13,12 @@
#include <QtWidgets/QShortcut>
#include <SettingHandle.h>
#include <shared/QtHelpers.h>
#include "../VrMenu.h"
#include "../OffscreenUi.h"
#include "Logging.h"
using namespace ui;
static QList<QString> groups;
@ -246,7 +246,7 @@ void Menu::removeAction(MenuWrapper* menu, const QString& actionName) {
void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) {
if (thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "setIsOptionChecked", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "setIsOptionChecked",
Q_ARG(const QString&, menuOption),
Q_ARG(bool, isChecked));
return;

View file

@ -25,6 +25,8 @@
#include <QtCore/QWaitCondition>
#include <shared/NsightHelpers.h>
#include <shared/GlobalAppProperties.h>
#include <shared/QtHelpers.h>
#include <PerfStat.h>
#include <DependencyManager.h>
#include <NumericalConstants.h>
@ -34,7 +36,6 @@
#include <AccountManager.h>
#include <NetworkAccessManager.h>
#include <GLMHelpers.h>
#include <shared/GlobalAppProperties.h>
#include <gl/OffscreenGLCanvas.h>
#include <gl/GLHelpers.h>
@ -899,7 +900,7 @@ void OffscreenQmlSurface::executeOnUiThread(std::function<void()> function, bool
QVariant OffscreenQmlSurface::returnFromUiThread(std::function<QVariant()> function) {
if (QThread::currentThread() != thread()) {
QVariant result;
QMetaObject::invokeMethod(this, "returnFromUiThread", Qt::BlockingQueuedConnection,
hifi::qt::blockingInvokeMethod(this, "returnFromUiThread",
Q_RETURN_ARG(QVariant, result),
Q_ARG(std::function<QVariant()>, function));
return result;

View file

@ -11,6 +11,8 @@
#include <QtCore/QThread>
#include <QtCore/QCoreApplication>
#include <shared/QtHelpers.h>
QmlWrapper::QmlWrapper(QObject* qmlObject, QObject* parent)
: QObject(parent), _qmlObject(qmlObject) {
Q_ASSERT(QThread::currentThread() == qApp->thread());
@ -36,7 +38,7 @@ void QmlWrapper::writeProperties(QVariant propertyMap) {
QVariant QmlWrapper::readProperty(const QString& propertyName) {
if (QThread::currentThread() != thread()) {
QVariant result;
QMetaObject::invokeMethod(this, "readProperty", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, result), Q_ARG(QString, propertyName));
hifi::qt::blockingInvokeMethod(this, "readProperty", Q_RETURN_ARG(QVariant, result), Q_ARG(QString, propertyName));
return result;
}
@ -46,7 +48,7 @@ QVariant QmlWrapper::readProperty(const QString& propertyName) {
QVariant QmlWrapper::readProperties(const QVariant& propertyList) {
if (QThread::currentThread() != thread()) {
QVariant result;
QMetaObject::invokeMethod(this, "readProperties", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, propertyList));
hifi::qt::blockingInvokeMethod(this, "readProperties", Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, propertyList));
return result;
}

View file

@ -11,6 +11,7 @@
#include <QtCore/QThread>
#include <QtQml/QQmlProperty>
#include <shared/QtHelpers.h>
#include <PathUtils.h>
#include <DependencyManager.h>
#include <AccountManager.h>
@ -42,7 +43,7 @@ ToolbarProxy* TabletScriptingInterface::getSystemToolbarProxy() {
TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) {
TabletProxy* tabletProxy = nullptr;
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "getTablet", Qt::BlockingQueuedConnection, Q_RETURN_ARG(TabletProxy*, tabletProxy), Q_ARG(QString, tabletId));
hifi::qt::blockingInvokeMethod(this, "getTablet", Q_RETURN_ARG(TabletProxy*, tabletProxy), Q_ARG(QString, tabletId));
return tabletProxy;
}
@ -292,7 +293,7 @@ void TabletProxy::initialScreen(const QVariant& url) {
bool TabletProxy::isMessageDialogOpen() {
if (QThread::currentThread() != thread()) {
bool result = false;
QMetaObject::invokeMethod(this, "isMessageDialogOpen", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result));
hifi::qt::blockingInvokeMethod(this, "isMessageDialogOpen", Q_RETURN_ARG(bool, result));
return result;
}
@ -317,7 +318,7 @@ void TabletProxy::emitWebEvent(const QVariant& msg) {
bool TabletProxy::isPathLoaded(const QVariant& path) {
if (QThread::currentThread() != thread()) {
bool result = false;
QMetaObject::invokeMethod(this, "isPathLoaded", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result), Q_ARG(QVariant, path));
hifi::qt::blockingInvokeMethod(this, "isPathLoaded", Q_RETURN_ARG(bool, result), Q_ARG(QVariant, path));
return result;
}
@ -480,7 +481,7 @@ void TabletProxy::loadQMLSource(const QVariant& path) {
bool TabletProxy::pushOntoStack(const QVariant& path) {
if (QThread::currentThread() != thread()) {
bool result = false;
QMetaObject::invokeMethod(this, "pushOntoStack", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result), Q_ARG(QVariant, path));
hifi::qt::blockingInvokeMethod(this, "pushOntoStack", Q_RETURN_ARG(bool, result), Q_ARG(QVariant, path));
return result;
}
@ -606,7 +607,7 @@ void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaS
TabletButtonProxy* TabletProxy::addButton(const QVariant& properties) {
if (QThread::currentThread() != thread()) {
TabletButtonProxy* result = nullptr;
QMetaObject::invokeMethod(this, "addButton", Qt::BlockingQueuedConnection, Q_RETURN_ARG(TabletButtonProxy*, result), Q_ARG(QVariant, properties));
hifi::qt::blockingInvokeMethod(this, "addButton", Q_RETURN_ARG(TabletButtonProxy*, result), Q_ARG(QVariant, properties));
return result;
}
@ -633,7 +634,7 @@ TabletButtonProxy* TabletProxy::addButton(const QVariant& properties) {
bool TabletProxy::onHomeScreen() {
if (QThread::currentThread() != thread()) {
bool result = false;
QMetaObject::invokeMethod(this, "onHomeScreen", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result));
hifi::qt::blockingInvokeMethod(this, "onHomeScreen", Q_RETURN_ARG(bool, result));
return result;
}
@ -840,7 +841,7 @@ void TabletButtonProxy::setToolbarButtonProxy(QObject* toolbarButtonProxy) {
QVariantMap TabletButtonProxy::getProperties() {
if (QThread::currentThread() != thread()) {
QVariantMap result;
QMetaObject::invokeMethod(this, "getProperties", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariantMap, result));
hifi::qt::blockingInvokeMethod(this, "getProperties", Q_RETURN_ARG(QVariantMap, result));
return result;
}

View file

@ -12,6 +12,8 @@
#include <QtQuick/QQuickItem>
#include <QtScript/QScriptValue>
#include <QtScript/QScriptEngine>
#include <shared/QtHelpers.h>
#include "../OffscreenUi.h"
QScriptValue toolbarToScriptValue(QScriptEngine* engine, ToolbarProxy* const &in) {
@ -68,7 +70,7 @@ ToolbarProxy::ToolbarProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(qml
ToolbarButtonProxy* ToolbarProxy::addButton(const QVariant& properties) {
if (QThread::currentThread() != thread()) {
ToolbarButtonProxy* result = nullptr;
QMetaObject::invokeMethod(this, "addButton", Qt::BlockingQueuedConnection, Q_RETURN_ARG(ToolbarButtonProxy*, result), Q_ARG(QVariant, properties));
hifi::qt::blockingInvokeMethod(this, "addButton", Q_RETURN_ARG(ToolbarButtonProxy*, result), Q_ARG(QVariant, properties));
return result;
}
@ -99,18 +101,14 @@ void ToolbarProxy::removeButton(const QVariant& name) {
ToolbarProxy* ToolbarScriptingInterface::getToolbar(const QString& toolbarId) {
if (QThread::currentThread() != thread()) {
ToolbarProxy* result = nullptr;
QMetaObject::invokeMethod(this, "getToolbar", Qt::BlockingQueuedConnection, Q_RETURN_ARG(ToolbarProxy*, result), Q_ARG(QString, toolbarId));
hifi::qt::blockingInvokeMethod(this, "getToolbar", Q_RETURN_ARG(ToolbarProxy*, result), Q_ARG(QString, toolbarId));
return result;
}
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto desktop = offscreenUi->getDesktop();
Qt::ConnectionType connectionType = Qt::AutoConnection;
if (QThread::currentThread() != desktop->thread()) {
connectionType = Qt::BlockingQueuedConnection;
}
QVariant resultVar;
bool invokeResult = QMetaObject::invokeMethod(desktop, "getToolbar", connectionType, Q_RETURN_ARG(QVariant, resultVar), Q_ARG(QVariant, toolbarId));
bool invokeResult = QMetaObject::invokeMethod(desktop, "getToolbar", Q_RETURN_ARG(QVariant, resultVar), Q_ARG(QVariant, toolbarId));
if (!invokeResult) {
return nullptr;
}