This is a slightly hacky way to make ScriptManager work without any networking, and minimize the number of dependencies needed to run a test.
Showing the changes to libraries/script-engine/src/ScriptManager.cpp (1 of 7 files). Show all
Unified · Split
| @@ -269,6 +269,9 @@ ScriptManager::ScriptManager(Context context, const QString& scriptContents, con · 268 unmodified lines | ||
| 269 | 269 | case Context::AGENT_SCRIPT: |
| 270 | 270 | _type = Type::AGENT; |
| 271 | 271 | break; |
| 272 | + case Context::NETWORKLESS_TEST_SCRIPT: | |
| 273 | + _type = Type::NETWORKLESS_TEST; | |
| 274 | + break; | |
| 272 | 275 | } |
| 273 | 276 | |
| 274 | 277 | _scriptingInterface = std::make_shared<ScriptManagerScriptingInterface>(this); |
| @@ -321,6 +324,8 @@ QString ScriptManager::getContext() const { · 46 unmodified lines | ||
| 321 | 324 | return "entity_server"; |
| 322 | 325 | case AGENT_SCRIPT: |
| 323 | 326 | return "agent"; |
| 327 | + case NETWORKLESS_TEST_SCRIPT: | |
| 328 | + return "networkless_test"; | |
| 324 | 329 | default: |
| 325 | 330 | return "unknown"; |
| 326 | 331 | } |
| @@ -664,15 +669,25 @@ void ScriptManager::init() { · 337 unmodified lines | ||
| 664 | 669 | } |
| 665 | 670 | |
| 666 | 671 | _isInitialized = true; |
| 667 | − runStaticInitializers(this); | |
| 672 | + | |
| 673 | + if (_context != NETWORKLESS_TEST_SCRIPT) { | |
| 674 | + // This initializes a bunch of systems that want network access. We | |
| 675 | + // want to avoid it in test script mode. | |
| 676 | + runStaticInitializers(this); | |
| 677 | + } | |
| 668 | 678 | |
| 669 | 679 | auto scriptEngine = _engine.get(); |
| 670 | 680 | |
| 671 | − ScriptValue xmlHttpRequestConstructorValue = scriptEngine->newFunction(XMLHttpRequestClass::constructor); | |
| 672 | − scriptEngine->globalObject().setProperty("XMLHttpRequest", xmlHttpRequestConstructorValue); | |
| 681 | + if (_context != NETWORKLESS_TEST_SCRIPT) { | |
| 682 | + // For test scripts we want to minimize the amount of functionality available, for the least | |
| 683 | + // amount of dependencies and faster test system startup. | |
| 684 | + | |
| 685 | + ScriptValue xmlHttpRequestConstructorValue = scriptEngine->newFunction(XMLHttpRequestClass::constructor); | |
| 686 | + scriptEngine->globalObject().setProperty("XMLHttpRequest", xmlHttpRequestConstructorValue); | |
| 673 | 687 | |
| 674 | − ScriptValue webSocketConstructorValue = scriptEngine->newFunction(WebSocketClass::constructor); | |
| 675 | − scriptEngine->globalObject().setProperty("WebSocket", webSocketConstructorValue); | |
| 688 | + ScriptValue webSocketConstructorValue = scriptEngine->newFunction(WebSocketClass::constructor); | |
| 689 | + scriptEngine->globalObject().setProperty("WebSocket", webSocketConstructorValue); | |
| 690 | + } | |
| 676 | 691 | |
| 677 | 692 | /*@jsdoc |
| 678 | 693 | * Prints a message to the program log and emits {@link Script.printedMessage}. |
| @@ -703,7 +718,12 @@ void ScriptManager::init() { · 24 unmodified lines | ||
| 703 | 718 | scriptEngine->registerGlobalObject("Vec3", &_vec3Library); |
| 704 | 719 | scriptEngine->registerGlobalObject("Mat4", &_mat4Library); |
| 705 | 720 | scriptEngine->registerGlobalObject("Uuid", &_uuidLibrary); |
| 706 | − scriptEngine->registerGlobalObject("Messages", DependencyManager::get<MessagesClient>().data()); | |
| 721 | + | |
| 722 | + if (_context != NETWORKLESS_TEST_SCRIPT) { | |
| 723 | + // This requires networking, we want to avoid the need for it in test scripts | |
| 724 | + scriptEngine->registerGlobalObject("Messages", DependencyManager::get<MessagesClient>().data()); | |
| 725 | + } | |
| 726 | + | |
| 707 | 727 | scriptEngine->registerGlobalObject("File", new FileScriptingInterface(this)); |
| 708 | 728 | scriptEngine->registerGlobalObject("console", &_consoleScriptingInterface); |
| 709 | 729 | scriptEngine->registerFunction("console", "info", ConsoleScriptingInterface::info, scriptEngine->currentContext()->argumentCount()); |
| @@ -717,25 +737,28 @@ void ScriptManager::init() { · 7 unmodified lines | ||
| 717 | 737 | scriptEngine->registerFunction("console", "groupCollapsed", ConsoleScriptingInterface::groupCollapsed, 1); |
| 718 | 738 | scriptEngine->registerFunction("console", "groupEnd", ConsoleScriptingInterface::groupEnd, 0); |
| 719 | 739 | |
| 720 | − // Scriptable cache access | |
| 721 | − auto resourcePrototype = createScriptableResourcePrototype(shared_from_this()); | |
| 722 | − scriptEngine->globalObject().setProperty("Resource", resourcePrototype); | |
| 723 | − scriptEngine->setDefaultPrototype(qMetaTypeId<ScriptableResource*>(), resourcePrototype); | |
| 724 | − | |
| 725 | 740 | // constants |
| 726 | 741 | scriptEngine->globalObject().setProperty("TREE_SCALE", scriptEngine->newValue(TREE_SCALE)); |
| 727 | 742 | |
| 728 | − scriptEngine->registerGlobalObject("Assets", _assetScriptingInterface); | |
| 729 | − scriptEngine->registerGlobalObject("Resources", DependencyManager::get<ResourceScriptingInterface>().data()); | |
| 743 | + if (_context != NETWORKLESS_TEST_SCRIPT) { | |
| 744 | + // Scriptable cache access | |
| 745 | + auto resourcePrototype = createScriptableResourcePrototype(shared_from_this()); | |
| 746 | + scriptEngine->globalObject().setProperty("Resource", resourcePrototype); | |
| 747 | + scriptEngine->setDefaultPrototype(qMetaTypeId<ScriptableResource*>(), resourcePrototype); | |
| 748 | + | |
| 749 | + scriptEngine->registerGlobalObject("Assets", _assetScriptingInterface); | |
| 750 | + scriptEngine->registerGlobalObject("Resources", DependencyManager::get<ResourceScriptingInterface>().data()); | |
| 730 | 751 | |
| 731 | − scriptEngine->registerGlobalObject("DebugDraw", &DebugDraw::getInstance()); | |
| 752 | + scriptEngine->registerGlobalObject("DebugDraw", &DebugDraw::getInstance()); | |
| 732 | 753 | |
| 733 | − scriptEngine->registerGlobalObject("UserActivityLogger", DependencyManager::get<UserActivityLoggerScriptingInterface>().data()); | |
| 754 | + scriptEngine->registerGlobalObject("UserActivityLogger", DependencyManager::get<UserActivityLoggerScriptingInterface>().data()); | |
| 755 | + } | |
| 734 | 756 | |
| 735 | 757 | #if DEV_BUILD || PR_BUILD |
| 736 | 758 | scriptEngine->registerGlobalObject("StackTest", new StackTestScriptingInterface(this)); |
| 737 | 759 | #endif |
| 738 | 760 | |
| 761 | + qCDebug(scriptengine) << "Engine initialized"; | |
| 739 | 762 | } |
| 740 | 763 | |
| 741 | 764 | // registers a global object by name |
| @@ -820,6 +843,10 @@ void ScriptManager::addEventHandler(const EntityItemID& entityID, const QString& · 78 unmodified lines | ||
| 820 | 843 | } |
| 821 | 844 | |
| 822 | 845 | bool ScriptManager::isStopped() const { |
| 846 | + if (_context == NETWORKLESS_TEST_SCRIPT) { | |
| 847 | + return false; | |
| 848 | + } | |
| 849 | + | |
| 823 | 850 | QSharedPointer<ScriptEngines> scriptEngines(_scriptEngines); |
| 824 | 851 | return !scriptEngines || scriptEngines->isStopped(); |
| 825 | 852 | } |
| @@ -841,6 +868,7 @@ void ScriptManager::run() { · 15 unmodified lines | ||
| 841 | 868 | PROFILE_SET_THREAD_NAME("Script: " + name); |
| 842 | 869 | |
| 843 | 870 | if (isStopped()) { |
| 871 | + qCCritical(scriptengine) << "ScriptManager is stopped or ScriptEngines is not available, refusing to run script"; | |
| 844 | 872 | return; // bail early - avoid setting state in init(), as evaluate() will bail too |
| 845 | 873 | } |
| 846 | 874 | |
| @@ -873,8 +901,12 @@ void ScriptManager::run() { · 26 unmodified lines | ||
| 873 | 901 | |
| 874 | 902 | std::chrono::microseconds totalUpdates(0); |
| 875 | 903 | |
| 904 | + qCDebug(scriptengine) << "Waiting for finish"; | |
| 905 | + | |
| 876 | 906 | // TODO: Integrate this with signals/slots instead of reimplementing throttling for ScriptManager |
| 877 | 907 | while (!_isFinished) { |
| 908 | + qCDebug(scriptengine) << "In script event loop"; | |
| 909 | + | |
| 878 | 910 | auto beforeSleep = clock::now(); |
| 879 | 911 | |
| 880 | 912 | // Throttle to SCRIPT_FPS |