Improve support for node iteration in the internal API
authorSimon Hausmann <simon.hausmann@digia.com>
Fri, 8 Aug 2014 10:10:44 +0000 (12:10 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 8 Aug 2014 18:06:57 +0000 (20:06 +0200)
Added a new node visitor that allows easier traversal of the specialized
node types such as the image or rectangle nodes.

Change-Id: I45a7d3e1513b4a4db9d07998a6bcee9eba34044e
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/quick/scenegraph/coreapi/qsgnode.cpp
src/quick/scenegraph/coreapi/qsgnode.h
src/quick/scenegraph/qsgadaptationlayer.cpp
src/quick/scenegraph/qsgadaptationlayer_p.h

index 4c25338..0950148 100644 (file)
@@ -135,6 +135,7 @@ static void qt_print_node_count()
     \value OwnsOpaqueMaterial Only valid for QSGGeometryNode. The node has
     ownership over the opaque material and will delete it when the node is
     destroyed or a material is assigned.
+    \value InternalReserved Reserved for internal use.
  */
 
 /*!
index 86977f7..3dc2a86 100644 (file)
@@ -95,9 +95,14 @@ public:
         // QSGBasicGeometryNode
         OwnsGeometry                = 0x00010000,
         OwnsMaterial                = 0x00020000,
-        OwnsOpaqueMaterial          = 0x00040000
+        OwnsOpaqueMaterial          = 0x00040000,
 
         // Uppermost 8 bits are reserved for internal use.
+#ifndef qdoc
+        IsVisitableNode             = 0x01000000
+#else
+        InternalReserved            = 0x01000000
+#endif
     };
     Q_DECLARE_FLAGS(Flags, Flag)
 
index 9826fa8..ee077db 100644 (file)
@@ -291,4 +291,52 @@ void QSGDistanceFieldGlyphCache::updateTexture(GLuint oldTex, GLuint newTex, con
     }
 }
 
+void QSGNodeVisitorEx::visitChildren(QSGNode *node)
+{
+    for (QSGNode *child = node->firstChild(); child; child = child->nextSibling()) {
+        switch (child->type()) {
+        case QSGNode::ClipNodeType: {
+            QSGClipNode *c = static_cast<QSGClipNode*>(child);
+            visit(c);
+            visitChildren(c);
+            endVisit(c);
+            break;
+        }
+        case QSGNode::TransformNodeType: {
+            QSGTransformNode *c = static_cast<QSGTransformNode*>(child);
+            visit(c);
+            visitChildren(c);
+            endVisit(c);
+            break;
+        }
+        case QSGNode::OpacityNodeType: {
+            QSGOpacityNode *c = static_cast<QSGOpacityNode*>(child);
+            visit(c);
+            visitChildren(c);
+            endVisit(c);
+            break;
+        }
+        case QSGNode::GeometryNodeType: {
+            if (child->flags() & QSGNode::IsVisitableNode) {
+                QSGVisitableNode *v = static_cast<QSGVisitableNode*>(child);
+                v->accept(this);
+            } else {
+                QSGGeometryNode *c = static_cast<QSGGeometryNode*>(child);
+                visit(c);
+                visitChildren(c);
+                endVisit(c);
+            }
+            break;
+        }
+        case QSGNode::BasicNodeType: {
+            visitChildren(child);
+            break;
+        }
+        default:
+            Q_UNREACHABLE();
+            break;
+        }
+    }
+}
+
 QT_END_NAMESPACE
index f2d7dc0..46531f7 100644 (file)
@@ -67,8 +67,41 @@ class TextureReference;
 class QSGDistanceFieldGlyphCacheManager;
 class QSGDistanceFieldGlyphNode;
 class QOpenGLContext;
+class QSGImageNode;
+class QSGRectangleNode;
+class QSGGlyphNode;
 
-class Q_QUICK_PRIVATE_EXPORT QSGRectangleNode : public QSGGeometryNode
+class Q_QUICK_PRIVATE_EXPORT QSGNodeVisitorEx
+{
+public:
+    virtual void visit(QSGTransformNode *) = 0;
+    virtual void endVisit(QSGTransformNode *) = 0;
+    virtual void visit(QSGClipNode *) = 0;
+    virtual void endVisit(QSGClipNode *) = 0;
+    virtual void visit(QSGGeometryNode *) = 0;
+    virtual void endVisit(QSGGeometryNode *) = 0;
+    virtual void visit(QSGOpacityNode *) = 0;
+    virtual void endVisit(QSGOpacityNode *) = 0;
+    virtual void visit(QSGImageNode *) = 0;
+    virtual void endVisit(QSGImageNode *) = 0;
+    virtual void visit(QSGRectangleNode *) = 0;
+    virtual void endVisit(QSGRectangleNode *) = 0;
+    virtual void visit(QSGGlyphNode *) = 0;
+    virtual void endVisit(QSGGlyphNode *) = 0;
+
+    void visitChildren(QSGNode *node);
+};
+
+
+class Q_QUICK_PRIVATE_EXPORT QSGVisitableNode : public QSGGeometryNode
+{
+public:
+    QSGVisitableNode() { setFlag(IsVisitableNode); }
+
+    virtual void accept(QSGNodeVisitorEx *) = 0;
+};
+
+class Q_QUICK_PRIVATE_EXPORT QSGRectangleNode : public QSGVisitableNode
 {
 public:
     virtual void setRect(const QRectF &rect) = 0;
@@ -81,10 +114,12 @@ public:
     virtual void setAligned(bool aligned) = 0;
 
     virtual void update() = 0;
+
+    virtual void accept(QSGNodeVisitorEx *visitor) { visitor->visit(this); visitor->visitChildren(this); visitor->endVisit(this); }
 };
 
 
-class Q_QUICK_PRIVATE_EXPORT QSGImageNode : public QSGGeometryNode
+class Q_QUICK_PRIVATE_EXPORT QSGImageNode : public QSGVisitableNode
 {
 public:
     virtual void setTargetRect(const QRectF &rect) = 0;
@@ -103,10 +138,12 @@ public:
     virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) = 0;
 
     virtual void update() = 0;
+
+    virtual void accept(QSGNodeVisitorEx *visitor) { visitor->visit(this); visitor->visitChildren(this); visitor->endVisit(this); }
 };
 
 
-class Q_QUICK_PRIVATE_EXPORT QSGGlyphNode : public QSGGeometryNode
+class Q_QUICK_PRIVATE_EXPORT QSGGlyphNode : public QSGVisitableNode
 {
 public:
     enum AntialiasingMode
@@ -134,6 +171,7 @@ public:
     void setOwnerElement(QQuickItem *ownerElement) { m_ownerElement = ownerElement; }
     QQuickItem *ownerElement() const { return m_ownerElement; }
 
+    virtual void accept(QSGNodeVisitorEx *visitor) { visitor->visit(this); visitor->visitChildren(this); visitor->endVisit(this); }
 protected:
     QRectF m_bounding_rect;
     QQuickItem *m_ownerElement;