11package org .embeddedt .modernfix .dynamicresources ;
22
3+ import com .google .common .base .Suppliers ;
34import com .google .common .cache .CacheBuilder ;
45import com .google .common .cache .CacheLoader ;
56import com .google .common .cache .LoadingCache ;
7+ import com .google .common .collect .Collections2 ;
68import com .google .common .collect .Iterators ;
79import com .google .common .collect .Maps ;
810import com .google .gson .JsonObject ;
6163import java .util .concurrent .TimeUnit ;
6264import java .util .function .BiFunction ;
6365import java .util .function .Function ;
66+ import java .util .function .Supplier ;
6467import java .util .stream .Collectors ;
6568
6669/**
@@ -149,28 +152,32 @@ public ItemModel getMissingItemModel() {
149152 return this .missingItemModel ;
150153 }
151154
152- public Map < ModelResourceLocation , BakedModel > getTopLevelEmulatedRegistry () {
153- Set <ModelResourceLocation > topLevelModelLocations = new HashSet <>();
155+ private static final Supplier < Set < ModelResourceLocation >> TOP_LEVEL_LOCATIONS_SUPPLIER = Suppliers . memoizeWithExpiration (() -> {
156+ Set <ModelResourceLocation > set = new HashSet <>();
154157 // Skip going through ModelLocationCache because most of the accesses will be misses
155158 BuiltInRegistries .BLOCK .entrySet ().forEach (entry -> {
156159 var location = entry .getKey ().location ();
157160 for (BlockState state : entry .getValue ().getStateDefinition ().getPossibleStates ()) {
158- topLevelModelLocations .add (BlockModelShaper .stateToModelLocation (location , state ));
161+ set .add (BlockModelShaper .stateToModelLocation (location , state ));
159162 }
160163 });
161- return new EmulatedRegistry <>(ModelResourceLocation .class , this .loadedBakedModels , topLevelModelLocations , this .mrlModelOverrides );
164+ return Collections .unmodifiableSet (set );
165+ }, 2 , TimeUnit .MINUTES );
166+
167+ public Map <ModelResourceLocation , BakedModel > getTopLevelEmulatedRegistry () {
168+ return new EmulatedRegistry <>(ModelResourceLocation .class , this .loadedBakedModels , TOP_LEVEL_LOCATIONS_SUPPLIER , this .mrlModelOverrides );
162169 }
163170
164171 public Map <ResourceLocation , BakedModel > getStandaloneEmulatedRegistry () {
165- return new EmulatedRegistry <>(ResourceLocation .class , this .loadedStandaloneModels , Set . of () , this .standaloneModelOverrides );
172+ return new EmulatedRegistry <>(ResourceLocation .class , this .loadedStandaloneModels , Set :: of , this .standaloneModelOverrides );
166173 }
167174
168175 public Map <ResourceLocation , ItemModel > getItemModelEmulatedRegistry () {
169- return new EmulatedRegistry <>(ResourceLocation .class , this .loadedItemModels , BuiltInRegistries .ITEM . keySet () , this .itemStackModelOverrides );
176+ return new EmulatedRegistry <>(ResourceLocation .class , this .loadedItemModels , BuiltInRegistries .ITEM :: keySet , this .itemStackModelOverrides );
170177 }
171178
172179 public Map <ResourceLocation , ClientItem .Properties > getItemPropertiesEmulatedRegistry () {
173- return Maps .transformValues (new EmulatedRegistry <>(ResourceLocation .class , this .loadedClientItemProperties , BuiltInRegistries .ITEM . keySet () , Map .of ()), ClientItem ::properties );
180+ return Maps .transformValues (new EmulatedRegistry <>(ResourceLocation .class , this .loadedClientItemProperties , BuiltInRegistries .ITEM :: keySet , Map .of ()), ClientItem ::properties );
174181 }
175182
176183 private <K , V > LoadingCache <K , Optional <V >> makeLoadingCache (Function <K , Optional <V >> loadingFunction ) {
@@ -189,14 +196,14 @@ public Optional<V> load(K key) {
189196
190197 private static class EmulatedRegistry <K , V > implements Map <K , V > {
191198 private final LoadingCache <K , Optional <V >> realCache ;
192- private final Set <K > keys ;
199+ private final Supplier < Set <K > > keys ;
193200 private final Map <K , V > overrides ;
194201 private final Class <K > keyClass ;
195202
196- public EmulatedRegistry (Class <K > keyClass , LoadingCache <K , Optional <V >> realCache , Set <K > keys , Map <K , V > overrides ) {
203+ public EmulatedRegistry (Class <K > keyClass , LoadingCache <K , Optional <V >> realCache , Supplier < Set <K > > keys , Map <K , V > overrides ) {
197204 this .keyClass = keyClass ;
198205 this .realCache = realCache ;
199- this .keys = Collections . unmodifiableSet ( keys ) ;
206+ this .keys = keys ;
200207 this .overrides = overrides ;
201208 }
202209
@@ -209,6 +216,15 @@ public V get(Object key) {
209216 }
210217 }
211218
219+ @ Override
220+ public V getOrDefault (Object key , V defaultValue ) {
221+ if (this .keyClass .isAssignableFrom (key .getClass ())) {
222+ return this .realCache .getUnchecked ((K )key ).orElse (defaultValue );
223+ } else {
224+ return defaultValue ;
225+ }
226+ }
227+
212228 @ Override
213229 public V put (K key , V value ) {
214230 V oldValue = this .realCache .getUnchecked (key ).orElse (null );
@@ -237,17 +253,17 @@ public void clear() {
237253
238254 @ Override
239255 public @ NotNull Set <K > keySet () {
240- return keys ;
256+ return keys . get () ;
241257 }
242258
243259 @ Override
244260 public @ NotNull Collection <V > values () {
245- return List . of ( );
261+ return Collections2 . transform ( this . realCache . asMap (). values (), v -> v . orElse ( null ) );
246262 }
247263
248264 @ Override
249265 public int size () {
250- return keys .size ();
266+ return keys .get (). size ();
251267 }
252268
253269 @ Override
@@ -257,7 +273,7 @@ public boolean isEmpty() {
257273
258274 @ Override
259275 public boolean containsKey (Object key ) {
260- return keys .contains (key );
276+ return keys .get (). contains (key );
261277 }
262278
263279 @ Override
@@ -270,7 +286,7 @@ public boolean containsValue(Object value) {
270286 return new AbstractSet <>() {
271287 @ Override
272288 public Iterator <Entry <K , V >> iterator () {
273- return Iterators .transform (keys .iterator (), key -> new Entry <>() {
289+ return Iterators .transform (keys .get (). iterator (), key -> new Entry <>() {
274290 @ Override
275291 public K getKey () {
276292 return key ;
@@ -290,14 +306,14 @@ public V setValue(V value) {
290306
291307 @ Override
292308 public int size () {
293- return keys .size ();
309+ return keys .get (). size ();
294310 }
295311 };
296312 }
297313
298314 @ Override
299315 public void replaceAll (BiFunction <? super K , ? super V , ? extends V > function ) {
300- for (K location : keys ) {
316+ for (K location : keys . get () ) {
301317 /*
302318 * Fetching every model is insanely slow. So we call the function with a null object first, since it
303319 * probably isn't expecting that. If we get an exception thrown, or it returns nonnull, then we know
0 commit comments