mirror of
https://github.com/lubosz/overte.git
synced 2025-08-08 04:08:13 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into betterAway
This commit is contained in:
commit
8e1ea5c57d
5 changed files with 150 additions and 67 deletions
|
@ -545,6 +545,10 @@ QObject* OffscreenQmlSurface::load(const QUrl& qmlSource, std::function<void(QQm
|
||||||
return finishQmlLoad(f);
|
return finishQmlLoad(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::clearCache() {
|
||||||
|
getRootContext()->engine()->clearComponentCache();
|
||||||
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::requestUpdate() {
|
void OffscreenQmlSurface::requestUpdate() {
|
||||||
_polish = true;
|
_polish = true;
|
||||||
_render = true;
|
_render = true;
|
||||||
|
|
|
@ -40,10 +40,12 @@ public:
|
||||||
virtual void create(QOpenGLContext* context);
|
virtual void create(QOpenGLContext* context);
|
||||||
void resize(const QSize& size, bool forceResize = false);
|
void resize(const QSize& size, bool forceResize = false);
|
||||||
QSize size() const;
|
QSize size() const;
|
||||||
|
|
||||||
Q_INVOKABLE QObject* load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {});
|
Q_INVOKABLE QObject* load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {});
|
||||||
Q_INVOKABLE QObject* load(const QString& qmlSourceFile, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {}) {
|
Q_INVOKABLE QObject* load(const QString& qmlSourceFile, std::function<void(QQmlContext*, QObject*)> f = [](QQmlContext*, QObject*) {}) {
|
||||||
return load(QUrl(qmlSourceFile), f);
|
return load(QUrl(qmlSourceFile), f);
|
||||||
}
|
}
|
||||||
|
void clearCache();
|
||||||
|
|
||||||
Q_INVOKABLE void executeOnUiThread(std::function<void()> function, bool blocking = false);
|
Q_INVOKABLE void executeOnUiThread(std::function<void()> function, bool blocking = false);
|
||||||
Q_INVOKABLE QVariant returnFromUiThread(std::function<QVariant()> function);
|
Q_INVOKABLE QVariant returnFromUiThread(std::function<QVariant()> function);
|
||||||
|
|
|
@ -17,3 +17,5 @@ if (NOT ANDROID)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
link_hifi_libraries(shared networking octree gpu ui procedural model model-networking recording avatars fbx entities controllers animation audio physics)
|
link_hifi_libraries(shared networking octree gpu ui procedural model model-networking recording avatars fbx entities controllers animation audio physics)
|
||||||
|
# ui includes gl, but link_hifi_libraries does not use transitive includes, so gl must be explicit
|
||||||
|
include_hifi_library_headers(gl)
|
|
@ -16,6 +16,8 @@
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
|
||||||
|
#include <OffscreenUi.h>
|
||||||
|
|
||||||
#include "ScriptEngine.h"
|
#include "ScriptEngine.h"
|
||||||
#include "ScriptEngineLogging.h"
|
#include "ScriptEngineLogging.h"
|
||||||
|
|
||||||
|
@ -367,28 +369,21 @@ QStringList ScriptEngines::getRunningScripts() {
|
||||||
|
|
||||||
void ScriptEngines::stopAllScripts(bool restart) {
|
void ScriptEngines::stopAllScripts(bool restart) {
|
||||||
QReadLocker lock(&_scriptEnginesHashLock);
|
QReadLocker lock(&_scriptEnginesHashLock);
|
||||||
if (restart) {
|
|
||||||
// Delete all running scripts from cache so that they are re-downloaded when they are restarted
|
|
||||||
auto scriptCache = DependencyManager::get<ScriptCache>();
|
|
||||||
for (QHash<QUrl, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
|
|
||||||
it != _scriptEnginesHash.constEnd(); it++) {
|
|
||||||
if (!it.value()->isFinished()) {
|
|
||||||
scriptCache->deleteScript(it.key());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop and possibly restart all currently running scripts
|
|
||||||
for (QHash<QUrl, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
|
for (QHash<QUrl, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
|
||||||
it != _scriptEnginesHash.constEnd(); it++) {
|
it != _scriptEnginesHash.constEnd(); it++) {
|
||||||
|
// skip already stopped scripts
|
||||||
if (it.value()->isFinished() || it.value()->isStopping()) {
|
if (it.value()->isFinished() || it.value()->isStopping()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// queue user scripts if restarting
|
||||||
if (restart && it.value()->isUserLoaded()) {
|
if (restart && it.value()->isUserLoaded()) {
|
||||||
connect(it.value(), &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) {
|
connect(it.value(), &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) {
|
||||||
reloadScript(scriptName);
|
reloadScript(scriptName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stop all scripts
|
||||||
it.value()->stop(true);
|
it.value()->stop(true);
|
||||||
qCDebug(scriptengine) << "stopping script..." << it.key();
|
qCDebug(scriptengine) << "stopping script..." << it.key();
|
||||||
}
|
}
|
||||||
|
@ -431,6 +426,7 @@ void ScriptEngines::setScriptsLocation(const QString& scriptsLocation) {
|
||||||
|
|
||||||
void ScriptEngines::reloadAllScripts() {
|
void ScriptEngines::reloadAllScripts() {
|
||||||
DependencyManager::get<ScriptCache>()->clearCache();
|
DependencyManager::get<ScriptCache>()->clearCache();
|
||||||
|
DependencyManager::get<OffscreenUi>()->clearCache();
|
||||||
emit scriptsReloading();
|
emit scriptsReloading();
|
||||||
stopAllScripts(true);
|
stopAllScripts(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ const appIcon = path.join(__dirname, '../resources/console.png');
|
||||||
const DELETE_LOG_FILES_OLDER_THAN_X_SECONDS = 60 * 60 * 24 * 7; // 7 Days
|
const DELETE_LOG_FILES_OLDER_THAN_X_SECONDS = 60 * 60 * 24 * 7; // 7 Days
|
||||||
const LOG_FILE_REGEX = /(domain-server|ac-monitor|ac)-.*-std(out|err).txt/;
|
const LOG_FILE_REGEX = /(domain-server|ac-monitor|ac)-.*-std(out|err).txt/;
|
||||||
|
|
||||||
|
const HOME_CONTENT_URL = "http://cachefly.highfidelity.com/home.tgz";
|
||||||
|
|
||||||
function getBuildInfo() {
|
function getBuildInfo() {
|
||||||
var buildInfoPath = null;
|
var buildInfoPath = null;
|
||||||
|
|
||||||
|
@ -486,6 +488,76 @@ function updateTrayMenu(serverState) {
|
||||||
|
|
||||||
const httpStatusPort = 60332;
|
const httpStatusPort = 60332;
|
||||||
|
|
||||||
|
function deleteResourceDirectories() {
|
||||||
|
const dsResourceDirectory = getDomainServerClientResourcesDirectory();
|
||||||
|
try {
|
||||||
|
fs.removeSync(dsResourceDirectory);
|
||||||
|
console.log("Deleted directory " + dsResourceDirectory);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
const acResourceDirectory = getAssignmentClientResourcesDirectory();
|
||||||
|
try {
|
||||||
|
fs.removeSync(acResourceDirectory);
|
||||||
|
console.log("Deleted directory " + acResourceDirectory);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteResourceDirectoriesAndRestart() {
|
||||||
|
homeServer.stop();
|
||||||
|
deleteResourceDirectories();
|
||||||
|
maybeInstallDefaultContentSet(onContentLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkNewContent() {
|
||||||
|
// Start downloading content set
|
||||||
|
var req = request.head({
|
||||||
|
url: HOME_CONTENT_URL
|
||||||
|
}, function (error, response, body) {
|
||||||
|
if (error === null) {
|
||||||
|
var localContent = Date.parse(userConfig.get('homeContentLastModified'));
|
||||||
|
var remoteContent = Date.parse(response.headers['last-modified']);
|
||||||
|
|
||||||
|
var shouldUpdate = isNaN(localContent) || (!isNaN(remoteContent) && (remoteContent > localContent));
|
||||||
|
|
||||||
|
var wantDebug = false;
|
||||||
|
if (wantDebug) {
|
||||||
|
console.log('Last Modified: ' + response.headers['last-modified']);
|
||||||
|
console.log(localContent + " " + remoteContent + " " + shouldUpdate + " " + new Date());
|
||||||
|
console.log("Remote content is " + (shouldUpdate ? "newer" : "older") + " that local content.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldUpdate) {
|
||||||
|
dialog.showMessageBox({
|
||||||
|
type: 'question',
|
||||||
|
buttons: ['Yes', 'No'],
|
||||||
|
title: 'New home content',
|
||||||
|
message: 'A newer version of the home content set is available.\nDo you wish to update?'
|
||||||
|
}, function(idx) {
|
||||||
|
if (idx === 0) {
|
||||||
|
dialog.showMessageBox({
|
||||||
|
type: 'question',
|
||||||
|
buttons: ['Yes', 'No'],
|
||||||
|
title: 'Are you sure?',
|
||||||
|
message: 'This action will delete your current sandbox content.\nDo you wish to continue?'
|
||||||
|
}, function(idx) {
|
||||||
|
if (idx === 0 && homeServer) {
|
||||||
|
deleteResourceDirectoriesAndRestart();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// They don't want to update, mark content set as current
|
||||||
|
userConfig.set('homeContentLastModified', new Date());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function maybeInstallDefaultContentSet(onComplete) {
|
function maybeInstallDefaultContentSet(onComplete) {
|
||||||
// Check for existing data
|
// Check for existing data
|
||||||
const acResourceDirectory = getAssignmentClientResourcesDirectory();
|
const acResourceDirectory = getAssignmentClientResourcesDirectory();
|
||||||
|
@ -517,6 +589,8 @@ function maybeInstallDefaultContentSet(onComplete) {
|
||||||
if (userHasExistingACData || userHasExistingDSData) {
|
if (userHasExistingACData || userHasExistingDSData) {
|
||||||
console.log("User has existing data, suppressing downloader");
|
console.log("User has existing data, suppressing downloader");
|
||||||
onComplete();
|
onComplete();
|
||||||
|
|
||||||
|
checkNewContent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,6 +602,7 @@ function maybeInstallDefaultContentSet(onComplete) {
|
||||||
return console.error(err)
|
return console.error(err)
|
||||||
}
|
}
|
||||||
console.log('Copied home content over to: ' + getRootHifiDataDirectory());
|
console.log('Copied home content over to: ' + getRootHifiDataDirectory());
|
||||||
|
userConfig.set('homeContentLastModified', new Date());
|
||||||
onComplete();
|
onComplete();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -566,7 +641,7 @@ function maybeInstallDefaultContentSet(onComplete) {
|
||||||
|
|
||||||
// Start downloading content set
|
// Start downloading content set
|
||||||
var req = progress(request.get({
|
var req = progress(request.get({
|
||||||
url: "http://cachefly.highfidelity.com/home.tgz"
|
url: HOME_CONTENT_URL
|
||||||
}, function(error, responseMessage, responseData) {
|
}, function(error, responseMessage, responseData) {
|
||||||
if (aborted) {
|
if (aborted) {
|
||||||
return;
|
return;
|
||||||
|
@ -607,6 +682,7 @@ function maybeInstallDefaultContentSet(onComplete) {
|
||||||
req.pipe(gunzip).pipe(tar.extract(getRootHifiDataDirectory())).on('error', extractError).on('finish', function(){
|
req.pipe(gunzip).pipe(tar.extract(getRootHifiDataDirectory())).on('error', extractError).on('finish', function(){
|
||||||
// response and decompression complete, return
|
// response and decompression complete, return
|
||||||
console.log("Finished unarchiving home content set");
|
console.log("Finished unarchiving home content set");
|
||||||
|
userConfig.set('homeContentLastModified', new Date());
|
||||||
sendStateUpdate('complete');
|
sendStateUpdate('complete');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -663,6 +739,62 @@ for (var key in trayIcons) {
|
||||||
|
|
||||||
const notificationIcon = path.join(__dirname, '../resources/console-notification.png');
|
const notificationIcon = path.join(__dirname, '../resources/console-notification.png');
|
||||||
|
|
||||||
|
function onContentLoaded() {
|
||||||
|
maybeShowSplash();
|
||||||
|
|
||||||
|
if (buildInfo.releaseType == 'PRODUCTION') {
|
||||||
|
var currentVersion = null;
|
||||||
|
try {
|
||||||
|
currentVersion = parseInt(buildInfo.buildIdentifier);
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentVersion !== null) {
|
||||||
|
const CHECK_FOR_UPDATES_INTERVAL_SECONDS = 60 * 30;
|
||||||
|
var hasShownUpdateNotification = false;
|
||||||
|
const updateChecker = new updater.UpdateChecker(currentVersion, CHECK_FOR_UPDATES_INTERVAL_SECONDS);
|
||||||
|
updateChecker.on('update-available', function(latestVersion, url) {
|
||||||
|
if (!hasShownUpdateNotification) {
|
||||||
|
notifier.notify({
|
||||||
|
icon: notificationIcon,
|
||||||
|
title: 'An update is available!',
|
||||||
|
message: 'High Fidelity version ' + latestVersion + ' is available',
|
||||||
|
wait: true,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
hasShownUpdateNotification = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
notifier.on('click', function(notifierObject, options) {
|
||||||
|
console.log("Got click", options.url);
|
||||||
|
shell.openExternal(options.url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteOldFiles(logPath, DELETE_LOG_FILES_OLDER_THAN_X_SECONDS, LOG_FILE_REGEX);
|
||||||
|
|
||||||
|
if (dsPath && acPath) {
|
||||||
|
domainServer = new Process('domain-server', dsPath, ["--get-temp-name"], logPath);
|
||||||
|
acMonitor = new ACMonitorProcess('ac-monitor', acPath, ['-n6',
|
||||||
|
'--log-directory', logPath,
|
||||||
|
'--http-status-port', httpStatusPort], httpStatusPort, logPath);
|
||||||
|
homeServer = new ProcessGroup('home', [domainServer, acMonitor]);
|
||||||
|
logWindow = new LogWindow(acMonitor, domainServer);
|
||||||
|
|
||||||
|
var processes = {
|
||||||
|
home: homeServer
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle process updates
|
||||||
|
homeServer.on('state-update', function(processGroup) { updateTrayMenu(processGroup.state); });
|
||||||
|
|
||||||
|
// start the home server
|
||||||
|
homeServer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
// This method will be called when Electron has finished
|
||||||
// initialization and is ready to create browser windows.
|
// initialization and is ready to create browser windows.
|
||||||
app.on('ready', function() {
|
app.on('ready', function() {
|
||||||
|
@ -682,58 +814,5 @@ app.on('ready', function() {
|
||||||
|
|
||||||
updateTrayMenu(ProcessGroupStates.STOPPED);
|
updateTrayMenu(ProcessGroupStates.STOPPED);
|
||||||
|
|
||||||
maybeInstallDefaultContentSet(function() {
|
maybeInstallDefaultContentSet(onContentLoaded);
|
||||||
maybeShowSplash();
|
|
||||||
|
|
||||||
if (buildInfo.releaseType == 'PRODUCTION') {
|
|
||||||
var currentVersion = null;
|
|
||||||
try {
|
|
||||||
currentVersion = parseInt(buildInfo.buildIdentifier);
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentVersion !== null) {
|
|
||||||
const CHECK_FOR_UPDATES_INTERVAL_SECONDS = 60 * 30;
|
|
||||||
var hasShownUpdateNotification = false;
|
|
||||||
const updateChecker = new updater.UpdateChecker(currentVersion, CHECK_FOR_UPDATES_INTERVAL_SECONDS);
|
|
||||||
updateChecker.on('update-available', function(latestVersion, url) {
|
|
||||||
if (!hasShownUpdateNotification) {
|
|
||||||
notifier.notify({
|
|
||||||
icon: notificationIcon,
|
|
||||||
title: 'An update is available!',
|
|
||||||
message: 'High Fidelity version ' + latestVersion + ' is available',
|
|
||||||
wait: true,
|
|
||||||
url: url
|
|
||||||
});
|
|
||||||
hasShownUpdateNotification = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
notifier.on('click', function(notifierObject, options) {
|
|
||||||
console.log("Got click", options.url);
|
|
||||||
shell.openExternal(options.url);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteOldFiles(logPath, DELETE_LOG_FILES_OLDER_THAN_X_SECONDS, LOG_FILE_REGEX);
|
|
||||||
|
|
||||||
if (dsPath && acPath) {
|
|
||||||
domainServer = new Process('domain-server', dsPath, ["--get-temp-name"], logPath);
|
|
||||||
acMonitor = new ACMonitorProcess('ac-monitor', acPath, ['-n6',
|
|
||||||
'--log-directory', logPath,
|
|
||||||
'--http-status-port', httpStatusPort], httpStatusPort, logPath);
|
|
||||||
homeServer = new ProcessGroup('home', [domainServer, acMonitor]);
|
|
||||||
logWindow = new LogWindow(acMonitor, domainServer);
|
|
||||||
|
|
||||||
var processes = {
|
|
||||||
home: homeServer
|
|
||||||
};
|
|
||||||
|
|
||||||
// handle process updates
|
|
||||||
homeServer.on('state-update', function(processGroup) { updateTrayMenu(processGroup.state); });
|
|
||||||
|
|
||||||
// start the home server
|
|
||||||
homeServer.start();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue