Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 8 files). Show all
Unified · Split
| @@ -258,6 +258,15 @@ void ScriptEngine::errorInLoadingScript(const QUrl& url) { · 257 unmodified lines | ||
| 258 | 258 | } |
| 259 | 259 | } |
| 260 | 260 | |
| 261 | +// Even though we never pass AnimVariantMap directly to and from javascript, the queued invokeMethod of | |
| 262 | +// invokeAnimationCallback requires that the type be registered. | |
| 263 | +static QScriptValue animVarMapToScriptValue(QScriptEngine* engine, const AnimVariantMap& parameters) { | |
| 264 | + return parameters.animVariantMapToScriptValue(engine); | |
| 265 | +} | |
| 266 | +static void animVarMapFromScriptValue(const QScriptValue& value, AnimVariantMap& parameters) { | |
| 267 | + parameters.animVariantMapFromScriptValue(value); | |
| 268 | +} | |
| 269 | + | |
| 261 | 270 | void ScriptEngine::init() { |
| 262 | 271 | if (_isInitialized) { |
| 263 | 272 | return; // only initialize once |
| @@ -316,6 +325,7 @@ void ScriptEngine::init() { · 52 unmodified lines | ||
| 316 | 325 | registerGlobalObject("Vec3", &_vec3Library); |
| 317 | 326 | registerGlobalObject("Uuid", &_uuidLibrary); |
| 318 | 327 | registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCache>().data()); |
| 328 | + qScriptRegisterMetaType(this, animVarMapToScriptValue, animVarMapFromScriptValue); | |
| 319 | 329 | |
| 320 | 330 | // constants |
| 321 | 331 | globalObject().setProperty("TREE_SCALE", newVariant(QVariant(TREE_SCALE))); |
| @@ -718,6 +728,21 @@ void ScriptEngine::stop() { · 396 unmodified lines | ||
| 718 | 728 | } |
| 719 | 729 | } |
| 720 | 730 | |
| 731 | +// Other threads can invoke this through invokeMethod, which causes the callback to be asynchronously executed in this script's thread. | |
| 732 | +void ScriptEngine::invokeAnimationCallback(QScriptValue callback, AnimVariantMap parameters) { | |
| 733 | + checkThread(); | |
| 734 | + QScriptValue javascriptParametgers = parameters.animVariantMapToScriptValue(this); | |
| 735 | + QScriptValueList callingArguments; | |
| 736 | + callingArguments << javascriptParametgers; | |
| 737 | + QScriptValue result = callback.call(QScriptValue(), callingArguments); | |
| 738 | + // We want to give the result back to the rig, but we don't have the rig or the avatar. But the global does. | |
| 739 | + // This is sort of like going through DependencyManager.get. | |
| 740 | + QScriptValue resultHandler = globalObject().property("MyAvatar").property("animationStateHandlerResult"); | |
| 741 | + QScriptValueList resultArguments; | |
| 742 | + resultArguments << callback << result; | |
| 743 | + resultHandler.call(QScriptValue(), resultArguments); // Call it synchronously, on our own time and thread. | |
| 744 | +} | |
| 745 | + | |
| 721 | 746 | void ScriptEngine::timerFired() { |
| 722 | 747 | QTimer* callingTimer = reinterpret_cast<QTimer*>(sender()); |
| 723 | 748 | QScriptValue timerFunction = _timerFunctionMap.value(callingTimer); |
| @@ -898,14 +923,20 @@ void ScriptEngine::load(const QString& loadFile) { · 174 unmodified lines | ||
| 898 | 923 | } |
| 899 | 924 | } |
| 900 | 925 | |
| 901 | −// Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args | |
| 902 | −void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& eventName, std::function<QScriptValueList()> argGenerator) { | |
| 926 | +bool ScriptEngine::checkThread() const { | |
| 903 | 927 | if (QThread::currentThread() != thread()) { |
| 904 | 928 | qDebug() << "*** ERROR *** ScriptEngine::generalHandler() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "]"; |
| 905 | 929 | assert(false); |
| 906 | − return; | |
| 930 | + return true; | |
| 907 | 931 | } |
| 932 | + return false; | |
| 933 | +} | |
| 908 | 934 | |
| 935 | +// Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args | |
| 936 | +void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& eventName, std::function<QScriptValueList()> argGenerator) { | |
| 937 | + if (checkThread()) { | |
| 938 | + return; | |
| 939 | + } | |
| 909 | 940 | if (!_registeredHandlers.contains(entityID)) { |
| 910 | 941 | return; |
| 911 | 942 | } |