@@ -1465,6 +1465,7 @@ class _ConstraintRenderBox extends RenderBox
1465
1465
1466
1466
bool _needsRecalculateConstraints = true ;
1467
1467
bool _needsReorderChildren = true ;
1468
+ int _buildNodeTreesCount = 0 ;
1468
1469
final Map <ConstraintId , _ConstrainedNode > _helperNodeMap = HashMap ();
1469
1470
1470
1471
/// For layout
@@ -1499,6 +1500,41 @@ class _ConstraintRenderBox extends RenderBox
1499
1500
}
1500
1501
if (! isSameList) {
1501
1502
_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
+ }
1502
1538
markNeedsRecalculateConstraints ();
1503
1539
markNeedsLayout ();
1504
1540
}
@@ -1639,6 +1675,13 @@ class _ConstraintRenderBox extends RenderBox
1639
1675
child = childParentData.nextSibling;
1640
1676
}
1641
1677
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
+
1642
1685
/// The id used by all constraints must be defined
1643
1686
Set <ConstraintId > illegalIdSet = constraintsIdSet.difference (idSet);
1644
1687
Set <RelativeConstraintId > relativeIds =
@@ -1647,18 +1690,6 @@ class _ConstraintRenderBox extends RenderBox
1647
1690
throw ConstraintLayoutException (
1648
1691
'These ids ${illegalIdSet .difference (relativeIds )} are not yet defined.' );
1649
1692
}
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
- // }
1662
1693
}
1663
1694
1664
1695
/// There should be no loop constraints
@@ -1781,26 +1812,59 @@ class _ConstraintRenderBox extends RenderBox
1781
1812
1782
1813
Map <ConstraintId , _ConstrainedNode > _buildConstrainedNodeTrees () {
1783
1814
Map <ConstraintId , _ConstrainedNode > nodesMap = HashMap ();
1815
+ _buildNodeTreesCount++ ;
1784
1816
1785
1817
_ConstrainedNode _getConstrainedNodeForChild (ConstraintId id) {
1786
1818
if (id == parent) {
1787
1819
return _parentNode;
1788
1820
}
1789
- _ConstrainedNode ? node = id.getCacheNode (hashCode);
1821
+
1822
+ /// Fewer reads to nodesMap for faster constraint building
1823
+ _ConstrainedNode ? node = id.getCacheNode (_buildNodeTreesCount ^ hashCode);
1790
1824
if (node != null ) {
1791
1825
return node;
1792
1826
}
1827
+
1793
1828
node = nodesMap[id];
1794
1829
if (node == null ) {
1795
1830
node = _ConstrainedNode ()..nodeId = id;
1796
1831
nodesMap[id] = node;
1797
1832
}
1798
- id.setCacheNode (hashCode, node);
1833
+ id.setCacheNode (_buildNodeTreesCount ^ hashCode, node);
1799
1834
return node;
1800
1835
}
1801
1836
1802
1837
if (_helperNodeMap.isNotEmpty) {
1803
1838
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
+ }
1804
1868
}
1805
1869
1806
1870
RenderBox ? child = firstChild;
@@ -3055,10 +3119,7 @@ class _ConstrainedNode {
3055
3119
}
3056
3120
3057
3121
class _HelperBox extends RenderBox {
3058
- @protected
3059
- @mustCallSuper
3060
- void updateParentData () {
3061
- _ConstraintBoxData constraintBoxData = parentData as _ConstraintBoxData ;
3122
+ static void initParentData (_ConstraintBoxData constraintBoxData) {
3062
3123
constraintBoxData.width = 0 ;
3063
3124
constraintBoxData.height = 0 ;
3064
3125
constraintBoxData.clickPadding = EdgeInsets .zero;
@@ -3095,6 +3156,13 @@ class _HelperBox extends RenderBox {
3095
3156
constraintBoxData._isBarrier = false ;
3096
3157
constraintBoxData._helperSize = null ;
3097
3158
}
3159
+
3160
+ @protected
3161
+ @mustCallSuper
3162
+ void updateParentData () {
3163
+ _ConstraintBoxData constraintBoxData = parentData as _ConstraintBoxData ;
3164
+ initParentData (constraintBoxData);
3165
+ }
3098
3166
}
3099
3167
3100
3168
class GuidelineDefine extends ConstraintDefine {
@@ -3192,10 +3260,10 @@ class Guideline extends LeafRenderObjectWidget {
3192
3260
3193
3261
class _GuidelineRenderBox extends _HelperBox {
3194
3262
late ConstraintId _id;
3263
+ late bool _horizontal;
3195
3264
double ? _guidelineBegin;
3196
3265
double ? _guidelineEnd;
3197
3266
double ? _guidelinePercent;
3198
- late bool _horizontal;
3199
3267
3200
3268
set id (ConstraintId value) {
3201
3269
if (_id != value) {
@@ -3242,65 +3310,107 @@ class _GuidelineRenderBox extends _HelperBox {
3242
3310
void updateParentData () {
3243
3311
super .updateParentData ();
3244
3312
_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 () {
3247
3325
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 ) {
3249
3344
constraintBoxData.left = parent.left;
3250
3345
constraintBoxData.top = parent.top;
3251
3346
constraintBoxData.right = parent.right;
3252
3347
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 ) {
3255
3350
constraintBoxData.left = parent.left;
3256
3351
constraintBoxData.right = parent.right;
3257
3352
constraintBoxData.bottom = parent.bottom;
3258
3353
constraintBoxData.width = matchParent;
3259
- constraintBoxData.margin = EdgeInsets .only (bottom: _guidelineEnd ! );
3354
+ constraintBoxData.margin = EdgeInsets .only (bottom: guidelineEnd );
3260
3355
} else {
3261
3356
constraintBoxData.left = parent.left;
3262
3357
constraintBoxData.top = parent.top;
3263
3358
constraintBoxData.right = parent.right;
3264
3359
constraintBoxData.width = matchParent;
3265
3360
constraintBoxData.margin = EdgeInsets .only (
3266
- top: _guidelinePercent ! ,
3361
+ top: guidelinePercent ! ,
3267
3362
);
3268
3363
constraintBoxData.percentageMargin = true ;
3269
3364
}
3270
3365
} else {
3271
- if (_guidelineBegin != null ) {
3366
+ if (guidelineBegin != null ) {
3272
3367
constraintBoxData.left = parent.left;
3273
3368
constraintBoxData.top = parent.top;
3274
3369
constraintBoxData.bottom = parent.bottom;
3275
3370
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 ) {
3278
3373
constraintBoxData.top = parent.top;
3279
3374
constraintBoxData.right = parent.right;
3280
3375
constraintBoxData.bottom = parent.bottom;
3281
3376
constraintBoxData.height = matchParent;
3282
- constraintBoxData.margin = EdgeInsets .only (right: _guidelineEnd ! );
3377
+ constraintBoxData.margin = EdgeInsets .only (right: guidelineEnd );
3283
3378
} else {
3284
3379
constraintBoxData.left = parent.left;
3285
3380
constraintBoxData.top = parent.top;
3286
3381
constraintBoxData.bottom = parent.bottom;
3287
3382
constraintBoxData.height = matchParent;
3288
3383
constraintBoxData.margin = EdgeInsets .only (
3289
- left: _guidelinePercent ! ,
3384
+ left: guidelinePercent ! ,
3290
3385
);
3291
3386
constraintBoxData.percentageMargin = true ;
3292
3387
}
3293
3388
}
3294
3389
}
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);
3295
3401
3296
3402
@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;
3304
3414
}
3305
3415
3306
3416
class Barrier extends LeafRenderObjectWidget {
@@ -3354,24 +3464,12 @@ class _BarrierRenderBox extends _HelperBox {
3354
3464
void updateParentData () {
3355
3465
super .updateParentData ();
3356
3466
_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
+ );
3375
3473
}
3376
3474
3377
3475
set id (ConstraintId value) {
@@ -3420,6 +3518,32 @@ class _BarrierRenderBox extends _HelperBox {
3420
3518
size = Size (0 , constraints.minHeight);
3421
3519
}
3422
3520
}
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
+ }
3423
3547
}
3424
3548
3425
3549
class ConstraintLayoutException implements Exception {
0 commit comments