Showing the changes to libraries/script-engine/src/TabletScriptingInterface.cpp (1 of 2 files). Show all
Unified · Split
| @@ -21,6 +21,8 @@ · 20 unmodified lines | |||
| 21 | #include <InfoView.h> | 21 | #include <InfoView.h> |
| 22 | #include "SoundEffect.h" | 22 | #include "SoundEffect.h" |
| 23 | 23 | ||
| 24 | const QString SYSTEM_TOOLBAR = "com.highfidelity.interface.toolbar.system"; | ||
| 25 | const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; | ||
| 24 | 26 | ||
| 25 | QScriptValue tabletToScriptValue(QScriptEngine* engine, TabletProxy* const &in) { | 27 | QScriptValue tabletToScriptValue(QScriptEngine* engine, TabletProxy* const &in) { |
| 26 | return engine->newQObject(in, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects); | 28 | return engine->newQObject(in, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects); |
| @@ -35,11 +37,11 @@ TabletScriptingInterface::TabletScriptingInterface() { · 8 unmodified lines | |||
| 35 | } | 37 | } |
| 36 | 38 | ||
| 37 | QObject* TabletScriptingInterface::getSystemToolbarProxy() { | 39 | QObject* TabletScriptingInterface::getSystemToolbarProxy() { |
| 38 | const QString SYSTEM_TOOLBAR = "com.highfidelity.interface.toolbar.system"; | ||
| 39 | Qt::ConnectionType connectionType = Qt::AutoConnection; | 40 | Qt::ConnectionType connectionType = Qt::AutoConnection; |
| 40 | if (QThread::currentThread() != _toolbarScriptingInterface->thread()) { | 41 | if (QThread::currentThread() != _toolbarScriptingInterface->thread()) { |
| 41 | connectionType = Qt::BlockingQueuedConnection; | 42 | connectionType = Qt::BlockingQueuedConnection; |
| 42 | } | 43 | } |
| 44 | |||
| 43 | QObject* toolbarProxy = nullptr; | 45 | QObject* toolbarProxy = nullptr; |
| 44 | bool hasResult = QMetaObject::invokeMethod(_toolbarScriptingInterface, "getToolbar", connectionType, Q_RETURN_ARG(QObject*, toolbarProxy), Q_ARG(QString, SYSTEM_TOOLBAR)); | 46 | bool hasResult = QMetaObject::invokeMethod(_toolbarScriptingInterface, "getToolbar", connectionType, Q_RETURN_ARG(QObject*, toolbarProxy), Q_ARG(QString, SYSTEM_TOOLBAR)); |
| 45 | if (hasResult) { | 47 | if (hasResult) { |
| @@ -51,28 +53,38 @@ QObject* TabletScriptingInterface::getSystemToolbarProxy() { · 5 unmodified lines | |||
| 51 | } | 53 | } |
| 52 | 54 | ||
| 53 | TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) { | 55 | TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) { |
| 54 | 56 | TabletProxy* tabletProxy = nullptr; | |
| 55 | std::lock_guard<std::mutex> guard(_mutex); | 57 | { |
| 56 | 58 | // the only thing guarded should be map mutation | |
| 57 | // look up tabletId in the map. | 59 | // this avoids a deadlock with the Main thread |
| 58 | auto iter = _tabletProxies.find(tabletId); | 60 | // from Qt::BlockingQueuedEvent invocations later in the call-tree |
| 59 | if (iter != _tabletProxies.end()) { | 61 | std::lock_guard<std::mutex> guard(_mapMutex); |
| 60 | // tablet already exists, just return it. | 62 | |
| 61 | return iter->second; | 63 | auto iter = _tabletProxies.find(tabletId); |
| 62 | } else { | 64 | if (iter != _tabletProxies.end()) { |
| 63 | // allocate a new tablet, add it to the map then return it. | 65 | // tablet already exists |
| 64 | auto tabletProxy = new TabletProxy(tabletId); | 66 | return iter->second; |
| 65 | tabletProxy->setParent(this); | 67 | } else { |
| 66 | _tabletProxies[tabletId] = tabletProxy; | 68 | // tablet must be created |
| 67 | tabletProxy->setToolbarMode(_toolbarMode); | 69 | tabletProxy = new TabletProxy(this, tabletId); |
| 68 | return tabletProxy; | 70 | _tabletProxies[tabletId] = tabletProxy; |
| 71 | } | ||
| 69 | } | 72 | } |
| 73 | |||
| 74 | assert(tabletProxy); | ||
| 75 | // initialize new tablet | ||
| 76 | tabletProxy->setToolbarMode(_toolbarMode); | ||
| 77 | return tabletProxy; | ||
| 70 | } | 78 | } |
| 71 | 79 | ||
| 72 | void TabletScriptingInterface::setToolbarMode(bool toolbarMode) { | 80 | void TabletScriptingInterface::setToolbarMode(bool toolbarMode) { |
| 73 | std::lock_guard<std::mutex> guard(_mutex); | 81 | { |
| 74 | 82 | // the only thing guarded should be _toolbarMode | |
| 75 | _toolbarMode = toolbarMode; | 83 | // this avoids a deadlock with the Main thread |
| 84 | // from Qt::BlockingQueuedEvent invocations later in the call-tree | ||
| 85 | std::lock_guard<std::mutex> guard(_mapMutex); | ||
| 86 | _toolbarMode = toolbarMode; | ||
| 87 | } | ||
| 76 | 88 | ||
| 77 | for (auto& iter : _tabletProxies) { | 89 | for (auto& iter : _tabletProxies) { |
| 78 | iter.second->setToolbarMode(toolbarMode); | 90 | iter.second->setToolbarMode(toolbarMode); |
| @@ -89,8 +101,9 @@ void TabletScriptingInterface::setQmlTabletRoot(QString tabletId, QQuickItem* qm · 10 unmodified lines | |||
| 89 | } | 101 | } |
| 90 | 102 | ||
| 91 | QQuickWindow* TabletScriptingInterface::getTabletWindow() { | 103 | QQuickWindow* TabletScriptingInterface::getTabletWindow() { |
| 92 | TabletProxy* tablet = qobject_cast<TabletProxy*>(getTablet("com.highfidelity.interface.tablet.system")); | 104 | TabletProxy* tablet = qobject_cast<TabletProxy*>(getTablet(SYSTEM_TABLET)); |
| 93 | QObject* qmlSurface = tablet->getTabletSurface(); | 105 | QObject* qmlSurface = tablet->getTabletSurface(); |
| 106 | |||
| 94 | OffscreenQmlSurface* surface = dynamic_cast<OffscreenQmlSurface*>(qmlSurface); | 107 | OffscreenQmlSurface* surface = dynamic_cast<OffscreenQmlSurface*>(qmlSurface); |
| 95 | 108 | ||
| 96 | if (!surface) { | 109 | if (!surface) { |
| @@ -156,7 +169,7 @@ void TabletScriptingInterface::processTabletEvents(QObject* object, const QKeyEv · 59 unmodified lines | |||
| 156 | 169 | ||
| 157 | 170 | ||
| 158 | void TabletScriptingInterface::processEvent(const QKeyEvent* event) { | 171 | void TabletScriptingInterface::processEvent(const QKeyEvent* event) { |
| 159 | TabletProxy* tablet = qobject_cast<TabletProxy*>(getTablet("com.highfidelity.interface.tablet.system")); | 172 | TabletProxy* tablet = qobject_cast<TabletProxy*>(getTablet(SYSTEM_TABLET)); |
| 160 | QObject* qmlTablet = tablet->getQmlTablet(); | 173 | QObject* qmlTablet = tablet->getQmlTablet(); |
| 161 | QObject* qmlMenu = tablet->getQmlMenu(); | 174 | QObject* qmlMenu = tablet->getQmlMenu(); |
| 162 | 175 | ||
| @@ -185,10 +198,12 @@ class TabletRootWindow : public QmlWindowClass { · 22 unmodified lines | |||
| 185 | virtual QString qmlSource() const override { return "hifi/tablet/WindowRoot.qml"; } | 198 | virtual QString qmlSource() const override { return "hifi/tablet/WindowRoot.qml"; } |
| 186 | }; | 199 | }; |
| 187 | 200 | ||
| 188 | TabletProxy::TabletProxy(QString name) : _name(name) { | 201 | TabletProxy::TabletProxy(QObject* parent, QString name) : QObject(parent), _name(name) { |
| 189 | } | 202 | } |
| 190 | 203 | ||
| 191 | void TabletProxy::setToolbarMode(bool toolbarMode) { | 204 | void TabletProxy::setToolbarMode(bool toolbarMode) { |
| 205 | std::lock_guard<std::mutex> guard(_tabletMutex); | ||
| 206 | |||
| 192 | if (toolbarMode == _toolbarMode) { | 207 | if (toolbarMode == _toolbarMode) { |
| 193 | return; | 208 | return; |
| 194 | } | 209 | } |
| @@ -288,7 +303,7 @@ bool TabletProxy::isPathLoaded(QVariant path) { · 93 unmodified lines | |||
| 288 | return path.toString() == _currentPathLoaded.toString(); | 303 | return path.toString() == _currentPathLoaded.toString(); |
| 289 | } | 304 | } |
| 290 | void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) { | 305 | void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) { |
| 291 | std::lock_guard<std::mutex> guard(_mutex); | 306 | std::lock_guard<std::mutex> guard(_tabletMutex); |
| 292 | _qmlOffscreenSurface = qmlOffscreenSurface; | 307 | _qmlOffscreenSurface = qmlOffscreenSurface; |
| 293 | _qmlTabletRoot = qmlTabletRoot; | 308 | _qmlTabletRoot = qmlTabletRoot; |
| 294 | if (_qmlTabletRoot && _qmlOffscreenSurface) { | 309 | if (_qmlTabletRoot && _qmlOffscreenSurface) { |
| @@ -519,7 +534,7 @@ void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaS · 224 unmodified lines | |||
| 519 | 534 | ||
| 520 | QObject* TabletProxy::addButton(const QVariant& properties) { | 535 | QObject* TabletProxy::addButton(const QVariant& properties) { |
| 521 | auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap())); | 536 | auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap())); |
| 522 | std::lock_guard<std::mutex> guard(_mutex); | 537 | std::lock_guard<std::mutex> guard(_tabletMutex); |
| 523 | _tabletButtonProxies.push_back(tabletButtonProxy); | 538 | _tabletButtonProxies.push_back(tabletButtonProxy); |
| 524 | if (!_toolbarMode && _qmlTabletRoot) { | 539 | if (!_toolbarMode && _qmlTabletRoot) { |
| 525 | auto tablet = getQmlTablet(); | 540 | auto tablet = getQmlTablet(); |
| @@ -555,7 +570,7 @@ bool TabletProxy::onHomeScreen() { · 29 unmodified lines | |||
| 555 | } | 570 | } |
| 556 | 571 | ||
| 557 | void TabletProxy::removeButton(QObject* tabletButtonProxy) { | 572 | void TabletProxy::removeButton(QObject* tabletButtonProxy) { |
| 558 | std::lock_guard<std::mutex> guard(_mutex); | 573 | std::lock_guard<std::mutex> guard(_tabletMutex); |
| 559 | 574 | ||
| 560 | auto tablet = getQmlTablet(); | 575 | auto tablet = getQmlTablet(); |
| 561 | if (!tablet) { | 576 | if (!tablet) { |
| @@ -743,12 +758,12 @@ TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) : · 181 unmodified lines | |||
| 743 | } | 758 | } |
| 744 | 759 | ||
| 745 | void TabletButtonProxy::setQmlButton(QQuickItem* qmlButton) { | 760 | void TabletButtonProxy::setQmlButton(QQuickItem* qmlButton) { |
| 746 | std::lock_guard<std::mutex> guard(_mutex); | 761 | std::lock_guard<std::mutex> guard(_buttonMutex); |
| 747 | _qmlButton = qmlButton; | 762 | _qmlButton = qmlButton; |
| 748 | } | 763 | } |
| 749 | 764 | ||
| 750 | void TabletButtonProxy::setToolbarButtonProxy(QObject* toolbarButtonProxy) { | 765 | void TabletButtonProxy::setToolbarButtonProxy(QObject* toolbarButtonProxy) { |
| 751 | std::lock_guard<std::mutex> guard(_mutex); | 766 | std::lock_guard<std::mutex> guard(_buttonMutex); |
| 752 | _toolbarButtonProxy = toolbarButtonProxy; | 767 | _toolbarButtonProxy = toolbarButtonProxy; |
| 753 | if (_toolbarButtonProxy) { | 768 | if (_toolbarButtonProxy) { |
| 754 | QObject::connect(_toolbarButtonProxy, SIGNAL(clicked()), this, SLOT(clickedSlot())); | 769 | QObject::connect(_toolbarButtonProxy, SIGNAL(clicked()), this, SLOT(clickedSlot())); |
| @@ -756,12 +771,12 @@ void TabletButtonProxy::setToolbarButtonProxy(QObject* toolbarButtonProxy) { · 1 unmodified line | |||
| 756 | } | 771 | } |
| 757 | 772 | ||
| 758 | QVariantMap TabletButtonProxy::getProperties() const { | 773 | QVariantMap TabletButtonProxy::getProperties() const { |
| 759 | std::lock_guard<std::mutex> guard(_mutex); | 774 | std::lock_guard<std::mutex> guard(_buttonMutex); |
| 760 | return _properties; | 775 | return _properties; |
| 761 | } | 776 | } |
| 762 | 777 | ||
| 763 | void TabletButtonProxy::editProperties(QVariantMap properties) { | 778 | void TabletButtonProxy::editProperties(QVariantMap properties) { |
| 764 | std::lock_guard<std::mutex> guard(_mutex); | 779 | std::lock_guard<std::mutex> guard(_buttonMutex); |
| 765 | 780 | ||
| 766 | QVariantMap::const_iterator iter = properties.constBegin(); | 781 | QVariantMap::const_iterator iter = properties.constBegin(); |
| 767 | while (iter != properties.constEnd()) { | 782 | while (iter != properties.constEnd()) { |