Merge pull request #14045 from sethalves/enterEntity-wait-for-script

don't call enterEntity before the entity's script is loaded
This commit is contained in:
John Conklin II 2018-09-28 16:07:08 -07:00 committed by GitHub
commit 11492ce8ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 5 deletions

View file

@ -187,6 +187,13 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event);
});
connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) {
EntityItemPointer entity = getTree()->findEntityByID(entityID);
if (entity) {
entity->setScriptHasFinishedPreload(true);
}
});
}
void EntityTreeRenderer::clear() {
@ -512,7 +519,11 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityIt
// be ignored because they can have events fired on them.
// FIXME - this could be optimized further by determining if the script is loaded
// and if it has either an enterEntity or leaveEntity method
if (isZone || hasScript) {
//
// also, don't flag a scripted entity as containing the avatar until the script is loaded,
// so that the script is awake in time to receive the "entityEntity" call (even if the entity is a zone).
if ((!hasScript && isZone) ||
(hasScript && entity->isScriptPreloadFinished())) {
// now check to see if the point contains our entity, this can be expensive if
// the entity has a collision hull
if (entity->contains(_avatarPosition)) {
@ -972,6 +983,7 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool
entity->scriptHasUnloaded();
}
if (shouldLoad) {
entity->setScriptHasFinishedPreload(false);
_entitiesScriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload);
entity->scriptHasPreloaded();
}

View file

@ -3197,3 +3197,26 @@ void EntityItem::setCloneIDs(const QVector<QUuid>& cloneIDs) {
_cloneIDs = cloneIDs;
});
}
bool EntityItem::shouldPreloadScript() const {
return !_script.isEmpty() && ((_loadedScript != _script) || (_loadedScriptTimestamp != _scriptTimestamp));
}
void EntityItem::scriptHasPreloaded() {
_loadedScript = _script;
_loadedScriptTimestamp = _scriptTimestamp;
}
void EntityItem::scriptHasUnloaded() {
_loadedScript = "";
_loadedScriptTimestamp = 0;
_scriptPreloadFinished = false;
}
void EntityItem::setScriptHasFinishedPreload(bool value) {
_scriptPreloadFinished = value;
}
bool EntityItem::isScriptPreloadFinished() {
return _scriptPreloadFinished;
}

View file

@ -470,10 +470,11 @@ public:
/// We only want to preload if:
/// there is some script, and either the script value or the scriptTimestamp
/// value have changed since our last preload
bool shouldPreloadScript() const { return !_script.isEmpty() &&
((_loadedScript != _script) || (_loadedScriptTimestamp != _scriptTimestamp)); }
void scriptHasPreloaded() { _loadedScript = _script; _loadedScriptTimestamp = _scriptTimestamp; }
void scriptHasUnloaded() { _loadedScript = ""; _loadedScriptTimestamp = 0; }
bool shouldPreloadScript() const;
void scriptHasPreloaded();
void scriptHasUnloaded();
void setScriptHasFinishedPreload(bool value);
bool isScriptPreloadFinished();
bool getClientOnly() const { return _clientOnly; }
virtual void setClientOnly(bool clientOnly) { _clientOnly = clientOnly; }
@ -584,6 +585,7 @@ protected:
QString _script { ENTITY_ITEM_DEFAULT_SCRIPT }; /// the value of the script property
QString _loadedScript; /// the value of _script when the last preload signal was sent
quint64 _scriptTimestamp { ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP }; /// the script loaded property used for forced reload
bool _scriptPreloadFinished { false };
QString _serverScripts;
/// keep track of time when _serverScripts property was last changed

View file

@ -2442,6 +2442,8 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
// if we got this far, then call the preload method
callEntityScriptMethod(entityID, "preload");
emit entityScriptPreloadFinished(entityID);
_occupiedScriptURLs.remove(entityScript);
processDeferredEntityLoads(entityScript, entityID);
}

View file

@ -712,6 +712,13 @@ signals:
// script is updated (goes from RUNNING to ERROR_RUNNING_SCRIPT, for example)
void entityScriptDetailsUpdated();
/**jsdoc
* @function Script.entityScriptPreloadFinished
* @returns {Signal}
*/
// Emitted when an entity script has finished running preload
void entityScriptPreloadFinished(const EntityItemID& entityID);
protected:
void init();