1313import it .unimi .dsi .fastutil .objects .ReferenceSets ;
1414import net .fabricmc .fabric .impl .client .model .loading .UnbakedModelDeserializerRegistry ;
1515import net .minecraft .client .color .block .BlockColors ;
16+ import net .minecraft .client .renderer .item .ClientItem ;
1617import net .minecraft .client .renderer .block .dispatch .BlockStateModel ;
1718import net .minecraft .client .resources .model .cuboid .ItemModelGenerator ;
1819import net .minecraft .client .resources .model .BlockStateModelLoader ;
3233import org .embeddedt .modernfix .common .mixin .perf .dynamic_resources .BlockStateDefinitionsAccessor ;
3334import org .embeddedt .modernfix .common .mixin .perf .dynamic_resources .IdMapperAccessor ;
3435import org .embeddedt .modernfix .common .mixin .perf .dynamic_resources .ModelDiscoveryAccessor ;
36+ import org .jetbrains .annotations .Nullable ;
3537
3638import java .io .Reader ;
3739import java .util .AbstractSet ;
4648public class DynamicModelSystem {
4749 private static final FileToIdConverter MODEL_LISTER = FileToIdConverter .json ("models" );
4850 private static final FileToIdConverter BLOCKSTATE_LISTER = FileToIdConverter .json ("blockstates" );
51+ private static final FileToIdConverter ITEM_LISTER = FileToIdConverter .json ("items" );
4952
5053 public static final boolean DEBUG_DYNAMIC_MODEL_LOADING = Boolean .getBoolean ("modernfix.debugDynamicModelLoading" );
5154
@@ -104,6 +107,41 @@ public BlockStateModelLoader.LoadedModels load(Identifier key) throws Exception
104107 }));
105108 }
106109
110+ public interface SingleClientItemEntryLoader {
111+ @ Nullable ClientItem loadEntry (Identifier resourceFileId , Resource resource );
112+ }
113+
114+ public static ClientItemInfoLoader .LoadedClientInfos createDynamicClientInfos (Map <Identifier , Resource > resourceMap , SingleClientItemEntryLoader entryLoader ) {
115+ Set <Identifier > itemIdSet = resourceMap .keySet ().stream ().map (ITEM_LISTER ::fileToId ).collect (Collectors .toUnmodifiableSet ());
116+ LoadingCache <Identifier , Object > clientItemCache = CacheBuilder .newBuilder ().softValues ().maximumSize (1000 ).build (new CacheLoader <>() {
117+ @ Override
118+ public Object load (Identifier key ) {
119+ Identifier fileId = ITEM_LISTER .idToFile (key );
120+ Resource resource = resourceMap .get (fileId );
121+ if (resource == null ) {
122+ return NULL_SENTINEL ;
123+ }
124+ if (DEBUG_DYNAMIC_MODEL_LOADING ) {
125+ ModernFix .LOGGER .info ("Loading client item info {}" , key );
126+ }
127+ try {
128+ ClientItem result = entryLoader .loadEntry (fileId , resource );
129+ return result != null ? result : NULL_SENTINEL ;
130+ } catch (RuntimeException e ) {
131+ ModernFix .LOGGER .warn ("Failed to build dynamic client item info for {}" , key , e );
132+ return NULL_SENTINEL ;
133+ }
134+ }
135+ });
136+ return new ClientItemInfoLoader .LoadedClientInfos (Maps .asMap (itemIdSet , key -> {
137+ if (key == null ) {
138+ return null ;
139+ }
140+ Object value = clientItemCache .getUnchecked (key );
141+ return value == NULL_SENTINEL ? null : (ClientItem ) value ;
142+ }));
143+ }
144+
107145 public record DynamicResolver (Map <Identifier , UnbakedModel > inputModels ,
108146 BlockStateModelLoader .LoadedModels loadedModels ,
109147 ClientItemInfoLoader .LoadedClientInfos loadedClientInfos ) {
@@ -167,7 +205,7 @@ public int getInt(Object key) {
167205 }
168206 }
169207
170- private static final Object NULL_BAKED = new Object ();
208+ private static final Object NULL_SENTINEL = new Object ();
171209
172210 public static <K , U , V > Map <K , V > createDynamicBakedRegistry (Map <K , U > input , BiFunction <K , U , V > baker ) {
173211 // TODO: support persistence of overrides
@@ -181,14 +219,14 @@ public Object load(K key) throws Exception {
181219 }
182220 return baker .apply (key , unbaked );
183221 } else {
184- return NULL_BAKED ;
222+ return NULL_SENTINEL ;
185223 }
186224 }
187225 });
188226 return new DynamicRegistryMap <>(input .keySet (), k -> {
189227 if (k != null ) {
190228 Object value = bakedCache .getUnchecked (k );
191- if (value == NULL_BAKED ) {
229+ if (value == NULL_SENTINEL ) {
192230 value = null ;
193231 }
194232 return (V ) value ;
@@ -197,4 +235,4 @@ public Object load(K key) throws Exception {
197235 }
198236 });
199237 }
200- }
238+ }
0 commit comments