Skip to content

Commit 8f6cad2

Browse files
authored
Merge Highlightmanager into structurize (#825)
1 parent 718a459 commit 8f6cad2

24 files changed

Lines changed: 1031 additions & 551 deletions

src/main/java/com/ldtteam/structurize/client/gui/WindowScan.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
import com.ldtteam.structurize.blockentities.interfaces.IBlueprintDataProviderBE;
1212
import com.ldtteam.structurize.client.gui.util.InputFilters;
1313
import com.ldtteam.structurize.client.gui.util.ItemPositionsStorage;
14+
import com.ldtteam.structurize.client.rendertask.RenderTaskManager;
15+
import com.ldtteam.structurize.client.rendertask.tasks.BoxPreviewData;
16+
import com.ldtteam.structurize.client.rendertask.tasks.BoxPreviewRenderTask;
1417
import com.ldtteam.structurize.network.messages.*;
1518
import com.ldtteam.structurize.placement.SimplePlacementContext;
1619
import com.ldtteam.structurize.placement.handlers.placement.IPlacementHandler;
1720
import com.ldtteam.structurize.placement.handlers.placement.PlacementHandlers;
18-
import com.ldtteam.structurize.storage.rendering.RenderingCache;
19-
import com.ldtteam.structurize.storage.rendering.types.BoxPreviewData;
2021
import com.ldtteam.structurize.util.PlacementSettings;
2122
import com.ldtteam.structurize.util.ScanToolData;
2223
import it.unimi.dsi.fastutil.objects.Object2IntMap;
@@ -313,7 +314,7 @@ public void onOpened()
313314
@Override
314315
public void onClosed()
315316
{
316-
if (RenderingCache.getBoxPreviewData("scan") != null) // not confirmed/cancelled
317+
if (RenderTaskManager.getTasksByGroup("scan") != null) // not confirmed/cancelled
317318
{
318319
updateBounds();
319320
}
@@ -341,16 +342,8 @@ public void onUpdate()
341342
*/
342343
private void discardClicked()
343344
{
344-
RenderingCache.removeBox("scan");
345-
346-
for (Iterator<Map.Entry<String, BoxPreviewData>> iterator = RenderingCache.boxRenderingCache.entrySet().iterator(); iterator.hasNext(); )
347-
{
348-
final var entry = iterator.next();
349-
if (entry.getKey().contains("clickedResource"))
350-
{
351-
iterator.remove();
352-
}
353-
}
345+
RenderTaskManager.removeTaskGroup("scan");
346+
RenderTaskManager.removeTaskGroup("clickedResource");
354347
close();
355348
}
356349

@@ -363,7 +356,7 @@ private void confirmClicked()
363356

364357
final ScanToolData.Slot slot = data.getCurrentSlotData();
365358
Network.getNetwork().sendToServer(new ScanOnServerMessage(slot, true));
366-
RenderingCache.removeBox("scan");
359+
RenderTaskManager.removeTaskGroup("scan");
367360
close();
368361
}
369362

@@ -395,7 +388,7 @@ private void loadSlot()
395388
pos2y.setText(String.valueOf(slot.getBox().getPos2().getY()));
396389
pos2z.setText(String.valueOf(slot.getBox().getPos2().getZ()));
397390

398-
RenderingCache.queue("scan", slot.getBox());
391+
RenderTaskManager.addRenderTask("scan", new BoxPreviewRenderTask("scan", slot.getBox(), 60 * 10));
399392

400393
findPaneOfTypeByID(NAME_LABEL, TextField.class).setText("");
401394
if (!slot.getName().isEmpty())
@@ -438,8 +431,7 @@ private void updateBounds()
438431
final String name = findPaneOfTypeByID(NAME_LABEL, TextField.class).getText();
439432
final ScanToolData.Slot slot = data.getCurrentSlotData();
440433
data.setCurrentSlotData(new ScanToolData.Slot(name, new BoxPreviewData(pos1, pos2, slot.getBox().getAnchor())));
441-
442-
RenderingCache.queue("scan", slot.getBox());
434+
RenderTaskManager.addRenderTask("scan", new BoxPreviewRenderTask("scan", data.getCurrentSlotData().getBox(), 60 * 10));
443435
Network.getNetwork().sendToServer(new UpdateScanToolMessage(data));
444436
}
445437

