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
721 registerGlobalObject("Midi", DependencyManager::get<Midi>().data());721 registerGlobalObject("Midi", DependencyManager::get<Midi>().data());
722 722
723 registerGlobalObject("Entities", entityScriptingInterface.data());723 registerGlobalObject("Entities", entityScriptingInterface.data());
724 registerFunction("Entities", "getMultipleEntityProperties", EntityScriptingInterface::getMultipleEntityProperties);
724 registerGlobalObject("Quat", &_quatLibrary);725 registerGlobalObject("Quat", &_quatLibrary);
725 registerGlobalObject("Vec3", &_vec3Library);726 registerGlobalObject("Vec3", &_vec3Library);
726 registerGlobalObject("Mat4", &_mat4Library);727 registerGlobalObject("Mat4", &_mat4Library);
@@ -1974,8 +1975,9 @@ void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QStrin · 1247 unmodified lines
1974}1975}
1975 1976
1976int ScriptEngine::getNumRunningEntityScripts() const {1977int ScriptEngine::getNumRunningEntityScripts() const {
1978 QReadLocker locker { &_entityScriptsLock };
1977 int sum = 0;1979 int sum = 0;
1978 for (auto& st : _entityScripts) {1980 for (const auto& st : _entityScripts) {
1979 if (st.status == EntityScriptStatus::RUNNING) {1981 if (st.status == EntityScriptStatus::RUNNING) {
1980 ++sum;1982 ++sum;
1981 }1983 }
@@ -1984,14 +1986,20 @@ int ScriptEngine::getNumRunningEntityScripts() const { · 2 unmodified lines
1984}1986}
1985 1987
1986void ScriptEngine::setEntityScriptDetails(const EntityItemID& entityID, const EntityScriptDetails& details) {1988void ScriptEngine::setEntityScriptDetails(const EntityItemID& entityID, const EntityScriptDetails& details) {
1987 _entityScripts[entityID] = details;1989 {
1990 QWriteLocker locker { &_entityScriptsLock };
1991 _entityScripts[entityID] = details;
1992 }
1988 emit entityScriptDetailsUpdated();1993 emit entityScriptDetailsUpdated();
1989}1994}
1990 1995
1991void ScriptEngine::updateEntityScriptStatus(const EntityItemID& entityID, const EntityScriptStatus &status, const QString& errorInfo) {1996void ScriptEngine::updateEntityScriptStatus(const EntityItemID& entityID, const EntityScriptStatus &status, const QString& errorInfo) {
1992 EntityScriptDetails &details = _entityScripts[entityID];1997 {
1993 details.status = status;1998 QWriteLocker locker { &_entityScriptsLock };
1994 details.errorInfo = errorInfo;1999 EntityScriptDetails& details = _entityScripts[entityID];
2000 details.status = status;
2001 details.errorInfo = errorInfo;
2002 }
1995 emit entityScriptDetailsUpdated();2003 emit entityScriptDetailsUpdated();
1996}2004}
1997 2005
@@ -2042,6 +2050,7 @@ QFuture<QVariant> ScriptEngine::getLocalEntityScriptDetails(const EntityItemID& · 44 unmodified lines
2042}2050}
2043 2051
2044bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const {2052bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const {
2053 QReadLocker locker { &_entityScriptsLock };
2045 auto it = _entityScripts.constFind(entityID);2054 auto it = _entityScripts.constFind(entityID);
2046 if (it == _entityScripts.constEnd()) {2055 if (it == _entityScripts.constEnd()) {
2047 return false;2056 return false;
@@ -2050,6 +2059,11 @@ bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntitySc · 2 unmodified lines
2050 return true;2059 return true;
2051}2060}
2052 2061
2062bool ScriptEngine::hasEntityScriptDetails(const EntityItemID& entityID) const {
2063 QReadLocker locker { &_entityScriptsLock };
2064 return _entityScripts.contains(entityID);
2065}
2066
2053const static EntityItemID BAD_SCRIPT_UUID_PLACEHOLDER { "{20170224-dead-face-0000-cee000021114}" };2067const static EntityItemID BAD_SCRIPT_UUID_PLACEHOLDER { "{20170224-dead-face-0000-cee000021114}" };
2054 2068
2055void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const EntityItemID& leaderID) {2069void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const EntityItemID& leaderID) {
@@ -2064,14 +2078,15 @@ void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const · 8 unmodified lines
2064 }2078 }
2065 foreach(DeferredLoadEntity retry, retryLoads) {2079 foreach(DeferredLoadEntity retry, retryLoads) {
2066 // check whether entity was since been deleted2080 // check whether entity was since been deleted
2067 if (!_entityScripts.contains(retry.entityID)) {2081
2082 EntityScriptDetails details;
2083 if (!getEntityScriptDetails(retry.entityID, details)) {
2068 qCDebug(scriptengine) << "processDeferredEntityLoads -- entity details gone (entity deleted?)"2084 qCDebug(scriptengine) << "processDeferredEntityLoads -- entity details gone (entity deleted?)"
2069 << retry.entityID;2085 << retry.entityID;
2070 continue;2086 continue;
2071 }2087 }
2072 2088
2073 // check whether entity has since been unloaded or otherwise errored-out2089 // check whether entity has since been unloaded or otherwise errored-out
2074 auto details = _entityScripts[retry.entityID];
2075 if (details.status != EntityScriptStatus::PENDING) {2090 if (details.status != EntityScriptStatus::PENDING) {
2076 qCDebug(scriptengine) << "processDeferredEntityLoads -- entity status no longer PENDING; "2091 qCDebug(scriptengine) << "processDeferredEntityLoads -- entity status no longer PENDING; "
2077 << retry.entityID << details.status;2092 << retry.entityID << details.status;
@@ -2079,7 +2094,11 @@ void ScriptEngine::processDeferredEntityLoads(const QString& entityScript, const · 1 unmodified line
2079 }2094 }
2080 2095
2081 // propagate leader's failure reasons to the pending entity2096 // 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 }
2083 if (leaderDetails.status != EntityScriptStatus::RUNNING) {2102 if (leaderDetails.status != EntityScriptStatus::RUNNING) {
2084 qCDebug(scriptengine) << QString("... pending load of %1 cancelled (leader: %2 status: %3)")2103 qCDebug(scriptengine) << QString("... pending load of %1 cancelled (leader: %2 status: %3)")
2085 .arg(retry.entityID.toString()).arg(leaderID.toString()).arg(leaderDetails.status);2104 .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
2125 return;2144 return;
2126 }2145 }
2127 2146
2128 if (!_entityScripts.contains(entityID)) {2147 if (!hasEntityScriptDetails(entityID)) {
2129 // make sure EntityScriptDetails has an entry for this UUID right away2148 // make sure EntityScriptDetails has an entry for this UUID right away
2130 // (which allows bailing from the loading/provisioning process early if the Entity gets deleted mid-flight)2149 // (which allows bailing from the loading/provisioning process early if the Entity gets deleted mid-flight)
2131 updateEntityScriptStatus(entityID, EntityScriptStatus::PENDING, "...pending...");2150 updateEntityScriptStatus(entityID, EntityScriptStatus::PENDING, "...pending...");
@@ -2166,9 +2185,12 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& · 34 unmodified lines
2166 _occupiedScriptURLs[entityScript] = entityID;2185 _occupiedScriptURLs[entityScript] = entityID;
2167 2186
2168#ifdef DEBUG_ENTITY_STATES2187#ifdef DEBUG_ENTITY_STATES
2169 auto previousStatus = _entityScripts.contains(entityID) ? _entityScripts[entityID].status : EntityScriptStatus::PENDING;2188 {
2170 qCDebug(scriptengine) << "loadEntityScript.LOADING: " << entityScript << entityID.toString()2189 EntityScriptDetails details;
2171 << "(previous: " << previousStatus << ")";2190 bool hasEntityScript = getEntityScriptDetails(entityID, details);
2191 qCDebug(scriptengine) << "loadEntityScript.LOADING: " << entityScript << entityID.toString()
2192 << "(previous: " << (hasEntityScript ? details.status : EntityScriptStatus::PENDING) << ")";
2193 }
2172#endif2194#endif
2173 2195
2174 EntityScriptDetails newDetails;2196 EntityScriptDetails newDetails;
@@ -2197,7 +2219,7 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& · 22 unmodified lines
2197#ifdef DEBUG_ENTITY_STATES2219#ifdef DEBUG_ENTITY_STATES
2198 qCDebug(scriptengine) << "loadEntityScript.contentAvailable" << status << QUrl(url).fileName() << entityID.toString();2220 qCDebug(scriptengine) << "loadEntityScript.contentAvailable" << status << QUrl(url).fileName() << entityID.toString();
2199#endif2221#endif
2200 if (!isStopping() && _entityScripts.contains(entityID)) {2222 if (!isStopping() && hasEntityScriptDetails(entityID)) {
2201 _contentAvailableQueue[entityID] = { entityID, url, contents, isURL, success, status };2223 _contentAvailableQueue[entityID] = { entityID, url, contents, isURL, success, status };
2202 } else {2224 } else {
2203#ifdef DEBUG_ENTITY_STATES2225#ifdef DEBUG_ENTITY_STATES
@@ -2267,8 +2289,11 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 63 unmodified lines
2267 bool isFileUrl = isURL && scriptOrURL.startsWith("file://");2289 bool isFileUrl = isURL && scriptOrURL.startsWith("file://");
2268 auto fileName = isURL ? scriptOrURL : "about:EmbeddedEntityScript";2290 auto fileName = isURL ? scriptOrURL : "about:EmbeddedEntityScript";
2269 2291
2270 const EntityScriptDetails &oldDetails = _entityScripts[entityID];2292 QString entityScript;
2271 const QString entityScript = oldDetails.scriptText;2293 {
2294 QWriteLocker locker { &_entityScriptsLock };
2295 entityScript = _entityScripts[entityID].scriptText;
2296 }
2272 2297
2273 EntityScriptDetails newDetails;2298 EntityScriptDetails newDetails;
2274 newDetails.scriptText = scriptOrURL;2299 newDetails.scriptText = scriptOrURL;
@@ -2418,6 +2443,8 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 143 unmodified lines
2418 // if we got this far, then call the preload method2443 // if we got this far, then call the preload method
2419 callEntityScriptMethod(entityID, "preload");2444 callEntityScriptMethod(entityID, "preload");
2420 2445
2446 emit entityScriptPreloadFinished(entityID);
2447
2421 _occupiedScriptURLs.remove(entityScript);2448 _occupiedScriptURLs.remove(entityScript);
2422 processDeferredEntityLoads(entityScript, entityID);2449 processDeferredEntityLoads(entityScript, entityID);
2423}2450}
@@ -2446,8 +2473,8 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldR · 22 unmodified lines
2446 "entityID:" << entityID;2473 "entityID:" << entityID;
2447#endif2474#endif
2448 2475
2449 if (_entityScripts.contains(entityID)) {2476 EntityScriptDetails oldDetails;
2450 const EntityScriptDetails &oldDetails = _entityScripts[entityID];2477 if (getEntityScriptDetails(entityID, oldDetails)) {
2451 auto scriptText = oldDetails.scriptText;2478 auto scriptText = oldDetails.scriptText;
2452 2479
2453 if (isEntityScriptRunning(entityID)) {2480 if (isEntityScriptRunning(entityID)) {
@@ -2460,7 +2487,10 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldR · 6 unmodified lines
2460#endif2487#endif
2461 if (shouldRemoveFromMap) {2488 if (shouldRemoveFromMap) {
2462 // this was a deleted entity, we've been asked to remove it from the map2489 // 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 }
2464 emit entityScriptDetailsUpdated();2494 emit entityScriptDetailsUpdated();
2465 } else if (oldDetails.status != EntityScriptStatus::UNLOADED) {2495 } else if (oldDetails.status != EntityScriptStatus::UNLOADED) {
2466 EntityScriptDetails newDetails;2496 EntityScriptDetails newDetails;
@@ -2491,10 +2521,19 @@ void ScriptEngine::unloadAllEntityScripts() { · 24 unmodified lines
2491#ifdef THREAD_DEBUGGING2521#ifdef THREAD_DEBUGGING
2492 qCDebug(scriptengine) << "ScriptEngine::unloadAllEntityScripts() called on correct thread [" << thread() << "]";2522 qCDebug(scriptengine) << "ScriptEngine::unloadAllEntityScripts() called on correct thread [" << thread() << "]";
2493#endif2523#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) {
2495 unloadEntityScript(entityID);2531 unloadEntityScript(entityID);
2496 }2532 }
2497 _entityScripts.clear();2533 {
2534 QWriteLocker locker{ &_entityScriptsLock };
2535 _entityScripts.clear();
2536 }
2498 emit entityScriptDetailsUpdated();2537 emit entityScriptDetailsUpdated();
2499 _occupiedScriptURLs.clear();2538 _occupiedScriptURLs.clear();
2500 2539
@@ -2508,7 +2547,7 @@ void ScriptEngine::unloadAllEntityScripts() { · 7 unmodified lines
2508}2547}
2509 2548
2510void ScriptEngine::refreshFileScript(const EntityItemID& entityID) {2549void ScriptEngine::refreshFileScript(const EntityItemID& entityID) {
2511 if (!HIFI_AUTOREFRESH_FILE_SCRIPTS || !_entityScripts.contains(entityID)) {2550 if (!HIFI_AUTOREFRESH_FILE_SCRIPTS || !hasEntityScriptDetails(entityID)) {
2512 return;2551 return;
2513 }2552 }
2514 2553
@@ -2518,7 +2557,11 @@ void ScriptEngine::refreshFileScript(const EntityItemID& entityID) { · 3 unmodified lines
2518 }2557 }
2519 recurseGuard = true;2558 recurseGuard = true;
2520 2559
2521 EntityScriptDetails details = _entityScripts[entityID];2560 EntityScriptDetails details;
2561 {
2562 QWriteLocker locker { &_entityScriptsLock };
2563 details = _entityScripts[entityID];
2564 }
2522 // Check to see if a file based script needs to be reloaded (easier debugging)2565 // Check to see if a file based script needs to be reloaded (easier debugging)
2523 if (details.lastModified > 0) {2566 if (details.lastModified > 0) {
2524 QString filePath = QUrl(details.scriptText).toLocalFile();2567 QString filePath = QUrl(details.scriptText).toLocalFile();
@@ -2584,7 +2627,11 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 59 unmodified lines
2584 refreshFileScript(entityID);2627 refreshFileScript(entityID);
2585 }2628 }
2586 if (isEntityScriptRunning(entityID)) {2629 if (isEntityScriptRunning(entityID)) {
2587 EntityScriptDetails details = _entityScripts[entityID];2630 EntityScriptDetails details;
2631 {
2632 QWriteLocker locker { &_entityScriptsLock };
2633 details = _entityScripts[entityID];
2634 }
2588 QScriptValue entityScript = details.scriptObject; // previously loaded2635 QScriptValue entityScript = details.scriptObject; // previously loaded
2589 2636
2590 // If this is a remote call, we need to check to see if the function is remotely callable2637 // 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
2646 refreshFileScript(entityID);2693 refreshFileScript(entityID);
2647 }2694 }
2648 if (isEntityScriptRunning(entityID)) {2695 if (isEntityScriptRunning(entityID)) {
2649 EntityScriptDetails details = _entityScripts[entityID];2696 EntityScriptDetails details;
2697 {
2698 QWriteLocker locker { &_entityScriptsLock };
2699 details = _entityScripts[entityID];
2700 }
2650 QScriptValue entityScript = details.scriptObject; // previously loaded2701 QScriptValue entityScript = details.scriptObject; // previously loaded
2651 if (entityScript.property(methodName).isFunction()) {2702 if (entityScript.property(methodName).isFunction()) {
2652 QScriptValueList args;2703 QScriptValueList args;
@@ -2680,7 +2731,11 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 27 unmodified lines
2680 refreshFileScript(entityID);2731 refreshFileScript(entityID);
2681 }2732 }
2682 if (isEntityScriptRunning(entityID)) {2733 if (isEntityScriptRunning(entityID)) {
2683 EntityScriptDetails details = _entityScripts[entityID];2734 EntityScriptDetails details;
2735 {
2736 QWriteLocker locker { &_entityScriptsLock };
2737 details = _entityScripts[entityID];
2738 }
2684 QScriptValue entityScript = details.scriptObject; // previously loaded2739 QScriptValue entityScript = details.scriptObject; // previously loaded
2685 if (entityScript.property(methodName).isFunction()) {2740 if (entityScript.property(methodName).isFunction()) {
2686 QScriptValueList args;2741 QScriptValueList args;