feat(renderer): Implement cloning of RenderingBo objects in commit process
This commit is contained in:
@@ -2,10 +2,8 @@ package de.extio.game_engine.renderer.work;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -21,8 +19,6 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
|
|||||||
|
|
||||||
private final BlockingQueue<Map<String, RenderingBo>> mapsPool = new ArrayBlockingQueue<>(100);
|
private final BlockingQueue<Map<String, RenderingBo>> mapsPool = new ArrayBlockingQueue<>(100);
|
||||||
|
|
||||||
private final BlockingQueue<Set<Class<? extends RenderingBo>>> setsPool = new ArrayBlockingQueue<>(100);
|
|
||||||
|
|
||||||
private final RenderingBoPool rendererBoPool;
|
private final RenderingBoPool rendererBoPool;
|
||||||
|
|
||||||
public RendererWorkingSetImpl(final RenderingBoPool rendererBoPool) {
|
public RendererWorkingSetImpl(final RenderingBoPool rendererBoPool) {
|
||||||
@@ -98,17 +94,22 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
|
|||||||
previousLiveRef.set(v.live());
|
previousLiveRef.set(v.live());
|
||||||
if (clone) {
|
if (clone) {
|
||||||
final Map<String, RenderingBo> newNext = this.obtainMapFromPool();
|
final Map<String, RenderingBo> newNext = this.obtainMapFromPool();
|
||||||
newNext.putAll(v.next());
|
v.next().entrySet().forEach(e -> {
|
||||||
|
final RenderingBo copy = this.rendererBoPool.copy(e.getValue());
|
||||||
|
newNext.put(e.getKey(), copy);
|
||||||
|
});
|
||||||
return new RendererWork(v.next(), newNext);
|
return new RendererWork(v.next(), newNext);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.live().values().forEach(this.rendererBoPool::release);
|
|
||||||
return new RendererWork(v.next(), this.obtainMapFromPool());
|
return new RendererWork(v.next(), this.obtainMapFromPool());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final var previousLiveSet = previousLiveRef.get();
|
final var previousLiveSet = previousLiveRef.get();
|
||||||
if (previousLiveSet != null) {
|
if (previousLiveSet != null) {
|
||||||
|
if (clone) {
|
||||||
|
previousLiveSet.values().forEach(this.rendererBoPool::release);
|
||||||
|
}
|
||||||
this.returnMapToPool(previousLiveSet);
|
this.returnMapToPool(previousLiveSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,11 +98,18 @@ public class RendererWorkingSetImplTest {
|
|||||||
void commitWithCloneCopiesUncommittedIntoNewUncommitted() {
|
void commitWithCloneCopiesUncommittedIntoNewUncommitted() {
|
||||||
final RenderingBo bo1 = mock(RenderingBo.class);
|
final RenderingBo bo1 = mock(RenderingBo.class);
|
||||||
when(bo1.getId()).thenReturn("bo1");
|
when(bo1.getId()).thenReturn("bo1");
|
||||||
|
final RenderingBo bo1Copy = mock(RenderingBo.class);
|
||||||
|
when(bo1Copy.getId()).thenReturn("bo1");
|
||||||
final RenderingBo bo2 = mock(RenderingBo.class);
|
final RenderingBo bo2 = mock(RenderingBo.class);
|
||||||
when(bo2.getId()).thenReturn("bo2");
|
when(bo2.getId()).thenReturn("bo2");
|
||||||
|
final RenderingBo bo2Copy = mock(RenderingBo.class);
|
||||||
|
when(bo2Copy.getId()).thenReturn("bo2");
|
||||||
final RenderingBo bo3 = mock(RenderingBo.class);
|
final RenderingBo bo3 = mock(RenderingBo.class);
|
||||||
when(bo3.getId()).thenReturn("bo3");
|
when(bo3.getId()).thenReturn("bo3");
|
||||||
|
|
||||||
|
when(this.renderingBoPool.copy(bo1)).thenReturn(bo1Copy);
|
||||||
|
when(this.renderingBoPool.copy(bo2)).thenReturn(bo2Copy);
|
||||||
|
|
||||||
this.workingSet.put(this.moduleA.getId(), bo1);
|
this.workingSet.put(this.moduleA.getId(), bo1);
|
||||||
this.workingSet.put(this.moduleA.getId(), bo2);
|
this.workingSet.put(this.moduleA.getId(), bo2);
|
||||||
|
|
||||||
@@ -110,13 +117,16 @@ public class RendererWorkingSetImplTest {
|
|||||||
final var currentUncommitted = this.workingSet.getUncommittedWork(this.moduleA.getId());
|
final var currentUncommitted = this.workingSet.getUncommittedWork(this.moduleA.getId());
|
||||||
|
|
||||||
assertEquals(currentUncommitted, returnedUncommitted);
|
assertEquals(currentUncommitted, returnedUncommitted);
|
||||||
assertEquals(Map.of("bo1", bo1, "bo2", bo2), currentUncommitted);
|
assertEquals(Map.of("bo1", bo1Copy, "bo2", bo2Copy), currentUncommitted);
|
||||||
|
|
||||||
final List<RenderingBo> live = new ArrayList<>();
|
final List<RenderingBo> live = new ArrayList<>();
|
||||||
this.workingSet.getLiveSet(live, null);
|
this.workingSet.getLiveSet(live, null);
|
||||||
assertEquals(2, live.size());
|
assertEquals(2, live.size());
|
||||||
assertTrue(live.containsAll(List.of(bo1, bo2)));
|
assertTrue(live.containsAll(List.of(bo1, bo2)));
|
||||||
|
|
||||||
|
verify(this.renderingBoPool, times(1)).copy(bo1);
|
||||||
|
verify(this.renderingBoPool, times(1)).copy(bo2);
|
||||||
|
|
||||||
this.workingSet.put(this.moduleA.getId(), bo3);
|
this.workingSet.put(this.moduleA.getId(), bo3);
|
||||||
final List<RenderingBo> liveAfterAdd = new ArrayList<>();
|
final List<RenderingBo> liveAfterAdd = new ArrayList<>();
|
||||||
this.workingSet.getLiveSet(liveAfterAdd, null);
|
this.workingSet.getLiveSet(liveAfterAdd, null);
|
||||||
@@ -204,20 +214,31 @@ public class RendererWorkingSetImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void secondCommitReleasesPreviousLiveWork() {
|
void secondCommitWithCloneReleasesPreviousLiveWork() {
|
||||||
final var bo1 = new TestBoA();
|
final var bo1 = new TestBoA();
|
||||||
bo1.setId("bo1");
|
bo1.setId("bo1");
|
||||||
final var bo2 = new TestBoA();
|
final var bo2 = new TestBoA();
|
||||||
bo2.setId("bo2");
|
bo2.setId("bo2");
|
||||||
|
final var bo1Copy = new TestBoA();
|
||||||
|
bo1Copy.setId("bo1");
|
||||||
|
final var bo2Copy = new TestBoA();
|
||||||
|
bo2Copy.setId("bo2");
|
||||||
|
|
||||||
|
when(this.renderingBoPool.copy(bo1)).thenReturn(bo1Copy);
|
||||||
|
when(this.renderingBoPool.copy(bo2)).thenReturn(bo2Copy);
|
||||||
|
|
||||||
this.workingSet.put(this.moduleA.getId(), bo1);
|
this.workingSet.put(this.moduleA.getId(), bo1);
|
||||||
this.workingSet.put(this.moduleA.getId(), bo2);
|
this.workingSet.put(this.moduleA.getId(), bo2);
|
||||||
this.workingSet.commit(this.moduleA.getId(), false);
|
this.workingSet.commit(this.moduleA.getId(), true);
|
||||||
|
|
||||||
final var bo3 = new TestBoB();
|
final var bo3 = new TestBoB();
|
||||||
bo3.setId("bo3");
|
bo3.setId("bo3");
|
||||||
|
final var bo3Copy = new TestBoB();
|
||||||
|
bo3Copy.setId("bo3");
|
||||||
|
when(this.renderingBoPool.copy(bo3)).thenReturn(bo3Copy);
|
||||||
|
|
||||||
this.workingSet.put(this.moduleA.getId(), bo3);
|
this.workingSet.put(this.moduleA.getId(), bo3);
|
||||||
this.workingSet.commit(this.moduleA.getId(), false);
|
this.workingSet.commit(this.moduleA.getId(), true);
|
||||||
|
|
||||||
verify(this.renderingBoPool, times(1)).release(bo1);
|
verify(this.renderingBoPool, times(1)).release(bo1);
|
||||||
verify(this.renderingBoPool, times(1)).release(bo2);
|
verify(this.renderingBoPool, times(1)).release(bo2);
|
||||||
@@ -356,6 +377,10 @@ public class RendererWorkingSetImplTest {
|
|||||||
private static abstract class TestBoBase implements RenderingBo {
|
private static abstract class TestBoBase implements RenderingBo {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
|
private boolean applied;
|
||||||
|
|
||||||
|
private boolean closed;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setId(final String id) {
|
public void setId(final String id) {
|
||||||
@@ -480,9 +505,15 @@ public class RendererWorkingSetImplTest {
|
|||||||
@Override
|
@Override
|
||||||
public void setRendererData(final RendererData RendererData) {
|
public void setRendererData(final RendererData RendererData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(RenderingBo other) {
|
||||||
|
this.applied = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
this.closed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user