22
33import com .google .common .collect .ImmutableSet ;
44import com .mojang .math .Transformation ;
5+ import it .unimi .dsi .fastutil .objects .Object2ObjectMaps ;
56import it .unimi .dsi .fastutil .objects .Object2ObjectOpenHashMap ;
67import net .minecraft .client .renderer .block .model .BakedQuad ;
78import net .minecraft .client .renderer .block .model .ItemOverrides ;
@@ -40,7 +41,8 @@ public class DynamicBakedModelProvider implements Map<ResourceLocation, BakedMod
4041 public static DynamicBakedModelProvider currentInstance = null ;
4142 private final ModelBakery bakery ;
4243 private final Map <ModelBakery .BakedCacheKey , BakedModel > bakedCache ;
43- private final Map <ResourceLocation , BakedModel > permanentOverrides ;
44+ private volatile Map <ResourceLocation , BakedModel > permanentOverridesView = null ;
45+ private final Map <ResourceLocation , BakedModel > permanentOverridesMutable ;
4446 private BakedModel missingModel ;
4547 private static final BakedModel SENTINEL = new BakedModel () {
4648 @ Override
@@ -87,7 +89,7 @@ public ItemOverrides getOverrides() {
8789 public DynamicBakedModelProvider (ModelBakery bakery , Map <ModelBakery .BakedCacheKey , BakedModel > cache ) {
8890 this .bakery = bakery ;
8991 this .bakedCache = cache ;
90- this .permanentOverrides = Collections . synchronizedMap ( new Object2ObjectOpenHashMap <>() );
92+ this .permanentOverridesMutable = new Object2ObjectOpenHashMap <>();
9193 if (currentInstance == null )
9294 currentInstance = this ;
9395 }
@@ -110,14 +112,27 @@ public boolean isEmpty() {
110112 return bakedCache .isEmpty ();
111113 }
112114
115+ private Map <ResourceLocation , BakedModel > getPermanentOverrides () {
116+ Map <ResourceLocation , BakedModel > map = permanentOverridesView ;
117+ if (map == null ) {
118+ synchronized (this ) {
119+ map = permanentOverridesView ;
120+ if (map == null ) {
121+ permanentOverridesView = map = Object2ObjectMaps .unmodifiable (new Object2ObjectOpenHashMap <>(permanentOverridesMutable ));
122+ }
123+ }
124+ }
125+ return map ;
126+ }
127+
113128 @ Override
114129 public boolean containsKey (Object o ) {
115- return permanentOverrides .getOrDefault (o , SENTINEL ) != null ;
130+ return getPermanentOverrides () .getOrDefault (o , SENTINEL ) != null ;
116131 }
117132
118133 @ Override
119134 public boolean containsValue (Object o ) {
120- return permanentOverrides .containsValue (o ) || bakedCache .containsValue (o );
135+ return getPermanentOverrides () .containsValue (o ) || bakedCache .containsValue (o );
121136 }
122137
123138 private static boolean isVanillaTopLevelModel (ResourceLocation location ) {
@@ -143,7 +158,7 @@ private static boolean isVanillaTopLevelModel(ResourceLocation location) {
143158
144159 @ Override
145160 public BakedModel get (Object o ) {
146- BakedModel model = permanentOverrides .getOrDefault (o , SENTINEL );
161+ BakedModel model = getPermanentOverrides () .getOrDefault (o , SENTINEL );
147162 if (model != SENTINEL )
148163 return model ;
149164 else {
@@ -159,15 +174,19 @@ public BakedModel get(Object o) {
159174 if (model == missingModel ) {
160175 // to correctly emulate the original map, we return null for missing models, unless they are top-level
161176 model = isVanillaTopLevelModel ((ResourceLocation )o ) ? model : null ;
162- permanentOverrides .put ((ResourceLocation ) o , model );
177+ this .put ((ResourceLocation ) o , model );
163178 }
164179 return model ;
165180 }
166181 }
167182
168183 @ Override
169184 public BakedModel put (ResourceLocation resourceLocation , BakedModel bakedModel ) {
170- BakedModel m = permanentOverrides .put (resourceLocation , bakedModel );
185+ BakedModel m ;
186+ synchronized (this ) {
187+ m = permanentOverridesMutable .put (resourceLocation , bakedModel );
188+ permanentOverridesView = null ;
189+ }
171190 if (m != null )
172191 return m ;
173192 else
@@ -176,15 +195,22 @@ public BakedModel put(ResourceLocation resourceLocation, BakedModel bakedModel)
176195
177196 @ Override
178197 public BakedModel remove (Object o ) {
179- BakedModel m = permanentOverrides .remove (o );
198+ BakedModel m ;
199+ synchronized (this ) {
200+ m = permanentOverridesMutable .remove (o );
201+ permanentOverridesView = null ;
202+ }
180203 if (m != null )
181204 return m ;
182205 return bakedCache .remove (vanillaKey (o ));
183206 }
184207
185208 @ Override
186209 public void putAll (@ NotNull Map <? extends ResourceLocation , ? extends BakedModel > map ) {
187- permanentOverrides .putAll (map );
210+ synchronized (this ) {
211+ permanentOverridesMutable .putAll (map );
212+ permanentOverridesView = null ;
213+ }
188214 }
189215
190216 @ Override
@@ -213,23 +239,27 @@ public Set<Entry<ResourceLocation, BakedModel>> entrySet() {
213239 @ Nullable
214240 @ Override
215241 public BakedModel replace (ResourceLocation key , BakedModel value ) {
216- BakedModel existingOverride = permanentOverrides .get (key );
217- // as long as no valid override was put in (null can mean unable to load model, so we treat as invalid), replace
218- // the model
219- if (existingOverride == null )
220- return this .put (key , value );
221- else
222- return existingOverride ;
242+ synchronized (this ) {
243+ BakedModel existingOverride = permanentOverridesMutable .get (key );
244+ // as long as no valid override was put in (null can mean unable to load model, so we treat as invalid), replace
245+ // the model
246+ if (existingOverride == null )
247+ return this .put (key , value );
248+ else
249+ return existingOverride ;
250+ }
223251 }
224252
225253 @ Override
226254 public void replaceAll (BiFunction <? super ResourceLocation , ? super BakedModel , ? extends BakedModel > function ) {
227- Set <ResourceLocation > overridenLocations = permanentOverrides .keySet ();
228- permanentOverrides .replaceAll (function );
255+ synchronized (this ) {
256+ permanentOverridesMutable .replaceAll (function );
257+ permanentOverridesView = null ;
258+ }
229259 boolean uvLock = BlockModelRotation .X0_Y0 .isUvLocked ();
230260 Transformation rotation = BlockModelRotation .X0_Y0 .getRotation ();
231261 bakedCache .replaceAll ((loc , oldModel ) -> {
232- if (loc .transformation () != rotation || loc .isUvLocked () != uvLock || overridenLocations . contains (loc .id ()))
262+ if (loc .transformation () != rotation || loc .isUvLocked () != uvLock || getPermanentOverrides (). containsKey (loc .id ()))
233263 return oldModel ;
234264 else
235265 return function .apply (loc .id (), oldModel );
0 commit comments