fix(ScrollArea): renderingBoIds concurrency and add immutable view

This commit is contained in:
extio-de
2026-10-04 08:57:05 +02:00
parent fe85b72348
commit 3f56dc9c59
5 changed files with 36 additions and 17 deletions

View File

@@ -134,7 +134,7 @@ public class OptionsModule extends AbstractClientModule implements OptionsModule
@Override
public void refreshContent() {
for (final var boId : this.contentScrollArea.getRenderingBoIds().toArray(new String[0])) {
for (final var boId : this.contentScrollArea.getRenderingBoIds()) {
this.contentScrollArea.removeRenderingBo(boId);
}
for (final var tab : this.tabs) {

View File

@@ -222,7 +222,7 @@ public class ThemeEditorModule extends AbstractClientModule implements OptionsTh
private void setupEditor() {
this.editorWindow.clearRenderingBos();
for (final var boId : this.scrollArea.getRenderingBoIds().toArray(new String[0])) {
for (final var boId : this.scrollArea.getRenderingBoIds()) {
this.scrollArea.removeRenderingBo(boId);
}
this.colorSlotByControlId.clear();

View File

@@ -2,6 +2,7 @@ package de.extio.game_engine.renderer.container;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -41,15 +42,19 @@ public class ScrollArea implements WindowComponent {
protected final Set<String> renderingBoIds = Collections.synchronizedSet(new HashSet<>());
protected volatile Set<String> renderingBoIdsView = null;
protected volatile boolean renderingBoIdsViewDirty = true;
protected final Area2 relativeArea = new Area2(ImmutableCoordI2.zero(), ImmutableCoordI2.one());
protected Window parent;
protected volatile Window parent;
protected double scrollPositionVertical = 1.0; // 1.0 = top, 0.0 = bottom
protected volatile double scrollPositionVertical = 1.0; // 1.0 = top, 0.0 = bottom
protected double scrollPositionHorizontal = 0.0; // 0.0 = left, 1.0 = right
protected volatile double scrollPositionHorizontal = 0.0; // 0.0 = left, 1.0 = right
protected int verticalScrollInputRevision = 0;
protected volatile int verticalScrollInputRevision = 0;
public ScrollArea(final RenderingBoPool renderingBoPool, final EventService eventService) {
this.renderingBoPool = renderingBoPool;
@@ -169,6 +174,7 @@ public class ScrollArea implements WindowComponent {
public void putRenderingBo(final RenderingBo renderingBo) {
this.renderingBoIds.add(renderingBo.getId());
this.renderingBoIdsViewDirty = true;
this.parent.putRenderingBo(renderingBo);
}
@@ -178,6 +184,7 @@ public class ScrollArea implements WindowComponent {
public void removeRenderingBo(final String renderingBoId) {
this.renderingBoIds.remove(renderingBoId);
this.renderingBoIdsViewDirty = true;
this.parent.removeRenderingBo(renderingBoId);
}
@@ -263,9 +270,21 @@ public class ScrollArea implements WindowComponent {
this.relativeArea.setDimension(relativeArea.getDimension().toImmutableCoordI2());
}
/**
* Returns an immutable copy of the rendering BO IDs currently in this scroll area.
*
* @return an immutable {@link List} containing all rendering BO IDs; safe to iterate
* while the scroll area is being modified
*/
@Override
public Set<String> getRenderingBoIds() {
return this.renderingBoIds;
synchronized (this.renderingBoIds) {
if (this.renderingBoIdsViewDirty) {
this.renderingBoIdsView = Collections.unmodifiableSet(new HashSet<>(this.renderingBoIds));
this.renderingBoIdsViewDirty = false;
}
return this.renderingBoIdsView;
}
}
@Override

View File

@@ -692,7 +692,7 @@ public class FileSelectionDialogModule extends AbstractClientModule {
}
private void clearScrollArea() {
for (final var boId : this.itemsScrollArea.getRenderingBoIds().toArray(new String[0])) {
for (final var boId : this.itemsScrollArea.getRenderingBoIds()) {
this.itemsScrollArea.removeRenderingBo(boId);
}
}

View File

@@ -357,7 +357,7 @@ public class FileSelectionMoveDialogModule extends AbstractClientModule {
}
private void clearScrollArea() {
for (final var boId : this.folderScrollArea.getRenderingBoIds().toArray(new String[0])) {
for (final var boId : this.folderScrollArea.getRenderingBoIds()) {
this.folderScrollArea.removeRenderingBo(boId);
}
}