diff options
author | Antti Määttä <antti.maatta@qt.io> | 2020-01-07 15:36:28 +0200 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2020-01-13 13:27:15 +0200 |
commit | 9f9c5497ac52b40ef336a0931cbac6068f6035e9 (patch) | |
tree | 5312a873efd9d669d676183f636e47c7dde7c5f3 | |
parent | 4a81ef40986e3903ad489a9314b1c38cd7542f86 (diff) |
Fix setting value for uninitialized attributes
Task-number: QT3DS-4033
Change-Id: Idd1af454c066a359e85c384124e3f8fe8466f4f5
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r-- | src/runtime/Qt3DSElementSystem.cpp | 7 | ||||
-rw-r--r-- | src/runtime/Qt3DSQmlElementHelper.cpp | 31 | ||||
-rw-r--r-- | src/runtime/Qt3DSQmlElementHelper.h | 1 | ||||
-rw-r--r-- | src/runtime/Qt3DSQmlEngine.cpp | 1 |
4 files changed, 38 insertions, 2 deletions
diff --git a/src/runtime/Qt3DSElementSystem.cpp b/src/runtime/Qt3DSElementSystem.cpp index 27bca95..28b3763 100644 --- a/src/runtime/Qt3DSElementSystem.cpp +++ b/src/runtime/Qt3DSElementSystem.cpp @@ -644,10 +644,13 @@ void SElement::SetAttribute(const Q3DStudio::TAttributeHash inKey, const Q3DStudio::UVariant inValue) { Option<TPropertyDescAndValuePtr> existing = FindProperty(inKey); - if (existing.hasValue() == false) { + if (!existing.hasValue()) { if (Q3DStudio::ATTRIBUTE_EYEBALL == inKey) SetFlag(Q3DStudio::ELEMENTFLAG_EXPLICITACTIVE, inValue.m_INT32 ? true : false); - return; + else + existing = FindDynamicProperty(inKey); + if (!existing.hasValue()) + return; } SetAttribute(*existing, inValue); } diff --git a/src/runtime/Qt3DSQmlElementHelper.cpp b/src/runtime/Qt3DSQmlElementHelper.cpp index 1ddd1c8..3353a6f 100644 --- a/src/runtime/Qt3DSQmlElementHelper.cpp +++ b/src/runtime/Qt3DSQmlElementHelper.cpp @@ -246,6 +246,37 @@ CQmlElementHelper::TypedAttributeAndValue CQmlElementHelper::getTypedAttributeAn return retVal; } +bool CQmlElementHelper::EnsureAttribute(TElement *theElement, const char *theAttName) +{ + SAttributeKey theAttributeKey; + theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); + + if (theAttributeKey.m_Hash == ATTRIBUTE_EYEBALL || theAttributeKey.m_Hash == ATTRIBUTE_URI) + return false; + + // first search if it is a static property + Option<qt3ds::runtime::element::TPropertyDescAndValuePtr> thePropertyInfo = + theElement->FindProperty(theAttributeKey.m_Hash); + + // Do not create property for eyeball, it uses the explicit activity flag + if (!thePropertyInfo.hasValue()) { + // if not search in the dynamic properties + thePropertyInfo = theElement->FindDynamicProperty(theAttributeKey.m_Hash); + if (!thePropertyInfo.hasValue()) { + // create a new dynamic porperty + qt3ds::runtime::IElementAllocator &theElemAllocator( + theElement->GetBelongedPresentation()->GetApplication().GetElementAllocator()); + qt3ds::foundation::IStringTable &theStringTable( + theElement->GetBelongedPresentation()->GetStringTable()); + IRuntimeMetaData &theMetaData = + theElement->GetBelongedPresentation()->GetApplication().GetMetaData(); + thePropertyInfo = theElemAllocator.CreateDynamicProperty( + theMetaData, *theElement, theStringTable.RegisterStr(theAttName)); + } + } + return true; +} + bool CQmlElementHelper::SetAttribute(TElement *theElement, const char *theAttName, const void *value) { diff --git a/src/runtime/Qt3DSQmlElementHelper.h b/src/runtime/Qt3DSQmlElementHelper.h index f516571..c7b83e0 100644 --- a/src/runtime/Qt3DSQmlElementHelper.h +++ b/src/runtime/Qt3DSQmlElementHelper.h @@ -49,6 +49,7 @@ public: TElement *inStartElement = NULL); static bool SetAttribute(TElement *inElement, const char *inAttribute, const void *value); + static bool EnsureAttribute(TElement *inElement, const char *inAttribute); static bool GetAttribute(TElement *inElement, const char *inAttribute, void *value); struct TypedAttributeAndValue { diff --git a/src/runtime/Qt3DSQmlEngine.cpp b/src/runtime/Qt3DSQmlEngine.cpp index 5ab5c10..f5390af 100644 --- a/src/runtime/Qt3DSQmlEngine.cpp +++ b/src/runtime/Qt3DSQmlEngine.cpp @@ -614,6 +614,7 @@ bool queueAttributeChange(TElement *target, const char *attName, const char *val // Queue changes to elements inside components that have not been activated even once if (component->GetCurrentSlide() == 0) { IPresentation *presentation = target->GetBelongedPresentation(); + CQmlElementHelper::EnsureAttribute(target, attName); presentation->GetComponentManager().queueChange(componentElement, target, attName, value); return true; |