History

decouple initialization from storage in Table.getTablet()

Zach Pomerantz committed 9 years ago

Commit 03539401 parent 53021102 files · +48 −33Browse files

Showing the changes to libraries/script-engine/src/TabletScriptingInterface.cpp (1 of 2 files). Show all

Unified · Split

libraries/script-engine/src/TabletScriptingInterface.cpp+44−29
@@ -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
24const QString SYSTEM_TOOLBAR = "com.highfidelity.interface.toolbar.system";
25const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system";
24 26
25QScriptValue tabletToScriptValue(QScriptEngine* engine, TabletProxy* const &in) {27QScriptValue 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
37QObject* TabletScriptingInterface::getSystemToolbarProxy() {39QObject* 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
53TabletProxy* TabletScriptingInterface::getTablet(const QString& tabletId) {55TabletProxy* 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
72void TabletScriptingInterface::setToolbarMode(bool toolbarMode) {80void 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
91QQuickWindow* TabletScriptingInterface::getTabletWindow() {103QQuickWindow* 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
158void TabletScriptingInterface::processEvent(const QKeyEvent* event) {171void 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
188TabletProxy::TabletProxy(QString name) : _name(name) {201TabletProxy::TabletProxy(QObject* parent, QString name) : QObject(parent), _name(name) {
189}202}
190 203
191void TabletProxy::setToolbarMode(bool toolbarMode) {204void 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}
290void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) {305void 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
520QObject* TabletProxy::addButton(const QVariant& properties) {535QObject* 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
557void TabletProxy::removeButton(QObject* tabletButtonProxy) {572void 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
745void TabletButtonProxy::setQmlButton(QQuickItem* qmlButton) {760void 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
750void TabletButtonProxy::setToolbarButtonProxy(QObject* toolbarButtonProxy) {765void 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
758QVariantMap TabletButtonProxy::getProperties() const {773QVariantMap 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
763void TabletButtonProxy::editProperties(QVariantMap properties) {778void 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()) {