mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-09 19:12:15 +02:00
commit
a5e671e0fd
5 changed files with 81 additions and 56 deletions
|
@ -65,21 +65,23 @@ var EventBridge;
|
|||
// we need to listen to events that might precede the addition of this elements.
|
||||
// A more robust hack will be to add a setInterval that look for DOM changes every 100-300 ms (low performance?)
|
||||
|
||||
window.onload = function(){
|
||||
window.addEventListener("load",function(event) {
|
||||
setTimeout(function() {
|
||||
EventBridge.forceHtmlAudioOutputDeviceUpdate();
|
||||
}, 1200);
|
||||
};
|
||||
document.onclick = function(){
|
||||
}, false);
|
||||
|
||||
document.addEventListener("click",function(){
|
||||
setTimeout(function() {
|
||||
EventBridge.forceHtmlAudioOutputDeviceUpdate();
|
||||
}, 1200);
|
||||
};
|
||||
document.onchange = function(){
|
||||
}, false);
|
||||
|
||||
document.addEventListener("change",function(){
|
||||
setTimeout(function() {
|
||||
EventBridge.forceHtmlAudioOutputDeviceUpdate();
|
||||
}, 1200);
|
||||
};
|
||||
}, false);
|
||||
|
||||
tempEventBridge._callbacks.forEach(function (callback) {
|
||||
EventBridge.scriptEventReceived.connect(callback);
|
||||
|
|
|
@ -121,63 +121,58 @@ uint64_t uvec2ToUint64(const uvec2& v) {
|
|||
class AudioHandler : public QObject, QRunnable {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioHandler(QObject* container, const QString& deviceName, int runDelayMs = 0, QObject* parent = nullptr) : QObject(parent) {
|
||||
_container = container;
|
||||
AudioHandler(QSharedPointer<OffscreenQmlSurface> surface, const QString& deviceName, QObject* parent = nullptr) : QObject(parent) {
|
||||
_newTargetDevice = deviceName;
|
||||
_runDelayMs = runDelayMs;
|
||||
_surface = surface;
|
||||
setAutoDelete(true);
|
||||
QThreadPool::globalInstance()->start(this);
|
||||
if (deviceName.size() > 0) {
|
||||
QThreadPool::globalInstance()->start(this);
|
||||
}
|
||||
}
|
||||
virtual ~AudioHandler() {
|
||||
qDebug() << "Audio Handler Destroyed";
|
||||
}
|
||||
void run() override {
|
||||
if (_newTargetDevice.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (_runDelayMs > 0) {
|
||||
QThread::msleep(_runDelayMs);
|
||||
}
|
||||
auto audioIO = DependencyManager::get<AudioClient>();
|
||||
QString deviceName = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName();
|
||||
for (auto player : _container->findChildren<QMediaPlayer*>()) {
|
||||
auto mediaState = player->state();
|
||||
QMediaService *svc = player->service();
|
||||
if (nullptr == svc) {
|
||||
return;
|
||||
}
|
||||
QAudioOutputSelectorControl *out = qobject_cast<QAudioOutputSelectorControl *>
|
||||
(svc->requestControl(QAudioOutputSelectorControl_iid));
|
||||
if (nullptr == out) {
|
||||
return;
|
||||
}
|
||||
QString deviceOuput;
|
||||
auto outputs = out->availableOutputs();
|
||||
for (int i = 0; i < outputs.size(); i++) {
|
||||
QString output = outputs[i];
|
||||
QString description = out->outputDescription(output);
|
||||
if (description == deviceName) {
|
||||
deviceOuput = output;
|
||||
break;
|
||||
if (!_surface.isNull() && _surface->getRootItem() && !_surface->getCleaned()) {
|
||||
for (auto player : _surface->getRootItem()->findChildren<QMediaPlayer*>()) {
|
||||
auto mediaState = player->state();
|
||||
QMediaService *svc = player->service();
|
||||
if (nullptr == svc) {
|
||||
return;
|
||||
}
|
||||
QAudioOutputSelectorControl *out = qobject_cast<QAudioOutputSelectorControl *>
|
||||
(svc->requestControl(QAudioOutputSelectorControl_iid));
|
||||
if (nullptr == out) {
|
||||
return;
|
||||
}
|
||||
QString deviceOuput;
|
||||
auto outputs = out->availableOutputs();
|
||||
for (int i = 0; i < outputs.size(); i++) {
|
||||
QString output = outputs[i];
|
||||
QString description = out->outputDescription(output);
|
||||
if (description == _newTargetDevice) {
|
||||
deviceOuput = output;
|
||||
break;
|
||||
}
|
||||
}
|
||||
out->setActiveOutput(deviceOuput);
|
||||
svc->releaseControl(out);
|
||||
// if multimedia was paused, it will start playing automatically after changing audio device
|
||||
// this will reset it back to a paused state
|
||||
if (mediaState == QMediaPlayer::State::PausedState) {
|
||||
player->pause();
|
||||
}
|
||||
else if (mediaState == QMediaPlayer::State::StoppedState) {
|
||||
player->stop();
|
||||
}
|
||||
}
|
||||
out->setActiveOutput(deviceOuput);
|
||||
svc->releaseControl(out);
|
||||
// if multimedia was paused, it will start playing automatically after changing audio device
|
||||
// this will reset it back to a paused state
|
||||
if (mediaState == QMediaPlayer::State::PausedState) {
|
||||
player->pause();
|
||||
} else if (mediaState == QMediaPlayer::State::StoppedState) {
|
||||
player->stop();
|
||||
}
|
||||
}
|
||||
qDebug() << "QML Audio changed to " << deviceName;
|
||||
qDebug() << "QML Audio changed to " << _newTargetDevice;
|
||||
}
|
||||
|
||||
private:
|
||||
QString _newTargetDevice;
|
||||
QObject* _container;
|
||||
int _runDelayMs;
|
||||
QSharedPointer<OffscreenQmlSurface> _surface;
|
||||
};
|
||||
|
||||
class OffscreenTextures {
|
||||
|
@ -502,6 +497,7 @@ QOpenGLContext* OffscreenQmlSurface::getSharedContext() {
|
|||
}
|
||||
|
||||
void OffscreenQmlSurface::cleanup() {
|
||||
_isCleaned = true;
|
||||
_canvas->makeCurrent();
|
||||
|
||||
_renderControl->invalidate();
|
||||
|
@ -600,6 +596,7 @@ OffscreenQmlSurface::OffscreenQmlSurface() {
|
|||
|
||||
OffscreenQmlSurface::~OffscreenQmlSurface() {
|
||||
QObject::disconnect(&_updateTimer);
|
||||
disconnectAudioOutputTimer();
|
||||
QObject::disconnect(qApp);
|
||||
|
||||
cleanup();
|
||||
|
@ -613,6 +610,15 @@ OffscreenQmlSurface::~OffscreenQmlSurface() {
|
|||
void OffscreenQmlSurface::onAboutToQuit() {
|
||||
_paused = true;
|
||||
QObject::disconnect(&_updateTimer);
|
||||
disconnectAudioOutputTimer();
|
||||
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::disconnectAudioOutputTimer() {
|
||||
if (_audioOutputUpdateTimer.isActive()) {
|
||||
_audioOutputUpdateTimer.stop();
|
||||
}
|
||||
QObject::disconnect(&_audioOutputUpdateTimer);
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::create() {
|
||||
|
@ -671,6 +677,14 @@ void OffscreenQmlSurface::create() {
|
|||
}
|
||||
});
|
||||
|
||||
// Setup the update of the QML media components with the current audio output device
|
||||
QObject::connect(&_audioOutputUpdateTimer, &QTimer::timeout, this, [this]() {
|
||||
new AudioHandler(sharedFromThis(), _currentAudioOutputDevice);
|
||||
});
|
||||
int waitForAudioQmlMs = 200;
|
||||
_audioOutputUpdateTimer.setInterval(waitForAudioQmlMs);
|
||||
_audioOutputUpdateTimer.setSingleShot(true);
|
||||
|
||||
// When Quick says there is a need to render, we will not render immediately. Instead,
|
||||
// a timer with a small interval is used to get better performance.
|
||||
QObject::connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
|
||||
|
@ -699,10 +713,11 @@ void OffscreenQmlSurface::forceQmlAudioOutputDeviceUpdate() {
|
|||
QMetaObject::invokeMethod(this, "forceQmlAudioOutputDeviceUpdate", Qt::QueuedConnection);
|
||||
} else {
|
||||
auto audioIO = DependencyManager::get<AudioClient>();
|
||||
QString deviceName = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName();
|
||||
int waitForAudioQmlMs = 500;
|
||||
// The audio device need to be change using oth
|
||||
new AudioHandler(_rootItem, deviceName, waitForAudioQmlMs);
|
||||
_currentAudioOutputDevice = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName();
|
||||
if (_audioOutputUpdateTimer.isActive()) {
|
||||
_audioOutputUpdateTimer.stop();
|
||||
}
|
||||
_audioOutputUpdateTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class QQuickItem;
|
|||
|
||||
using QmlContextCallback = std::function<void(QQmlContext*, QObject*)>;
|
||||
|
||||
class OffscreenQmlSurface : public QObject {
|
||||
class OffscreenQmlSurface : public QObject, public QEnableSharedFromThis<OffscreenQmlSurface> {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool focusText READ isFocusText NOTIFY focusTextChanged)
|
||||
public:
|
||||
|
@ -75,6 +75,7 @@ public:
|
|||
void pause();
|
||||
void resume();
|
||||
bool isPaused() const;
|
||||
bool getCleaned() { return _isCleaned; }
|
||||
|
||||
void setBaseUrl(const QUrl& baseUrl);
|
||||
QQuickItem* getRootItem();
|
||||
|
@ -116,6 +117,7 @@ public slots:
|
|||
void changeAudioOutputDevice(const QString& deviceName, bool isHtmlUpdate = false);
|
||||
void forceHtmlAudioOutputDeviceUpdate();
|
||||
void forceQmlAudioOutputDeviceUpdate();
|
||||
|
||||
signals:
|
||||
void audioOutputDeviceChanged(const QString& deviceName);
|
||||
|
||||
|
@ -147,6 +149,7 @@ private:
|
|||
void render();
|
||||
void cleanup();
|
||||
QJsonObject getGLContextData();
|
||||
void disconnectAudioOutputTimer();
|
||||
|
||||
private slots:
|
||||
void updateQuick();
|
||||
|
@ -170,6 +173,9 @@ private:
|
|||
uint64_t _lastRenderTime { 0 };
|
||||
uvec2 _size;
|
||||
|
||||
QTimer _audioOutputUpdateTimer;
|
||||
QString _currentAudioOutputDevice;
|
||||
|
||||
// Texture management
|
||||
TextureAndFence _latestTextureAndFence { 0, 0 };
|
||||
|
||||
|
@ -177,6 +183,7 @@ private:
|
|||
bool _polish { true };
|
||||
bool _paused { true };
|
||||
bool _focusText { false };
|
||||
bool _isCleaned{ false };
|
||||
uint8_t _maxFps { 60 };
|
||||
MouseTranslator _mouseTranslator { [](const QPointF& p) { return p.toPoint(); } };
|
||||
QWindow* _proxyWindow { nullptr };
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
this.pointingAtTablet = function(controllerData) {
|
||||
var rayPick = controllerData.rayPicks[this.hand];
|
||||
return (rayPick.objectID === HMD.tabletScreenID || rayPick.objectID === HMD.homeButtonID);
|
||||
return (HMD.tabletScreenID && HMD.homeButtonID && (rayPick.objectID === HMD.tabletScreenID || rayPick.objectID === HMD.homeButtonID));
|
||||
};
|
||||
|
||||
this.getOtherModule = function() {
|
||||
|
|
|
@ -81,7 +81,8 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
};
|
||||
|
||||
this.otherHandIsParent = function(props) {
|
||||
return this.getOtherModule().thisHandIsParent(props);
|
||||
var otherModule = this.getOtherModule();
|
||||
return (otherModule.thisHandIsParent(props) && otherModule.grabbing);
|
||||
};
|
||||
|
||||
this.startNearParentingGrabEntity = function (controllerData, targetProps) {
|
||||
|
|
Loading…
Reference in a new issue