mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 20:58:34 +01:00
Added a fail-safe for elements with conflicting auto-sizing settings so that they don't cause a cryptic stack overflow
This commit is contained in:
parent
eeedb0ae5c
commit
333b4b033e
2 changed files with 22 additions and 5 deletions
|
@ -175,6 +175,7 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private bool areaDirty;
|
private bool areaDirty;
|
||||||
|
private int areaUpdateRecursionCount;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="UnscrolledArea"/> of this element, but with <see cref="ScaledScrollOffset"/> applied.
|
/// The <see cref="UnscrolledArea"/> of this element, but with <see cref="ScaledScrollOffset"/> applied.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -612,14 +613,14 @@ namespace MLEM.Ui.Elements {
|
||||||
child.ForceUpdateArea();
|
child.ForceUpdateArea();
|
||||||
|
|
||||||
if (this.Children.Count > 0) {
|
if (this.Children.Count > 0) {
|
||||||
var changed = false;
|
Element foundChild = null;
|
||||||
if (this.SetHeightBasedOnChildren) {
|
if (this.SetHeightBasedOnChildren) {
|
||||||
var lowest = this.GetLowestChild(e => !e.IsHidden);
|
var lowest = this.GetLowestChild(e => !e.IsHidden);
|
||||||
if (lowest != null) {
|
if (lowest != null) {
|
||||||
var newHeight = (lowest.UnscrolledArea.Bottom - pos.Y + this.ScaledChildPadding.Bottom) / this.Scale;
|
var newHeight = (lowest.UnscrolledArea.Bottom - pos.Y + this.ScaledChildPadding.Bottom) / this.Scale;
|
||||||
if (!newHeight.Equals(this.size.Y, 0.01F)) {
|
if (!newHeight.Equals(this.size.Y, 0.01F)) {
|
||||||
this.size.Y = newHeight;
|
this.size.Y = newHeight;
|
||||||
changed = true;
|
foundChild = lowest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -629,13 +630,21 @@ namespace MLEM.Ui.Elements {
|
||||||
var newWidth = (rightmost.UnscrolledArea.Right - pos.X + this.ScaledChildPadding.Right) / this.Scale;
|
var newWidth = (rightmost.UnscrolledArea.Right - pos.X + this.ScaledChildPadding.Right) / this.Scale;
|
||||||
if (!newWidth.Equals(this.size.X, 0.01F)) {
|
if (!newWidth.Equals(this.size.X, 0.01F)) {
|
||||||
this.size.X = newWidth;
|
this.size.X = newWidth;
|
||||||
changed = true;
|
foundChild = rightmost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed)
|
if (foundChild != null) {
|
||||||
|
this.areaUpdateRecursionCount++;
|
||||||
|
if (this.areaUpdateRecursionCount >= 16) {
|
||||||
|
throw new ArithmeticException($"The area of {this} with root {this.Root?.Name} has recursively updated too often. Does its child {foundChild} contain any conflicting auto-sizing settings?");
|
||||||
|
} else {
|
||||||
this.ForceUpdateArea();
|
this.ForceUpdateArea();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.areaUpdateRecursionCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -191,6 +191,14 @@ namespace Sandbox {
|
||||||
testPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(0.25F, -1)));
|
testPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(0.25F, -1)));
|
||||||
testPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(2500, 1)) {PreventParentSpill = true});
|
testPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(2500, 1)) {PreventParentSpill = true});
|
||||||
this.UiSystem.Add("Test", testPanel);
|
this.UiSystem.Add("Test", testPanel);
|
||||||
|
|
||||||
|
var invalidPanel = new Panel(Anchor.Center, Vector2.Zero, Vector2.Zero) {
|
||||||
|
SetWidthBasedOnChildren = true,
|
||||||
|
SetHeightBasedOnChildren = true
|
||||||
|
};
|
||||||
|
invalidPanel.AddChild(new Paragraph(Anchor.AutoRight, 1, "This is some test text!", true));
|
||||||
|
invalidPanel.AddChild(new VerticalSpace(1));
|
||||||
|
this.UiSystem.Add("Invalid", invalidPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DoUpdate(GameTime gameTime) {
|
protected override void DoUpdate(GameTime gameTime) {
|
||||||
|
|
Loading…
Reference in a new issue