Fix broken eventBridge on tablet after Reload All Scripts.

The main issue here was the "webEventReceived" connection between the OffscreenQMLSurface and the TabletProxy object.
For whatever reason, if this is not a direct Signal to Slot connection, the webEventReceived event does not propagate.
This commit is contained in:
Anthony J. Thibault 2017-04-03 16:03:55 -07:00
parent 76ef2b5d9f
commit 8ff457a1b6
6 changed files with 92 additions and 50 deletions

View file

@ -576,7 +576,9 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::function<void(QQmlContext*, QOb
return nullptr;
}
_qmlEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
newObject->setProperty("eventBridge", QVariant::fromValue(this));
newContext->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject));
f(newContext, newObject);

View file

@ -974,6 +974,8 @@ void ScriptEngine::run() {
return; // bail early - avoid setting state in init(), as evaluate() will bail too
}
scriptInfoMessage("Script Engine starting:" + getFilename());
if (!_isInitialized) {
init();
}

View file

@ -201,7 +201,7 @@ void TabletProxy::setToolbarMode(bool toolbarMode) {
QObject::connect(quickItem, SIGNAL(windowClosed()), this, SLOT(desktopWindowClosed()));
QObject::connect(tabletRootWindow, SIGNAL(webEventReceived(QVariant)), this, SIGNAL(webEventReceived(QVariant)));
QObject::connect(tabletRootWindow, SIGNAL(webEventReceived(QVariant)), this, SLOT(emitWebEvent(QVariant)), Qt::DirectConnection);
// forward qml surface events to interface js
connect(tabletRootWindow, &QmlWindowClass::fromQml, this, &TabletProxy::fromQml);
@ -271,12 +271,17 @@ bool TabletProxy::isMessageDialogOpen() {
return false;
}
void TabletProxy::emitWebEvent(QVariant msg) {
emit webEventReceived(msg);
}
void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) {
std::lock_guard<std::mutex> guard(_mutex);
_qmlOffscreenSurface = qmlOffscreenSurface;
_qmlTabletRoot = qmlTabletRoot;
if (_qmlTabletRoot && _qmlOffscreenSurface) {
QObject::connect(_qmlOffscreenSurface, SIGNAL(webEventReceived(QVariant)), this, SIGNAL(webEventReceived(QVariant)));
QObject::connect(_qmlOffscreenSurface, SIGNAL(webEventReceived(QVariant)), this, SLOT(emitWebEvent(QVariant)), Qt::DirectConnection);
// forward qml surface events to interface js
connect(dynamic_cast<OffscreenQmlSurface*>(_qmlOffscreenSurface), &OffscreenQmlSurface::fromQml, [this](QVariant message) {
@ -398,7 +403,7 @@ void TabletProxy::popFromStack() {
auto stack = _desktopWindow->asQuickItem()->findChild<QQuickItem*>("stack");
if (stack) {
QMetaObject::invokeMethod(stack, "popSource");
} else {
} else {
qCDebug(scriptengine) << "tablet cannot pop QML because _desktopWindow doesn't have child stack";
}
} else {
@ -705,4 +710,3 @@ void TabletButtonProxy::editProperties(QVariantMap properties) {
}
#include "TabletScriptingInterface.moc"

View file

@ -63,7 +63,7 @@ signals:
* @returns {Signal}
*/
void tabletNotification();
private:
void processMenuEvents(QObject* object, const QKeyEvent* event);
void processTabletEvents(QObject* object, const QKeyEvent* event);
@ -209,6 +209,7 @@ signals:
protected slots:
void addButtonsToHomeScreen();
void desktopWindowClosed();
void emitWebEvent(QVariant msg);
protected:
void removeButtonsFromHomeScreen();
void loadHomeScreen(bool forceOntoHomeScreen);
@ -216,7 +217,7 @@ protected:
void removeButtonsFromToolbar();
bool _initialScreen { false };
QVariant _initialPath { "" };
QVariant _initialPath { "" };
QString _name;
std::mutex _mutex;
std::vector<QSharedPointer<TabletButtonProxy>> _tabletButtonProxies;

View file

@ -16,66 +16,92 @@
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var tabletButton = tablet.addButton({
text: "SOUNDS"
text: "SOUNDS",
icon: "http://s3.amazonaws.com/hifi-public/tony/icons/trombone-i.png",
activeIcon: "http://s3.amazonaws.com/hifi-public/tony/icons/trombone-a.png"
});
var WEB_BRIDGE_TEST_HTML = "https://s3.amazonaws.com/hifi-public/tony/webBridgeTest.html?2";
var TROMBONE_URL = "https://s3.amazonaws.com/hifi-public/tony/audio/sad-trombone.wav";
var tromboneSound = SoundCache.getSound(TROMBONE_URL);
var tromboneInjector;
var SCREAM_URL = "https://s3.amazonaws.com/hifi-public/tony/audio/wilhelm-scream.wav";
var screamSound = SoundCache.getSound(SCREAM_URL);
var screamInjector;
tabletButton.clicked.connect(function () {
tablet.gotoWebScreen(WEB_BRIDGE_TEST_HTML);
if (shown) {
tablet.gotoHomeScreen();
} else {
tablet.gotoWebScreen(WEB_BRIDGE_TEST_HTML);
}
});
// hook up to the event bridge
tablet.webEventReceived.connect(function (msg) {
var shown = false;
function onScreenChanged(type, url) {
if (type === "Web" && url === WEB_BRIDGE_TEST_HTML) {
tabletButton.editProperties({isActive: true});
if (!shown) {
// hook up to the event bridge
tablet.webEventReceived.connect(onWebEventReceived);
}
shown = true;
} else {
tabletButton.editProperties({isActive: false});
if (shown) {
// disconnect from the event bridge
tablet.webEventReceived.disconnect(onWebEventReceived);
}
shown = false;
}
}
tablet.screenChanged.connect(onScreenChanged);
// ctor
function SoundBuddy(url) {
this.sound = SoundCache.getSound(url);
this.injector = null;
}
SoundBuddy.prototype.play = function (options, doneCallback) {
if (this.sound.downloaded) {
if (this.injector) {
this.injector.setOptions(options);
this.injector.restart();
} else {
this.injector = Audio.playSound(this.sound, options);
this.injector.finished.connect(function () {
if (doneCallback) {
doneCallback();
}
});
}
}
};
var tromboneSound = new SoundBuddy(TROMBONE_URL);
var screamSound = new SoundBuddy(SCREAM_URL);
var soundOptions = { position: MyAvatar.position, volume: 1.0, loop: false, localOnly: true };
function onWebEventReceived(msg) {
Script.print("HIFI: recv web event = " + JSON.stringify(msg));
if (msg === "button-1-play") {
// play sad trombone
if (tromboneSound.downloaded) {
if (tromboneInjector) {
tromboneInjector.restart();
} else {
tromboneInjector = Audio.playSound(tromboneSound, { position: MyAvatar.position,
volume: 1.0,
loop: false });
}
}
// wait until sound is finished then send a done event
Script.setTimeout(function () {
soundOptions.position = MyAvatar.position;
tromboneSound.play(soundOptions, function () {
tablet.emitScriptEvent("button-1-done");
}, 3500);
}
if (msg === "button-2-play") {
// play scream
if (screamSound.downloaded) {
if (screamInjector) {
screamInjector.restart();
} else {
screamInjector = Audio.playSound(screamSound, { position: MyAvatar.position,
volume: 1.0,
loop: false });
}
}
// wait until sound is finished then send a done event
Script.setTimeout(function () {
});
} else if (msg === "button-2-play") {
soundOptions.position = MyAvatar.position;
screamSound.play(soundOptions, function () {
tablet.emitScriptEvent("button-2-done");
}, 1000);
});
}
});
}
Script.scriptEnding.connect(function () {
tablet.removeButton(tabletButton);
if (shown) {
tablet.webEventReceived.disconnect(onWebEventReceived);
}
});

View file

@ -271,6 +271,13 @@
}
Script.scriptEnding.connect(function () {
// if we reload scripts in tablet mode make sure we close the currently open window, by calling gotoHomeScreen
var tabletProxy = Tablet.getTablet("com.highfidelity.interface.tablet.system");
if (tabletProxy && tabletProxy.toolbarMode) {
tabletProxy.gotoHomeScreen();
}
var tabletID = HMD.tabletID;
Entities.deleteEntity(tabletID);
Overlays.deleteOverlay(tabletID)