-
Notifications
You must be signed in to change notification settings - Fork 58
Expand file tree
/
Copy pathBlockRenderingRegistry.java
More file actions
152 lines (132 loc) · 5.8 KB
/
BlockRenderingRegistry.java
File metadata and controls
152 lines (132 loc) · 5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package codechicken.lib.render.block;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.material.Fluid;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.fml.ModList;
import org.embeddedt.embeddium.api.BlockRendererRegistry;
import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
/**
* Registry for {@link ICCBlockRenderer} instances.
* <p>
* Created by covers1624 on 8/09/2016.
*
* @see ICCBlockRenderer
*/
@Deprecated(forRemoval = true) // No replacement.
@ScheduledForRemoval (inVersion = "mc 1.21.2+")
public class BlockRenderingRegistry {
private static boolean initialized = false;
private static final Map<Block, ICCBlockRenderer> blockRenderers = new HashMap<>();
private static final Map<Fluid, ICCBlockRenderer> fluidRenderers = new HashMap<>();
private static final List<ICCBlockRenderer> globalRenderers = new ArrayList<>();
@OnlyIn (Dist.CLIENT)
public static void init() {
if (!initialized) {
Minecraft mc = Minecraft.getInstance();
BlockRenderDispatcher parentDispatcher = mc.getBlockRenderer();
mc.blockRenderer = new CCBlockRendererDispatcher(parentDispatcher, mc.getBlockColors());
initialized = true;
}
if (ModList.get().isLoaded("embeddium")) {
EmbeddiumSupport.init();
}
}
/**
* Register an {@link ICCBlockRenderer} for the given block.
* <p>
* Unlike {@link #registerGlobalRenderer}, registering your {@link ICCBlockRenderer} via this method
* is guaranteed to only be tested against the block provided.
*
* @param block The block to register to.
* @param renderer The {@link ICCBlockRenderer}.
* @throws IllegalArgumentException If the same Block is registered twice.
*/
@Deprecated // No replacement. Use a mixin.
public static synchronized void registerRenderer(Block block, ICCBlockRenderer renderer) {
ICCBlockRenderer prev = blockRenderers.get(block);
if (prev != null) {
throw new IllegalArgumentException("Renderer already registered for block. " + BuiltInRegistries.BLOCK.getKey(block));
}
blockRenderers.put(block, renderer);
}
/**
* Register an {@link ICCBlockRenderer} for the given fluid.
* <p>
* Unlike {@link #registerGlobalRenderer}, registering your {@link ICCBlockRenderer} via this method
* is guaranteed to only be tested against the fluid provided.
*
* @param fluid The fluid to register to.
* @param renderer The {@link ICCBlockRenderer}.
* @throws IllegalArgumentException If the same Fluid is registered twice.
*/
@Deprecated // No replacement. Use a mixin.
public static synchronized void registerRenderer(Fluid fluid, ICCBlockRenderer renderer) {
ICCBlockRenderer prev = fluidRenderers.get(fluid);
if (prev != null) {
throw new IllegalArgumentException("Renderer already registered for fluid. " + BuiltInRegistries.FLUID.getKey(fluid));
}
fluidRenderers.put(fluid, renderer);
}
/**
* Register a global {@link ICCBlockRenderer}, capable of overriding the
* rendering of any block in world.
*
* @param renderer The {@link ICCBlockRenderer}.
*/
@Deprecated // No replacement. Use a mixin.
public static synchronized void registerGlobalRenderer(ICCBlockRenderer renderer) {
globalRenderers.add(renderer);
}
@Nullable
static ICCBlockRenderer findFor(Block block, Predicate<ICCBlockRenderer> pred) {
for (ICCBlockRenderer renderer : globalRenderers) {
if (pred.test(renderer)) {
return renderer;
}
}
ICCBlockRenderer found = blockRenderers.get(block);
if (found != null && pred.test(found)) return found;
return null;
}
@Nullable
static ICCBlockRenderer findFor(Fluid fluid, Predicate<ICCBlockRenderer> pred) {
for (ICCBlockRenderer renderer : globalRenderers) {
if (pred.test(renderer)) {
return renderer;
}
}
ICCBlockRenderer found = fluidRenderers.get(fluid);
if (found != null && pred.test(found)) return found;
return null;
}
private static class EmbeddiumSupport {
private static final Map<ICCBlockRenderer, BlockRendererRegistry.Renderer> ADAPTERS = new ConcurrentHashMap<>();
private static final ThreadLocal<PoseStack> POSE_STACK_CACHE = ThreadLocal.withInitial(PoseStack::new);
private static BlockRendererRegistry.Renderer adapt(ICCBlockRenderer renderer) {
return ADAPTERS.computeIfAbsent(renderer, e -> (ctx, random, consumer) -> {
e.renderBlock(ctx.state(), ctx.pos(), ctx.world(), POSE_STACK_CACHE.get(), consumer, random, ctx.modelData(), ctx.renderLayer());
return BlockRendererRegistry.RenderResult.OVERRIDE;
});
}
public static void init() {
BlockRendererRegistry.instance().registerRenderPopulator((resultList, ctx) -> {
ICCBlockRenderer renderer = BlockRenderingRegistry.findFor(ctx.state().getBlock(), e -> e.canHandleBlock(ctx.world(), ctx.pos(), ctx.state(), ctx.renderLayer()));
if (renderer != null) {
resultList.add(adapt(renderer));
}
});
}
}
}