@@ -686,9 +678,9 @@ private void doHighLightBlocks(Button button, final ItemStorage block)
686678
final ItemPositionsStorage itemPositionsStorage = allResources.get(block);
687679
for (final BlockPos position : itemPositionsStorage.positions)
688680
{
689-
BoxPreviewData previewData = new BoxPreviewData(position, position, Optional.empty());
690-
previewData.setExpireTime(30);
691-
RenderingCache.queue("clickedResource" + position.toShortString(), previewData);
681+
BoxPreviewRenderTask previewData =
682+
new BoxPreviewRenderTask("clickedResource" + position.toShortString(), new BoxPreviewData(position, position, Optional.empty()), 30);
683+
RenderTaskManager.addRenderTask("clickedResource", previewData);
692684
}
693685
window.close();
694686
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.ldtteam.structurize.client.rendercontext;
2+
3+
import com.ldtteam.structurize.client.rendertask.RenderTaskManager;
4+
import com.ldtteam.structurize.client.rendertask.util.WorldRenderMacros;
5+
import com.mojang.blaze3d.vertex.PoseStack;
6+
import net.minecraft.client.Minecraft;
7+
import net.minecraft.client.multiplayer.ClientLevel;
8+
import net.minecraft.client.player.LocalPlayer;
9+
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
10+
import net.minecraft.world.item.ItemStack;
11+
import net.minecraft.world.phys.Vec3;
12+
import net.minecraftforge.client.event.RenderLevelStageEvent;
13+
14+
/**
15+
* Main class for handling world rendering.
16+
* Also holds all possible values which may be needed during rendering.
17+
*/
18+
public class WorldEventRenderContext
19+
{
20+
public static final WorldEventRenderContext INSTANCE = new WorldEventRenderContext();
21+
22+
private WorldEventRenderContext()
23+
{
24+
// singleton
25+
}
26+
27+
public RenderLevelStageEvent stageEvent;
28+
public BufferSource bufferSource;
29+
public PoseStack poseStack;
30+
public float partialTicks;
31+
public ClientLevel clientLevel;
32+
public LocalPlayer clientPlayer;
33+
public ItemStack mainHandItem;
34+
35+
/**
36+
* In chunks
37+
*/
38+
int clientRenderDist;
39+
40+
public void renderWorldLastEvent(final RenderLevelStageEvent event)
41+
{
42+
stageEvent = event;
43+
bufferSource = WorldRenderMacros.getBufferSource();
44+
poseStack = event.getPoseStack();
45+
partialTicks = event.getPartialTick();
46+
clientLevel = Minecraft.getInstance().level;
47+
clientPlayer = Minecraft.getInstance().player;
48+
mainHandItem = clientPlayer.getMainHandItem();
49+
clientRenderDist = Minecraft.getInstance().options.renderDistance().get();
50+
51+
final Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
52+
poseStack.pushPose();
53+
poseStack.translate(-cameraPos.x(), -cameraPos.y(), -cameraPos.z());
54+
55+
runRenderTasks(event);
56+
57+
bufferSource.endBatch();
58+
59+
poseStack.popPose();
60+
}
61+
62+
private void runRenderTasks(final RenderLevelStageEvent event)
63+
{
64+
RenderTaskManager.render(this);
65+
}
66+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package com.ldtteam.structurize.client.rendertask;
2+
3+
import com.ldtteam.structurize.client.rendercontext.WorldEventRenderContext;
4+
import com.ldtteam.structurize.client.rendertask.task.IRenderTask;
5+
6+
import javax.annotation.Nullable;
7+
import java.util.Iterator;
8+
import java.util.LinkedHashMap;
9+
import java.util.Map;
10+
11+
public class RenderTaskManager
12+
{
13+
// Uses:
14+
// Render a box with: Text, color, duration, transparency, infront/behind blocks
15+
// Render text at a position(box optional?)
16+
// Render a large box in world(claim borders, lumberjack etc)
17+
// Timed task: enables/disables citizen glowing effect with duration
18+
19+
/**
20+
* A position to highlight with a group and key.
21+
*/
22+
private static final Map<String, Map<String, IRenderTask>> RENDER_TASKS = new LinkedHashMap<>();
23+
24+
/**
25+
* Highlights positions
26+
*
27+
* @param context rendering context
28+
*/
29+
public static void render(final WorldEventRenderContext context)
30+
{
31+
if (RENDER_TASKS.isEmpty())
32+
{
33+
return;
34+
}
35+
36+
for (final Iterator<Map<String, IRenderTask>> groups = RENDER_TASKS.values().iterator(); groups.hasNext(); )
37+
{
38+
final Map<String, IRenderTask> group = groups.next();
39+
for (final Iterator<IRenderTask> renderTaskIterator = group.values().iterator(); renderTaskIterator.hasNext(); )
40+
{
41+
final IRenderTask renderTask = renderTaskIterator.next();
42+
43+
if (renderTask.shouldRenderIn(context.stageEvent.getStage()))
44+
{
45+
renderTask.render(context);
46+
}
47+
}
48+
}
49+
}
50+
51+
/**
52+
* Client tick callback
53+
*/
54+
public static void onClientTick()
55+
{
56+
for (final Iterator<Map<String, IRenderTask>> groups = RENDER_TASKS.values().iterator(); groups.hasNext(); )
57+
{
58+
final Map<String, IRenderTask> group = groups.next();
59+
for (final Iterator<IRenderTask> containers = group.values().iterator(); containers.hasNext(); )
60+
{
61+
final IRenderTask renderDataContainer = containers.next();
62+
boolean isDone = renderDataContainer.tick();
63+
if (isDone)
64+
{
65+
containers.remove();
66+
}
67+
}
68+
69+
if (group.isEmpty())
70+
{
71+
groups.remove();
72+
}
73+
}
74+
}
75+
76+
/**
77+
* Clears all highlight items for the given group key.
78+
*
79+
* @param key the key to remove the render data for.
80+
*/
81+
public static void clearHighlightsForKey(final String key)
82+
{
83+
RENDER_TASKS.remove(key);
84+
}
85+
86+
/**
87+
* Adds a highlight item for the given key.
88+
*
89+
* @param key the group key of the item to render.
90+
* @return the previous entry or null
91+
*/
92+
public static IRenderTask addRenderTask(final String key, final IRenderTask task)
93+
{
94+
return RENDER_TASKS.computeIfAbsent(key, k -> new LinkedHashMap<>()).put(task.id(), task);
95+
}
96+
97+
@Nullable
98+
public static Map<String, IRenderTask> getTasksByGroup(final String groupID)
99+
{
100+
return RENDER_TASKS.get(groupID);
101+
}
102+
103+
public static boolean removeTaskGroup(final String groupID)
104+
{
105+
return RENDER_TASKS.remove(groupID) != null;
106+
}
107+
108+
public static boolean removeTaskEntry(final String groupID, final String taskID)
109+
{
110+
Map<String, IRenderTask> entry = RENDER_TASKS.get(groupID);
111+
if (entry != null)
112+
{
113+
return entry.remove(taskID) != null;
114+
}
115+
116+
return false;
117+
}
118+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.ldtteam.structurize.client.rendertask.task;
2+
3+
public interface IClientTask extends ITickingTask
4+
{
5+
6+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.ldtteam.structurize.client.rendertask.task;
2+
3+
import com.ldtteam.structurize.client.rendercontext.WorldEventRenderContext;
4+
import net.minecraftforge.client.event.RenderLevelStageEvent;
5+
6+
public interface IRenderTask extends IClientTask
7+
{
8+
/**
9+
* Indicate the render data it should continue rendering.
10+
*/
11+
void render(final WorldEventRenderContext context);
12+
13+
/**
14+
* Precheck for the render stage, as render(WorldEventRenderContext) is run for all stages
15+
*
16+
* @return true if rendering active for this stage
17+
*/
18+
boolean shouldRenderIn(RenderLevelStageEvent.Stage renderStage);
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.ldtteam.structurize.client.rendertask.task;
2+
3+
public interface ITickingTask
4+
{
5+
/**
6+
* Client Tick callback
7+
*
8+
* @return true if task finished, false if not
9+
*/
10+
public boolean tick();
11+
12+
/**
13+
* Task string identifier
14+
*
15+
* @return
16+
*/
17+
public String id();
18+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.ldtteam.structurize.client.rendertask.task;
2+
3+
public abstract class TimedTask implements IClientTask
4+
{
5+
private final String id;
6+
private int ticksLeft = 0;
7+
8+
protected TimedTask(final String id, final int seconds)
9+
{
10+
this.id = id;
11+
this.ticksLeft = seconds * 20;
12+
}
13+
14+
/**
15+
* Duration of the task
16+
*/
17+
public void setDurationSeconds(final int seconds)
18+
{
19+
this.ticksLeft = seconds * 20;
20+
}
21+
22+
public boolean isExpired()
23+
{
24+
return ticksLeft <= 0;
25+
}
26+
27+
@Override
28+
public boolean tick()
29+
{
30+
ticksLeft--;
31+
return isExpired();
32+
}
33+
34+
@Override
35+
public String id()
36+
{
37+
return id;
38+
}
39+
}

src/main/java/com/ldtteam/structurize/storage/rendering/types/BoxPreviewData.java renamed to src/main/java/com/ldtteam/structurize/client/rendertask/tasks/BoxPreviewData.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.ldtteam.structurize.storage.rendering.types;
1+
package com.ldtteam.structurize.client.rendertask.tasks;
22

33
import net.minecraft.core.BlockPos;
44
import org.jetbrains.annotations.NotNull;
@@ -19,8 +19,6 @@ public class BoxPreviewData
1919
@NotNull
2020
private Optional<BlockPos> anchor;
2121

22-
private long expireTime = Long.MAX_VALUE;
23-
2422
/**
2523
* Create a new box.
2624
* @param pos1 the first pos.
@@ -53,14 +51,4 @@ public void setAnchor(final Optional<BlockPos> anchor)
5351
{
5452
this.anchor = anchor;
5553
}
56-
57-
public boolean isExpired()
58-
{
59-
return System.currentTimeMillis() - expireTime > 0;
60-
}
61-
62-
public void setExpireTime(final int seconds)
63-
{
64-
expireTime = System.currentTimeMillis() + seconds * 1000;
65-
}
6654
}

0 commit comments

Comments
 (0)