History

merge from upstream

Seth Alves committed 9 years ago

Commit c317ba82 parents bbe3f11 42083a195 files · +1644 −403Browse files

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

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+70−15
@@ -148,25 +148,29 @@ static bool hasCorrectSyntax(const QScriptProgram& program, ScriptEngine* report · 147 unmodified lines
148 return true;148 return true;
149}149}
150 150
151static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName, ScriptEngine* reportingEngine) {151static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName, ScriptEngine* reportingEngine, QString* exceptionMessage = nullptr) {
152 if (engine.hasUncaughtException()) {152 if (engine.hasUncaughtException()) {
153 const auto backtrace = engine.uncaughtExceptionBacktrace();153 const auto backtrace = engine.uncaughtExceptionBacktrace();
154 const auto exception = engine.uncaughtException().toString();154 const auto exception = engine.uncaughtException().toString();
155 const auto line = QString::number(engine.uncaughtExceptionLineNumber());155 const auto line = QString::number(engine.uncaughtExceptionLineNumber());
156 engine.clearExceptions();156 engine.clearExceptions();
157 157
158 auto message = QString(SCRIPT_EXCEPTION_FORMAT).arg(exception, fileName, line);158 QString message = QString(SCRIPT_EXCEPTION_FORMAT).arg(exception, fileName, line);
159 if (!backtrace.empty()) {159 if (!backtrace.empty()) {
160 static const auto lineSeparator = "\n ";160 static const auto lineSeparator = "\n ";
161 message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator));161 message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator));
162 }162 }
163 reportingEngine->scriptErrorMessage(qPrintable(message));163 reportingEngine->scriptErrorMessage(qPrintable(message));
164 if (exceptionMessage) {
165 *exceptionMessage = message;
166 }
164 return true;167 return true;
165 }168 }
166 return false;169 return false;
167}170}
168 171
169ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNameString) :172ScriptEngine::ScriptEngine(Context context, const QString& scriptContents, const QString& fileNameString) :
173 _context(context),
170 _scriptContents(scriptContents),174 _scriptContents(scriptContents),
171 _timerFunctionMap(),175 _timerFunctionMap(),
172 _fileNameString(fileNameString),176 _fileNameString(fileNameString),
@@ -181,6 +185,22 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam · 8 unmodified lines
181 setProcessEventsInterval(MSECS_PER_SECOND);185 setProcessEventsInterval(MSECS_PER_SECOND);
182}186}
183 187
188QString ScriptEngine::getContext() const {
189 switch (_context) {
190 case CLIENT_SCRIPT:
191 return "client";
192 case ENTITY_CLIENT_SCRIPT:
193 return "entity_client";
194 case ENTITY_SERVER_SCRIPT:
195 return "entity_server";
196 case AGENT_SCRIPT:
197 return "agent";
198 default:
199 return "unknown";
200 }
201 return "unknown";
202}
203
184ScriptEngine::~ScriptEngine() {204ScriptEngine::~ScriptEngine() {
185 scriptInfoMessage("Script Engine shutting down:" + getFilename());205 scriptInfoMessage("Script Engine shutting down:" + getFilename());
186 206
@@ -563,11 +583,7 @@ void ScriptEngine::init() { · 376 unmodified lines
563 // constants583 // constants
564 globalObject().setProperty("TREE_SCALE", newVariant(QVariant(TREE_SCALE)));584 globalObject().setProperty("TREE_SCALE", newVariant(QVariant(TREE_SCALE)));
565 585
566 auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
567 registerGlobalObject("Recording", recordingInterface.data());
568
569 registerGlobalObject("Tablet", DependencyManager::get<TabletScriptingInterface>().data());586 registerGlobalObject("Tablet", DependencyManager::get<TabletScriptingInterface>().data());
570
571 registerGlobalObject("Assets", &_assetScriptingInterface);587 registerGlobalObject("Assets", &_assetScriptingInterface);
572 registerGlobalObject("Resources", DependencyManager::get<ResourceScriptingInterface>().data());588 registerGlobalObject("Resources", DependencyManager::get<ResourceScriptingInterface>().data());
573}589}
@@ -1377,6 +1393,15 @@ void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QStrin · 803 unmodified lines
1377 }1393 }
1378}1394}
1379 1395
1396bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const {
1397 auto it = _entityScripts.constFind(entityID);
1398 if (it == _entityScripts.constEnd()) {
1399 return false;
1400 }
1401 details = it.value();
1402 return true;
1403}
1404
1380// since all of these operations can be asynch we will always do the actual work in the response handler1405// since all of these operations can be asynch we will always do the actual work in the response handler
1381// for the download1406// for the download
1382void ScriptEngine::loadEntityScript(QWeakPointer<ScriptEngine> theEngine, const EntityItemID& entityID, const QString& entityScript, bool forceRedownload) {1407void ScriptEngine::loadEntityScript(QWeakPointer<ScriptEngine> theEngine, const EntityItemID& entityID, const QString& entityScript, bool forceRedownload) {
@@ -1424,11 +1449,24 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 41 unmodified lines
1424 bool isFileUrl = isURL && scriptOrURL.startsWith("file://");1449 bool isFileUrl = isURL && scriptOrURL.startsWith("file://");
1425 auto fileName = isURL ? scriptOrURL : "EmbeddedEntityScript";1450 auto fileName = isURL ? scriptOrURL : "EmbeddedEntityScript";
1426 1451
1452 EntityScriptDetails newDetails;
1453 newDetails.scriptText = scriptOrURL;
1454
1455 if (!success) {
1456 newDetails.status = ERROR_LOADING_SCRIPT;
1457 newDetails.errorInfo = "Failed to load script";
1458 _entityScripts[entityID] = newDetails;
1459 return;
1460 }
1461
1427 QScriptProgram program(contents, fileName);1462 QScriptProgram program(contents, fileName);
1428 if (!hasCorrectSyntax(program, this)) {1463 if (!hasCorrectSyntax(program, this)) {
1429 if (!isFileUrl) {1464 if (!isFileUrl) {
1430 scriptCache->addScriptToBadScriptList(scriptOrURL);1465 scriptCache->addScriptToBadScriptList(scriptOrURL);
1431 }1466 }
1467 newDetails.status = ERROR_RUNNING_SCRIPT;
1468 newDetails.errorInfo = "Bad syntax";
1469 _entityScripts[entityID] = newDetails;
1432 return; // done processing script1470 return; // done processing script
1433 }1471 }
1434 1472
@@ -1453,7 +1491,13 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 18 unmodified lines
1453 });1491 });
1454 testConstructor = sandbox.evaluate(program);1492 testConstructor = sandbox.evaluate(program);
1455 }1493 }
1456 if (hadUncaughtExceptions(sandbox, program.fileName(), this)) {1494
1495 QString exceptionMessage;
1496 if (hadUncaughtExceptions(sandbox, program.fileName(), this, &exceptionMessage)) {
1497 newDetails.status = ERROR_RUNNING_SCRIPT;
1498 newDetails.errorInfo = exceptionMessage;
1499 _entityScripts[entityID] = newDetails;
1500
1457 return;1501 return;
1458 }1502 }
1459 1503
@@ -1476,6 +1520,10 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 16 unmodified lines
1476 scriptCache->addScriptToBadScriptList(scriptOrURL);1520 scriptCache->addScriptToBadScriptList(scriptOrURL);
1477 }1521 }
1478 1522
1523 newDetails.status = ERROR_RUNNING_SCRIPT;
1524 newDetails.errorInfo = "Could not find constructor";
1525 _entityScripts[entityID] = newDetails;
1526
1479 return; // done processing script1527 return; // done processing script
1480 }1528 }
1481 1529
@@ -1492,8 +1540,11 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 10 unmodified lines
1492 };1540 };
1493 doWithEnvironment(entityID, sandboxURL, initialization);1541 doWithEnvironment(entityID, sandboxURL, initialization);
1494 1542
1495 EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified, sandboxURL };1543 newDetails.scriptObject = entityScriptObject;
1544 newDetails.lastModified = lastModified;
1545 newDetails.definingSandboxURL = sandboxURL;
1496 _entityScripts[entityID] = newDetails;1546 _entityScripts[entityID] = newDetails;
1547
1497 if (isURL) {1548 if (isURL) {
1498 setParentURL("");1549 setParentURL("");
1499 }1550 }
@@ -1519,7 +1570,9 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID) { · 19 unmodified lines
1519#endif1570#endif
1520 1571
1521 if (_entityScripts.contains(entityID)) {1572 if (_entityScripts.contains(entityID)) {
1522 callEntityScriptMethod(entityID, "unload");1573 if (_entityScripts[entityID].status == RUNNING) {
1574 callEntityScriptMethod(entityID, "unload");
1575 }
1523 _entityScripts.remove(entityID);1576 _entityScripts.remove(entityID);
1524 stopAllTimersForEntityScript(entityID);1577 stopAllTimersForEntityScript(entityID);
1525 }1578 }
@@ -1538,7 +1591,9 @@ void ScriptEngine::unloadAllEntityScripts() { · 12 unmodified lines
1538 qCDebug(scriptengine) << "ScriptEngine::unloadAllEntityScripts() called on correct thread [" << thread() << "]";1591 qCDebug(scriptengine) << "ScriptEngine::unloadAllEntityScripts() called on correct thread [" << thread() << "]";
1539#endif1592#endif
1540 foreach(const EntityItemID& entityID, _entityScripts.keys()) {1593 foreach(const EntityItemID& entityID, _entityScripts.keys()) {
1541 callEntityScriptMethod(entityID, "unload");1594 if (_entityScripts[entityID].status == RUNNING) {
1595 callEntityScriptMethod(entityID, "unload");
1596 }
1542 }1597 }
1543 _entityScripts.clear();1598 _entityScripts.clear();
1544 1599
@@ -1577,7 +1632,7 @@ void ScriptEngine::refreshFileScript(const EntityItemID& entityID) { · 32 unmodified lines
1577 QString scriptContents = QTextStream(&file).readAll();1632 QString scriptContents = QTextStream(&file).readAll();
1578 this->unloadEntityScript(entityID);1633 this->unloadEntityScript(entityID);
1579 this->entityScriptContentAvailable(entityID, details.scriptText, scriptContents, true, true);1634 this->entityScriptContentAvailable(entityID, details.scriptText, scriptContents, true, true);
1580 if (!_entityScripts.contains(entityID)) {1635 if (!_entityScripts.contains(entityID) || _entityScripts[entityID].status != RUNNING) {
1581 scriptWarningMessage("Reload script " + details.scriptText + " failed");1636 scriptWarningMessage("Reload script " + details.scriptText + " failed");
1582 } else {1637 } else {
1583 details = _entityScripts[entityID];1638 details = _entityScripts[entityID];
@@ -1636,7 +1691,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 52 unmodified lines
1636#endif1691#endif
1637 1692
1638 refreshFileScript(entityID);1693 refreshFileScript(entityID);
1639 if (_entityScripts.contains(entityID)) {1694 if (_entityScripts.contains(entityID) && _entityScripts[entityID].status == RUNNING) {
1640 EntityScriptDetails details = _entityScripts[entityID];1695 EntityScriptDetails details = _entityScripts[entityID];
1641 QScriptValue entityScript = details.scriptObject; // previously loaded1696 QScriptValue entityScript = details.scriptObject; // previously loaded
1642 if (entityScript.property(methodName).isFunction()) {1697 if (entityScript.property(methodName).isFunction()) {
@@ -1668,7 +1723,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 25 unmodified lines
1668#endif1723#endif
1669 1724
1670 refreshFileScript(entityID);1725 refreshFileScript(entityID);
1671 if (_entityScripts.contains(entityID)) {1726 if (_entityScripts.contains(entityID) && _entityScripts[entityID].status == RUNNING) {
1672 EntityScriptDetails details = _entityScripts[entityID];1727 EntityScriptDetails details = _entityScripts[entityID];
1673 QScriptValue entityScript = details.scriptObject; // previously loaded1728 QScriptValue entityScript = details.scriptObject; // previously loaded
1674 if (entityScript.property(methodName).isFunction()) {1729 if (entityScript.property(methodName).isFunction()) {
@@ -1701,7 +1756,7 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 26 unmodified lines
1701#endif1756#endif
1702 1757
1703 refreshFileScript(entityID);1758 refreshFileScript(entityID);
1704 if (_entityScripts.contains(entityID)) {1759 if (_entityScripts.contains(entityID) && _entityScripts[entityID].status == RUNNING) {
1705 EntityScriptDetails details = _entityScripts[entityID];1760 EntityScriptDetails details = _entityScripts[entityID];
1706 QScriptValue entityScript = details.scriptObject; // previously loaded1761 QScriptValue entityScript = details.scriptObject; // previously loaded
1707 if (entityScript.property(methodName).isFunction()) {1762 if (entityScript.property(methodName).isFunction()) {