Merge pull request #14077 from sabrina-shanman/crash_ray-pick-dtor_pointer-only

Prevent thread issues with PickResults modified by Pointers
This commit is contained in:
John Conklin II 2018-09-26 12:12:58 -07:00 committed by GitHub
commit c1dc0ff2ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 32 additions and 1 deletions

View file

@ -35,6 +35,14 @@ void LaserPointer::editRenderStatePath(const std::string& state, const QVariant&
}
}
PickResultPointer LaserPointer::getPickResultCopy(const PickResultPointer& pickResult) const {
auto rayPickResult = std::dynamic_pointer_cast<RayPickResult>(pickResult);
if (!rayPickResult) {
return std::make_shared<RayPickResult>();
}
return std::make_shared<RayPickResult>(*rayPickResult.get());
}
QVariantMap LaserPointer::toVariantMap() const {
QVariantMap qVariantMap;

View file

@ -47,6 +47,8 @@ public:
static std::shared_ptr<StartEndRenderState> buildRenderState(const QVariantMap& propMap);
protected:
PickResultPointer getPickResultCopy(const PickResultPointer& pickResult) const override;
void editRenderStatePath(const std::string& state, const QVariant& pathProps) override;
glm::vec3 getPickOrigin(const PickResultPointer& pickResult) const override;

View file

@ -30,6 +30,14 @@ ParabolaPointer::ParabolaPointer(const QVariant& rayProps, const RenderStateMap&
{
}
PickResultPointer ParabolaPointer::getPickResultCopy(const PickResultPointer& pickResult) const {
auto parabolaPickResult = std::dynamic_pointer_cast<ParabolaPickResult>(pickResult);
if (!parabolaPickResult) {
return std::make_shared<ParabolaPickResult>();
}
return std::make_shared<ParabolaPickResult>(*parabolaPickResult.get());
}
void ParabolaPointer::editRenderStatePath(const std::string& state, const QVariant& pathProps) {
auto renderState = std::static_pointer_cast<RenderState>(_renderStates[state]);
if (renderState) {

View file

@ -102,6 +102,8 @@ public:
static std::shared_ptr<StartEndRenderState> buildRenderState(const QVariantMap& propMap);
protected:
virtual PickResultPointer getPickResultCopy(const PickResultPointer& pickResult) const override;
void editRenderStatePath(const std::string& state, const QVariant& pathProps) override;
glm::vec3 getPickOrigin(const PickResultPointer& pickResult) const override;

View file

@ -147,6 +147,14 @@ bool StylusPointer::shouldTrigger(const PickResultPointer& pickResult) {
return false;
}
PickResultPointer StylusPointer::getPickResultCopy(const PickResultPointer& pickResult) const {
auto stylusPickResult = std::dynamic_pointer_cast<StylusPickResult>(pickResult);
if (!stylusPickResult) {
return std::make_shared<StylusPickResult>();
}
return std::make_shared<StylusPickResult>(*stylusPickResult.get());
}
Pointer::PickedObject StylusPointer::getHoveredObject(const PickResultPointer& pickResult) {
auto stylusPickResult = std::static_pointer_cast<const StylusPickResult>(pickResult);
if (!stylusPickResult) {

View file

@ -42,6 +42,7 @@ protected:
Buttons getPressedButtons(const PickResultPointer& pickResult) override;
bool shouldHover(const PickResultPointer& pickResult) override;
bool shouldTrigger(const PickResultPointer& pickResult) override;
virtual PickResultPointer getPickResultCopy(const PickResultPointer& pickResult) const override;
PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, const std::string& button = "", bool hover = true) override;

View file

@ -68,7 +68,8 @@ void Pointer::update(unsigned int pointerID) {
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
withReadLock([&] {
auto pickResult = getPrevPickResult();
auto visualPickResult = getVisualPickResult(pickResult);
// Pointer needs its own PickResult object so it doesn't modify the cached pick result
auto visualPickResult = getVisualPickResult(getPickResultCopy(pickResult));
updateVisuals(visualPickResult);
generatePointerEvents(pointerID, visualPickResult);
});

View file

@ -91,6 +91,7 @@ protected:
virtual bool shouldHover(const PickResultPointer& pickResult) { return true; }
virtual bool shouldTrigger(const PickResultPointer& pickResult) { return true; }
virtual PickResultPointer getPickResultCopy(const PickResultPointer& pickResult) const = 0;
virtual PickResultPointer getVisualPickResult(const PickResultPointer& pickResult) { return pickResult; };
static const float POINTER_MOVE_DELAY;