mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
tighten up locking in actions
This commit is contained in:
parent
9a9e5b962e
commit
fa2bf2b2d9
4 changed files with 135 additions and 94 deletions
|
@ -37,37 +37,41 @@ AvatarActionHold::~AvatarActionHold() {
|
|||
}
|
||||
|
||||
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
||||
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
|
||||
AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID);
|
||||
std::shared_ptr<Avatar> holdingAvatar = std::static_pointer_cast<Avatar>(holdingAvatarData);
|
||||
bool gotLock = false;
|
||||
glm::quat rotation;
|
||||
glm::vec3 position;
|
||||
std::shared_ptr<Avatar> holdingAvatar = nullptr;
|
||||
|
||||
gotLock = withTryReadLock([&]{
|
||||
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
|
||||
AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID);
|
||||
holdingAvatar = std::static_pointer_cast<Avatar>(holdingAvatarData);
|
||||
|
||||
if (holdingAvatar) {
|
||||
glm::vec3 offset;
|
||||
glm::vec3 palmPosition;
|
||||
glm::quat palmRotation;
|
||||
if (_hand == "right") {
|
||||
palmPosition = holdingAvatar->getRightPalmPosition();
|
||||
palmRotation = holdingAvatar->getRightPalmRotation();
|
||||
} else {
|
||||
palmPosition = holdingAvatar->getLeftPalmPosition();
|
||||
palmRotation = holdingAvatar->getLeftPalmRotation();
|
||||
}
|
||||
|
||||
rotation = palmRotation * _relativeRotation;
|
||||
offset = rotation * _relativePosition;
|
||||
position = palmPosition + offset;
|
||||
}
|
||||
});
|
||||
|
||||
if (holdingAvatar) {
|
||||
glm::quat rotation;
|
||||
glm::vec3 position;
|
||||
glm::vec3 offset;
|
||||
bool gotLock = withTryReadLock([&]{
|
||||
glm::vec3 palmPosition;
|
||||
glm::quat palmRotation;
|
||||
if (_hand == "right") {
|
||||
palmPosition = holdingAvatar->getRightPalmPosition();
|
||||
palmRotation = holdingAvatar->getRightPalmRotation();
|
||||
} else {
|
||||
palmPosition = holdingAvatar->getLeftPalmPosition();
|
||||
palmRotation = holdingAvatar->getLeftPalmRotation();
|
||||
}
|
||||
|
||||
rotation = palmRotation * _relativeRotation;
|
||||
offset = rotation * _relativePosition;
|
||||
position = palmPosition + offset;
|
||||
});
|
||||
|
||||
if (gotLock) {
|
||||
gotLock = withTryWriteLock([&]{
|
||||
_positionalTarget = position;
|
||||
_rotationalTarget = rotation;
|
||||
});
|
||||
_positionalTarget = position;
|
||||
_rotationalTarget = rotation;
|
||||
});
|
||||
}
|
||||
|
||||
if (gotLock) {
|
||||
ObjectActionSpring::updateActionWorker(deltaTimeStep);
|
||||
}
|
||||
|
@ -76,46 +80,61 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
|||
|
||||
|
||||
bool AvatarActionHold::updateArguments(QVariantMap arguments) {
|
||||
if (!ObjectAction::updateArguments(arguments)) {
|
||||
return false;
|
||||
}
|
||||
bool ok = true;
|
||||
glm::vec3 relativePosition =
|
||||
EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false);
|
||||
if (!ok) {
|
||||
relativePosition = _relativePosition;
|
||||
}
|
||||
glm::vec3 relativePosition;
|
||||
glm::quat relativeRotation;
|
||||
float timeScale;
|
||||
QString hand;
|
||||
QUuid holderID;
|
||||
bool needUpdate = false;
|
||||
bool updateArgumentsSuceeded = true;
|
||||
|
||||
ok = true;
|
||||
glm::quat relativeRotation =
|
||||
EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false);
|
||||
if (!ok) {
|
||||
relativeRotation = _relativeRotation;
|
||||
}
|
||||
withReadLock([&]{
|
||||
if (!ObjectAction::updateArguments(arguments)) {
|
||||
updateArgumentsSuceeded = false;
|
||||
return;
|
||||
}
|
||||
bool ok = true;
|
||||
relativePosition = EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false);
|
||||
if (!ok) {
|
||||
relativePosition = _relativePosition;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
float timeScale =
|
||||
EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false);
|
||||
if (!ok) {
|
||||
timeScale = _linearTimeScale;
|
||||
}
|
||||
ok = true;
|
||||
relativeRotation = EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false);
|
||||
if (!ok) {
|
||||
relativeRotation = _relativeRotation;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
QString hand =
|
||||
EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false);
|
||||
if (!ok || !(hand == "left" || hand == "right")) {
|
||||
hand = _hand;
|
||||
}
|
||||
ok = true;
|
||||
timeScale = EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false);
|
||||
if (!ok) {
|
||||
timeScale = _linearTimeScale;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
auto holderID = myAvatar->getSessionUUID();
|
||||
ok = true;
|
||||
hand = EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false);
|
||||
if (!ok || !(hand == "left" || hand == "right")) {
|
||||
hand = _hand;
|
||||
}
|
||||
|
||||
if (relativePosition != _relativePosition
|
||||
ok = true;
|
||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
holderID = myAvatar->getSessionUUID();
|
||||
|
||||
if (relativePosition != _relativePosition
|
||||
|| relativeRotation != _relativeRotation
|
||||
|| timeScale != _linearTimeScale
|
||||
|| hand != _hand
|
||||
|| holderID != _holderID) {
|
||||
needUpdate = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!updateArgumentsSuceeded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (needUpdate) {
|
||||
withWriteLock([&] {
|
||||
_relativePosition = relativePosition;
|
||||
_relativeRotation = relativeRotation;
|
||||
|
@ -154,18 +173,20 @@ QByteArray AvatarActionHold::serialize() const {
|
|||
QByteArray serializedActionArguments;
|
||||
QDataStream dataStream(&serializedActionArguments, QIODevice::WriteOnly);
|
||||
|
||||
dataStream << ACTION_TYPE_HOLD;
|
||||
dataStream << getID();
|
||||
dataStream << AvatarActionHold::holdVersion;
|
||||
withReadLock([&]{
|
||||
dataStream << ACTION_TYPE_HOLD;
|
||||
dataStream << getID();
|
||||
dataStream << AvatarActionHold::holdVersion;
|
||||
|
||||
dataStream << _holderID;
|
||||
dataStream << _relativePosition;
|
||||
dataStream << _relativeRotation;
|
||||
dataStream << _linearTimeScale;
|
||||
dataStream << _hand;
|
||||
dataStream << _holderID;
|
||||
dataStream << _relativePosition;
|
||||
dataStream << _relativeRotation;
|
||||
dataStream << _linearTimeScale;
|
||||
dataStream << _hand;
|
||||
|
||||
dataStream << _expires;
|
||||
dataStream << _tag;
|
||||
dataStream << _expires;
|
||||
dataStream << _tag;
|
||||
});
|
||||
|
||||
return serializedActionArguments;
|
||||
}
|
||||
|
@ -187,15 +208,21 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) {
|
|||
return;
|
||||
}
|
||||
|
||||
dataStream >> _holderID;
|
||||
dataStream >> _relativePosition;
|
||||
dataStream >> _relativeRotation;
|
||||
dataStream >> _linearTimeScale;
|
||||
_angularTimeScale = _linearTimeScale;
|
||||
dataStream >> _hand;
|
||||
withWriteLock([&]{
|
||||
dataStream >> _holderID;
|
||||
dataStream >> _relativePosition;
|
||||
dataStream >> _relativeRotation;
|
||||
dataStream >> _linearTimeScale;
|
||||
_angularTimeScale = _linearTimeScale;
|
||||
dataStream >> _hand;
|
||||
|
||||
dataStream >> _expires;
|
||||
dataStream >> _tag;
|
||||
dataStream >> _expires;
|
||||
dataStream >> _tag;
|
||||
|
||||
_active = true;
|
||||
qDebug() << "deserialize hold: " << _holderID
|
||||
<< _relativePosition.x << _relativePosition.y << _relativePosition.z
|
||||
<< _hand;
|
||||
|
||||
_active = true;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -53,16 +53,6 @@ public:
|
|||
|
||||
virtual bool shouldSuppressLocationEdits() { return false; }
|
||||
|
||||
protected:
|
||||
virtual glm::vec3 getPosition() = 0;
|
||||
virtual void setPosition(glm::vec3 position) = 0;
|
||||
virtual glm::quat getRotation() = 0;
|
||||
virtual void setRotation(glm::quat rotation) = 0;
|
||||
virtual glm::vec3 getLinearVelocity() = 0;
|
||||
virtual void setLinearVelocity(glm::vec3 linearVelocity) = 0;
|
||||
virtual glm::vec3 getAngularVelocity() = 0;
|
||||
virtual void setAngularVelocity(glm::vec3 angularVelocity) = 0;
|
||||
|
||||
// these look in the arguments map for a named argument. if it's not found or isn't well formed,
|
||||
// ok will be set to false (note that it's never set to true -- set it to true before calling these).
|
||||
// if required is true, failure to extract an argument will cause a warning to be printed.
|
||||
|
@ -77,6 +67,16 @@ protected:
|
|||
static QString extractStringArgument(QString objectName, QVariantMap arguments,
|
||||
QString argumentName, bool& ok, bool required = true);
|
||||
|
||||
protected:
|
||||
virtual glm::vec3 getPosition() = 0;
|
||||
virtual void setPosition(glm::vec3 position) = 0;
|
||||
virtual glm::quat getRotation() = 0;
|
||||
virtual void setRotation(glm::quat rotation) = 0;
|
||||
virtual glm::vec3 getLinearVelocity() = 0;
|
||||
virtual void setLinearVelocity(glm::vec3 linearVelocity) = 0;
|
||||
virtual glm::vec3 getAngularVelocity() = 0;
|
||||
virtual void setAngularVelocity(glm::vec3 angularVelocity) = 0;
|
||||
|
||||
QUuid _id;
|
||||
EntityActionType _type;
|
||||
};
|
||||
|
|
|
@ -1630,8 +1630,6 @@ void EntityItem::deserializeActionsInternal() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Keep track of which actions got added or updated by the new actionData
|
||||
|
||||
EntityTreePointer entityTree = _element ? _element->getTree() : nullptr;
|
||||
assert(entityTree);
|
||||
EntitySimulation* simulation = entityTree ? entityTree->getSimulation() : nullptr;
|
||||
|
@ -1643,6 +1641,7 @@ void EntityItem::deserializeActionsInternal() {
|
|||
serializedActionsStream >> serializedActions;
|
||||
}
|
||||
|
||||
// Keep track of which actions got added or updated by the new actionData
|
||||
QSet<QUuid> updated;
|
||||
|
||||
foreach(QByteArray serializedAction, serializedActions) {
|
||||
|
@ -1658,12 +1657,14 @@ void EntityItem::deserializeActionsInternal() {
|
|||
updated << actionID;
|
||||
|
||||
if (_objectActions.contains(actionID)) {
|
||||
qDebug() << "EntityItem::deserializeActionsInternal is UPDATING" << actionID;
|
||||
EntityActionPointer action = _objectActions[actionID];
|
||||
// TODO: make sure types match? there isn't currently a way to
|
||||
// change the type of an existing action.
|
||||
action->deserialize(serializedAction);
|
||||
action->locallyAddedButNotYetReceived = false;
|
||||
} else {
|
||||
qDebug() << "EntityItem::deserializeActionsInternal is ADDING" << actionID;
|
||||
auto actionFactory = DependencyManager::get<EntityActionFactoryInterface>();
|
||||
EntityItemPointer entity = shared_from_this();
|
||||
EntityActionPointer action = actionFactory->factoryBA(entity, serializedAction);
|
||||
|
|
|
@ -24,20 +24,33 @@ ObjectAction::~ObjectAction() {
|
|||
}
|
||||
|
||||
void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
|
||||
if (_ownerEntity.expired()) {
|
||||
bool ownerEntityExpired = false;
|
||||
quint64 expiresWhen = 0;
|
||||
|
||||
withReadLock([&]{
|
||||
ownerEntityExpired = _ownerEntity.expired();
|
||||
expiresWhen = _expires;
|
||||
});
|
||||
|
||||
if (ownerEntityExpired) {
|
||||
qDebug() << "warning -- action with no entity removing self from btCollisionWorld.";
|
||||
btDynamicsWorld* dynamicsWorld = static_cast<btDynamicsWorld*>(collisionWorld);
|
||||
dynamicsWorld->removeAction(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_expires > 0) {
|
||||
if (expiresWhen > 0) {
|
||||
quint64 now = usecTimestampNow();
|
||||
if (now > _expires) {
|
||||
EntityItemPointer ownerEntity = _ownerEntity.lock();
|
||||
_active = false;
|
||||
if (now > expiresWhen) {
|
||||
EntityItemPointer ownerEntity = nullptr;
|
||||
QUuid myID;
|
||||
withWriteLock([&]{
|
||||
ownerEntity = _ownerEntity.lock();
|
||||
_active = false;
|
||||
myID = getID();
|
||||
});
|
||||
if (ownerEntity) {
|
||||
ownerEntity->removeAction(nullptr, getID());
|
||||
ownerEntity->removeAction(nullptr, myID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue