44import com .google .common .cache .CacheLoader ;
55import com .google .common .cache .LoadingCache ;
66import com .google .common .collect .Maps ;
7- import com .google .common .collect .Sets ;
87import it .unimi .dsi .fastutil .objects .AbstractObject2IntMap ;
98import it .unimi .dsi .fastutil .objects .Object2IntMap ;
109import it .unimi .dsi .fastutil .objects .Object2IntOpenHashMap ;
1110import it .unimi .dsi .fastutil .objects .ObjectSet ;
1211import it .unimi .dsi .fastutil .objects .ObjectSets ;
13- import it .unimi .dsi .fastutil .objects .ReferenceSets ;
1412import net .minecraft .client .color .block .BlockColors ;
1513import net .minecraft .client .resources .model .BlockStateModelLoader ;
14+ import net .minecraft .client .renderer .item .ClientItem ;
1615import net .minecraft .client .resources .model .ClientItemInfoLoader ;
16+ import org .jetbrains .annotations .Nullable ;
1717import net .minecraft .client .resources .model .ModelDiscovery ;
1818import net .minecraft .client .resources .model .ModelManager ;
1919import net .minecraft .client .resources .model .ResolvedModel ;
3838import java .util .Iterator ;
3939import java .util .List ;
4040import java .util .Map ;
41+ import java .util .Objects ;
4142import java .util .Set ;
4243import java .util .function .BiFunction ;
43- import java .util .function .Function ;
4444import java .util .stream .Collectors ;
4545
4646public class DynamicModelSystem {
4747 private static final FileToIdConverter MODEL_LISTER = FileToIdConverter .json ("models" );
4848 private static final FileToIdConverter BLOCKSTATE_LISTER = FileToIdConverter .json ("blockstates" );
49+ private static final FileToIdConverter ITEM_LISTER = FileToIdConverter .json ("items" );
4950
5051 public static final boolean DEBUG_DYNAMIC_MODEL_LOADING = Boolean .getBoolean ("modernfix.debugDynamicModelLoading" );
51-
52- public static Map <Identifier , UnbakedModel > createDynamicUnbakedModelMap (Map <Identifier , Resource > resourceMap ) {
53- LoadingCache <Identifier , UnbakedModel > unbakedModelCache = CacheBuilder .newBuilder ().softValues ().maximumSize (1000 ).build (new CacheLoader <>() {
52+
53+ private interface ResultLoader <RESOURCE , RESULT > {
54+ RESULT load (Identifier file , @ Nullable RESOURCE resource ) throws Exception ;
55+ }
56+
57+ private static <RESOURCE , RESULT > Map <Identifier , RESULT > createCachedResourceBackedMap (Map <Identifier , RESOURCE > resourceMap ,
58+ FileToIdConverter converter ,
59+ String debugName ,
60+ ResultLoader <RESOURCE , RESULT > loader ) {
61+ LoadingCache <Identifier , RESULT > resultCache = CacheBuilder .newBuilder ().softValues ().maximumSize (1000 ).build (new CacheLoader <>() {
5462 @ Override
55- public UnbakedModel load (Identifier key ) throws Exception {
56- var resource = resourceMap .get (MODEL_LISTER .idToFile (key ));
57- if (resource == null ) {
58- throw new IllegalArgumentException ("Model " + key + " does not exist in map" );
59- }
63+ public RESULT load (Identifier id ) throws Exception {
64+ var file = converter .idToFile (id );
65+ var resource = resourceMap .get (file );
6066 if (DEBUG_DYNAMIC_MODEL_LOADING ) {
61- ModernFix .LOGGER .info ("Loading unbaked model {}" , key );
62- }
63- try (Reader reader = resource .openAsReader ()) {
64- return UnbakedModelParser .parse (reader );
67+ ModernFix .LOGGER .info ("Loading {} {}" , debugName , id );
6568 }
69+ return loader .load (file , resource );
70+ }
71+ });
72+ Set <Identifier > idSet = resourceMap .keySet ().stream ().map (converter ::fileToId ).collect (Collectors .toUnmodifiableSet ());
73+ return Maps .asMap (idSet , key -> key != null ? resultCache .getUnchecked (key ) : null );
74+ }
75+
76+ public static Map <Identifier , UnbakedModel > createDynamicUnbakedModelMap (Map <Identifier , Resource > resourceMap ) {
77+ return createCachedResourceBackedMap (resourceMap , MODEL_LISTER , "unbaked model" , (id , resource ) -> {
78+ Objects .requireNonNull (resource , "unbaked model not present" );
79+ try (Reader reader = resource .openAsReader ()) {
80+ return UnbakedModelParser .parse (reader );
6681 }
6782 });
68- Set <Identifier > unbakedIdSet = resourceMap .keySet ().stream ().map (MODEL_LISTER ::fileToId ).collect (Collectors .toUnmodifiableSet ());
69- return Maps .asMap (unbakedIdSet , key -> key != null ? unbakedModelCache .getUnchecked (key ) : null );
7083 }
7184
7285 public interface SingleBlockStateEntryLoader {
@@ -96,17 +109,7 @@ public int size() {
96109 }
97110
98111 public static BlockStateModelLoader .LoadedModels createDynamicBlockStateLoadedModels (Map <Identifier , List <Resource >> resourceMap , SingleBlockStateEntryLoader entryLoader ) {
99- LoadingCache <Identifier , BlockStateModelLoader .LoadedModels > definitionCache = CacheBuilder .newBuilder ().softValues ().maximumSize (1000 ).build (new CacheLoader <>() {
100- @ Override
101- public BlockStateModelLoader .LoadedModels load (Identifier key ) throws Exception {
102- if (DEBUG_DYNAMIC_MODEL_LOADING ) {
103- ModernFix .LOGGER .info ("Loading blockstate definition for {}" , key );
104- }
105- var file = BLOCKSTATE_LISTER .idToFile (key );
106- var resources = resourceMap .getOrDefault (file , List .of ());
107- return entryLoader .loadEntry (file , resources );
108- }
109- });
112+ var blockStateDefinitions = createCachedResourceBackedMap (resourceMap , BLOCKSTATE_LISTER , "blockstate definition" , entryLoader ::loadEntry );
110113 var staticDefinitions = BlockStateDefinitionsAccessor .getStaticDefinitions ();
111114 var staticIdentifiers = staticDefinitions .entrySet ()
112115 .stream ()
@@ -118,11 +121,20 @@ public BlockStateModelLoader.LoadedModels load(Identifier key) throws Exception
118121 if (identifier == null ) {
119122 identifier = state .getBlock ().builtInRegistryHolder ().getKey ().identifier ();
120123 }
121- var loadedModels = definitionCache . getUnchecked (identifier );
124+ var loadedModels = blockStateDefinitions . get (identifier );
122125 return loadedModels .models ().get (state );
123126 }));
124127 }
125128
129+ public interface SingleClientItemEntryLoader {
130+ @ Nullable ClientItem loadEntry (Identifier resourceId , Resource resource );
131+ }
132+
133+ public static ClientItemInfoLoader .LoadedClientInfos createDynamicClientInfos (Map <Identifier , Resource > resourceMap , SingleClientItemEntryLoader entryLoader ) {
134+ var clientItems = createCachedResourceBackedMap (resourceMap , ITEM_LISTER , "client item info" , entryLoader ::loadEntry );
135+ return new ClientItemInfoLoader .LoadedClientInfos (clientItems );
136+ }
137+
126138 public record DynamicResolver (Map <Identifier , UnbakedModel > inputModels ,
127139 BlockStateModelLoader .LoadedModels loadedModels ,
128140 ClientItemInfoLoader .LoadedClientInfos loadedClientInfos ,
0 commit comments