Fix entity scripts not loading in certain cases

This fixes a bug where an entity script would be loaded but immediately
unloaded. This happens when the script property of the entity is changed shortly
after it is added.

Flow of events:

  Entity added
  => Entity added event emitted
  Entity edited
  => Script changing event emitted
  <= Entity added event received
  Script loaded
  <= Script changing event received
  Script stopped
  Tries to load script again, but because the script hasn't changed
    since it was last loaded, it is not loaded again.

The change here is to modify the behavior when receiving a script
changing event. Instead of always unloading and then conditionally
loading the script, it will either do both (unload + load) or neither.
This commit is contained in:
Ryan Huffman 2017-02-13 13:33:29 -08:00
parent f4ff5cf746
commit d0cddd01d7
3 changed files with 11 additions and 8 deletions

View file

@ -938,17 +938,19 @@ void EntityTreeRenderer::addEntityToScene(EntityItemPointer entity) {
void EntityTreeRenderer::entityScriptChanging(const EntityItemID& entityID, const bool reload) {
if (_tree && !_shuttingDown) {
_entitiesScriptEngine->unloadEntityScript(entityID);
checkAndCallPreload(entityID, reload);
}
checkAndCallPreload(entityID, reload, true);
}
void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, const bool reload) {
void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, const bool reload, const bool unloadFirst) {
if (_tree && !_shuttingDown) {
EntityItemPointer entity = getTree()->findEntityByEntityItemID(entityID);
if (entity && entity->shouldPreloadScript() && _entitiesScriptEngine) {
QString scriptUrl = entity->getScript();
bool shouldLoad = entity && entity->shouldPreloadScript() && _entitiesScriptEngine;
QString scriptUrl = entity->getScript();
if ((unloadFirst && shouldLoad) || scriptUrl.isEmpty()) {
_entitiesScriptEngine->unloadEntityScript(entityID);
entity->scriptHasUnloaded();
}
if (shouldLoad && !scriptUrl.isEmpty()) {
scriptUrl = ResourceManager::normalizeURL(scriptUrl);
ScriptEngine::loadEntityScript(_entitiesScriptEngine, entityID, scriptUrl, reload);
entity->scriptHasPreloaded();

View file

@ -148,7 +148,7 @@ private:
bool layerZoneAndHasSkybox(const std::shared_ptr<ZoneEntityItem>& zone);
bool applySkyboxAndHasAmbient();
void checkAndCallPreload(const EntityItemID& entityID, const bool reload = false);
void checkAndCallPreload(const EntityItemID& entityID, const bool reload = false, const bool unloadFirst = false);
QList<ModelPointer> _releasedModels;
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,

View file

@ -446,6 +446,7 @@ public:
bool shouldPreloadScript() const { return !_script.isEmpty() &&
((_loadedScript != _script) || (_loadedScriptTimestamp != _scriptTimestamp)); }
void scriptHasPreloaded() { _loadedScript = _script; _loadedScriptTimestamp = _scriptTimestamp; }
void scriptHasUnloaded() { _loadedScript = ""; _loadedScriptTimestamp = 0; }
bool getClientOnly() const { return _clientOnly; }
void setClientOnly(bool clientOnly) { _clientOnly = clientOnly; }