feat(renderer): Implement getOrAcquire and remove methods in RendererWorkingSet interface and update RendererWorkingSetImpl

This commit is contained in:
extio-de
2025-12-25 13:23:25 +01:00
parent 5d80ba3f9e
commit 3e17849093
4 changed files with 42 additions and 62 deletions

View File

@@ -2,7 +2,6 @@ package de.extio.game_engine.renderer.g2d;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
@@ -25,7 +24,6 @@ import org.slf4j.LoggerFactory;
import de.extio.game_engine.module.AbstractClientModule;
import de.extio.game_engine.renderer.Renderer;
import de.extio.game_engine.renderer.RendererData;
import de.extio.game_engine.renderer.g2d.G2DRenderer.G2DRendererModule;
import de.extio.game_engine.renderer.g2d.bo.rendering.G2DAbstractRenderingBo;
import de.extio.game_engine.renderer.g2d.bo.rendering.G2DDrawBackground;
import de.extio.game_engine.renderer.g2d.bo.rendering.G2DDrawFont;
@@ -54,6 +52,8 @@ public class G2DRenderer implements Renderer {
private final List<RenderingBo> renderingBOs = new ArrayList<>();
private final Map<Class<? extends RenderingBo>, RenderingBo> usedRenderingBoTypes = new HashMap<>();
private volatile G2DMainFrame mainFrame;
private String rendererModuleId;
@@ -190,8 +190,10 @@ public class G2DRenderer implements Renderer {
screenGraphics.setColor(Color.BLACK);
screenGraphics.fillRect(0, 0, viewPortDimension.getX(), viewPortDimension.getY());
usedRenderingBoTypes.clear();
for (final RenderingBo renderingBO : this.renderingBOs) {
if (renderingBO instanceof final G2DAbstractRenderingBo g2dAbstractRenderingBo) {
usedRenderingBoTypes.putIfAbsent(g2dAbstractRenderingBo.getClass(), g2dAbstractRenderingBo);
g2dAbstractRenderingBo.render(screenGraphics, this.rendererData.getRendererControl().getScaleFactor(), false);
if (takeScreenshot_ && g2dAbstractRenderingBo.isScreenshotRelevant()) {
g2dAbstractRenderingBo.render(screenshotGraphics, this.rendererData.getRendererControl().getScaleFactor(), true);
@@ -199,7 +201,9 @@ public class G2DRenderer implements Renderer {
}
}
this.rendererData.getRendererWorkingSet().get(this.rendererModuleId, "G2DRenderer_tooltip").closeStatic();
for (final RenderingBo bo : usedRenderingBoTypes.values()) {
bo.closeStatic();
}
//
// Rendering cycle END

View File

@@ -17,6 +17,8 @@ public interface RendererWorkingSet {
<T extends RenderingBo> T get(String producerId, String id, Class<T> type);
<T extends RenderingBo> T getOrAcquire(String producerId, String id, Class<T> type);
void remove(String producerId, String id);
Map<String, RenderingBo> getUncommittedWork(String producerId);

View File

@@ -31,22 +31,38 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
@Override
public void put(final String producerId, final RenderingBo work) {
this.getWorkingSetByProducer(producerId)
final var previous = this.getWorkingSetByProducer(producerId)
.next()
.put(work.getId(), work);
if (previous != null) {
this.rendererBoPool.release(previous);
}
}
@Override
public void put(final String producerId, final List<RenderingBo> work) {
final var nextMap = this.getWorkingSetByProducer(producerId).next();
for (final RenderingBo bo : work) {
nextMap.put(bo.getId(), bo);
final var previous = nextMap.put(bo.getId(), bo);
if (previous != null) {
this.rendererBoPool.release(previous);
}
}
}
@Override
public void remove(final String producerId, final String id) {
final var previous = this.getWorkingSetByProducer(producerId)
.next()
.remove(id);
if (previous != null) {
this.rendererBoPool.release(previous);
}
}
@Override
public Map<String, RenderingBo> getUncommittedWork(final String producerId) {
return this.getWorkingSetByProducer(producerId).next();
return Map.copyOf(this.getWorkingSetByProducer(producerId).next());
}
@Override
@@ -74,25 +90,26 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
@Override
public Map<String, RenderingBo> commit(final String producerId, final boolean clone) {
final AtomicReference<Map<String, RenderingBo>> previousWork = new AtomicReference<>();
final AtomicReference<Map<String, RenderingBo>> previousLiveRef = new AtomicReference<>();
final RendererWork rendererWork = this.workingSet.compute(producerId, (k, v) -> {
if (v == null) {
return new RendererWork(this.obtainMapFromPool(), this.obtainMapFromPool());
}
previousWork.set(v.live());
previousLiveRef.set(v.live());
if (clone) {
final Map<String, RenderingBo> newNext = this.obtainMapFromPool();
newNext.putAll(v.next());
return new RendererWork(v.next(), newNext);
}
else {
v.live().values().forEach(this.rendererBoPool::release);
return new RendererWork(v.next(), this.obtainMapFromPool());
}
});
final var previousWorkMap = previousWork.get();
if (previousWorkMap != null) {
this.releaseBoClasses(previousWorkMap);
final var previousLiveSet = previousLiveRef.get();
if (previousLiveSet != null) {
this.returnMapToPool(previousLiveSet);
}
return rendererWork.next();
@@ -102,8 +119,8 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
public void clear(final String producerId) {
final RendererWork rendererWork = this.workingSet.remove(producerId);
if (rendererWork != null) {
this.releaseBoClasses(rendererWork.live());
this.releaseBoClasses(rendererWork.next());
rendererWork.live().values().forEach(this.rendererBoPool::release);
rendererWork.next().values().forEach(this.rendererBoPool::release);
}
}
@@ -120,23 +137,6 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
return this.workingSet.computeIfAbsent(producerId, k -> new RendererWork(this.obtainMapFromPool(), this.obtainMapFromPool()));
}
private void releaseBoClasses(final Map<String, RenderingBo> work) {
if (work == null || work.isEmpty()) {
return;
}
final var releasedBoClasses = this.obtainSetFromPool();
for (final RenderingBo renderingBO : work.values()) {
if (releasedBoClasses.add(renderingBO.getClass())) {
renderingBO.closeStatic();
}
this.rendererBoPool.release(renderingBO);
}
this.returnMapToPool(work);
this.returnSetToPool(releasedBoClasses);
}
private Map<String, RenderingBo> obtainMapFromPool() {
var map = this.mapsPool.poll();
if (map == null) {
@@ -150,19 +150,6 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
this.mapsPool.offer(map);
}
private Set<Class<? extends RenderingBo>> obtainSetFromPool() {
var set = this.setsPool.poll();
if (set == null) {
set = new HashSet<>();
}
return set;
}
private void returnSetToPool(final Set<Class<? extends RenderingBo>> set) {
set.clear();
this.setsPool.offer(set);
}
private static record RendererWork(Map<String, RenderingBo> live, Map<String, RenderingBo> next) {
}