11package org .embeddedt .modernfix .common .mixin .perf .dynamic_resources ;
22
3+ import com .google .common .cache .Cache ;
4+ import com .google .common .cache .CacheBuilder ;
35import com .google .common .collect .ImmutableList ;
6+ import com .llamalad7 .mixinextras .injector .wrapmethod .WrapMethod ;
7+ import com .llamalad7 .mixinextras .injector .wrapoperation .Operation ;
8+ import com .llamalad7 .mixinextras .injector .wrapoperation .WrapOperation ;
9+ import it .unimi .dsi .fastutil .Pair ;
410import it .unimi .dsi .fastutil .objects .Object2IntMap ;
511import it .unimi .dsi .fastutil .objects .Object2IntMaps ;
6- import net . minecraft . client . Minecraft ;
12+ import it . unimi . dsi . fastutil . objects . ReferenceObjectImmutablePair ;
713import net .minecraft .client .color .block .BlockColors ;
14+ import net .minecraft .client .renderer .block .model .BlockModelDefinition ;
815import net .minecraft .client .resources .model .BlockStateModelLoader ;
916import net .minecraft .client .resources .model .ModelResourceLocation ;
1017import net .minecraft .client .resources .model .UnbakedModel ;
1522import net .minecraft .world .level .block .Block ;
1623import net .minecraft .world .level .block .state .BlockState ;
1724import net .minecraft .world .level .block .state .StateDefinition ;
18- import org .embeddedt .modernfix .ModernFix ;
1925import org .embeddedt .modernfix .annotation .ClientOnlyMixin ;
2026import org .embeddedt .modernfix .duck .IBlockStateModelLoader ;
21- import org .embeddedt .modernfix .dynamicresources .ModelBakeryHelpers ;
2227import org .spongepowered .asm .mixin .Final ;
2328import org .spongepowered .asm .mixin .Mixin ;
2429import org .spongepowered .asm .mixin .Mutable ;
3136import java .util .Collections ;
3237import java .util .Iterator ;
3338import java .util .Map ;
39+ import java .util .concurrent .ExecutionException ;
3440import java .util .function .BiConsumer ;
41+ import java .util .function .Predicate ;
3542
3643@ Mixin (BlockStateModelLoader .class )
3744@ ClientOnlyMixin
@@ -51,13 +58,17 @@ private void makeModelGroupsSynchronized(Map map, ProfilerFiller profilerFiller,
5158 public void loadSpecificBlock (ModelResourceLocation location ) {
5259 var optionalBlock = BuiltInRegistries .BLOCK .getOptional (location .id ());
5360 if (optionalBlock .isPresent ()) {
61+ // embeddedt note - filtering is currently disabled as it's quite inefficient to do vs. just loading
62+ // the extra models and letting LRU deal with it
63+ /*
5464 try {
5565 // Only filter states if we are in a world and not in the loading overlay
5666 filteredStates = (Minecraft.getInstance().getOverlay() == null && Minecraft.getInstance().level != null) ? ModelBakeryHelpers.getBlockStatesForMRL(optionalBlock.get().getStateDefinition(), location) : null;
5767 } catch(RuntimeException e) {
5868 ModernFix.LOGGER.error("Exception filtering states on {}", location, e);
5969 filteredStates = null;
6070 }
71+ */
6172 try {
6273 this .loadBlockStateDefinitions (location .id (), optionalBlock .get ().getStateDefinition ());
6374 } finally {
@@ -75,4 +86,32 @@ private Iterator<?> skipIteratingBlocks(DefaultedRegistry instance) {
7586 private ImmutableList <BlockState > getFilteredStates (StateDefinition <Block , BlockState > instance ) {
7687 return this .filteredStates != null ? this .filteredStates : instance .getPossibleStates ();
7788 }
89+
90+ // Add some caching around key hot paths
91+
92+ private final Cache <ReferenceObjectImmutablePair <BlockStateModelLoader .LoadedJson , ResourceLocation >, BlockModelDefinition > cachedBlockModelDefs = CacheBuilder .newBuilder ()
93+ .maximumSize (100 )
94+ .build ();
95+
96+ private static final Cache <Pair <StateDefinition <Block , BlockState >, String >, Predicate <BlockState >> cachedBlockStatePredicates = CacheBuilder .newBuilder ()
97+ .maximumSize (100 )
98+ .build ();
99+
100+ @ WrapOperation (method = "loadBlockStateDefinitions" , at = @ At (value = "INVOKE" , target = "Lnet/minecraft/client/resources/model/BlockStateModelLoader$LoadedJson;parse(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/client/renderer/block/model/BlockModelDefinition$Context;)Lnet/minecraft/client/renderer/block/model/BlockModelDefinition;" ))
101+ private BlockModelDefinition avoidMultipleParses (BlockStateModelLoader .LoadedJson instance , ResourceLocation blockStateId , BlockModelDefinition .Context context , Operation <BlockModelDefinition > original ) {
102+ try {
103+ return cachedBlockModelDefs .get (ReferenceObjectImmutablePair .of (instance , blockStateId ), () -> original .call (instance , blockStateId , context ));
104+ } catch (ExecutionException e ) {
105+ throw new RuntimeException (e );
106+ }
107+ }
108+
109+ @ WrapMethod (method = "predicate" )
110+ private static Predicate <BlockState > memoizePredicate (StateDefinition <Block , BlockState > stateDefentition , String properties , Operation <Predicate <BlockState >> original ) {
111+ try {
112+ return cachedBlockStatePredicates .get (Pair .of (stateDefentition , properties ), () -> original .call (stateDefentition , properties ));
113+ } catch (ExecutionException e ) {
114+ throw new RuntimeException (e );
115+ }
116+ }
78117}
0 commit comments