@@ -1465,6 +1465,7 @@ class _ConstraintRenderBox extends RenderBox
14651465
14661466 bool _needsRecalculateConstraints = true ;
14671467 bool _needsReorderChildren = true ;
1468+ int _buildNodeTreesCount = 0 ;
14681469 final Map <ConstraintId , _ConstrainedNode > _helperNodeMap = HashMap ();
14691470
14701471 /// For layout
@@ -1499,6 +1500,41 @@ class _ConstraintRenderBox extends RenderBox
14991500 }
15001501 if (! isSameList) {
15011502 _childConstraints = value;
1503+ _helperNodeMap.clear ();
1504+ for (final element in _childConstraints ?? []) {
1505+ if (element is GuidelineDefine ) {
1506+ _ConstraintBoxData constraintBoxData = _ConstraintBoxData ();
1507+ _HelperBox .initParentData (constraintBoxData);
1508+ _GuidelineRenderBox .initParentData (
1509+ constraintBoxData,
1510+ id: element.id! ,
1511+ horizontal: element.horizontal,
1512+ guidelineBegin: element.guidelineBegin,
1513+ guidelineEnd: element.guidelineEnd,
1514+ guidelinePercent: element.guidelinePercent,
1515+ );
1516+ _ConstrainedNode constrainedNode = _ConstrainedNode ()
1517+ ..nodeId = element.id!
1518+ ..parentData = constraintBoxData
1519+ ..index = - 1
1520+ ..depth = 1 ;
1521+ _helperNodeMap[element.id! ] = constrainedNode;
1522+ } else if (element is BarrierDefine ) {
1523+ _ConstraintBoxData constraintBoxData = _ConstraintBoxData ();
1524+ _HelperBox .initParentData (constraintBoxData);
1525+ _BarrierRenderBox .initParentData (
1526+ constraintBoxData,
1527+ id: element.id! ,
1528+ direction: element.direction,
1529+ referencedIds: element.referencedIds,
1530+ );
1531+ _ConstrainedNode constrainedNode = _ConstrainedNode ()
1532+ ..nodeId = element.id!
1533+ ..parentData = constraintBoxData
1534+ ..index = - 1 ;
1535+ _helperNodeMap[element.id! ] = constrainedNode;
1536+ }
1537+ }
15021538 markNeedsRecalculateConstraints ();
15031539 markNeedsLayout ();
15041540 }
@@ -1639,6 +1675,13 @@ class _ConstraintRenderBox extends RenderBox
16391675 child = childParentData.nextSibling;
16401676 }
16411677
1678+ /// All ids referenced by Barrier must be defined
1679+ for (final element in _helperNodeMap.values) {
1680+ if (element.isBarrier) {
1681+ constraintsIdSet.addAll (element.referencedIds! );
1682+ }
1683+ }
1684+
16421685 /// The id used by all constraints must be defined
16431686 Set <ConstraintId > illegalIdSet = constraintsIdSet.difference (idSet);
16441687 Set <RelativeConstraintId > relativeIds =
@@ -1647,18 +1690,6 @@ class _ConstraintRenderBox extends RenderBox
16471690 throw ConstraintLayoutException (
16481691 'These ids ${illegalIdSet .difference (relativeIds )} are not yet defined.' );
16491692 }
1650-
1651- /// All ids referenced by Barrier must be defined
1652- // for (final element in _helperNodeMap.values) {
1653- // if (element.isBarrier) {
1654- // Set<ConstraintId> illegalIdSet =
1655- // element.referencedIds!.toSet().difference(idSet);
1656- // if (illegalIdSet.isNotEmpty) {
1657- // throw ConstraintLayoutException(
1658- // 'These ids $illegalIdSet are not yet defined.');
1659- // }
1660- // }
1661- // }
16621693 }
16631694
16641695 /// There should be no loop constraints
@@ -1781,26 +1812,59 @@ class _ConstraintRenderBox extends RenderBox
17811812
17821813 Map <ConstraintId , _ConstrainedNode > _buildConstrainedNodeTrees () {
17831814 Map <ConstraintId , _ConstrainedNode > nodesMap = HashMap ();
1815+ _buildNodeTreesCount++ ;
17841816
17851817 _ConstrainedNode _getConstrainedNodeForChild (ConstraintId id) {
17861818 if (id == parent) {
17871819 return _parentNode;
17881820 }
1789- _ConstrainedNode ? node = id.getCacheNode (hashCode);
1821+
1822+ /// Fewer reads to nodesMap for faster constraint building
1823+ _ConstrainedNode ? node = id.getCacheNode (_buildNodeTreesCount ^ hashCode);
17901824 if (node != null ) {
17911825 return node;
17921826 }
1827+
17931828 node = nodesMap[id];
17941829 if (node == null ) {
17951830 node = _ConstrainedNode ()..nodeId = id;
17961831 nodesMap[id] = node;
17971832 }
1798- id.setCacheNode (hashCode, node);
1833+ id.setCacheNode (_buildNodeTreesCount ^ hashCode, node);
17991834 return node;
18001835 }
18011836
18021837 if (_helperNodeMap.isNotEmpty) {
18031838 nodesMap.addAll (_helperNodeMap);
1839+ for (final element in _helperNodeMap.values) {
1840+ if (element.parentData.left != null ) {
1841+ element.leftConstraint =
1842+ _getConstrainedNodeForChild (element.parentData.left! .id! );
1843+ element.leftAlignType = element.parentData.left! .type;
1844+ }
1845+
1846+ if (element.parentData.top != null ) {
1847+ element.topConstraint =
1848+ _getConstrainedNodeForChild (element.parentData.top! .id! );
1849+ element.topAlignType = element.parentData.top! .type;
1850+ }
1851+
1852+ if (element.parentData.right != null ) {
1853+ element.rightConstraint =
1854+ _getConstrainedNodeForChild (element.parentData.right! .id! );
1855+ element.rightAlignType = element.parentData.right! .type;
1856+ }
1857+
1858+ if (element.parentData.bottom != null ) {
1859+ element.bottomConstraint =
1860+ _getConstrainedNodeForChild (element.parentData.bottom! .id! );
1861+ element.bottomAlignType = element.parentData.bottom! .type;
1862+ }
1863+
1864+ if (element.isBarrier) {
1865+ element.parentData._constrainedNodeMap = nodesMap;
1866+ }
1867+ }
18041868 }
18051869
18061870 RenderBox ? child = firstChild;
@@ -3055,10 +3119,7 @@ class _ConstrainedNode {
30553119}
30563120
30573121class _HelperBox extends RenderBox {
3058- @protected
3059- @mustCallSuper
3060- void updateParentData () {
3061- _ConstraintBoxData constraintBoxData = parentData as _ConstraintBoxData ;
3122+ static void initParentData (_ConstraintBoxData constraintBoxData) {
30623123 constraintBoxData.width = 0 ;
30633124 constraintBoxData.height = 0 ;
30643125 constraintBoxData.clickPadding = EdgeInsets .zero;
@@ -3095,6 +3156,13 @@ class _HelperBox extends RenderBox {
30953156 constraintBoxData._isBarrier = false ;
30963157 constraintBoxData._helperSize = null ;
30973158 }
3159+
3160+ @protected
3161+ @mustCallSuper
3162+ void updateParentData () {
3163+ _ConstraintBoxData constraintBoxData = parentData as _ConstraintBoxData ;
3164+ initParentData (constraintBoxData);
3165+ }
30983166}
30993167
31003168class GuidelineDefine extends ConstraintDefine {
@@ -3192,10 +3260,10 @@ class Guideline extends LeafRenderObjectWidget {
31923260
31933261class _GuidelineRenderBox extends _HelperBox {
31943262 late ConstraintId _id;
3263+ late bool _horizontal;
31953264 double ? _guidelineBegin;
31963265 double ? _guidelineEnd;
31973266 double ? _guidelinePercent;
3198- late bool _horizontal;
31993267
32003268 set id (ConstraintId value) {
32013269 if (_id != value) {
@@ -3242,65 +3310,107 @@ class _GuidelineRenderBox extends _HelperBox {
32423310 void updateParentData () {
32433311 super .updateParentData ();
32443312 _ConstraintBoxData constraintBoxData = parentData as _ConstraintBoxData ;
3245- constraintBoxData.id = _id;
3246- constraintBoxData._isGuideline = true ;
3313+ initParentData (
3314+ constraintBoxData,
3315+ id: _id,
3316+ horizontal: _horizontal,
3317+ guidelineBegin: _guidelineBegin,
3318+ guidelineEnd: _guidelineEnd,
3319+ guidelinePercent: _guidelinePercent,
3320+ );
3321+ }
3322+
3323+ @override
3324+ void performLayout () {
32473325 if (_horizontal) {
3248- if (_guidelineBegin != null ) {
3326+ size = Size (constraints.minWidth, 0 );
3327+ } else {
3328+ size = Size (0 , constraints.minHeight);
3329+ }
3330+ }
3331+
3332+ static void initParentData (
3333+ _ConstraintBoxData constraintBoxData, {
3334+ required ConstraintId id,
3335+ required bool horizontal,
3336+ double ? guidelineBegin,
3337+ double ? guidelineEnd,
3338+ double ? guidelinePercent,
3339+ }) {
3340+ constraintBoxData.id = id;
3341+ constraintBoxData._isGuideline = true ;
3342+ if (horizontal) {
3343+ if (guidelineBegin != null ) {
32493344 constraintBoxData.left = parent.left;
32503345 constraintBoxData.top = parent.top;
32513346 constraintBoxData.right = parent.right;
32523347 constraintBoxData.width = matchParent;
3253- constraintBoxData.margin = EdgeInsets .only (top: _guidelineBegin ! );
3254- } else if (_guidelineEnd != null ) {
3348+ constraintBoxData.margin = EdgeInsets .only (top: guidelineBegin );
3349+ } else if (guidelineEnd != null ) {
32553350 constraintBoxData.left = parent.left;
32563351 constraintBoxData.right = parent.right;
32573352 constraintBoxData.bottom = parent.bottom;
32583353 constraintBoxData.width = matchParent;
3259- constraintBoxData.margin = EdgeInsets .only (bottom: _guidelineEnd ! );
3354+ constraintBoxData.margin = EdgeInsets .only (bottom: guidelineEnd );
32603355 } else {
32613356 constraintBoxData.left = parent.left;
32623357 constraintBoxData.top = parent.top;
32633358 constraintBoxData.right = parent.right;
32643359 constraintBoxData.width = matchParent;
32653360 constraintBoxData.margin = EdgeInsets .only (
3266- top: _guidelinePercent ! ,
3361+ top: guidelinePercent ! ,
32673362 );
32683363 constraintBoxData.percentageMargin = true ;
32693364 }
32703365 } else {
3271- if (_guidelineBegin != null ) {
3366+ if (guidelineBegin != null ) {
32723367 constraintBoxData.left = parent.left;
32733368 constraintBoxData.top = parent.top;
32743369 constraintBoxData.bottom = parent.bottom;
32753370 constraintBoxData.height = matchParent;
3276- constraintBoxData.margin = EdgeInsets .only (left: _guidelineBegin ! );
3277- } else if (_guidelineEnd != null ) {
3371+ constraintBoxData.margin = EdgeInsets .only (left: guidelineBegin );
3372+ } else if (guidelineEnd != null ) {
32783373 constraintBoxData.top = parent.top;
32793374 constraintBoxData.right = parent.right;
32803375 constraintBoxData.bottom = parent.bottom;
32813376 constraintBoxData.height = matchParent;
3282- constraintBoxData.margin = EdgeInsets .only (right: _guidelineEnd ! );
3377+ constraintBoxData.margin = EdgeInsets .only (right: guidelineEnd );
32833378 } else {
32843379 constraintBoxData.left = parent.left;
32853380 constraintBoxData.top = parent.top;
32863381 constraintBoxData.bottom = parent.bottom;
32873382 constraintBoxData.height = matchParent;
32883383 constraintBoxData.margin = EdgeInsets .only (
3289- left: _guidelinePercent ! ,
3384+ left: guidelinePercent ! ,
32903385 );
32913386 constraintBoxData.percentageMargin = true ;
32923387 }
32933388 }
32943389 }
3390+ }
3391+
3392+ class BarrierDefine extends ConstraintDefine {
3393+ final BarrierDirection direction;
3394+ final List <ConstraintId > referencedIds;
3395+
3396+ BarrierDefine ({
3397+ required ConstraintId id,
3398+ required this .direction,
3399+ required this .referencedIds,
3400+ }) : super (id);
32953401
32963402 @override
3297- void performLayout () {
3298- if (_horizontal) {
3299- size = Size (constraints.minWidth, 0 );
3300- } else {
3301- size = Size (0 , constraints.minHeight);
3302- }
3303- }
3403+ bool operator == (Object other) =>
3404+ identical (this , other) ||
3405+ super == other &&
3406+ other is BarrierDefine &&
3407+ runtimeType == other.runtimeType &&
3408+ direction == other.direction &&
3409+ referencedIds == other.referencedIds;
3410+
3411+ @override
3412+ int get hashCode =>
3413+ super .hashCode ^ direction.hashCode ^ referencedIds.hashCode;
33043414}
33053415
33063416class Barrier extends LeafRenderObjectWidget {
@@ -3354,24 +3464,12 @@ class _BarrierRenderBox extends _HelperBox {
33543464 void updateParentData () {
33553465 super .updateParentData ();
33563466 _ConstraintBoxData constraintBoxData = parentData as _ConstraintBoxData ;
3357- constraintBoxData.id = _id;
3358- constraintBoxData._isBarrier = true ;
3359- constraintBoxData._direction = _direction;
3360- constraintBoxData._referencedIds = _referencedIds;
3361- if (_direction == BarrierDirection .top ||
3362- _direction == BarrierDirection .bottom) {
3363- constraintBoxData.width = matchParent;
3364- constraintBoxData.height = 0 ;
3365- constraintBoxData.top = parent.top;
3366- constraintBoxData.left = parent.left;
3367- constraintBoxData.right = parent.right;
3368- } else {
3369- constraintBoxData.width = 0 ;
3370- constraintBoxData.height = matchParent;
3371- constraintBoxData.left = parent.left;
3372- constraintBoxData.top = parent.top;
3373- constraintBoxData.bottom = parent.bottom;
3374- }
3467+ initParentData (
3468+ constraintBoxData,
3469+ id: _id,
3470+ direction: _direction,
3471+ referencedIds: _referencedIds,
3472+ );
33753473 }
33763474
33773475 set id (ConstraintId value) {
@@ -3420,6 +3518,32 @@ class _BarrierRenderBox extends _HelperBox {
34203518 size = Size (0 , constraints.minHeight);
34213519 }
34223520 }
3521+
3522+ static void initParentData (
3523+ _ConstraintBoxData constraintBoxData, {
3524+ required ConstraintId id,
3525+ required BarrierDirection direction,
3526+ required List <ConstraintId > referencedIds,
3527+ }) {
3528+ constraintBoxData.id = id;
3529+ constraintBoxData._isBarrier = true ;
3530+ constraintBoxData._direction = direction;
3531+ constraintBoxData._referencedIds = referencedIds;
3532+ if (direction == BarrierDirection .top ||
3533+ direction == BarrierDirection .bottom) {
3534+ constraintBoxData.width = matchParent;
3535+ constraintBoxData.height = 0 ;
3536+ constraintBoxData.top = parent.top;
3537+ constraintBoxData.left = parent.left;
3538+ constraintBoxData.right = parent.right;
3539+ } else {
3540+ constraintBoxData.width = 0 ;
3541+ constraintBoxData.height = matchParent;
3542+ constraintBoxData.left = parent.left;
3543+ constraintBoxData.top = parent.top;
3544+ constraintBoxData.bottom = parent.bottom;
3545+ }
3546+ }
34233547}
34243548
34253549class ConstraintLayoutException implements Exception {
0 commit comments