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; return nullptr;
} }
_qmlEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
newObject->setProperty("eventBridge", QVariant::fromValue(this)); newObject->setProperty("eventBridge", QVariant::fromValue(this));
newContext->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject)); newContext->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject));
f(newContext, newObject); 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 return; // bail early - avoid setting state in init(), as evaluate() will bail too
} }
scriptInfoMessage("Script Engine starting:" + getFilename());
if (!_isInitialized) { if (!_isInitialized) {
init(); init();
} }

View file

@ -201,7 +201,7 @@ void TabletProxy::setToolbarMode(bool toolbarMode) {
QObject::connect(quickItem, SIGNAL(windowClosed()), this, SLOT(desktopWindowClosed())); 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 // forward qml surface events to interface js
connect(tabletRootWindow, &QmlWindowClass::fromQml, this, &TabletProxy::fromQml); connect(tabletRootWindow, &QmlWindowClass::fromQml, this, &TabletProxy::fromQml);
@ -271,12 +271,17 @@ bool TabletProxy::isMessageDialogOpen() {
return false; return false;
} }
void TabletProxy::emitWebEvent(QVariant msg) {
emit webEventReceived(msg);
}
void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) { void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface) {
std::lock_guard<std::mutex> guard(_mutex); std::lock_guard<std::mutex> guard(_mutex);
_qmlOffscreenSurface = qmlOffscreenSurface; _qmlOffscreenSurface = qmlOffscreenSurface;
_qmlTabletRoot = qmlTabletRoot; _qmlTabletRoot = qmlTabletRoot;
if (_qmlTabletRoot && _qmlOffscreenSurface) { 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 // forward qml surface events to interface js
connect(dynamic_cast<OffscreenQmlSurface*>(_qmlOffscreenSurface), &OffscreenQmlSurface::fromQml, [this](QVariant message) { connect(dynamic_cast<OffscreenQmlSurface*>(_qmlOffscreenSurface), &OffscreenQmlSurface::fromQml, [this](QVariant message) {
@ -705,4 +710,3 @@ void TabletButtonProxy::editProperties(QVariantMap properties) {
} }
#include "TabletScriptingInterface.moc" #include "TabletScriptingInterface.moc"

View file

@ -209,6 +209,7 @@ signals:
protected slots: protected slots:
void addButtonsToHomeScreen(); void addButtonsToHomeScreen();
void desktopWindowClosed(); void desktopWindowClosed();
void emitWebEvent(QVariant msg);
protected: protected:
void removeButtonsFromHomeScreen(); void removeButtonsFromHomeScreen();
void loadHomeScreen(bool forceOntoHomeScreen); void loadHomeScreen(bool forceOntoHomeScreen);

View file

@ -16,66 +16,92 @@
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var tabletButton = tablet.addButton({ 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 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 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 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 () { tabletButton.clicked.connect(function () {
if (shown) {
tablet.gotoHomeScreen();
} else {
tablet.gotoWebScreen(WEB_BRIDGE_TEST_HTML); tablet.gotoWebScreen(WEB_BRIDGE_TEST_HTML);
}
}); });
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 // hook up to the event bridge
tablet.webEventReceived.connect(function (msg) { 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)); Script.print("HIFI: recv web event = " + JSON.stringify(msg));
if (msg === "button-1-play") { if (msg === "button-1-play") {
soundOptions.position = MyAvatar.position;
// play sad trombone tromboneSound.play(soundOptions, function () {
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 () {
tablet.emitScriptEvent("button-1-done"); 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 () {
tablet.emitScriptEvent("button-2-done");
}, 1000);
}
}); });
} else if (msg === "button-2-play") {
soundOptions.position = MyAvatar.position;
screamSound.play(soundOptions, function () {
tablet.emitScriptEvent("button-2-done");
});
}
}
Script.scriptEnding.connect(function () { Script.scriptEnding.connect(function () {
tablet.removeButton(tabletButton); tablet.removeButton(tabletButton);
if (shown) {
tablet.webEventReceived.disconnect(onWebEventReceived);
}
}); });

View file

@ -271,6 +271,13 @@
} }
Script.scriptEnding.connect(function () { 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; var tabletID = HMD.tabletID;
Entities.deleteEntity(tabletID); Entities.deleteEntity(tabletID);
Overlays.deleteOverlay(tabletID) Overlays.deleteOverlay(tabletID)