mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-09 02:52:13 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into sysTray
This commit is contained in:
commit
f419937157
8 changed files with 121 additions and 49 deletions
BIN
interface/resources/images/interstitialPage/goTo_button.png
Normal file
BIN
interface/resources/images/interstitialPage/goTo_button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9 KiB |
|
@ -45,10 +45,11 @@ const float LOD_ADJUST_RUNNING_AVG_TIMESCALE = 0.08f; // sec
|
|||
const float LOD_BATCH_TO_PRESENT_CUSHION_TIME = 3.0f; // msec
|
||||
|
||||
void LODManager::setRenderTimes(float presentTime, float engineRunTime, float batchTime, float gpuTime) {
|
||||
_presentTime = presentTime;
|
||||
_engineRunTime = engineRunTime;
|
||||
_batchTime = batchTime;
|
||||
_gpuTime = gpuTime;
|
||||
// Make sure the sampled time are positive values
|
||||
_presentTime = std::max(0.0f, presentTime);
|
||||
_engineRunTime = std::max(0.0f, engineRunTime);
|
||||
_batchTime = std::max(0.0f, batchTime);
|
||||
_gpuTime = std::max(0.0f, gpuTime);
|
||||
}
|
||||
|
||||
void LODManager::autoAdjustLOD(float realTimeDelta) {
|
||||
|
@ -64,16 +65,29 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
auto presentTime = (_presentTime > _batchTime + LOD_BATCH_TO_PRESENT_CUSHION_TIME ? _batchTime + LOD_BATCH_TO_PRESENT_CUSHION_TIME : _presentTime);
|
||||
float maxRenderTime = glm::max(glm::max(presentTime, _engineRunTime), _gpuTime);
|
||||
|
||||
// compute time-weighted running average maxRenderTime
|
||||
// Note: we MUST clamp the blend to 1.0 for stability
|
||||
// maxRenderTime must be a realistic valid duration in order for the regulation to work correctly.
|
||||
// We make sure it s a non zero positive value (1.0ms) under 1 sec
|
||||
maxRenderTime = std::max(1.0f, std::min(maxRenderTime, (float)MSECS_PER_SECOND));
|
||||
|
||||
// realTimeDelta must be a realistic valid duration in order for the regulation to work correctly.
|
||||
// We make sure it a positive value under 1 sec
|
||||
// note that if real time delta is very small we will early exit to avoid division by zero
|
||||
realTimeDelta = std::max(0.0f, std::min(realTimeDelta, 1.0f));
|
||||
|
||||
// compute time-weighted running average render time (now and smooth)
|
||||
// We MUST clamp the blend between 0.0 and 1.0 for stability
|
||||
float nowBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f;
|
||||
_nowRenderTime = (1.0f - nowBlend) * _nowRenderTime + nowBlend * maxRenderTime; // msec
|
||||
|
||||
float smoothBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) ? realTimeDelta / (LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) : 1.0f;
|
||||
_smoothRenderTime = (1.0f - smoothBlend) * _smoothRenderTime + smoothBlend * maxRenderTime; // msec
|
||||
|
||||
if (!_automaticLODAdjust || _nowRenderTime == 0.0f || _smoothRenderTime == 0.0f) {
|
||||
// early exit
|
||||
//Evaluate the running averages for the render time
|
||||
// We must sanity check for the output average evaluated to be in a valid range to avoid issues
|
||||
_nowRenderTime = (1.0f - nowBlend) * _nowRenderTime + nowBlend * maxRenderTime; // msec
|
||||
_nowRenderTime = std::max(0.0f, std::min(_nowRenderTime, (float)MSECS_PER_SECOND));
|
||||
_smoothRenderTime = (1.0f - smoothBlend) * _smoothRenderTime + smoothBlend * maxRenderTime; // msec
|
||||
_smoothRenderTime = std::max(0.0f, std::min(_smoothRenderTime, (float)MSECS_PER_SECOND));
|
||||
|
||||
// Early exit if not regulating or if the simulation or render times don't matter
|
||||
if (!_automaticLODAdjust || realTimeDelta <= 0.0f || _nowRenderTime <= 0.0f || _smoothRenderTime <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -130,7 +144,8 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
|||
glm::clamp(integral, -1.0f, 1.0f);
|
||||
|
||||
// Compute derivative
|
||||
auto derivative = (error - previous_error) / dt;
|
||||
// dt is never zero because realTimeDelta would have early exit above, but if it ever was let's zero the derivative term
|
||||
auto derivative = (dt <= 0.0f ? 0.0f : (error - previous_error) / dt);
|
||||
|
||||
// remember history
|
||||
_pidHistory.x = error;
|
||||
|
|
|
@ -1974,8 +1974,9 @@ void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QStrin
|
|||
}
|
||||
|
||||
int ScriptEngine::getNumRunningEntityScripts() const {
|
||||
QReadLocker locker { &_entityScriptsLock };
|
||||
int sum = 0;
|
||||
for (auto& st : _entityScripts) {
|
||||
for (const auto& st : _entityScripts) {
|
||||
if (st.status == EntityScriptStatus::RUNNING) {
|
||||
++sum;
|
||||
}
|
||||
|
@ -1984,14 +1985,20 @@ int ScriptEngine::getNumRunningEntityScripts() const {
|
|||
}
|
||||
|
||||
void ScriptEngine::setEntityScriptDetails(const EntityItemID& entityID, const EntityScriptDetails& details) {
|
||||
_entityScripts[entityID] = details;
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
_entityScripts[entityID] = details;
|
||||
}
|
||||
emit entityScriptDetailsUpdated();
|
||||
}
|
||||
|
||||
void ScriptEngine::updateEntityScriptStatus(const EntityItemID& entityID, const EntityScriptStatus &status, const QString& errorInfo) {
|
||||
EntityScriptDetails &details = _entityScripts[entityID];
|
||||
details.status = status;
|
||||
details.errorInfo = errorInfo;
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
EntityScriptDetails& details = _entityScripts[entityID];
|
||||
details.status = status;
|
||||
details.errorInfo = errorInfo;
|
||||
}
|
||||
emit entityScriptDetailsUpdated();
|
||||
}
|
||||
|
||||
|
@ -2042,6 +2049,7 @@ QFuture<QVariant> ScriptEngine::getLocalEntityScriptDetails(const EntityItemID&
|
|||
}
|
||||
|
||||
bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const {
|
||||
QReadLocker locker { &_entityScriptsLock };
|
||||
auto it = _entityScripts.constFind(entityID);
|
||||
if (it == _entityScripts.constEnd()) {
|
||||
return false;
|
||||
|
@ -2050,6 +2058,11 @@ bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntitySc
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ScriptEngine::hasEntityScriptDetails(const EntityItemID& entityID) const {
|
||||
QReadLocker locker { &_entityScriptsLock };
|
||||
return _entityScripts.contains(entityID);
|
||||
}
|
||||
|
||||
const static EntityItemID BAD_SCRIPT_UUID_PLACEHOLDER { "{20170224-dead-face-0000-cee000021114}" };
|
||||
|
||||
void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const EntityItemID& leaderID) {
|
||||
|
@ -2064,14 +2077,15 @@ void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const
|
|||
}
|
||||
foreach(DeferredLoadEntity retry, retryLoads) {
|
||||
// check whether entity was since been deleted
|
||||
if (!_entityScripts.contains(retry.entityID)) {
|
||||
|
||||
EntityScriptDetails details;
|
||||
if (!getEntityScriptDetails(retry.entityID, details)) {
|
||||
qCDebug(scriptengine) << "processDeferredEntityLoads -- entity details gone (entity deleted?)"
|
||||
<< retry.entityID;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check whether entity has since been unloaded or otherwise errored-out
|
||||
auto details = _entityScripts[retry.entityID];
|
||||
if (details.status != EntityScriptStatus::PENDING) {
|
||||
qCDebug(scriptengine) << "processDeferredEntityLoads -- entity status no longer PENDING; "
|
||||
<< retry.entityID << details.status;
|
||||
|
@ -2079,7 +2093,11 @@ void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const
|
|||
}
|
||||
|
||||
// propagate leader's failure reasons to the pending entity
|
||||
const auto leaderDetails = _entityScripts[leaderID];
|
||||
EntityScriptDetails leaderDetails;
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
leaderDetails = _entityScripts[leaderID];
|
||||
}
|
||||
if (leaderDetails.status != EntityScriptStatus::RUNNING) {
|
||||
qCDebug(scriptengine) << QString("... pending load of %1 cancelled (leader: %2 status: %3)")
|
||||
.arg(retry.entityID.toString()).arg(leaderID.toString()).arg(leaderDetails.status);
|
||||
|
@ -2125,7 +2143,7 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString&
|
|||
return;
|
||||
}
|
||||
|
||||
if (!_entityScripts.contains(entityID)) {
|
||||
if (!hasEntityScriptDetails(entityID)) {
|
||||
// make sure EntityScriptDetails has an entry for this UUID right away
|
||||
// (which allows bailing from the loading/provisioning process early if the Entity gets deleted mid-flight)
|
||||
updateEntityScriptStatus(entityID, EntityScriptStatus::PENDING, "...pending...");
|
||||
|
@ -2166,9 +2184,12 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString&
|
|||
_occupiedScriptURLs[entityScript] = entityID;
|
||||
|
||||
#ifdef DEBUG_ENTITY_STATES
|
||||
auto previousStatus = _entityScripts.contains(entityID) ? _entityScripts[entityID].status : EntityScriptStatus::PENDING;
|
||||
qCDebug(scriptengine) << "loadEntityScript.LOADING: " << entityScript << entityID.toString()
|
||||
<< "(previous: " << previousStatus << ")";
|
||||
{
|
||||
EntityScriptDetails details;
|
||||
bool hasEntityScript = getEntityScriptDetails(entityID, details);
|
||||
qCDebug(scriptengine) << "loadEntityScript.LOADING: " << entityScript << entityID.toString()
|
||||
<< "(previous: " << (hasEntityScript ? details.status : EntityScriptStatus::PENDING) << ")";
|
||||
}
|
||||
#endif
|
||||
|
||||
EntityScriptDetails newDetails;
|
||||
|
@ -2197,7 +2218,7 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString&
|
|||
#ifdef DEBUG_ENTITY_STATES
|
||||
qCDebug(scriptengine) << "loadEntityScript.contentAvailable" << status << QUrl(url).fileName() << entityID.toString();
|
||||
#endif
|
||||
if (!isStopping() && _entityScripts.contains(entityID)) {
|
||||
if (!isStopping() && hasEntityScriptDetails(entityID)) {
|
||||
_contentAvailableQueue[entityID] = { entityID, url, contents, isURL, success, status };
|
||||
} else {
|
||||
#ifdef DEBUG_ENTITY_STATES
|
||||
|
@ -2267,8 +2288,11 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
|||
bool isFileUrl = isURL && scriptOrURL.startsWith("file://");
|
||||
auto fileName = isURL ? scriptOrURL : "about:EmbeddedEntityScript";
|
||||
|
||||
const EntityScriptDetails &oldDetails = _entityScripts[entityID];
|
||||
const QString entityScript = oldDetails.scriptText;
|
||||
QString entityScript;
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
entityScript = _entityScripts[entityID].scriptText;
|
||||
}
|
||||
|
||||
EntityScriptDetails newDetails;
|
||||
newDetails.scriptText = scriptOrURL;
|
||||
|
@ -2446,8 +2470,8 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldR
|
|||
"entityID:" << entityID;
|
||||
#endif
|
||||
|
||||
if (_entityScripts.contains(entityID)) {
|
||||
const EntityScriptDetails &oldDetails = _entityScripts[entityID];
|
||||
EntityScriptDetails oldDetails;
|
||||
if (getEntityScriptDetails(entityID, oldDetails)) {
|
||||
auto scriptText = oldDetails.scriptText;
|
||||
|
||||
if (isEntityScriptRunning(entityID)) {
|
||||
|
@ -2460,7 +2484,10 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldR
|
|||
#endif
|
||||
if (shouldRemoveFromMap) {
|
||||
// this was a deleted entity, we've been asked to remove it from the map
|
||||
_entityScripts.remove(entityID);
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
_entityScripts.remove(entityID);
|
||||
}
|
||||
emit entityScriptDetailsUpdated();
|
||||
} else if (oldDetails.status != EntityScriptStatus::UNLOADED) {
|
||||
EntityScriptDetails newDetails;
|
||||
|
@ -2491,10 +2518,19 @@ void ScriptEngine::unloadAllEntityScripts() {
|
|||
#ifdef THREAD_DEBUGGING
|
||||
qCDebug(scriptengine) << "ScriptEngine::unloadAllEntityScripts() called on correct thread [" << thread() << "]";
|
||||
#endif
|
||||
foreach(const EntityItemID& entityID, _entityScripts.keys()) {
|
||||
|
||||
QList<EntityItemID> keys;
|
||||
{
|
||||
QReadLocker locker{ &_entityScriptsLock };
|
||||
keys = _entityScripts.keys();
|
||||
}
|
||||
foreach(const EntityItemID& entityID, keys) {
|
||||
unloadEntityScript(entityID);
|
||||
}
|
||||
_entityScripts.clear();
|
||||
{
|
||||
QWriteLocker locker{ &_entityScriptsLock };
|
||||
_entityScripts.clear();
|
||||
}
|
||||
emit entityScriptDetailsUpdated();
|
||||
_occupiedScriptURLs.clear();
|
||||
|
||||
|
@ -2508,7 +2544,7 @@ void ScriptEngine::unloadAllEntityScripts() {
|
|||
}
|
||||
|
||||
void ScriptEngine::refreshFileScript(const EntityItemID& entityID) {
|
||||
if (!HIFI_AUTOREFRESH_FILE_SCRIPTS || !_entityScripts.contains(entityID)) {
|
||||
if (!HIFI_AUTOREFRESH_FILE_SCRIPTS || !hasEntityScriptDetails(entityID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2518,7 +2554,11 @@ void ScriptEngine::refreshFileScript(const EntityItemID& entityID) {
|
|||
}
|
||||
recurseGuard = true;
|
||||
|
||||
EntityScriptDetails details = _entityScripts[entityID];
|
||||
EntityScriptDetails details;
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
details = _entityScripts[entityID];
|
||||
}
|
||||
// Check to see if a file based script needs to be reloaded (easier debugging)
|
||||
if (details.lastModified > 0) {
|
||||
QString filePath = QUrl(details.scriptText).toLocalFile();
|
||||
|
@ -2584,7 +2624,11 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
|||
refreshFileScript(entityID);
|
||||
}
|
||||
if (isEntityScriptRunning(entityID)) {
|
||||
EntityScriptDetails details = _entityScripts[entityID];
|
||||
EntityScriptDetails details;
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
details = _entityScripts[entityID];
|
||||
}
|
||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||
|
||||
// If this is a remote call, we need to check to see if the function is remotely callable
|
||||
|
@ -2646,7 +2690,11 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
|||
refreshFileScript(entityID);
|
||||
}
|
||||
if (isEntityScriptRunning(entityID)) {
|
||||
EntityScriptDetails details = _entityScripts[entityID];
|
||||
EntityScriptDetails details;
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
details = _entityScripts[entityID];
|
||||
}
|
||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||
if (entityScript.property(methodName).isFunction()) {
|
||||
QScriptValueList args;
|
||||
|
@ -2680,7 +2728,11 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
|||
refreshFileScript(entityID);
|
||||
}
|
||||
if (isEntityScriptRunning(entityID)) {
|
||||
EntityScriptDetails details = _entityScripts[entityID];
|
||||
EntityScriptDetails details;
|
||||
{
|
||||
QWriteLocker locker { &_entityScriptsLock };
|
||||
details = _entityScripts[entityID];
|
||||
}
|
||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||
if (entityScript.property(methodName).isFunction()) {
|
||||
QScriptValueList args;
|
||||
|
|
|
@ -461,7 +461,9 @@ public:
|
|||
* @returns {boolean}
|
||||
*/
|
||||
Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID) {
|
||||
return _entityScripts.contains(entityID) && _entityScripts[entityID].status == EntityScriptStatus::RUNNING;
|
||||
QReadLocker locker { &_entityScriptsLock };
|
||||
auto it = _entityScripts.constFind(entityID);
|
||||
return it != _entityScripts.constEnd() && it->status == EntityScriptStatus::RUNNING;
|
||||
}
|
||||
QVariant cloneEntityScriptDetails(const EntityItemID& entityID);
|
||||
QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID) override;
|
||||
|
@ -559,6 +561,7 @@ public:
|
|||
void clearDebugLogWindow();
|
||||
int getNumRunningEntityScripts() const;
|
||||
bool getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const;
|
||||
bool hasEntityScriptDetails(const EntityItemID& entityID) const;
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -771,6 +774,7 @@ protected:
|
|||
bool _isInitialized { false };
|
||||
QHash<QTimer*, CallbackData> _timerFunctionMap;
|
||||
QSet<QUrl> _includedURLs;
|
||||
mutable QReadWriteLock _entityScriptsLock { QReadWriteLock::Recursive };
|
||||
QHash<EntityItemID, EntityScriptDetails> _entityScripts;
|
||||
QHash<QString, EntityItemID> _occupiedScriptURLs;
|
||||
QList<DeferredLoadEntity> _deferredEntityLoads;
|
||||
|
|
|
@ -282,14 +282,15 @@ function loaded() {
|
|||
function refreshEntityList() {
|
||||
PROFILE("refresh-entity-list", function() {
|
||||
PROFILE("filter", function() {
|
||||
let searchTerm = elFilter.value;
|
||||
let searchTerm = elFilter.value.toLowerCase();
|
||||
if (searchTerm === '') {
|
||||
visibleEntities = entities.slice(0);
|
||||
} else {
|
||||
visibleEntities = entities.filter(function(e) {
|
||||
return e.name.indexOf(searchTerm) > -1
|
||||
|| e.type.indexOf(searchTerm) > -1
|
||||
|| e.fullUrl.indexOf(searchTerm) > -1;
|
||||
return e.name.toLowerCase().indexOf(searchTerm) > -1
|
||||
|| e.type.toLowerCase().indexOf(searchTerm) > -1
|
||||
|| e.fullUrl.toLowerCase().indexOf(searchTerm) > -1
|
||||
|| e.id.toLowerCase().indexOf(searchTerm) > -1;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
|
||||
var span = document.createElement('span');
|
||||
span.style = "margin:10px 5px;color:#1b6420;font-size:15px;";
|
||||
span.innerHTML = "<a href='#' onclick='emitWalletSetupEvent(); return false;'>Setup your Wallet</a> to get money and shop in Marketplace.";
|
||||
span.innerHTML = "<a href='#' onclick='emitWalletSetupEvent(); return false;'>Activate your Wallet</a> to get money and shop in Marketplace.";
|
||||
|
||||
var xButton = document.createElement('a');
|
||||
xButton.id = "xButton";
|
||||
|
|
|
@ -137,10 +137,10 @@
|
|||
|
||||
var loadingToTheSpotID = Overlays.addOverlay("image3d", {
|
||||
name: "Loading-Destination-Card-Text",
|
||||
localPosition: { x: 0.0 , y: -1.8, z: 0.0 },
|
||||
url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/goTo_button.png",
|
||||
localPosition: { x: 0.0 , y: -1.5, z: -0.3 },
|
||||
url: Script.resourcesPath() + "images/interstitialPage/goTo_button.png",
|
||||
alpha: 1,
|
||||
dimensions: { x: 1.2, y: 0.6},
|
||||
dimensions: { x: 1.5, y: 1.0 },
|
||||
visible: isVisible,
|
||||
emissive: true,
|
||||
ignoreRayIntersection: false,
|
||||
|
@ -415,13 +415,13 @@
|
|||
Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay);
|
||||
Overlays.hoverEnterOverlay.connect(function(overlayID, event) {
|
||||
if (overlayID === loadingToTheSpotID) {
|
||||
Overlays.editOverlay(loadingToTheSpotID, { color: greyColor});
|
||||
Overlays.editOverlay(loadingToTheSpotID, { color: greyColor });
|
||||
}
|
||||
});
|
||||
|
||||
Overlays.hoverLeaveOverlay.connect(function(overlayID, event) {
|
||||
if (overlayID === loadingToTheSpotID) {
|
||||
Overlays.editOverlay(loadingToTheSpotID, { color: whiteColor});
|
||||
Overlays.editOverlay(loadingToTheSpotID, { color: whiteColor });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -564,7 +564,7 @@
|
|||
}
|
||||
|
||||
function walletNotSetup() {
|
||||
createNotification("Your wallet isn't set up. Open the WALLET app.", NotificationType.WALLET);
|
||||
createNotification("Your wallet isn't activated yet. Open the WALLET app.", NotificationType.WALLET);
|
||||
}
|
||||
|
||||
function connectionAdded(connectionName) {
|
||||
|
|
Loading…
Reference in a new issue