diff options
author | Antti Määttä <antti.maatta@qt.io> | 2020-01-20 09:05:11 +0200 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2020-01-22 13:29:00 +0200 |
commit | aee9f758b2fe152d95dcd7ac9776b4e0cd765d0c (patch) | |
tree | 392884eac23a7f1829b49ace65ec5e3632c2cbe8 | |
parent | 88849a83a6f9ca3524cf3ba32c3a4ed7e6fabdb9 (diff) |
Optimize element attribute name hashing
Task-number: QT3DS-4041
Change-Id: I64ccd129b12053b057e5e992d89a05a2bc6cd33d
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
23 files changed, 372 insertions, 318 deletions
diff --git a/src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp b/src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp index 88d591f..c8a148b 100644 --- a/src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp +++ b/src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp @@ -1031,8 +1031,8 @@ struct SPathSubPathTranslator : public Qt3DSTranslator bool updatePath = false; CRegisteredString theAnchorType = inParser.m_RenderContext.GetStringTable().RegisterStr("PathAnchorPoint"); - for (Q3DStudio::TElement *theChild = Element().GetChild(); theChild; - theChild = theChild->GetSibling()) { + const auto children = Element().children(); + for (auto theChild : children) { if (theChild->GetType() == theAnchorType) { ++numAnchors; if (theChild->IsDirty()) @@ -1044,8 +1044,7 @@ struct SPathSubPathTranslator : public Qt3DSTranslator theManager.ResizePathSubPathBuffer(theItem, numAnchors); if (thePathBuffer.size()) { QT3DSU32 anchorIndex = 0; - for (Q3DStudio::TElement *theChild = Element().GetChild(); theChild; - theChild = theChild->GetSibling()) { + for (auto theChild : children) { if (theChild->GetType() == theAnchorType) { if (theChild->IsDirty()) { qt3ds::render::SPathAnchorPoint &thePoint(thePathBuffer[anchorIndex]); @@ -1054,7 +1053,7 @@ struct SPathSubPathTranslator : public Qt3DSTranslator ++idx) { qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = theChild->GetPropertyByIndex(idx); - switch (thePropInfo.first.GetNameHash()) { + switch (thePropInfo.first.nameHash()) { case Q3DStudio::ATTRIBUTE_POSITION_X: thePoint.m_Position.x = thePropInfo.second->m_FLOAT; break; @@ -1367,13 +1366,13 @@ struct SDynamicObjectTranslatorContext : public STranslatorContext qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = *element.GetPropertyByIndex(idx); THashToOffsetMap::iterator theFind = - m_PropertyHashes.find(thePropInfo.first.GetNameHash()); + m_PropertyHashes.find(thePropInfo.first.nameHash()); if (theFind != m_PropertyHashes.end()) { const SEffectPropertyEntry &theEntry(theFind->second); const qt3ds::render::dynamic::SPropertyDefinition &theDefinition( theProperties[theEntry.m_PropertyOffset]); if (theEntry.m_AttributeType - == (Q3DStudio::EAttributeType)thePropInfo.first.m_Type) { + == (Q3DStudio::EAttributeType)thePropInfo.first.type()) { switch (theEntry.m_AttributeType) { case Q3DStudio::ATTRIBUTETYPE_BOOL: theItem.SetPropertyValue(theDefinition, @@ -1542,11 +1541,11 @@ struct SRenderPluginTranslator : public Qt3DSTranslator qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = *Element().GetPropertyByIndex(idx); nvhash_map<int, CRegisteredString>::iterator theFind = - theTransContext.m_AttribHashIndexMap.find(thePropInfo.first.GetNameHash()); + theTransContext.m_AttribHashIndexMap.find(thePropInfo.first.nameHash()); if (theFind != theTransContext.m_AttribHashIndexMap.end()) { CRegisteredString thePropName(theFind->second); Q3DStudio::EAttributeType theType = - (Q3DStudio::EAttributeType)thePropInfo.first.m_Type; + (Q3DStudio::EAttributeType)thePropInfo.first.type(); switch (theType) { case Q3DStudio::ATTRIBUTETYPE_BOOL: theTransContext.m_PropertyUpdates.push_back(SRenderPropertyValueUpdate( @@ -1654,8 +1653,8 @@ struct STranslatorCreator ++idx) { qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = *theTranslator.Element().GetPropertyByIndex(idx); - theParser.Setup(thePropInfo.first.GetNameHash(), *thePropInfo.second, - (Q3DStudio::EAttributeType)thePropInfo.first.m_Type); + theParser.Setup(thePropInfo.first.nameHash(), *thePropInfo.second, + (Q3DStudio::EAttributeType)thePropInfo.first.type()); // right now, this is the best we can do because the attribute's dirty system // is all jacked up. theTranslator.OnSpecificPropertyChange(theParser); @@ -1665,8 +1664,8 @@ struct STranslatorCreator ++idx) { qt3ds::runtime::element::TPropertyDescAndValuePtr thePropInfo = *theTranslator.Element().GetDynamicPropertyByIndex(idx); - theParser.Setup(thePropInfo.first.GetNameHash(), *thePropInfo.second, - (Q3DStudio::EAttributeType)thePropInfo.first.m_Type); + theParser.Setup(thePropInfo.first.nameHash(), *thePropInfo.second, + (Q3DStudio::EAttributeType)thePropInfo.first.type()); // right now, this is the best we can do because the attribute's dirty system // is all jacked up. theTranslator.OnSpecificPropertyChange(theParser); diff --git a/src/engine/Qt3DSRuntimeView.cpp b/src/engine/Qt3DSRuntimeView.cpp index 2335cf1..c1b5669 100644 --- a/src/engine/Qt3DSRuntimeView.cpp +++ b/src/engine/Qt3DSRuntimeView.cpp @@ -829,7 +829,7 @@ bool CRuntimeView::PeekCustomAction(char *&outElementPath, char *&outActionName) Q3DStudio::TElement *theElement = nullptr; actionAvailable = theBridgeEngine.PeekSignal(theElement, outActionName); if (actionAvailable && theElement) - outElementPath = (char *)theElement->m_Path.c_str(); + outElementPath = (char *)theElement->path().c_str(); } return actionAvailable; diff --git a/src/runtime/Qt3DSActivationManager.cpp b/src/runtime/Qt3DSActivationManager.cpp index 9ee77ae..e975c7d 100644 --- a/src/runtime/Qt3DSActivationManager.cpp +++ b/src/runtime/Qt3DSActivationManager.cpp @@ -420,23 +420,23 @@ struct STimeContext QT3DS_ASSERT(m_TimeDataNeedsUpdate); m_TimeDataNeedsUpdate = false; SComponent &myNode = m_Component; - SElement *theChild = myNode.m_Child; - if (theChild == NULL) { + const auto children = myNode.children(); + if (children.isEmpty()) return; - } + inScanBuffer.clear(); - for (SElement *theChild = myNode.m_Child; theChild; theChild = theChild->m_Sibling) { - inScanBuffer.push_back(theChild); - } + for (auto child : children) + inScanBuffer.push_back(child); + for (QT3DSU32 idx = 0, end = (QT3DSU32)inScanBuffer.size(); idx < end; ++idx) { SScanBufferEntry theEntry(inScanBuffer[idx]); bool careAboutChildren = BuildTimeContextElementNode( *theEntry.m_Node, theEntry.m_StartTime, theEntry.m_EndTime); if (careAboutChildren && theEntry.m_Node->IsComponent() == false) { - for (SElement *theChild = theEntry.m_Node->m_Child; theChild; - theChild = theChild->m_Sibling) { + const auto nodeChildren = theEntry.m_Node->children(); + for (auto child : nodeChildren) { inScanBuffer.push_back(SScanBufferEntry( - theChild, theEntry.m_Node->m_ActivationManagerNode.m_StartTime, + child, theEntry.m_Node->m_ActivationManagerNode.m_StartTime, theEntry.m_Node->m_ActivationManagerNode.m_StopTime)); } end = (QT3DSU32)inScanBuffer.size(); @@ -449,8 +449,8 @@ struct STimeContext void SetElementDirty(SElement &inNode) { SElement *theComponentParent = &inNode.GetComponentParent(); - if (inNode.IsComponent() && inNode.m_Parent) - theComponentParent = &inNode.m_Parent->GetComponentParent(); + if (inNode.IsComponent() && inNode.GetParent()) + theComponentParent = &inNode.GetParent()->GetComponentParent(); QT3DS_ASSERT(theComponentParent == &m_Component); if (m_AllNodesDirty == false) { @@ -466,7 +466,7 @@ struct STimeContext // This also makes sure that if we mark all nodes dirty we continue the activate scan // till we hit at least // this node. - SElement *theParent = inNode.m_Parent; + SElement *theParent = inNode.GetParent(); while (theParent) { if (theParent->IsComponent() || theParent->m_ActivationManagerNode.m_Flags.IsChildDirty()) @@ -474,7 +474,7 @@ struct STimeContext else { SActivationManagerNode &theNode = theParent->m_ActivationManagerNode; theNode.m_Flags.SetChildDirty(); - theParent = theParent->m_Parent; + theParent = theParent->GetParent(); } } } @@ -484,7 +484,7 @@ struct STimeContext { if (!m_ControlledList.contains(item)) { m_ControlledList.insert(item); - qCInfo(TRACE_INFO) << "Element" << item.m_Name.c_str() + qCInfo(TRACE_INFO) << "Element" << item.name().c_str() << "visibility now controlled by datainput. " "Visibility will no longer be affected by slide transitions."; } @@ -549,7 +549,7 @@ struct STimeContext // Block used to hide variables to avoid an error. { bool parentActive = true; - SElement *theParent = inNode.m_Parent; + SElement *theParent = inNode.GetParent(); if (theParent != NULL) parentActive = theParent->IsGlobalActive(); @@ -581,13 +581,13 @@ struct STimeContext != theScanNode->IsControlledActive())) { // Notify only if datainput control actually disagreed with activity value // coming from activity manager. - qCInfo(TRACE_INFO) << "Element" << theScanNode->m_Name.c_str() + qCInfo(TRACE_INFO) << "Element" << theScanNode->name().c_str() << "visibility persistently controlled by datainput."; } - if (checkChildren && theScanNode->m_Child) { - for (SElement *theScanNodeChild = theScanNode->m_Child; theScanNodeChild; - theScanNodeChild = theScanNodeChild->m_Sibling) { + if (checkChildren && !theScanNode->children().isEmpty()) { + const auto children = theScanNode->children(); + for (auto theScanNodeChild : children) { // Override visibility for master slide elements that have datainput // eyeball controller. isControlledByDi @@ -612,7 +612,8 @@ struct STimeContext if (m_AllNodesDirty == true) { inTempDirtyList.clear(); SComponent &myNode = m_Component; - for (SElement *theChild = myNode.m_Child; theChild; theChild = theChild->m_Sibling) { + const auto children = myNode.children(); + for (auto theChild : children) { // Independent nodes don't need to be in the dirty list. if (theChild->IsIndependent() == false) inTempDirtyList.push_back(theChild); @@ -647,7 +648,7 @@ struct STimeContext { SComponent &theContextNode = m_Component; bool parentActive = true; - SElement *theParent = theContextNode.m_Parent; + SElement *theParent = theContextNode.GetParent(); if (theParent != NULL) parentActive = theParent->IsGlobalActive(); @@ -830,10 +831,10 @@ struct SActivityZone : public IActivityZone m_Foundation.getAllocator(), static_cast<SComponent &>(theComponent), m_ElementAccessMutex); STimeContext &theNewContext = *inserter.first->second; - if (theComponent.m_Parent == NULL) + if (theComponent.GetParent() == NULL) m_RootContexts.push_back(theNewContext); else { - STimeContext &parentContext = GetItemTimeContext(*theComponent.m_Parent); + STimeContext &parentContext = GetItemTimeContext(*theComponent.GetParent()); parentContext.m_Children.push_back(theNewContext); } } @@ -842,7 +843,7 @@ struct SActivityZone : public IActivityZone void AddActivityItems(TActivityItem inNode) override { - if (inNode.m_Parent == NULL) + if (inNode.GetParent() == NULL) m_RootElements.push_back(&inNode); GetItemTimeContext(inNode); @@ -872,8 +873,8 @@ struct SActivityZone : public IActivityZone // else travel up the chain till you find an indpendent node. SElement &GetItemTimeParentNode(SElement &inNode) { - if (inNode.m_Parent != NULL) { - SElement &theParent = *inNode.m_Parent; + if (inNode.GetParent() != NULL) { + SElement &theParent = *inNode.GetParent(); if (theParent.IsIndependent()) return theParent; return GetItemTimeParentNode(theParent); @@ -931,8 +932,8 @@ struct SActivityZone : public IActivityZone TTimeUnit GetItemLocalTime(TActivityItem item) override { SElement *theElem = &item.GetComponentParent(); - if (item.IsComponent() && item.m_Parent) - theElem = &item.m_Parent->GetComponentParent(); + if (item.IsComponent() && item.GetParent()) + theElem = &item.GetParent()->GetComponentParent(); return GetItemTimeContext(*theElem).m_CurrentTime; } diff --git a/src/runtime/Qt3DSAnimationSystem.cpp b/src/runtime/Qt3DSAnimationSystem.cpp index 199b7f2..b0ad2e6 100644 --- a/src/runtime/Qt3DSAnimationSystem.cpp +++ b/src/runtime/Qt3DSAnimationSystem.cpp @@ -213,7 +213,7 @@ struct SAnimSystem : public IAnimationSystem theProperty = inElement.GetPropertyByIndex(*theIndex); if (theProperty.hasValue() == false - || theProperty->first.m_Type != Q3DStudio::ATTRIBUTETYPE_FLOAT) { + || theProperty->first.type() != Q3DStudio::ATTRIBUTETYPE_FLOAT) { QT3DS_ASSERT(false); return 0; } diff --git a/src/runtime/Qt3DSAnimationSystem.h b/src/runtime/Qt3DSAnimationSystem.h index d8ee501..843c83e 100644 --- a/src/runtime/Qt3DSAnimationSystem.h +++ b/src/runtime/Qt3DSAnimationSystem.h @@ -45,7 +45,7 @@ namespace runtime { using namespace qt3ds::foundation; namespace element { - struct SElement; + class SElement; } class IElementAllocator; diff --git a/src/runtime/Qt3DSApplication.cpp b/src/runtime/Qt3DSApplication.cpp index 79866c5..39387ab 100644 --- a/src/runtime/Qt3DSApplication.cpp +++ b/src/runtime/Qt3DSApplication.cpp @@ -1219,7 +1219,7 @@ struct SApp : public IApplication key.m_Index = index; slidesystem.setUnloadSlide(key, false); const QString completeName = presentation->GetName() + QLatin1Char(':') - + QString::fromUtf8(key.m_Component->m_Name) + QLatin1Char(':') + slideName; + + QString::fromUtf8(key.m_Component->name()) + QLatin1Char(':') + slideName; qCInfo(TRACE_INFO) << "Load component slide resources: " << completeName; m_resourceCounter.handleLoadSlide(completeName, key, slidesystem); if (m_uploadRenderTask) @@ -1291,7 +1291,7 @@ struct SApp : public IApplication slidesystem.setUnloadSlide(key, true); if (!slidesystem.isActiveSlide(key)) { const QString completeName = presentation->GetName() + QLatin1Char(':') - + QString::fromUtf8(key.m_Component->m_Name) + QLatin1Char(':') + slideName; + + QString::fromUtf8(key.m_Component->name()) + QLatin1Char(':') + slideName; qCInfo(TRACE_INFO) << "Unload component slide resources: " << completeName; m_resourceCounter.handleUnloadSlide(completeName, key, slidesystem); @@ -1717,7 +1717,7 @@ struct SApp : public IApplication // else assume main presentation and component:slide } component = presentation->GetRoot(); - if (!componentName.isNull() && componentName != component->m_Name) { + if (!componentName.isNull() && componentName != component->name()) { component = CQmlElementHelper::GetElement(*this, presentation, qPrintable(componentName), nullptr); } @@ -1912,19 +1912,22 @@ struct SApp : public IApplication Q3DStudio::IRuntimeFactory &GetRuntimeFactory() const override { return *m_RuntimeFactory.mPtr; } Q3DStudio::IRuntimeFactoryCore &GetRuntimeFactoryCore() override { return *m_CoreFactory; } + Q3DStudio::CPresentation *m_primaryPresentation = nullptr; Q3DStudio::CPresentation *GetPrimaryPresentation() override { - return GetPresentationById(m_PresentationId.c_str()); + if (!m_primaryPresentation) + m_primaryPresentation = GetPresentationById(m_PresentationId.c_str()); + return m_primaryPresentation; } - virtual Q3DStudio::CPresentation *LoadAndGetPresentationById(const char8_t *inId) override + virtual Q3DStudio::CPresentation *LoadAndGetPresentationById(const QString &inId) override { return GetPresentationById(inId, true); } - Q3DStudio::CPresentation *GetPresentationById(const char8_t *inId, bool load = false) + Q3DStudio::CPresentation *GetPresentationById(const QString &inId, bool load = false) { - if (!isTrivial(inId)) { + if (!inId.isEmpty()) { TIdAssetMap::iterator iter = m_AssetMap.find(m_CoreFactory->GetStringTable().RegisterStr(inId)); if (iter != m_AssetMap.end() diff --git a/src/runtime/Qt3DSApplication.h b/src/runtime/Qt3DSApplication.h index ad447f7..97d8528 100644 --- a/src/runtime/Qt3DSApplication.h +++ b/src/runtime/Qt3DSApplication.h @@ -169,7 +169,7 @@ public: virtual Q3DStudio::CPresentation *GetPrimaryPresentation() = 0; - virtual Q3DStudio::CPresentation *LoadAndGetPresentationById(const char8_t *inId) = 0; + virtual Q3DStudio::CPresentation *LoadAndGetPresentationById(const QString &inId) = 0; virtual QList<Q3DStudio::CPresentation *> GetPresentationList() = 0; diff --git a/src/runtime/Qt3DSComponentManager.cpp b/src/runtime/Qt3DSComponentManager.cpp index 1700222..fd77467 100644 --- a/src/runtime/Qt3DSComponentManager.cpp +++ b/src/runtime/Qt3DSComponentManager.cpp @@ -106,7 +106,7 @@ void CComponentManager::GotoSlideIndex(TElement *inComponent, if (&m_Presentation != m_Presentation.GetApplication().GetPrimaryPresentation()) elementPath = m_Presentation.GetName() + QLatin1Char(':'); - elementPath.append(QString::fromUtf8(inComponent->m_Path.c_str())); + elementPath.append(QString::fromUtf8(inComponent->path().c_str())); if (inSlideExit) { SEventCommand theEvent = { inComponent, EVENT_ONSLIDEEXIT }; @@ -335,10 +335,10 @@ void CComponentManager::applyQueuedChanges(TElement *component) } void CComponentManager::queueChange(TElement *component, TElement *target, const char *attName, - const char *value) + const char *value, TAttributeHash attrHash) { CQmlElementHelper::TypedAttributeAndValue attributeAndValue - = CQmlElementHelper::getTypedAttributeAndValue(target, attName, value); + = CQmlElementHelper::getTypedAttributeAndValue(target, attName, value, attrHash); if (attributeAndValue.attribute.m_Hash != 0) { auto &targetQueue = m_queuedChanges[component]; auto &attQueue = targetQueue[target]; diff --git a/src/runtime/Qt3DSComponentManager.h b/src/runtime/Qt3DSComponentManager.h index 6ede073..6933ab4 100644 --- a/src/runtime/Qt3DSComponentManager.h +++ b/src/runtime/Qt3DSComponentManager.h @@ -93,7 +93,7 @@ public: // Slide void PlaythroughToSlide(TElement *inComponent); void applyQueuedChanges(TElement *component) override; void queueChange(TElement *component, TElement *target, const char *attName, - const char *value) override; + const char *value, Q3DStudio::TAttributeHash attrHash) override; bool hasSlideChangeQueued(TElement *component) override; UINT8 GetSlideCount(TElement *inComponent) override; diff --git a/src/runtime/Qt3DSElementSystem.cpp b/src/runtime/Qt3DSElementSystem.cpp index 28b3763..8954ae4 100644 --- a/src/runtime/Qt3DSElementSystem.cpp +++ b/src/runtime/Qt3DSElementSystem.cpp @@ -65,7 +65,7 @@ struct SPropertyDescSorter { bool operator()(const TPropertyDescAndValue &lhs, const TPropertyDescAndValue &rhs) const { - return strcmp(lhs.first.m_Name.c_str(), rhs.first.m_Name.c_str()) < 0; + return strcmp(lhs.first.name().c_str(), rhs.first.name().c_str()) < 0; } }; QT3DSU32 GetNumValueAllocations(const STypeDesc &inTypeDesc) @@ -165,7 +165,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator GetIgnoredProperties(); const bool isImage = inType == m_StringTable.RegisterStr("Image"); for (QT3DSU32 idx = 0, end = inPropertyDescriptions.size(); idx < end; ++idx) { - QT3DSU32 nameHash = inPropertyDescriptions[idx].first.GetNameHash(); + QT3DSU32 nameHash = inPropertyDescriptions[idx].first.nameHash(); // Make image instances explicitly not participate in the timegraph. This way their // default start/end time does not have impact into lifetimes of their parents. // This fixes QT3DS-3669 where image default end time overrode parent endtime when @@ -175,7 +175,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator participatesInTimeGraph = true; } if (eastl::find(m_IgnoredProperties.begin(), m_IgnoredProperties.end(), - inPropertyDescriptions[idx].first.m_Name) + inPropertyDescriptions[idx].first.name()) == m_IgnoredProperties.end()) { m_TempPropertyDescsAndValues.push_back(inPropertyDescriptions[idx]); } @@ -210,19 +210,11 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator SElement *retval = inIsComponent ? m_Components.construct(theTypeDesc, __FILE__, __LINE__) : m_Elements.construct(theTypeDesc, __FILE__, __LINE__); retval->m_BelongedPresentation = inPresentation; - retval->m_Name = inName; + retval->setName(inName); // children - if (inParent) { - retval->m_Parent = inParent; - if (inParent->m_Child == NULL) { - inParent->m_Child = retval; - } else { - SElement *lastChild = inParent->m_Child; - while (lastChild->m_Sibling) - lastChild = lastChild->m_Sibling; - lastChild->m_Sibling = retval; - } - } + if (inParent) + retval->setParent(inParent); + while (FindElementByHandle(m_NextElementHandle)) { ++m_NextElementHandle; if (!m_NextElementHandle) @@ -264,25 +256,13 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator void ReleaseElement(SElement &inElement, bool inRecurse) override { if (inRecurse) { - while (inElement.m_Child) - ReleaseElement(*inElement.m_Child, true); + const auto children = inElement.children(); + for (auto child : children) + ReleaseElement(*child, true); } // Trim out the element. - if (inElement.m_Parent) { - SElement *theParent = inElement.m_Parent; - if (theParent->m_Child == &inElement) - theParent->m_Child = inElement.m_Sibling; - else { - SElement *thePreviousChild = NULL; - // Empty loop to find the previous child - for (thePreviousChild = theParent->m_Child; - thePreviousChild->m_Sibling != &inElement && thePreviousChild; - thePreviousChild = thePreviousChild->m_Sibling) { - } - if (thePreviousChild) - thePreviousChild->m_Sibling = inElement.m_Sibling; - } - } + if (inElement.GetParent()) + inElement.GetParent()->removeChild(&inElement); m_HandleToElements.erase(inElement.m_Handle); @@ -369,7 +349,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator newProp = (SPropertyDesc *)m_AutoAllocator.allocate(allocSize, "SPropertyDesc", __FILE__, __LINE__, 0); - newProp->m_Name = inName; + newProp->setName(inName); // convert to appropriate type if (thePropertyType == Q3DStudio::ERuntimeDataModelDataTypeFloat) { @@ -377,7 +357,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator element.m_TypeDescription->m_TypeName, theWorkSpaceString, element.m_TypeDescription->m_SubtypeName); - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; + newProp->setType(Q3DStudio::ATTRIBUTETYPE_FLOAT); Q3DStudio::UVariant theValue; theValue.m_FLOAT = value; @@ -389,7 +369,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator qt3ds::QT3DSVec2 value = theMetaData.GetPropertyValueVector2( element.m_TypeDescription->m_TypeName, theWorkSpaceString, element.m_TypeDescription->m_SubtypeName); - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; + newProp->setType(Q3DStudio::ATTRIBUTETYPE_FLOAT); Q3DStudio::UVariant theVarValue; theVarValue.m_FLOAT = value[extIndex]; @@ -404,7 +384,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator element.m_TypeDescription->m_SubtypeName); if (separateProperties) { - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; + newProp->setType(Q3DStudio::ATTRIBUTETYPE_FLOAT); Q3DStudio::UVariant theVarValue; theVarValue.m_FLOAT = value[extIndex]; @@ -412,7 +392,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator SPropertyDesc(theWorkSpaceString, Q3DStudio::ATTRIBUTETYPE_FLOAT), theVarValue)); } else { - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT3; + newProp->setType(Q3DStudio::ATTRIBUTETYPE_FLOAT3); Q3DStudio::UVariant theVarValue; theVarValue.m_FLOAT3[0] = value[0]; @@ -429,7 +409,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator element.m_TypeDescription->m_TypeName, theWorkSpaceString, element.m_TypeDescription->m_SubtypeName); - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_INT32; + newProp->setType(Q3DStudio::ATTRIBUTETYPE_INT32); Q3DStudio::UVariant theVarValue; theVarValue.m_INT32 = value; @@ -443,7 +423,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator element.m_TypeDescription->m_TypeName, theWorkSpaceString, element.m_TypeDescription->m_SubtypeName); - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_BOOL; + newProp->setType(Q3DStudio::ATTRIBUTETYPE_BOOL); Q3DStudio::UVariant theVarValue; theVarValue.m_INT32 = value; @@ -456,7 +436,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator element.m_TypeDescription->m_TypeName, theWorkSpaceString, element.m_TypeDescription->m_SubtypeName); - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_STRING; + newProp->setType(Q3DStudio::ATTRIBUTETYPE_STRING); CStringHandle theString = m_StringTable.GetHandle(theRuntimeStr->c_str()); Q3DStudio::UVariant theVarValue; @@ -467,7 +447,7 @@ struct SElementAllocator : public qt3ds::runtime::IElementAllocator theTypeDesc->m_DynamicProperties.push_back(*newProp); } else { - newProp->m_Type = Q3DStudio::ATTRIBUTETYPE_FLOAT; + newProp->setType(Q3DStudio::ATTRIBUTETYPE_FLOAT); theTypeDesc->m_DynamicProperties.push_back(*newProp); } @@ -539,7 +519,7 @@ bool STypeDesc::operator==(const STypeDesc &inOther) const for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { const SPropertyDesc &lhs = m_Properties[idx]; const SPropertyDesc &rhs = inOther.m_Properties[idx]; - if (lhs.m_Name != rhs.m_Name || lhs.m_Type != rhs.m_Type) + if (lhs.name() != rhs.name() || lhs.type() != rhs.type()) return false; } return true; @@ -551,7 +531,7 @@ Option<QT3DSU32> STypeDesc::FindProperty(QT3DSU32 inNameHash) const { for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { const SPropertyDesc &theDesc = m_Properties[idx]; - if (Q3DStudio::CHash::HashAttribute(theDesc.m_Name) == inNameHash) + if (theDesc.nameHash() == inNameHash) return idx; } return Empty(); @@ -559,19 +539,15 @@ Option<QT3DSU32> STypeDesc::FindProperty(QT3DSU32 inNameHash) const Option<QT3DSU32> STypeDesc::FindProperty(CRegisteredString inName) const { - for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { - const SPropertyDesc &theDesc = m_Properties[idx]; - if (theDesc.m_Name == inName) - return idx; - } - return Empty(); + const auto hash = Q3DStudio::CHash::HashAttribute(inName); + return FindProperty(hash); } Option<QT3DSU32> STypeDesc::FindDynamicProperty(QT3DSU32 inNameHash) const { for (QT3DSU32 idx = 0, end = m_DynamicProperties.size(); idx < end; ++idx) { const SPropertyDesc &theDesc = m_DynamicProperties[idx]; - if (Q3DStudio::CHash::HashAttribute(theDesc.m_Name) == inNameHash) + if (theDesc.nameHash() == inNameHash) return idx; } return Empty(); @@ -581,16 +557,29 @@ void STypeDesc::SetHashValue() { size_t typeDescHash = m_TypeName.hash() ^ m_SubtypeName.hash(); for (QT3DSU32 idx = 0, end = m_Properties.size(); idx < end; ++idx) { - typeDescHash = typeDescHash ^ m_Properties[idx].m_Name.hash(); - typeDescHash = typeDescHash ^ eastl::hash<QT3DSU32>()(m_Properties[idx].m_Type); + typeDescHash = typeDescHash ^ m_Properties[idx].name().hash(); + typeDescHash = typeDescHash ^ eastl::hash<QT3DSU32>()(m_Properties[idx].type()); } // TODO check 64 bit compatibility m_HashValue = (QT3DSU32)typeDescHash; } -QT3DSU32 SPropertyDesc::GetNameHash() const +SPropertyDesc::SPropertyDesc(CRegisteredString inStr, Q3DStudio::EAttributeType inType) + : m_Name(inStr) + , m_nameHash(Q3DStudio::CHash::HashAttribute(inStr.c_str())) + , m_Type(inType) +{ +} + +void SPropertyDesc::setName(CRegisteredString name) { - return Q3DStudio::CHash::HashAttribute(m_Name.c_str()); + m_Name = name; + m_nameHash = Q3DStudio::CHash::HashAttribute(name.c_str()); +} + +QT3DSU32 SPropertyDesc::nameHash() const +{ + return m_nameHash; } Q3DStudio::SAttributeKey SPropertyDesc::GetAttributeKey() const @@ -598,7 +587,7 @@ Q3DStudio::SAttributeKey SPropertyDesc::GetAttributeKey() const Q3DStudio::SAttributeKey retval; memZero(&retval, sizeof(retval)); retval.m_Type = m_Type; - retval.m_Hash = GetNameHash(); + retval.m_Hash = nameHash(); return retval; } @@ -670,9 +659,9 @@ void SElement::stopAnimations(QT3DSU32 propHash) void SElement::SetAttribute(TPropertyDescAndValuePtr inKey, const Q3DStudio::UVariant inValue, bool forceSet) { - Q3DStudio::EAttributeType theType = inKey.first.m_Type; + Q3DStudio::EAttributeType theType = inKey.first.type(); Q3DStudio::UVariant *currentValue = inKey.second; - QT3DSU32 attHash = inKey.first.GetNameHash(); + QT3DSU32 attHash = inKey.first.nameHash(); // If there is an active animation for this property, disable it. Otherwise the set value // gets overwritten immediately as animation update takes place. @@ -719,10 +708,44 @@ void SElement::SetAttribute(TPropertyDescAndValuePtr inKey, const Q3DStudio::UVa SetDirty(); } +void SElement::setParent(SElement *parent) +{ + if (m_Parent) + m_Parent->removeChild(this); + m_Parent = parent; + if (m_Parent) + m_Parent->addChild(this); +} +void SElement::addChild(SElement *child) +{ + m_children.insert(child->GetNameHash(), child); +} + +void SElement::removeChild(SElement *child) +{ + auto key = m_children.key(child); + m_children.remove(key); +} + +void SElement::updateChildName(SElement *child) +{ + auto key = m_children.key(child); + m_children.remove(key); + m_children.insert(child->GetNameHash(), child); +} + +void SElement::setName(CRegisteredString name) +{ + m_Name = name; + m_nameHash = Q3DStudio::CHash::HashString(name); + if (m_Parent) + m_Parent->updateChildName(this); +} + // SElement implementation QT3DSU32 SElement::GetNameHash() const { - return Q3DStudio::CHash::HashString(m_Name.c_str()); + return m_nameHash; } // Q3DStudio::CHash::HashAttribute @@ -848,11 +871,7 @@ const SElement &SElement::GetComponentParent() const SElement *SElement::FindChild(QT3DSU32 inNameHash) { - for (SElement *theChild = m_Child; theChild; theChild = theChild->m_Sibling) { - if (theChild->GetNameHash() == inNameHash) - return theChild; - } - return NULL; + return m_children.value(inNameHash); } Q3DStudio::TTimeUnit SElement::GetInnerTime() const diff --git a/src/runtime/Qt3DSElementSystem.h b/src/runtime/Qt3DSElementSystem.h index 4eda166..a633ea8 100644 --- a/src/runtime/Qt3DSElementSystem.h +++ b/src/runtime/Qt3DSElementSystem.h @@ -68,19 +68,23 @@ namespace runtime { namespace element { struct SPropertyDesc { + private: CRegisteredString m_Name; + QT3DSU32 m_nameHash; Q3DStudio::EAttributeType m_Type; + public: SPropertyDesc() - : m_Type(Q3DStudio::ATTRIBUTETYPE_NONE) - { - } - SPropertyDesc(CRegisteredString inStr, Q3DStudio::EAttributeType inType) - : m_Name(inStr) - , m_Type(inType) + : m_nameHash(0) + , m_Type(Q3DStudio::ATTRIBUTETYPE_NONE) { } - QT3DSU32 GetNameHash() const; // CHash::HashAttribute + SPropertyDesc(CRegisteredString inStr, Q3DStudio::EAttributeType inType); + QT3DSU32 nameHash() const; // CHash::HashAttribute Q3DStudio::SAttributeKey GetAttributeKey() const; + Q3DStudio::EAttributeType type() const { return m_Type; } + CRegisteredString name() const { return m_Name; } + void setName(CRegisteredString name); + void setType(Q3DStudio::EAttributeType type) { m_Type = type; }; }; struct STypeDesc @@ -157,7 +161,7 @@ namespace runtime { } }; - struct SElement; + class SElement; struct SActivationManagerNode { @@ -259,17 +263,19 @@ namespace runtime { Q3DStudio::UVariant m_Data[4]; SPropertyValueGroup *m_NextNode; SPropertyValueGroup() - : m_NextNode(NULL) + : m_NextNode(nullptr) { for (QT3DSU32 idx = 0; idx < NumValues; ++idx) m_Data[idx].m_INT32 = 0; } }; - struct SElement + class SElement { CRegisteredString m_Name; // const, do not set after creation. CRegisteredString m_Path; + QT3DSU32 m_nameHash; + public: const STypeDesc *m_TypeDescription; ///< static information created on load time // The property values are in order described in the type description. SPropertyValueGroup *m_PropertyValues; @@ -283,29 +289,35 @@ namespace runtime { QT3DSU32 m_Handle; QT3DSU32 m_ScriptID; ///< Superfluous, could use handle to link to script representation QT3DSU32 m_Depth; ///< Distance from this node to the root of the graph. + private: SElement *m_Parent; ///< Parent element in activity graph - SElement *m_Sibling; ///< Next sibling element in activity graph - SElement *m_Child; ///< First child element in activity graph + QHash<QT3DSU32, SElement *> m_children; + public: bool m_OnMaster = false; void *m_Association; ///< Link to associated asset in scene Q3DStudio::IPresentation *m_BelongedPresentation; SActivationManagerNode m_ActivationManagerNode; SElement(const STypeDesc &inDesc) - : m_TypeDescription(&inDesc) - , m_PropertyValues(NULL) - , m_DynamicTypeDescription(NULL) - , m_DynamicPropertyValues(NULL) + : m_nameHash(0) + , m_TypeDescription(&inDesc) + , m_PropertyValues(nullptr) + , m_DynamicTypeDescription(nullptr) + , m_DynamicPropertyValues(nullptr) , m_Handle(0) , m_ScriptID(0) , m_Depth(0) - , m_Parent(NULL) - , m_Sibling(NULL) - , m_Child(NULL) - , m_Association(NULL) - , m_BelongedPresentation(NULL) + , m_Parent(nullptr) + , m_Association(nullptr) + , m_BelongedPresentation(nullptr) { } + void updateChildName(SElement *child); + QList<SElement *> children() const { return m_children.values(); }; + CRegisteredString name() const { return m_Name; } + CRegisteredString path() const { return m_Path; } + void setName(CRegisteredString name); + void setPath(CRegisteredString path) { m_Path = path; } QT3DSU32 GetHandle() const { return m_Handle; } const STypeDesc &GetTypeDescription() const { return *m_TypeDescription; } void SetTypeDescription(const STypeDesc *inDesc) { m_TypeDescription = inDesc; } @@ -356,7 +368,7 @@ namespace runtime { if (theVal.hasValue()) return theVal->second; } - return NULL; + return nullptr; } const Q3DStudio::UVariant *FindPropertyValue(QT3DSU32 inNameHash) const { @@ -366,7 +378,7 @@ namespace runtime { if (theVal.hasValue()) return theVal->second; } - return NULL; + return nullptr; } Q3DStudio::UVariant *FindPropertyValue(CRegisteredString inNameHash) { @@ -376,7 +388,7 @@ namespace runtime { if (theVal.hasValue()) return theVal->second; } - return NULL; + return nullptr; } const Q3DStudio::UVariant *FindPropertyValue(CRegisteredString inNameHash) const @@ -387,7 +399,7 @@ namespace runtime { if (theVal.hasValue()) return theVal->second; } - return NULL; + return nullptr; } Option<TPropertyDescAndValuePtr> FindProperty(QT3DSU32 inNameHash) @@ -407,12 +419,11 @@ namespace runtime { return Empty(); } + void setParent(SElement *parent); + void addChild(SElement *child); + void removeChild(SElement *child); SElement *GetParent() { return m_Parent; } const SElement *GetParent() const { return m_Parent; } - SElement *GetSibling() { return m_Sibling; } - const SElement *GetSibling() const { return m_Sibling; } - SElement *GetChild() { return m_Child; } - const SElement *GetChild() const { return m_Child; } CRegisteredString GetType() const { return m_TypeDescription->m_TypeName; } bool IsComponent() const { return m_Flags.IsComponent(); } @@ -514,7 +525,7 @@ namespace runtime { bool IsTimeActive() const { - if (m_Parent != NULL) + if (m_Parent != nullptr) return m_ActivationManagerNode.m_Flags.IsTimeActive(); return true; } @@ -532,11 +543,9 @@ namespace runtime { { if (IsComponent()) components.push_back(this); - SElement *child = m_Child; - while (child) { + const auto list = children(); + for (auto child : list) child->findComponents(components); - child = child->m_Sibling; - } } // Sets animation on property to inactive. @@ -569,15 +578,18 @@ namespace runtime { } }; - struct SComponent : public SElement + class SComponent : public SElement { Q3DStudio::SAlignedTimeUnit m_BeginTime; Q3DStudio::SAlignedTimeUnit m_Duration; // Slide related + public: QT3DSU8 m_SlideCount; ///< Number of slides starting from base index + private: QT3DSU8 m_CurrentSlide; ///< Current slide number QT3DSU8 m_PreviousSlide; ///< Previous slide number + public: SComponent(const STypeDesc &inDesc) : SElement(inDesc) , m_SlideCount(0) diff --git a/src/runtime/Qt3DSIComponentManager.h b/src/runtime/Qt3DSIComponentManager.h index 50afe05..2008e01 100644 --- a/src/runtime/Qt3DSIComponentManager.h +++ b/src/runtime/Qt3DSIComponentManager.h @@ -122,7 +122,7 @@ public: // Slides virtual const CHAR *GetCurrentSlideName(TElement *inComponent) = 0; virtual void applyQueuedChanges(TElement *component) = 0; virtual void queueChange(TElement *component, TElement *target, const char *attName, - const char *value) = 0; + const char *value, TAttributeHash attrHash) = 0; virtual bool hasSlideChangeQueued(TElement *component) = 0; virtual void OnElementDeactivated(TElement *inElement) = 0; diff --git a/src/runtime/Qt3DSIScriptBridge.h b/src/runtime/Qt3DSIScriptBridge.h index f424aac..246dc81 100644 --- a/src/runtime/Qt3DSIScriptBridge.h +++ b/src/runtime/Qt3DSIScriptBridge.h @@ -165,8 +165,8 @@ public: // Elements // Use inProvider to create a new table and associate with inElement: currently a render plugin // element this mimics render plugin as an behavior element virtual void SetTableForElement(TElement &inElement, IScriptTableProvider &inProvider) = 0; - virtual void SetAttribute(TElement *element, const char *attName, const char *value) = 0; - virtual void SetAttribute(const char *element, const char *attName, const char *value) = 0; + virtual void SetAttribute(TElement *element, const QString &attName, const char *value) = 0; + virtual void SetAttribute(const QString &element, const QString &attName, const char *value) = 0; virtual void FireEvent(const char *element, const char *evtName) = 0; virtual void SetDataInputValue( const QString &name, const QVariant &value, diff --git a/src/runtime/Qt3DSKernelTypes.h b/src/runtime/Qt3DSKernelTypes.h index 6af4ab7..866196d 100644 --- a/src/runtime/Qt3DSKernelTypes.h +++ b/src/runtime/Qt3DSKernelTypes.h @@ -38,8 +38,8 @@ namespace qt3ds { namespace runtime { namespace element { - struct SElement; - struct SComponent; + class SElement; + class SComponent; } } } diff --git a/src/runtime/Qt3DSPresentation.cpp b/src/runtime/Qt3DSPresentation.cpp index 504e7b6..851cfef 100644 --- a/src/runtime/Qt3DSPresentation.cpp +++ b/src/runtime/Qt3DSPresentation.cpp @@ -237,16 +237,16 @@ void CPresentation::NotifyDataOutputs() Q3DStudio::TElementList &dirtyList = GetFrameData().GetDirtyList(); for (int idx = 0, end = dirtyList.GetCount(); idx < end; ++idx) { Q3DStudio::TElement &element = *dirtyList[idx]; - if (m_pathToDataOutMap.contains(element.m_Path)) { - auto outDefIter = m_pathToDataOutMap.find(element.m_Path); + if (m_pathToDataOutMap.contains(element.path())) { + auto outDefIter = m_pathToDataOutMap.find(element.path()); - while (outDefIter != m_pathToDataOutMap.end() && outDefIter.key() == element.m_Path) { + while (outDefIter != m_pathToDataOutMap.end() && outDefIter.key() == element.path()) { qt3ds::runtime::DataOutputDef &outDef = outDefIter.value(); // Get current value Q3DStudio::UVariant value; - qt3ds::QT3DSU32 attribHash - = CHash::HashAttribute(outDef.observedAttribute.attributeName[0]); + qt3ds::QT3DSU32 attribHash = CHash::HashAttribute( + outDef.observedAttribute.attributeName[0].constData()); element.GetAttribute(attribHash, value); QVariant qvar; switch (outDef.observedAttribute.propertyType) { @@ -439,7 +439,7 @@ void CPresentation::ProcessEventBubbling(SEventCommand &ioEvent, INT32 &ioEventC // Event bubbling if (ioEvent.m_BubbleUp) { - TElement *theParent = ioEvent.m_Target->m_Parent; + TElement *theParent = ioEvent.m_Target->GetParent(); if (theParent) { ioEvent.m_Target = theParent; ProcessEvent(ioEvent, ioEventCount); @@ -513,7 +513,7 @@ void CPresentation::ProcessCommand(const SEventCommand &inCommand) } else if (inCommand.m_Type == COMMAND_EMITSIGNAL) { CRegisteredString nameStr = GetStringTable().HandleToStr(inCommand.m_Arg1.m_INT32); m_Application->GetRuntimeFactoryCore().GetScriptEngineQml().ProcessSignal(this, inCommand); - QString path = QString::fromLatin1(inCommand.m_Target->m_Path.c_str()); + QString path = QString::fromLatin1(inCommand.m_Target->path().c_str()); QString name = QString::fromLatin1(nameStr.c_str()); signalProxy()->SigCustomSignal(path, name); } else { diff --git a/src/runtime/Qt3DSQmlElementHelper.cpp b/src/runtime/Qt3DSQmlElementHelper.cpp index 3353a6f..4dad315 100644 --- a/src/runtime/Qt3DSQmlElementHelper.cpp +++ b/src/runtime/Qt3DSQmlElementHelper.cpp @@ -67,98 +67,79 @@ CQmlElementHelper::~CQmlElementHelper() } TElement *CQmlElementHelper::GetElement(qt3ds::runtime::IApplication &inApplication, - IPresentation *inDefaultPresentation, const char *inPath, + IPresentation *inDefaultPresentation, const QString &inPath, TElement *inStartElement) { - if (inPath == nullptr || *inPath == 0) + if (inPath.isNull()) return nullptr; - const char *thePath(inPath); - const char *theSubPath = nullptr; - IPresentation *thePresentation = nullptr; - size_t thePathLength = ::strlen(thePath) + 1; - char *theToken = - Q3DStudio_allocate_desc(CHAR, thePathLength, "Token:TempPath"); // Temporary token storage - // Try to get the specified presentation - theSubPath = ::strchr(thePath, PRESENTATION_DELIMITER); - TElement *theElement = inStartElement; - if (theSubPath != nullptr) { - UINT32 theSubPathLength = static_cast<UINT32>(theSubPath - thePath); - - ::strncpy(theToken, thePath, theSubPathLength); - theToken[theSubPathLength] = '\0'; - thePath = theSubPath + 1; - - const CHAR *thePresentationName = theToken; + int delimIndex = inPath.indexOf(QLatin1Char(PRESENTATION_DELIMITER)); + IPresentation *thePresentation = nullptr; + QString path = inPath; - thePresentation = inApplication.LoadAndGetPresentationById(thePresentationName); + TElement *theElement = inStartElement; + if (delimIndex > 0) { + thePresentation = inApplication.LoadAndGetPresentationById(path.left(delimIndex)); + path = path.right(delimIndex + 1); } + if (thePresentation == nullptr) thePresentation = inDefaultPresentation; // Return nil if the inStartElement is not in the specified presentation if (theElement != nullptr - && (theSubPath == nullptr && theElement->GetBelongedPresentation() != thePresentation)) { + && (delimIndex < 0 && theElement->GetBelongedPresentation() != thePresentation)) { thePresentation = theElement->GetBelongedPresentation(); } if (thePresentation == nullptr) return nullptr; - TStringHash theName; - INT32 theParseCounter = 0; - - while (thePath != nullptr && thePath[0] != '\0') { - ++theParseCounter; + int curIdx = 0; + int nodeDelim; + int theParseCounter = 0; + bool last = false; - // Do some strtok() work here - theSubPath = ::strchr(thePath, NODE_DELIMITER); - if (theSubPath) { - UINT32 theSubPathLength = static_cast<UINT32>(theSubPath - thePath); - Q3DStudio_ASSERT(theSubPathLength < thePathLength); - - ::strncpy(theToken, thePath, theSubPathLength); - theToken[theSubPathLength] = '\0'; - - thePath = theSubPath + 1; - } else { - ::strcpy(theToken, thePath); - thePath = nullptr; + do { + nodeDelim = path.indexOf(QLatin1Char(NODE_DELIMITER), curIdx); + if (nodeDelim < 0) { + nodeDelim = path.length(); + last = true; } - // Hash the token and do some element searching - theName = CHash::HashString(theToken); + ++theParseCounter; - if (theName == RESERVED_PARENT) { + auto name = CHash::HashString(path, curIdx, nodeDelim); + if (name == RESERVED_PARENT) { if (theElement) theElement = theElement->GetParent(); - } else if (theName == RESERVED_THIS) { + } else if (RESERVED_THIS == name) { //Keep the original element if "this" wanted } else { - if (theName == RESERVED_SCENE && theParseCounter == 1) - theElement = - thePresentation->GetRoot(); // theElement is nullptr, so using absolute path - + if (name == RESERVED_SCENE && theParseCounter == 1) + theElement = thePresentation->GetRoot(); else if (theElement) - theElement = theElement->FindChild(theName); // Using relative path + theElement = theElement->FindChild(name); } - if (!theElement) - thePath = nullptr; - } // while + break; + + curIdx = nodeDelim + 1; + } while (!last); - Q3DStudio_free(theToken, CHAR, thePathLength); return theElement; } CQmlElementHelper::TypedAttributeAndValue CQmlElementHelper::getTypedAttributeAndValue( - TElement *theElement, const char *theAttName, const void *value) + TElement *theElement, const char *theAttName, const void *value, TAttributeHash attrHash) { TypedAttributeAndValue retVal = { SAttributeKey(), UVariant() }; retVal.attribute.m_Hash = 0; SAttributeKey theAttributeKey; - theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); + theAttributeKey.m_Hash = attrHash; + if (!attrHash) + theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); // Early out for our single 'read only' attribute if (ATTRIBUTE_URI == theAttributeKey.m_Hash) { @@ -184,8 +165,8 @@ CQmlElementHelper::TypedAttributeAndValue CQmlElementHelper::getTypedAttributeAn retVal.value = theNewValue; } else if (thePropertyInfo.hasValue()) { UVariant theNewValue; - QString name(thePropertyInfo->first.m_Name.c_str()); - EAttributeType theAttributeType = thePropertyInfo->first.m_Type; + QString name(thePropertyInfo->first.name().c_str()); + EAttributeType theAttributeType = thePropertyInfo->first.type(); switch (theAttributeType) { case ATTRIBUTETYPE_INT32: case ATTRIBUTETYPE_HASH: @@ -246,10 +227,13 @@ CQmlElementHelper::TypedAttributeAndValue CQmlElementHelper::getTypedAttributeAn return retVal; } -bool CQmlElementHelper::EnsureAttribute(TElement *theElement, const char *theAttName) +bool CQmlElementHelper::EnsureAttribute(TElement *theElement, const char *theAttName, + TAttributeHash attrHash) { SAttributeKey theAttributeKey; - theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); + theAttributeKey.m_Hash = attrHash; + if (!attrHash) + theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); if (theAttributeKey.m_Hash == ATTRIBUTE_EYEBALL || theAttributeKey.m_Hash == ATTRIBUTE_URI) return false; @@ -278,10 +262,12 @@ bool CQmlElementHelper::EnsureAttribute(TElement *theElement, const char *theAtt } bool CQmlElementHelper::SetAttribute(TElement *theElement, const char *theAttName, - const void *value) + const void *value, TAttributeHash attrHash) { SAttributeKey theAttributeKey; - theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); + theAttributeKey.m_Hash = attrHash; + if (!attrHash) + theAttributeKey.m_Hash = CHash::HashAttribute(theAttName); bool force = false; // Fail if trying to change the activation state of an object in another slide @@ -326,8 +312,8 @@ bool CQmlElementHelper::SetAttribute(TElement *theElement, const char *theAttNam } } - TypedAttributeAndValue attributeAndValue = getTypedAttributeAndValue(theElement, theAttName, - value); + TypedAttributeAndValue attributeAndValue + = getTypedAttributeAndValue(theElement, theAttName, value, theAttributeKey.m_Hash); if (attributeAndValue.attribute.m_Hash == 0) return false; @@ -359,7 +345,7 @@ bool CQmlElementHelper::GetAttribute(TElement *inElement, const char *inAttribut *(INT32 *)value = val; } else if (thePropertyInfo.hasValue()) { UVariant *theValuePtr = thePropertyInfo->second; - EAttributeType theAttributeType = thePropertyInfo->first.m_Type; + EAttributeType theAttributeType = thePropertyInfo->first.type(); switch (theAttributeType) { case ATTRIBUTETYPE_INT32: case ATTRIBUTETYPE_HASH: diff --git a/src/runtime/Qt3DSQmlElementHelper.h b/src/runtime/Qt3DSQmlElementHelper.h index c7b83e0..507be66 100644 --- a/src/runtime/Qt3DSQmlElementHelper.h +++ b/src/runtime/Qt3DSQmlElementHelper.h @@ -45,11 +45,13 @@ private: public: static TElement *GetElement(qt3ds::runtime::IApplication &inApplication, - IPresentation *inDefaultPresentation, const char *inPath, + IPresentation *inDefaultPresentation, const QString &inPath, TElement *inStartElement = NULL); - static bool SetAttribute(TElement *inElement, const char *inAttribute, const void *value); - static bool EnsureAttribute(TElement *inElement, const char *inAttribute); + static bool SetAttribute(TElement *inElement, const char *inAttribute, const void *value, + TAttributeHash attrHash); + static bool EnsureAttribute(TElement *inElement, const char *inAttribute, + TAttributeHash attrHash); static bool GetAttribute(TElement *inElement, const char *inAttribute, void *value); struct TypedAttributeAndValue { @@ -59,7 +61,8 @@ public: static TypedAttributeAndValue getTypedAttributeAndValue(TElement *inElement, const char *inAttribute, - const void *value); + const void *value, + TAttributeHash attrHash); }; } diff --git a/src/runtime/Qt3DSQmlEngine.cpp b/src/runtime/Qt3DSQmlEngine.cpp index f5390af..d6c563a 100644 --- a/src/runtime/Qt3DSQmlEngine.cpp +++ b/src/runtime/Qt3DSQmlEngine.cpp @@ -428,8 +428,8 @@ public: void ProcessCustomCallback(IPresentation *, const SEventCommand &) override {} void SetTableForElement(TElement &, IScriptTableProvider &) override {} - void SetAttribute(TElement *target, const char *attName, const char *value) override; - void SetAttribute(const char *element, const char *attName, const char *value) override; + void SetAttribute(TElement *target, const QString &attName, const char *value) override; + void SetAttribute(const QString &element, const QString &attName, const char *value) override; bool GetAttribute(TElement *target, const char *attName, char *value) override; bool GetAttribute(const char *element, const char *attName, char *value) override; void FireEvent(const char *element, const char *evtName) override; @@ -480,7 +480,7 @@ public: private: TElement *createMaterialContainer(TElement *parent, CPresentation *presentation); void createComponent(QQmlComponent *component, TElement *element); - TElement *getTarget(const char *component); + TElement *getTarget(const QString &component); void listAllElements(TElement *root, QList<TElement *> &elements); void initializeDataInputsInPresentation(CPresentation &presentation, bool isPrimary, bool isDynamicAdd = false, @@ -606,7 +606,8 @@ void CQmlEngineImpl::Initialize() } } -bool queueAttributeChange(TElement *target, const char *attName, const char *value) +bool queueAttributeChange(TElement *target, const char *attName, const char *value, + TAttributeHash attrHash) { if (target->m_BelongedPresentation->GetActivityZone()) { TElement *componentElement = target->GetActivityZone().GetItemTimeParent(*target); @@ -614,40 +615,46 @@ 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); + CQmlElementHelper::EnsureAttribute(target, attName, attrHash); presentation->GetComponentManager().queueChange(componentElement, target, - attName, value); + attName, value, attrHash); return true; } } return false; } -void CQmlEngineImpl::SetAttribute(TElement *target, const char *attName, const char *value) +void CQmlEngineImpl::SetAttribute(TElement *target, const QString &attName, const char *value) { QML_ENGINE_MULTITHREAD_PROTECT_METHOD; if (target) { - if (!queueAttributeChange(target, attName, value)) { - bool success = CQmlElementHelper::SetAttribute(target, attName, value); + QByteArray att = attName.toUtf8(); + auto attrHash = CHash::HashAttribute(attName); + if (!queueAttributeChange(target, att.constData(), value, attrHash)) { + bool success = CQmlElementHelper::SetAttribute(target, att.constData(), value, + attrHash); if (!success) { qCCritical(qt3ds::INVALID_OPERATION) << "CQmlEngineImpl::SetAttribute: " << "failed to set attribute on element" - << target->m_Path.c_str() << ":" << attName << ":" << value; + << target->path().c_str() << ":" << attName << ":" << value; } } } } -void CQmlEngineImpl::SetAttribute(const char *element, const char *attName, const char *value) +void CQmlEngineImpl::SetAttribute(const QString &element, const QString &attName, const char *value) { QML_ENGINE_MULTITHREAD_PROTECT_METHOD; TElement *theTarget = getTarget(element); if (theTarget) { - if (!queueAttributeChange(theTarget, attName, value)) { - bool success = CQmlElementHelper::SetAttribute(theTarget, attName, value); + QByteArray att = attName.toUtf8(); + auto attrHash = CHash::HashAttribute(attName); + if (!queueAttributeChange(theTarget, att.constData(), value, attrHash)) { + bool success = CQmlElementHelper::SetAttribute(theTarget, att.constData(), value, + attrHash); if (!success) { qCCritical(qt3ds::INVALID_OPERATION) << "CQmlEngineImpl::SetAttribute: " @@ -934,7 +941,7 @@ void CQmlEngineImpl::SetDataInputValue( // on master slide, and whose visibility setting must be persistent over // slide changes. TElement *element = getTarget(ctrlElem.elementPath.constData()); - auto hash = CHash::HashAttribute(ctrlElem.attributeName.first().constData()); + auto hash = CHash::HashAttribute(QString(ctrlElem.attributeName.first())); if (hash == Q3DStudio::ATTRIBUTE_EYEBALL && element->m_OnMaster) { element->GetActivityZone().setControlled(*element); @@ -1104,14 +1111,14 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr // Make sure the name is not duplicate TElement *existingChild - = parentElement->FindChild(CHash::HashString(newElementNameBa.constData())); + = parentElement->FindChild(CHash::HashString(newElementName)); if (existingChild) { error = QObject::tr("Element already exists: '%1'").arg(elementPaths[elementIndex]); handleError(); return; } - const CRegisteredString regName = strTable.RegisterStr(newElementNameBa); + const CRegisteredString regName = strTable.RegisterStr(newElementName); TPropertyDescAndValueList elementProperties; CRegisteredString metaType; const CRegisteredString elementSubType; @@ -1191,7 +1198,7 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr regName, metaType, elementSubType, toConstDataRef(elementProperties.data(), QT3DSU32(elementProperties.size())), presentation, parentElement, false); - newElem.m_Path = strTable.RegisterStr(localElementPath); + newElem.setPath(strTable.RegisterStr(localElementPath)); // Insert the new element into the correct slide if (!slideSystem.addSlideElement(component, slideIndex, newElem, eyeBall)) { @@ -1214,7 +1221,7 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr presentation, &newElem, false); QString matElemPath = localElementPath + QLatin1String(".refmat"); - newMatElem.m_Path = strTable.RegisterStr(matElemPath); + newMatElem.setPath(strTable.RegisterStr(matElemPath)); if (!slideSystem.addSlideElement(component, slideIndex, newMatElem, eyeBall)) { // Delete created element and material element if adding to slide failed @@ -1231,10 +1238,11 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr TElement *container = rootElement->FindChild(CHash::HashString("__Container")); TElement *firstChild = nullptr; if (container) { - TElement *nextChild = container->GetChild(); - firstChild = nextChild; - while (nextChild) { - QString childName = QString::fromUtf8(nextChild->m_Name); + auto children = container->children(); + if (!children.isEmpty()) + firstChild = children.first(); + for (auto nextChild : children) { + QString childName = QString::fromUtf8(nextChild->name()); if (childName.endsWith(refMatName)) { auto tr = static_cast<Qt3DSTranslator *>( nextChild->GetAssociation()); @@ -1242,7 +1250,6 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr &tr->RenderObject()); break; } - nextChild = nextChild->GetSibling(); } } @@ -1459,17 +1466,14 @@ void CQmlEngineImpl::createMaterials(const QString &subPresId, materialInfo->materialProps.remove(pathStr); // Check that the material doesn't already exist in container - TElement *firstChild = nullptr; - TElement *nextChild = container->GetChild(); - firstChild = nextChild; - while (nextChild) { - QString childName = QString::fromUtf8(nextChild->m_Name); + const auto children = container->children(); + for (auto nextChild : children) { + QString childName = QString::fromUtf8(nextChild->name()); if (childName == materialInfo->materialName) { error = QObject::tr("Material already exists in material container"); handleError(); return; } - nextChild = nextChild->GetSibling(); } // Create material element in the container based on the material definition @@ -1721,7 +1725,7 @@ void CQmlEngineImpl::createMaterials(const QString &subPresId, while (imageIter.hasNext()) { imageIter.next(); TElement *imageElem = imageIter.value(); - UVariant *propValue = newMatElem.FindPropertyValue(imageElem->m_Name); + UVariant *propValue = newMatElem.FindPropertyValue(imageElem->name()); if (propValue) { propValue->m_ElementHandle = imageIter.value()->GetHandle(); @@ -1787,18 +1791,15 @@ void CQmlEngineImpl::deleteMaterials(const QStringList &materialNames, IQt3DSRen QVector<TElement *> elementsToDelete; const QList<QString> matNames = presMaterialMap.values(presId); for (const auto &materialName : matNames) { - TElement *firstChild = nullptr; - TElement *nextChild = container->GetChild(); - firstChild = nextChild; + const auto children = container->children(); bool added = false; - while (nextChild) { - QString childName = QString::fromUtf8(nextChild->m_Name); + for (auto nextChild : children) { + QString childName = QString::fromUtf8(nextChild->name()); if (childName == materialName) { elementsToDelete << nextChild; added = true; break; } - nextChild = nextChild->GetSibling(); } if (!added) { if (presId.isEmpty()) { @@ -2106,19 +2107,19 @@ void CQmlEngineImpl::createComponent(QQmlComponent *component, TElement *element m_scripts.push_back(script); } -TElement *CQmlEngineImpl::getTarget(const char *component) { +TElement *CQmlEngineImpl::getTarget(const QString &component) { TElement *target = NULL; - QStringList split = QString(component).split(":"); - if (split.size() > 1) { + int delimIndex = component.indexOf(":"); + if (delimIndex > 0) { target = CQmlElementHelper::GetElement( *m_Application, - m_Application->LoadAndGetPresentationById(split.at(0).toStdString().c_str()), - split.at(1).toStdString().c_str(), NULL); + m_Application->LoadAndGetPresentationById(component.left(delimIndex)), + component.right(delimIndex + 1), NULL); } else { target = CQmlElementHelper::GetElement( *m_Application, m_Application->GetPrimaryPresentation(), - split.at(0).toStdString().c_str(), NULL); + component, NULL); } return target; } @@ -2126,11 +2127,9 @@ TElement *CQmlEngineImpl::getTarget(const char *component) { void CQmlEngineImpl::listAllElements(TElement *root, QList<TElement *> &elements) { elements.append(root); - TElement *nextChild = root->GetChild(); - while (nextChild) { + const auto children(root->children()); + for (auto nextChild : children) listAllElements(nextChild, elements); - nextChild = nextChild->GetSibling(); - } } // Initializes datainput bindings in the presentation starting by default from the root element. @@ -2179,11 +2178,11 @@ void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentat if (ctrlElem.attributeName.first() == QByteArrayLiteral("@timeline")) { ctrlElem.propertyType = ATTRIBUTETYPE_DATAINPUT_TIMELINE; TElement *component = &element->GetComponentParent(); - ctrlElem.elementPath.append(component->m_Path); + ctrlElem.elementPath.append(component->path()); } else if (ctrlElem.attributeName.first() == QByteArrayLiteral("@slide")) { ctrlElem.propertyType = ATTRIBUTETYPE_DATAINPUT_SLIDE; TElement *component = &element->GetComponentParent(); - ctrlElem.elementPath.append(component->m_Path); + ctrlElem.elementPath.append(component->path()); } else if (diMap[controllerName].type == qt3ds::runtime::DataInOutTypeVector4) { // special handling for vector datatype to handle @@ -2194,7 +2193,7 @@ void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentat element); if (!attVec.empty() && success) { ctrlElem.attributeName = attVec; - ctrlElem.elementPath.append(element->m_Path); + ctrlElem.elementPath.append(element->path()); ctrlElem.propertyType = ATTRIBUTETYPE_FLOAT4; } else { qWarning() << __FUNCTION__ << "Property " @@ -2212,7 +2211,7 @@ void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentat element); if (!attVec.empty() && success) { ctrlElem.attributeName = attVec; - ctrlElem.elementPath.append(element->m_Path); + ctrlElem.elementPath.append(element->path()); ctrlElem.propertyType = ATTRIBUTETYPE_FLOAT3; } else { qWarning() << __FUNCTION__ << "Property " @@ -2230,7 +2229,7 @@ void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentat element); if (!attVec.empty() && success) { ctrlElem.attributeName = attVec; - ctrlElem.elementPath.append(element->m_Path); + ctrlElem.elementPath.append(element->path()); ctrlElem.propertyType = ATTRIBUTETYPE_FLOAT2; } else { qWarning() << __FUNCTION__ << "Property " @@ -2250,22 +2249,22 @@ void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentat for (auto ref : referencedDIs) diMap[ref].dependents.append(controllerName); - ctrlElem.elementPath.append(element->m_Path); + ctrlElem.elementPath.append(element->path()); TStringHash attHash = CHash::HashAttribute( - ctrlElem.attributeName.first().constData()); + QString(ctrlElem.attributeName.first())); Option<qt3ds::runtime::element::TPropertyDescAndValuePtr> attInfo = element->FindProperty(attHash); if (attInfo.hasValue()) - ctrlElem.propertyType = attInfo->first.m_Type; + ctrlElem.propertyType = attInfo->first.type(); } else { // all other scalar datatypes - ctrlElem.elementPath.append(element->m_Path); + ctrlElem.elementPath.append(element->path()); TStringHash attHash = CHash::HashAttribute( - ctrlElem.attributeName.first().constData()); + QString(ctrlElem.attributeName.first())); Option<qt3ds::runtime::element::TPropertyDescAndValuePtr> attInfo = element->FindProperty(attHash); if (attInfo.hasValue()) { - ctrlElem.propertyType = attInfo->first.m_Type; + ctrlElem.propertyType = attInfo->first.type(); } else { ctrlElem.propertyType = ATTRIBUTETYPE_NONE; qWarning() << __FUNCTION__ << "Property " @@ -2373,7 +2372,7 @@ void CQmlEngineImpl::initializeDataOutputsInPresentation(CPresentation &presenta // Timeline requires special additional handling obsElem.propertyType = ATTRIBUTETYPE_DATAINPUT_TIMELINE; TElement *component = &element->GetComponentParent(); - obsElem.elementPath.append(component->m_Path); + obsElem.elementPath.append(component->path()); // Find the TElement for the @timeline attrib TElement *target = nullptr; @@ -2396,13 +2395,13 @@ void CQmlEngineImpl::initializeDataOutputsInPresentation(CPresentation &presenta // slide transitions } else { // Every other type is handled by CPresentation - obsElem.elementPath.append(element->m_Path); + obsElem.elementPath.append(element->path()); TStringHash attHash = CHash::HashAttribute( obsElem.attributeName.first().constData()); Option<qt3ds::runtime::element::TPropertyDescAndValuePtr> attInfo = element->FindProperty(attHash); if (attInfo.hasValue()) { - obsElem.propertyType = attInfo->first.m_Type; + obsElem.propertyType = attInfo->first.type(); } else { obsElem.propertyType = ATTRIBUTETYPE_NONE; qWarning() << __FUNCTION__ << "Property" @@ -2437,7 +2436,7 @@ void CQmlEngineImpl::removeDataInputControl(const QVector<TElement *> &inElement while (diMapIter.hasNext()) { diMapIter.next(); for (const auto &inOutAttr : qAsConst(diMapIter.value().controlledAttributes)) { - if (inOutAttr.elementPath == QByteArray(elem->m_Path)) + if (inOutAttr.elementPath == QByteArray(elem->path())) elemAttrsToRemove.append({diMapIter.key(), inOutAttr}); } } @@ -2457,7 +2456,7 @@ bool CQmlEngineImpl::getAttributeVector4(QVector<QByteArray> &outAttVec, const QByteArray &attName, TElement *elem) { - auto hashName = Q3DStudio::CHash::HashAttribute(attName + ".x"); + auto hashName = Q3DStudio::CHash::HashAttribute(QString(attName + ".x")); if (!elem->FindProperty(hashName).isEmpty()) { outAttVec.append(attName + ".x"); @@ -2466,7 +2465,7 @@ bool CQmlEngineImpl::getAttributeVector4(QVector<QByteArray> &outAttVec, outAttVec.append(attName + ".w"); return true; } - hashName = Q3DStudio::CHash::HashAttribute(attName + ".r"); + hashName = Q3DStudio::CHash::HashAttribute(QString(attName + ".r")); if (!elem->FindProperty(hashName).isEmpty()) { outAttVec.append(attName + ".r"); outAttVec.append(attName + ".g"); @@ -2481,7 +2480,7 @@ bool CQmlEngineImpl::getAttributeVector3(QVector<QByteArray> &outAttVec, const QByteArray &attName, TElement *elem) { - auto hashName = Q3DStudio::CHash::HashAttribute(attName + ".x"); + auto hashName = Q3DStudio::CHash::HashAttribute(QString(attName + ".x")); if (!elem->FindProperty(hashName).isEmpty()) { outAttVec.append(attName + ".x"); @@ -2489,7 +2488,7 @@ bool CQmlEngineImpl::getAttributeVector3(QVector<QByteArray> &outAttVec, outAttVec.append(attName + ".z"); return true; } - hashName = Q3DStudio::CHash::HashAttribute(attName + ".r"); + hashName = Q3DStudio::CHash::HashAttribute(QString(attName + ".r")); if (!elem->FindProperty(hashName).isEmpty()) { outAttVec.append(attName + ".r"); outAttVec.append(attName + ".g"); @@ -2503,7 +2502,7 @@ bool CQmlEngineImpl::getAttributeVector2(QVector<QByteArray> &outAttVec, const QByteArray &attName, TElement *elem) { - auto hashName = Q3DStudio::CHash::HashAttribute(attName + ".x"); + auto hashName = Q3DStudio::CHash::HashAttribute(QString(attName + ".x")); if (!elem->FindProperty(hashName).isEmpty()) { outAttVec.append(attName + ".x"); @@ -2511,7 +2510,7 @@ bool CQmlEngineImpl::getAttributeVector2(QVector<QByteArray> &outAttVec, return true; } - hashName = Q3DStudio::CHash::HashAttribute(attName + ".u"); + hashName = Q3DStudio::CHash::HashAttribute(QString(attName + ".u")); if (!elem->FindProperty(hashName).isEmpty()) { outAttVec.append(attName + ".u"); outAttVec.append(attName + ".v"); @@ -2798,12 +2797,9 @@ void CQmlEngineImpl::deleteElements(const QVector<TElement *> &elements, if (m_elementIdMap.contains(elem)) releaseId(m_elementIdMap.take(elem)); - TElement *child = elem->m_Child; - while (child) { - TElement *sibling = child->m_Sibling; + const auto children(elem->children()); + for (auto child : children) deleteRenderObjects(child); - child = sibling; - } auto translator = static_cast<qt3ds::render::Qt3DSTranslator *>(elem->GetAssociation()); if (translator) { diff --git a/src/runtime/Qt3DSSlideSystem.cpp b/src/runtime/Qt3DSSlideSystem.cpp index 7e7d77f..4eaa698 100644 --- a/src/runtime/Qt3DSSlideSystem.cpp +++ b/src/runtime/Qt3DSSlideSystem.cpp @@ -337,11 +337,9 @@ struct SSlideSystem : public ISlideSystem void removeElementRecursive(SSlide *slide, element::SElement &inElement) { - element::SElement *child = inElement.m_Child; - while (child) { + const auto children = inElement.children(); + for (auto child : children) removeElementRecursive(slide, *child); - child = child->m_Sibling; - } SSlideElement *slideElement = slide->m_FirstElement; SSlideElement *previousElement = nullptr; diff --git a/src/runtime/q3dsqmlscript.cpp b/src/runtime/q3dsqmlscript.cpp index 725c752..85a1a84 100644 --- a/src/runtime/q3dsqmlscript.cpp +++ b/src/runtime/q3dsqmlscript.cpp @@ -99,7 +99,7 @@ Q3DSQmlScript::Q3DSQmlScript(CQmlEngine &api, Q3DSQmlBehavior &object, auto nameHash = CHash::HashAttribute(property.name()); Option<element::TPropertyDescAndValuePtr> value = behavior.FindProperty(nameHash); if (value.hasValue()) { - switch (value->first.m_Type) { + switch (value->first.type()) { case ATTRIBUTETYPE_INT32: case ATTRIBUTETYPE_HASH: t = QVariant::Int; @@ -235,7 +235,7 @@ Q3DSQmlScript::Q3DSQmlScript(CQmlEngine &api, Q3DSQmlBehavior &object, std::function<void()> mapper; auto nameHash = CHash::HashAttribute(property.name()); Option<element::TPropertyDescAndValuePtr> prop = behavior.FindProperty(nameHash); - if (prop.hasValue() && prop->first.m_Type == Q3DStudio::ATTRIBUTETYPE_FLOAT2) { + if (prop.hasValue() && prop->first.type() == Q3DStudio::ATTRIBUTETYPE_FLOAT2) { mapper = [&object, property, prop]() { QVector2D vec; Q3DStudio::UVariant *value = prop->second; @@ -271,7 +271,7 @@ Q3DSQmlScript::Q3DSQmlScript(CQmlEngine &api, Q3DSQmlBehavior &object, std::function<void()> mapper; auto nameHash = CHash::HashAttribute(property.name()); Option<element::TPropertyDescAndValuePtr> prop = behavior.FindProperty(nameHash); - if (prop.hasValue() && prop->first.m_Type == Q3DStudio::ATTRIBUTETYPE_FLOAT3) { + if (prop.hasValue() && prop->first.type() == Q3DStudio::ATTRIBUTETYPE_FLOAT3) { mapper = [&object, property, prop]() { QVector3D vec; Q3DStudio::UVariant *value = prop->second; @@ -314,7 +314,7 @@ Q3DSQmlScript::Q3DSQmlScript(CQmlEngine &api, Q3DSQmlBehavior &object, std::function<void()> mapper; auto nameHash = CHash::HashAttribute(property.name()); Option<element::TPropertyDescAndValuePtr> prop = behavior.FindProperty(nameHash); - if (prop.hasValue() && prop->first.m_Type == Q3DStudio::ATTRIBUTETYPE_FLOAT4) { + if (prop.hasValue() && prop->first.type() == Q3DStudio::ATTRIBUTETYPE_FLOAT4) { mapper = [&object, property, prop]() { QVector4D vec; Q3DStudio::UVariant *value = prop->second; @@ -578,7 +578,7 @@ void Q3DSQmlScript::fireEvent(const QString &event) { if (!m_behavior.GetActive()) return; - m_api.FireEvent(m_behavior.m_Path, event.toUtf8().constData()); + m_api.FireEvent(m_behavior.path(), event.toUtf8().constData()); } void Q3DSQmlScript::registerForEvent(const QString &event, const QJSValue &function) @@ -720,7 +720,7 @@ QString Q3DSQmlScript::getParent(const QString &handle) TElement *parent = element->GetParent(); if (!parent) return ""; - return parent->m_Path.c_str(); + return parent->path().c_str(); } void Q3DSQmlScript::setDataInputValue(const QString &name, const QVariant &value, diff --git a/src/system/Qt3DSHash.h b/src/system/Qt3DSHash.h index 8baa2db..b074d9c 100644 --- a/src/system/Qt3DSHash.h +++ b/src/system/Qt3DSHash.h @@ -30,6 +30,7 @@ #pragma once #include "Qt3DSConfig.h" +#include <qstring.h> //============================================================================== // Namespace @@ -77,6 +78,37 @@ public: // Static utility return theHash; } + static TStringHash HashString(const QString &inString) + { + TStringHash theHash = 0; + INT32 theCount = 0; + for (auto theChar : inString) { + if (theCount == HASH_LIMIT) + break; + theHash = theChar.toLatin1() + (theHash << 6) + (theHash << 16) - theHash; + ++theCount; + } + theHash = (theHash << 6) + (theHash << 16) - theHash; + + return theHash; + } + + static TStringHash HashString(const QString &inString, int begin, int end) + { + TStringHash theHash = 0; + INT32 theCount = 0; + for (int i = begin; i < end; ++i) { + if (theCount == HASH_LIMIT) + break; + theHash = inString.at(i).toLatin1() + (theHash << 6) + (theHash << 16) - theHash; + ++theCount; + } + theHash = (theHash << 6) + (theHash << 16) - theHash; + + return theHash; + } + + //============================================================================== /** * 31-bit hash with MSB set to 0 @@ -100,6 +132,11 @@ public: // Static utility { return HashString(inString) & 0x03ffffff; } + + static TAttributeHash HashAttribute(const QString &inString) + { + return HashString(inString) & 0x03ffffff; + } }; } // namespace Q3DStudio diff --git a/src/uipparser/Qt3DSUIPParserActionHelper.cpp b/src/uipparser/Qt3DSUIPParserActionHelper.cpp index ab6d751..68c6be3 100644 --- a/src/uipparser/Qt3DSUIPParserActionHelper.cpp +++ b/src/uipparser/Qt3DSUIPParserActionHelper.cpp @@ -341,7 +341,7 @@ void CUIPParserActionHelper::BuildAction(TElement &inElement, UINT32 inEventName Q3DStudio_ASSERT(theActionCount > 0); for (UINT32 theActionIndex = 0; theActionIndex < theActionCount; ++theActionIndex) { INT32 actionId = theAdder.AddAction( - COMMAND_SETPROPERTY, theProperties[theActionIndex].first.GetNameHash(), + COMMAND_SETPROPERTY, theProperties[theActionIndex].first.nameHash(), theProperties[theActionIndex].second.m_INT32); if (theActionIndex == 0) theAddActionIndex = actionId; diff --git a/src/uipparser/Qt3DSUIPParserImpl.cpp b/src/uipparser/Qt3DSUIPParserImpl.cpp index d0868ee..6503dbe 100644 --- a/src/uipparser/Qt3DSUIPParserImpl.cpp +++ b/src/uipparser/Qt3DSUIPParserImpl.cpp @@ -1156,7 +1156,7 @@ BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &i thePath.insert(0, theNode->m_Name); } if (thePath.size()) - theNewElem.m_Path = m_ParseElementManager.m_StringTable.RegisterStr(thePath.c_str()); + theNewElem.setPath(m_ParseElementManager.m_StringTable.RegisterStr(thePath.c_str())); if (isBehavior) { if (theFileString.find(".qml") != eastl::string::npos) { @@ -2321,7 +2321,7 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m for (QT3DSU32 idx = previousListSize, end = theAttributeList.size(); idx < end; ++idx) { UVariant *theValue = inElementData.m_Element->FindPropertyValue( - theAttributeList[idx].first.m_Name); + theAttributeList[idx].first.name()); if (theValue) { *theValue = theAttributeList[idx].second; } |