Optimize CSS selector traversal and fix sibling combinators:

- inline hot-path node and stylesheet traversal accessors
  - correct adjacent and general sibling matching direction
  - preserve inverse sibling operator behavior
  - add selector traversal and sibling regression tests
This commit is contained in:
Martín Lucas Golini
2026-07-10 01:26:06 -03:00
parent 2bc18f0ded
commit 6b4179b896
7 changed files with 154 additions and 97 deletions

View File

@@ -215,7 +215,7 @@ class EE_API Node : public Transformable {
virtual bool isType( const Uint32& type ) const;
/** @return True if this node is a UITextNode, false otherwise. */
bool isTextNode() const;
inline bool isTextNode() const { return 0 != ( mNodeFlags & NODE_FLAG_TEXTNODE ); }
/**
* @brief Posts a message to this node and its ancestors.
@@ -369,7 +369,7 @@ class EE_API Node : public Transformable {
*
* @return Pointer to the parent node or nullptr.
*/
Node* getParent() const;
inline Node* getParent() const { return mParentNode; }
/**
* @brief Sets the parent node.
@@ -429,7 +429,7 @@ class EE_API Node : public Transformable {
*
* @return Pointer to the next sibling node or nullptr.
*/
Node* getNextNode() const;
inline Node* getNextNode() const { return mNext; }
/**
* @brief Gets the previous sibling node in the parent's child list.
@@ -439,7 +439,7 @@ class EE_API Node : public Transformable {
*
* @return Pointer to the previous sibling node or nullptr.
*/
Node* getPrevNode() const;
inline Node* getPrevNode() const { return mPrev; }
/**
* @brief Gets the next sibling node, wrapping to first if at end.
@@ -525,7 +525,7 @@ class EE_API Node : public Transformable {
*
* @return The flags as a Uint32 bitmask.
*/
const Uint32& getNodeFlags() const;
inline const Uint32& getNodeFlags() const { return mNodeFlags; }
/**
* @brief Sets the node flags directly.
@@ -571,7 +571,7 @@ class EE_API Node : public Transformable {
*
* @return True if this node is a UIWidget, false otherwise.
*/
bool isWidget() const;
inline bool isWidget() const { return 0 != ( mNodeFlags & NODE_FLAG_WIDGET ); }
/**
* @brief Checks if this node is a Window.

View File

@@ -784,7 +784,11 @@ class EE_API UIWidget : public UINode {
*
* @return Pointer to the parent element widget or nullptr.
*/
UIWidget* getStyleSheetParentElement() const;
inline UIWidget* getStyleSheetParentElement() const {
return NULL != mParentNode && mParentNode->isWidget() && getType() != UI_TYPE_HTML_HTML
? mParentNode->asType<UIWidget>()
: NULL;
}
/**
* @brief Gets the previous sibling element for CSS styling.
@@ -793,7 +797,15 @@ class EE_API UIWidget : public UINode {
*
* @return Pointer to the previous sibling element widget or nullptr.
*/
UIWidget* getStyleSheetPreviousSiblingElement() const;
inline UIWidget* getStyleSheetPreviousSiblingElement() const {
Node* node = mPrev;
while ( NULL != node ) {
if ( node->isWidget() && !node->isTextNode() )
return node->asType<UIWidget>();
node = node->getPrevNode();
}
return NULL;
}
/**
* @brief Gets the next sibling element for CSS styling.
@@ -802,7 +814,15 @@ class EE_API UIWidget : public UINode {
*
* @return Pointer to the next sibling element widget or nullptr.
*/
UIWidget* getStyleSheetNextSiblingElement() const;
inline UIWidget* getStyleSheetNextSiblingElement() const {
Node* node = mNext;
while ( NULL != node ) {
if ( node->isWidget() && !node->isTextNode() )
return node->asType<UIWidget>();
node = node->getNextNode();
}
return NULL;
}
/**
* @brief Gets the active pseudo-classes for this widget.
@@ -811,7 +831,7 @@ class EE_API UIWidget : public UINode {
*
* @return Bitmask of active pseudo-classes.
*/
Uint32 getStyleSheetPseudoClasses() const { return mPseudoClasses; }
inline Uint32 getStyleSheetPseudoClasses() const { return mPseudoClasses; }
/**
* @brief Gets the pseudo-classes as string array.