From 802551195ba60f21c634081e9e694f93feed26a3 Mon Sep 17 00:00:00 2001
From: Juuxel <6596629+Juuxel@users.noreply.github.com>
Date: Wed, 9 Jun 2021 11:43:05 +0300
Subject: Prevent adding widgets to themselves recursively
Also includes any parents.
---
.../github/cottonmc/cotton/gui/widget/WPanel.java | 61 +++++++++++++++++++++-
1 file changed, 60 insertions(+), 1 deletion(-)
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java
index 227376b..912c1c0 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java
@@ -9,6 +9,7 @@ import io.github.cottonmc.cotton.gui.client.BackgroundPainter;
import io.github.cottonmc.cotton.gui.widget.data.Insets;
import org.jetbrains.annotations.Nullable;
+import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -23,7 +24,7 @@ public abstract class WPanel extends WWidget {
*
*
The list is mutable.
*/
- protected final List children = new ArrayList<>();
+ protected final List children = new WidgetList(this, new ArrayList<>());
@Environment(EnvType.CLIENT)
private BackgroundPainter backgroundPainter = null;
@@ -250,4 +251,62 @@ public abstract class WPanel extends WWidget {
public String toString() {
return getClass().getSimpleName() + " {\n" + children.stream().map(Object::toString).map(x -> x + ",").flatMap(x -> Stream.of(x.split("\n")).filter(y -> !y.isEmpty()).map(y -> "\t" + y)).collect(Collectors.joining("\n")) + "\n}";
}
+
+ private static final class WidgetList extends AbstractList {
+ private final WPanel owner;
+ private final List backing;
+
+ private WidgetList(WPanel owner, List backing) {
+ this.owner = owner;
+ this.backing = backing;
+ }
+
+ @Override
+ public WWidget get(int index) {
+ return backing.get(index);
+ }
+
+ private void checkWidget(WWidget widget) {
+ if (widget == null) {
+ throw new NullPointerException("Adding null widget to " + owner);
+ }
+
+ int n = 0;
+ WWidget parent = owner;
+ while (parent != null) {
+ if (widget == parent) {
+ if (n == 0) {
+ throw new IllegalArgumentException("Adding panel to itself: " + widget);
+ } else {
+ throw new IllegalArgumentException("Adding level " + n + " parent recursively to " + owner + ": " + widget);
+ }
+ }
+
+ parent = parent.getParent();
+ n++;
+ }
+ }
+
+ @Override
+ public WWidget set(int index, WWidget element) {
+ checkWidget(element);
+ return backing.set(index, element);
+ }
+
+ @Override
+ public void add(int index, WWidget element) {
+ checkWidget(element);
+ backing.add(index, element);
+ }
+
+ @Override
+ public WWidget remove(int index) {
+ return backing.remove(index);
+ }
+
+ @Override
+ public int size() {
+ return backing.size();
+ }
+ }
}
--
cgit