History

Merge branch 'master' into scriptvec3

Sam Gondelman committed 8 years ago

Commit 5b6e7b22 parents c522d1b 7c94645266 files · +8008 −3669Browse files

Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 266 files). Show all

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+80−25
@@ -721,6 +721,7 @@ void ScriptEngine::init() { · 720 unmodified lines
721721 registerGlobalObject("Midi", DependencyManager::get<Midi>().data());
722722
723723 registerGlobalObject("Entities", entityScriptingInterface.data());
724+ registerFunction("Entities", "getMultipleEntityProperties", EntityScriptingInterface::getMultipleEntityProperties);
724725 registerGlobalObject("Quat", &_quatLibrary);
725726 registerGlobalObject("Vec3", &_vec3Library);
726727 registerGlobalObject("Mat4", &_mat4Library);
@@ -1974,8 +1975,9 @@ void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QStrin · 1247 unmodified lines
19741975 }
19751976
19761977 int ScriptEngine::getNumRunningEntityScripts() const {
1978+ QReadLocker locker { &_entityScriptsLock };
19771979 int sum = 0;
1978− for (auto& st : _entityScripts) {
1980+ for (const auto& st : _entityScripts) {
19791981 if (st.status == EntityScriptStatus::RUNNING) {
19801982 ++sum;
19811983 }
@@ -1984,14 +1986,20 @@ int ScriptEngine::getNumRunningEntityScripts() const { · 2 unmodified lines
19841986 }
19851987
19861988 void ScriptEngine::setEntityScriptDetails(const EntityItemID& entityID, const EntityScriptDetails& details) {
1987− _entityScripts[entityID] = details;
1989+ {
1990+ QWriteLocker locker { &_entityScriptsLock };
1991+ _entityScripts[entityID] = details;
1992+ }
19881993 emit entityScriptDetailsUpdated();
19891994 }
19901995
19911996 void ScriptEngine::updateEntityScriptStatus(const EntityItemID& entityID, const EntityScriptStatus &status, const QString& errorInfo) {
1992− EntityScriptDetails &details = _entityScripts[entityID];
1993− details.status = status;
1994− details.errorInfo = errorInfo;
1997+ {
1998+ QWriteLocker locker { &_entityScriptsLock };
1999+ EntityScriptDetails& details = _entityScripts[entityID];
2000+ details.status = status;
2001+ details.errorInfo = errorInfo;
2002+ }
19952003 emit entityScriptDetailsUpdated();
19962004 }
19972005
@@ -2042,6 +2050,7 @@ QFuture<QVariant> ScriptEngine::getLocalEntityScriptDetails(const EntityItemID& · 44 unmodified lines
20422050 }
20432051
20442052 bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const {
2053+ QReadLocker locker { &_entityScriptsLock };
20452054 auto it = _entityScripts.constFind(entityID);
20462055 if (it == _entityScripts.constEnd()) {
20472056 return false;
@@ -2050,6 +2059,11 @@ bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntitySc · 2 unmodified lines
20502059 return true;
20512060 }
20522061
2062+bool ScriptEngine::hasEntityScriptDetails(const EntityItemID& entityID) const {
2063+ QReadLocker locker { &_entityScriptsLock };
2064+ return _entityScripts.contains(entityID);
2065+}
2066+
20532067 const static EntityItemID BAD_SCRIPT_UUID_PLACEHOLDER { "{20170224-dead-face-0000-cee000021114}" };
20542068
20552069 void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const EntityItemID& leaderID) {
@@ -2064,14 +2078,15 @@ void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const · 8 unmodified lines
20642078 }
20652079 foreach(DeferredLoadEntity retry, retryLoads) {
20662080 // check whether entity was since been deleted
2067− if (!_entityScripts.contains(retry.entityID)) {
2081+
2082+ EntityScriptDetails details;
2083+ if (!getEntityScriptDetails(retry.entityID, details)) {
20682084 qCDebug(scriptengine) << "processDeferredEntityLoads -- entity details gone (entity deleted?)"
20692085 << retry.entityID;
20702086 continue;
20712087 }
20722088
20732089 // check whether entity has since been unloaded or otherwise errored-out
2074− auto details = _entityScripts[retry.entityID];
20752090 if (details.status != EntityScriptStatus::PENDING) {
20762091 qCDebug(scriptengine) << "processDeferredEntityLoads -- entity status no longer PENDING; "
20772092 << retry.entityID << details.status;
@@ -2079,7 +2094,11 @@ void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const · 1 unmodified line
20792094 }
20802095
20812096 // propagate leader's failure reasons to the pending entity
2082− const auto leaderDetails = _entityScripts[leaderID];
2097+ EntityScriptDetails leaderDetails;
2098+ {
2099+ QWriteLocker locker { &_entityScriptsLock };
2100+ leaderDetails = _entityScripts[leaderID];
2101+ }
20832102 if (leaderDetails.status != EntityScriptStatus::RUNNING) {
20842103 qCDebug(scriptengine) << QString("... pending load of %1 cancelled (leader: %2 status: %3)")
20852104 .arg(retry.entityID.toString()).arg(leaderID.toString()).arg(leaderDetails.status);
@@ -2125,7 +2144,7 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& · 39 unmodified lines
21252144 return;
21262145 }
21272146
2128− if (!_entityScripts.contains(entityID)) {
2147+ if (!hasEntityScriptDetails(entityID)) {
21292148 // make sure EntityScriptDetails has an entry for this UUID right away
21302149 // (which allows bailing from the loading/provisioning process early if the Entity gets deleted mid-flight)
21312150 updateEntityScriptStatus(entityID, EntityScriptStatus::PENDING, "...pending...");
@@ -2166,9 +2185,12 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& · 34 unmodified lines
21662185 _occupiedScriptURLs[entityScript] = entityID;
21672186
21682187 #ifdef DEBUG_ENTITY_STATES
2169− auto previousStatus = _entityScripts.contains(entityID) ? _entityScripts[entityID].status : EntityScriptStatus::PENDING;
2170− qCDebug(scriptengine) << "loadEntityScript.LOADING: " << entityScript << entityID.toString()
2171− << "(previous: " << previousStatus << ")";
2188+ {
2189+ EntityScriptDetails details;
2190+ bool hasEntityScript = getEntityScriptDetails(entityID, details);
2191+ qCDebug(scriptengine) << "loadEntityScript.LOADING: " << entityScript << entityID.toString()
2192+ << "(previous: " << (hasEntityScript ? details.status : EntityScriptStatus::PENDING) << ")";
2193+ }
21722194 #endif
21732195
21742196 EntityScriptDetails newDetails;
@@ -2197,7 +2219,7 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& · 22 unmodified lines
21972219 #ifdef DEBUG_ENTITY_STATES
21982220 qCDebug(scriptengine) << "loadEntityScript.contentAvailable" << status << QUrl(url).fileName() << entityID.toString();
21992221 #endif
2200− if (!isStopping() && _entityScripts.contains(entityID)) {
2222+ if (!isStopping() && hasEntityScriptDetails(entityID)) {
22012223 _contentAvailableQueue[entityID] = { entityID, url, contents, isURL, success, status };
22022224 } else {
22032225 #ifdef DEBUG_ENTITY_STATES
@@ -2267,8 +2289,11 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 63 unmodified lines
22672289 bool isFileUrl = isURL && scriptOrURL.startsWith("file://");
22682290 auto fileName = isURL ? scriptOrURL : "about:EmbeddedEntityScript";
22692291
2270− const EntityScriptDetails &oldDetails = _entityScripts[entityID];
2271− const QString entityScript = oldDetails.scriptText;
2292+ QString entityScript;
2293+ {
2294+ QWriteLocker locker { &_entityScriptsLock };
2295+ entityScript = _entityScripts[entityID].scriptText;
2296+ }
22722297
22732298 EntityScriptDetails newDetails;
22742299 newDetails.scriptText = scriptOrURL;
@@ -2418,6 +2443,8 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 143 unmodified lines
24182443 // if we got this far, then call the preload method
24192444 callEntityScriptMethod(entityID, "preload");
24202445
2446+ emit entityScriptPreloadFinished(entityID);
2447+
24212448 _occupiedScriptURLs.remove(entityScript);
24222449 processDeferredEntityLoads(entityScript, entityID);
24232450 }
@@ -2446,8 +2473,8 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldR · 22 unmodified lines
24462473 "entityID:" << entityID;
24472474 #endif
24482475
2449− if (_entityScripts.contains(entityID)) {
2450− const EntityScriptDetails &oldDetails = _entityScripts[entityID];
2476+ EntityScriptDetails oldDetails;
2477+ if (getEntityScriptDetails(entityID, oldDetails)) {
24512478 auto scriptText = oldDetails.scriptText;
24522479
24532480 if (isEntityScriptRunning(entityID)) {
@@ -2460,7 +2487,10 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldR · 6 unmodified lines
24602487 #endif
24612488 if (shouldRemoveFromMap) {
24622489 // this was a deleted entity, we've been asked to remove it from the map
2463− _entityScripts.remove(entityID);
2490+ {
2491+ QWriteLocker locker { &_entityScriptsLock };
2492+ _entityScripts.remove(entityID);
2493+ }
24642494 emit entityScriptDetailsUpdated();
24652495 } else if (oldDetails.status != EntityScriptStatus::UNLOADED) {
24662496 EntityScriptDetails newDetails;
@@ -2491,10 +2521,19 @@ void ScriptEngine::unloadAllEntityScripts() { · 24 unmodified lines
24912521 #ifdef THREAD_DEBUGGING
24922522 qCDebug(scriptengine) << "ScriptEngine::unloadAllEntityScripts() called on correct thread [" << thread() << "]";
24932523 #endif
2494− foreach(const EntityItemID& entityID, _entityScripts.keys()) {
2524+
2525+ QList<EntityItemID> keys;
2526+ {
2527+ QReadLocker locker{ &_entityScriptsLock };
2528+ keys = _entityScripts.keys();
2529+ }
2530+ foreach(const EntityItemID& entityID, keys) {
24952531 unloadEntityScript(entityID);
24962532 }
2497− _entityScripts.clear();
2533+ {
2534+ QWriteLocker locker{ &_entityScriptsLock };
2535+ _entityScripts.clear();
2536+ }
24982537 emit entityScriptDetailsUpdated();
24992538 _occupiedScriptURLs.clear();
25002539
@@ -2508,7 +2547,7 @@ void ScriptEngine::unloadAllEntityScripts() { · 7 unmodified lines
25082547 }
25092548
25102549 void ScriptEngine::refreshFileScript(const EntityItemID& entityID) {
2511− if (!HIFI_AUTOREFRESH_FILE_SCRIPTS || !_entityScripts.contains(entityID)) {
2550+ if (!HIFI_AUTOREFRESH_FILE_SCRIPTS || !hasEntityScriptDetails(entityID)) {
25122551 return;
25132552 }
25142553
@@ -2518,7 +2557,11 @@ void ScriptEngine::refreshFileScript(const EntityItemID& entityID) { · 3 unmodified lines
25182557 }
25192558 recurseGuard = true;
25202559
2521− EntityScriptDetails details = _entityScripts[entityID];
2560+ EntityScriptDetails details;
2561+ {
2562+ QWriteLocker locker { &_entityScriptsLock };
2563+ details = _entityScripts[entityID];
2564+ }
25222565 // Check to see if a file based script needs to be reloaded (easier debugging)
25232566 if (details.lastModified > 0) {
25242567 QString filePath = QUrl(details.scriptText).toLocalFile();
@@ -2584,7 +2627,11 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 59 unmodified lines
25842627 refreshFileScript(entityID);
25852628 }
25862629 if (isEntityScriptRunning(entityID)) {
2587− EntityScriptDetails details = _entityScripts[entityID];
2630+ EntityScriptDetails details;
2631+ {
2632+ QWriteLocker locker { &_entityScriptsLock };
2633+ details = _entityScripts[entityID];
2634+ }
25882635 QScriptValue entityScript = details.scriptObject; // previously loaded
25892636
25902637 // If this is a remote call, we need to check to see if the function is remotely callable
@@ -2646,7 +2693,11 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 55 unmodified lines
26462693 refreshFileScript(entityID);
26472694 }
26482695 if (isEntityScriptRunning(entityID)) {
2649− EntityScriptDetails details = _entityScripts[entityID];
2696+ EntityScriptDetails details;
2697+ {
2698+ QWriteLocker locker { &_entityScriptsLock };
2699+ details = _entityScripts[entityID];
2700+ }
26502701 QScriptValue entityScript = details.scriptObject; // previously loaded
26512702 if (entityScript.property(methodName).isFunction()) {
26522703 QScriptValueList args;
@@ -2680,7 +2731,11 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 27 unmodified lines
26802731 refreshFileScript(entityID);
26812732 }
26822733 if (isEntityScriptRunning(entityID)) {
2683− EntityScriptDetails details = _entityScripts[entityID];
2734+ EntityScriptDetails details;
2735+ {
2736+ QWriteLocker locker { &_entityScriptsLock };
2737+ details = _entityScripts[entityID];
2738+ }
26842739 QScriptValue entityScript = details.scriptObject; // previously loaded
26852740 if (entityScript.property(methodName).isFunction()) {
26862741 QScriptValueList args;