Skip to content

Commit 486b7ff

Browse files
ekulxam8s2
andauthored
Backport FabricRenderState to 1.21.8 (#5004)
* Add `FabricRenderState` * Add getDataOrDefault method to FabricRenderState (#4917) * spotlessApply and check --------- Co-authored-by: EightSidedSquare <[email protected]>
1 parent 2b7ecb8 commit 486b7ff

File tree

10 files changed

+435
-3
lines changed

10 files changed

+435
-3
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.fabricmc.fabric.api.client.rendering.v1;
18+
19+
import org.jetbrains.annotations.ApiStatus;
20+
import org.jetbrains.annotations.Nullable;
21+
22+
import net.minecraft.client.render.MapRenderState;
23+
import net.minecraft.client.render.entity.state.EntityRenderState;
24+
import net.minecraft.client.render.item.ItemRenderState;
25+
26+
/**
27+
* Fabric-provided extensions for render states, allowing for the addition of extra render data.
28+
*
29+
* <p>Note: This interface is automatically implemented on the following classes via Mixin and interface injection:
30+
* <ul>
31+
* <li>{@link EntityRenderState},
32+
* <li>{@link ItemRenderState} and {@link ItemRenderState.LayerRenderState}
33+
* <li>{@link MapRenderState} and {@link MapRenderState.Decoration}
34+
* </ul>
35+
*/
36+
@ApiStatus.NonExtendable
37+
public interface FabricRenderState {
38+
/**
39+
* Get extra render data from the render state.
40+
* @param key the key of the data
41+
* @param <T> the type of the data
42+
* @return the data, or {@code null} if it cannot be found.
43+
*/
44+
@Nullable
45+
default <T> T getData(RenderStateDataKey<T> key) {
46+
throw new UnsupportedOperationException("Implemented via mixin");
47+
}
48+
49+
/**
50+
* Get extra render data from the render state, or a default value if it cannot be found.
51+
* @param key the key of the data
52+
* @param defaultValue the default value
53+
* @param <T> the type of the data
54+
* @return the data, or the default value if it cannot be found.
55+
*/
56+
default <T> T getDataOrDefault(RenderStateDataKey<T> key, T defaultValue) {
57+
throw new UnsupportedOperationException("Implemented via mixin");
58+
}
59+
60+
/**
61+
* Set extra render data to the render state.
62+
* @param key the key of the data
63+
* @param value the data
64+
* @param <T> the type of the data
65+
*/
66+
default <T> void setData(RenderStateDataKey<T> key, @Nullable T value) {
67+
throw new UnsupportedOperationException("Implemented via mixin");
68+
}
69+
70+
/**
71+
* Clears all extra render data on the render state.
72+
*/
73+
default void clearExtraData() {
74+
throw new UnsupportedOperationException("Implemented via mixin");
75+
}
76+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.fabricmc.fabric.api.client.rendering.v1;
18+
19+
import java.util.function.Supplier;
20+
21+
/**
22+
* A unique key representing extra data to attach to a render state.
23+
* @param <T> The type of the render state data.
24+
* @see FabricRenderState#getData(RenderStateDataKey)
25+
* @see FabricRenderState#setData(RenderStateDataKey, Object)
26+
*/
27+
public final class RenderStateDataKey<T> {
28+
private final Supplier<String> name;
29+
30+
private RenderStateDataKey(Supplier<String> debugName) {
31+
this.name = debugName;
32+
}
33+
34+
/**
35+
* Creates a new unique data key.
36+
* @param debugName The name of this data key, shown in error messages.
37+
* @param <T> The type of the render state data.
38+
* @return The newly created data key.
39+
*/
40+
public static <T> RenderStateDataKey<T> create(Supplier<String> debugName) {
41+
return new RenderStateDataKey<>(debugName);
42+
}
43+
44+
/**
45+
* Creates a new unique data key.
46+
* @param <T> The type of the render state data.
47+
* @return The newly created data key.
48+
*/
49+
public static <T> RenderStateDataKey<T> create() {
50+
return new RenderStateDataKey<>(() -> "unnamed");
51+
}
52+
53+
@Override
54+
public String toString() {
55+
return "RenderStateDataKey(" + name.get() + ")";
56+
}
57+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.fabricmc.fabric.mixin.client.rendering;
18+
19+
import java.util.Map;
20+
21+
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
22+
import org.jetbrains.annotations.Nullable;
23+
import org.spongepowered.asm.mixin.Mixin;
24+
import org.spongepowered.asm.mixin.Unique;
25+
26+
import net.minecraft.client.render.MapRenderState;
27+
import net.minecraft.client.render.entity.state.EntityRenderState;
28+
import net.minecraft.client.render.item.ItemRenderState;
29+
30+
import net.fabricmc.fabric.api.client.rendering.v1.FabricRenderState;
31+
import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey;
32+
33+
@Mixin({
34+
EntityRenderState.class,
35+
ItemRenderState.class,
36+
ItemRenderState.LayerRenderState.class,
37+
MapRenderState.class,
38+
MapRenderState.Decoration.class,
39+
})
40+
public abstract class RenderStateMixin implements FabricRenderState {
41+
@Unique
42+
@Nullable
43+
private Map<RenderStateDataKey<?>, Object> renderStateData;
44+
45+
@Override
46+
@SuppressWarnings("unchecked")
47+
public <T> @Nullable T getData(RenderStateDataKey<T> key) {
48+
return renderStateData == null ? null : (T) renderStateData.get(key);
49+
}
50+
51+
@Override
52+
@SuppressWarnings("unchecked")
53+
public <T> T getDataOrDefault(RenderStateDataKey<T> key, T defaultValue) {
54+
return renderStateData == null ? defaultValue : (T) renderStateData.getOrDefault(key, defaultValue);
55+
}
56+
57+
@Override
58+
public <T> void setData(RenderStateDataKey<T> key, T value) {
59+
if (renderStateData == null) {
60+
renderStateData = new Reference2ObjectOpenHashMap<>();
61+
}
62+
63+
renderStateData.put(key, value);
64+
}
65+
66+
@Override
67+
public void clearExtraData() {
68+
if (renderStateData != null) {
69+
renderStateData.clear();
70+
}
71+
}
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.fabricmc.fabric.mixin.client.rendering.renderstate;
18+
19+
import org.spongepowered.asm.mixin.Mixin;
20+
import org.spongepowered.asm.mixin.injection.At;
21+
import org.spongepowered.asm.mixin.injection.Inject;
22+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
23+
24+
import net.minecraft.client.render.item.ItemRenderState;
25+
26+
import net.fabricmc.fabric.api.client.rendering.v1.FabricRenderState;
27+
28+
@Mixin(ItemRenderState.LayerRenderState.class)
29+
public class ItemRenderStateLayerRenderStateMixin {
30+
@Inject(method = "clear", at = @At("TAIL"))
31+
private void clearExtraRenderData(CallbackInfo ci) {
32+
((FabricRenderState) this).clearExtraData();
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.fabricmc.fabric.mixin.client.rendering.renderstate;
18+
19+
import org.spongepowered.asm.mixin.Mixin;
20+
import org.spongepowered.asm.mixin.injection.At;
21+
import org.spongepowered.asm.mixin.injection.Inject;
22+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
23+
24+
import net.minecraft.client.render.item.ItemRenderState;
25+
26+
import net.fabricmc.fabric.api.client.rendering.v1.FabricRenderState;
27+
28+
@Mixin(ItemRenderState.class)
29+
public class ItemRenderStateMixin {
30+
@Inject(method = "clear", at = @At("TAIL"))
31+
private void clearExtraRenderData(CallbackInfo ci) {
32+
((FabricRenderState) this).clearExtraData();
33+
}
34+
}

fabric-rendering-v1/src/client/resources/fabric-rendering-v1.mixins.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@
2323
"LivingEntityRendererAccessor",
2424
"LivingEntityRendererMixin",
2525
"RenderLayersMixin",
26+
"RenderStateMixin",
2627
"SpecialModelTypesMixin",
2728
"TooltipComponentMixin",
28-
"WorldRendererMixin"
29+
"WorldRendererMixin",
30+
"renderstate.ItemRenderStateLayerRenderStateMixin",
31+
"renderstate.ItemRenderStateMixin"
2932
],
3033
"injectors": {
3134
"defaultRequire": 1

fabric-rendering-v1/src/client/resources/fabric.mod.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@
3030
"fabric-rendering-v1.mixins.json"
3131
],
3232
"custom": {
33-
"fabric-api:module-lifecycle": "stable"
33+
"fabric-api:module-lifecycle": "stable",
34+
"loom:injected_interfaces": {
35+
"net/minecraft/class_10017": [
36+
"net/fabricmc/fabric/api/client/rendering/v1/FabricRenderState"
37+
],
38+
"net/minecraft/class_10090": [
39+
"net/fabricmc/fabric/api/client/rendering/v1/FabricRenderState"
40+
],
41+
"net/minecraft/class_10090\u0024class_10091": [
42+
"net/fabricmc/fabric/api/client/rendering/v1/FabricRenderState"
43+
],
44+
"net/minecraft/class_10444": [
45+
"net/fabricmc/fabric/api/client/rendering/v1/FabricRenderState"
46+
],
47+
"net/minecraft/class_10444\u0024class_10446": [
48+
"net/fabricmc/fabric/api/client/rendering/v1/FabricRenderState"
49+
]
50+
}
3451
}
3552
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.fabricmc.fabric.impl.client.rendering.state;
18+
19+
import org.junit.jupiter.api.Assertions;
20+
import org.junit.jupiter.api.BeforeAll;
21+
import org.junit.jupiter.api.Test;
22+
23+
import net.minecraft.Bootstrap;
24+
import net.minecraft.SharedConstants;
25+
import net.minecraft.client.render.MapRenderState;
26+
import net.minecraft.client.render.entity.state.EntityRenderState;
27+
import net.minecraft.client.render.item.ItemRenderState;
28+
29+
import net.fabricmc.fabric.api.client.rendering.v1.FabricRenderState;
30+
import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey;
31+
32+
public class RenderStateDataTest {
33+
private static final RenderStateDataKey<String> DEBUG = RenderStateDataKey.create(() -> "Debug");
34+
35+
@BeforeAll
36+
static void beforeAll() {
37+
SharedConstants.createGameVersion();
38+
Bootstrap.initialize();
39+
}
40+
41+
@Test
42+
void assertFabricRenderStateMethods() {
43+
ItemRenderState itemRenderState = new ItemRenderState();
44+
FabricRenderState[] states = new FabricRenderState[]{
45+
new EntityRenderState(),
46+
itemRenderState,
47+
itemRenderState.new LayerRenderState(),
48+
new MapRenderState(),
49+
new MapRenderState.Decoration(),
50+
};
51+
52+
for (FabricRenderState state : states) {
53+
Assertions.assertNull(state.getData(DEBUG));
54+
Assertions.assertEquals("pass", state.getDataOrDefault(DEBUG, "pass"));
55+
state.setData(DEBUG, "test");
56+
Assertions.assertEquals("test", state.getData(DEBUG));
57+
Assertions.assertEquals("test", state.getDataOrDefault(DEBUG, "fail"));
58+
state.clearExtraData();
59+
Assertions.assertNull(state.getData(DEBUG));
60+
Assertions.assertEquals("pass", state.getDataOrDefault(DEBUG, "pass"));
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)