Fixed deadlock in updating animation state handlers

This commit is contained in:
ksuprynowicz 2023-03-03 22:13:51 +01:00
parent cae1e1195d
commit 3be4fdc33d
2 changed files with 7 additions and 7 deletions

View file

@ -1598,7 +1598,7 @@ ScriptValue Rig::addAnimationStateHandler(const ScriptValue& handler, const Scri
_nextStateHandlerId++; _nextStateHandlerId++;
} }
StateHandler& data = _stateHandlers[_nextStateHandlerId]; StateHandler& data = _stateHandlers[_nextStateHandlerId];
data.function = handler; data.function = std::make_shared<ScriptValue>(handler);
data.useNames = propertiesList.isArray(); data.useNames = propertiesList.isArray();
if (data.useNames) { if (data.useNames) {
data.propertyNames = propertiesList.toVariant().toStringList(); data.propertyNames = propertiesList.toVariant().toStringList();
@ -1639,7 +1639,7 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
// call out: // call out:
int identifier = data.key(); int identifier = data.key();
StateHandler& value = data.value(); StateHandler& value = data.value();
ScriptValue& function = value.function; std::shared_ptr<ScriptValue> function = value.function;
int rigId = _rigId; int rigId = _rigId;
auto handleResult = [rigId, identifier](const ScriptValue& result) { // called in script thread to get the result back to us. auto handleResult = [rigId, identifier](const ScriptValue& result) { // called in script thread to get the result back to us.
// Hold the rigRegistryMutex to ensure thread-safe access to the rigRegistry, but // Hold the rigRegistryMutex to ensure thread-safe access to the rigRegistry, but
@ -1660,7 +1660,7 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
// Copies of AnimVariantMap do copy the underlying map, so this will correctly capture // Copies of AnimVariantMap do copy the underlying map, so this will correctly capture
// the state of _animVars and allow continued changes to _animVars in this thread without conflict. // the state of _animVars and allow continued changes to _animVars in this thread without conflict.
const AnimVariantMap& animVars = _animVars; const AnimVariantMap& animVars = _animVars;
ScriptEnginePointer engine = function.engine(); ScriptEnginePointer engine = function->engine();
const QStringList& names = value.propertyNames; const QStringList& names = value.propertyNames;
bool useNames = value.useNames; bool useNames = value.useNames;
@ -1670,7 +1670,7 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
ScriptValue javascriptParameters = animVars.animVariantMapToScriptValue(engine.get(), names, useNames); ScriptValue javascriptParameters = animVars.animVariantMapToScriptValue(engine.get(), names, useNames);
ScriptValueList callingArguments; ScriptValueList callingArguments;
callingArguments << javascriptParameters; callingArguments << javascriptParameters;
ScriptValue result = function.call(ScriptValue(), callingArguments); ScriptValue result = function->call(ScriptValue(), callingArguments);
// validate result from callback function. // validate result from callback function.
if (result.isValid() && result.isObject()) { if (result.isValid() && result.isObject()) {
@ -1678,7 +1678,7 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
} else { } else {
qCWarning(animation) << "Rig::updateAnimationStateHandlers invalid return argument from " qCWarning(animation) << "Rig::updateAnimationStateHandlers invalid return argument from "
"callback, expected an object"; "callback, expected an object";
} } //V8TODO: std::shared_ptr<ScriptValue> function should probably be reset here if it's a local copy?
}, },
Qt::QueuedConnection); Qt::QueuedConnection);
} }
@ -1713,7 +1713,7 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons
++_evaluationCount; ++_evaluationCount;
// V8TODO: this causes a deadlock right now // V8TODO: this causes a deadlock right now
//updateAnimationStateHandlers(); updateAnimationStateHandlers();
_animVars.setRigToGeometryTransform(_rigToGeometryTransform); _animVars.setRigToGeometryTransform(_rigToGeometryTransform);
if (_networkNode) { if (_networkNode) {
_networkVars.setRigToGeometryTransform(_rigToGeometryTransform); _networkVars.setRigToGeometryTransform(_rigToGeometryTransform);

View file

@ -42,7 +42,7 @@ public:
struct StateHandler { struct StateHandler {
AnimVariantMap results; AnimVariantMap results;
QStringList propertyNames; QStringList propertyNames;
ScriptValue function; std::shared_ptr<ScriptValue> function;
bool useNames; bool useNames;
}; };