[Development] [Interest] [Qt3D] Mixing C++ and QML
Svenn-Arne Dragly
svenn-arne.dragly at qt.io
Mon Oct 30 09:51:38 CET 2017
>>> A typical pattern in QtQuick is that a QQmlListProperty is the
>>> default property, so declared children are automatically added. But
>>> instead you have to declare the Components first, and then also add
>>> them to a vector. Why is that? It seems needlessly cumbersome to
>>> me. If Components are naturally always children of Entities,
>> ^ that is your broken assumption. Components do not have to be children of the entity. We actually started out with that but found that it prohibits sharing components which can sometimes be handy.
> “sometimes”… so maybe add declared child Components to the vector automatically, but also allow sharing them by ID when necessary?
I would rather say "often" than "sometimes" for this one. In simple
examples, each component is often used only in one entity, but in more
realistic use cases, components like materials tend to be shared. While
I would also prefer a solution that "just works" when you add components
as children to an entity, I think this is hard to get right.
The naive solution is to allow both uses and just add them to the
parent's vector, but because you would typically add shared components
as children of some root component, this would end up drawing the root
entity as a mix of all shared components in addition to the entities
using those components. I.e., this would draw the mesh three times:
Entity {
id: root
Mesh { id: mesh }
Material { id: material }
Transform { id: transform1 }
Transform { id: transform2 }
Entity { components: [ transform1, material, mesh ] }
Entity { components: [ transform2, material, mesh ] }
}
To work around that issue, we could detect any sharing of components and
remove it from its parent if it's shared, but this seems like a bad
solution in my opinion.
Alternatively, we could add `shared` property to each component that
should not be added to its parent's vector:
Entity {
id: root
Mesh { id: mesh; shared: true }
Material { id: material; shared: true }
Transform { id: transform1; shared: true }
Transform { id: transform2; shared: true }
Entity { components: [ transform1, material, mesh ] }
Entity { components: [ transform2, material, mesh ] }
}
Or we could introduce some new node that isn't an Entity and can hold
the shared components, while any component added as a child to an entity
becomes added to the parent's vector:
Entity {
id: root
SharedComponents {
Mesh { id: mesh }
Material { id: material }
Transform { id: transform1 }
Transform { id: transform2 }
}
Entity { components: [ transform1, material, mesh ] }
Entity { components: [ transform2, material, mesh ] }
}
I think last option is the best of the three, but there might be better
alternatives. And neither is much better than the current API, in my
opinion.
Svenn-Arne
More information about the Development
mailing list