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 ;
@@ -39,7 +40,8 @@ public class DynamicBakedModelProvider implements Map<ResourceLocation, BakedMod
3940 public static DynamicBakedModelProvider currentInstance = null ;
4041 private final ModelBakery bakery ;
4142 private final Map <Triple <ResourceLocation , Transformation , Boolean >, BakedModel > bakedCache ;
42- private final Map <ResourceLocation , BakedModel > permanentOverrides ;
43+ private volatile Map <ResourceLocation , BakedModel > permanentOverridesView = null ;
44+ private final Map <ResourceLocation , BakedModel > permanentOverridesMutable ;
4345 private BakedModel missingModel ;
4446 private static final BakedModel SENTINEL = new BakedModel () {
4547 @ Override
@@ -86,7 +88,7 @@ public ItemOverrides getOverrides() {
8688 public DynamicBakedModelProvider (ModelBakery bakery , Map <Triple <ResourceLocation , Transformation , Boolean >, BakedModel > cache ) {
8789 this .bakery = bakery ;
8890 this .bakedCache = cache ;
89- this .permanentOverrides = Collections . synchronizedMap ( new Object2ObjectOpenHashMap <>() );
91+ this .permanentOverridesMutable = new Object2ObjectOpenHashMap <>();
9092 if (currentInstance == null )
9193 currentInstance = this ;
9294 }
@@ -108,14 +110,27 @@ public boolean isEmpty() {
108110 return bakedCache .isEmpty ();
109111 }
110112
113+ private Map <ResourceLocation , BakedModel > getPermanentOverrides () {
114+ Map <ResourceLocation , BakedModel > map = permanentOverridesView ;
115+ if (map == null ) {
116+ synchronized (this ) {
117+ map = permanentOverridesView ;
118+ if (map == null ) {
119+ permanentOverridesView = map = Object2ObjectMaps .unmodifiable (new Object2ObjectOpenHashMap <>(permanentOverridesMutable ));
120+ }
121+ }
122+ }
123+ return map ;
124+ }
125+
111126 @ Override
112127 public boolean containsKey (Object o ) {
113- return permanentOverrides .getOrDefault (o , SENTINEL ) != null ;
128+ return getPermanentOverrides () .getOrDefault (o , SENTINEL ) != null ;
114129 }
115130
116131 @ Override
117132 public boolean containsValue (Object o ) {
118- return permanentOverrides .containsValue (o ) || bakedCache .containsValue (o );
133+ return getPermanentOverrides () .containsValue (o ) || bakedCache .containsValue (o );
119134 }
120135
121136 private static boolean isVanillaTopLevelModel (ResourceLocation location ) {
@@ -141,7 +156,7 @@ private static boolean isVanillaTopLevelModel(ResourceLocation location) {
141156
142157 @ Override
143158 public BakedModel get (Object o ) {
144- BakedModel model = permanentOverrides .getOrDefault (o , SENTINEL );
159+ BakedModel model = getPermanentOverrides () .getOrDefault (o , SENTINEL );
145160 if (model != SENTINEL )
146161 return model ;
147162 else {
@@ -157,15 +172,19 @@ public BakedModel get(Object o) {
157172 if (model == missingModel ) {
158173 // to correctly emulate the original map, we return null for missing models, unless they are top-level
159174 model = isVanillaTopLevelModel ((ResourceLocation )o ) ? model : null ;
160- permanentOverrides .put ((ResourceLocation ) o , model );
175+ this .put ((ResourceLocation ) o , model );
161176 }
162177 return model ;
163178 }
164179 }
165180
166181 @ Override
167182 public BakedModel put (ResourceLocation resourceLocation , BakedModel bakedModel ) {
168- BakedModel m = permanentOverrides .put (resourceLocation , bakedModel );
183+ BakedModel m ;
184+ synchronized (this ) {
185+ m = permanentOverridesMutable .put (resourceLocation , bakedModel );
186+ permanentOverridesView = null ;
187+ }
169188 if (m != null )
170189 return m ;
171190 else
@@ -174,15 +193,22 @@ public BakedModel put(ResourceLocation resourceLocation, BakedModel bakedModel)
174193
175194 @ Override
176195 public BakedModel remove (Object o ) {
177- BakedModel m = permanentOverrides .remove (o );
196+ BakedModel m ;
197+ synchronized (this ) {
198+ m = permanentOverridesMutable .remove (o );
199+ permanentOverridesView = null ;
200+ }
178201 if (m != null )
179202 return m ;
180203 return bakedCache .remove (vanillaKey (o ));
181204 }
182205
183206 @ Override
184207 public void putAll (@ NotNull Map <? extends ResourceLocation , ? extends BakedModel > map ) {
185- permanentOverrides .putAll (map );
208+ synchronized (this ) {
209+ permanentOverridesMutable .putAll (map );
210+ permanentOverridesView = null ;
211+ }
186212 }
187213
188214 @ Override
@@ -211,23 +237,27 @@ public Set<Entry<ResourceLocation, BakedModel>> entrySet() {
211237 @ Nullable
212238 @ Override
213239 public BakedModel replace (ResourceLocation key , BakedModel value ) {
214- BakedModel existingOverride = permanentOverrides .get (key );
215- // as long as no valid override was put in (null can mean unable to load model, so we treat as invalid), replace
216- // the model
217- if (existingOverride == null )
218- return this .put (key , value );
219- else
220- return existingOverride ;
240+ synchronized (this ) {
241+ BakedModel existingOverride = permanentOverridesMutable .get (key );
242+ // as long as no valid override was put in (null can mean unable to load model, so we treat as invalid), replace
243+ // the model
244+ if (existingOverride == null )
245+ return this .put (key , value );
246+ else
247+ return existingOverride ;
248+ }
221249 }
222250
223251 @ Override
224252 public void replaceAll (BiFunction <? super ResourceLocation , ? super BakedModel , ? extends BakedModel > function ) {
225- Set <ResourceLocation > overridenLocations = permanentOverrides .keySet ();
226- permanentOverrides .replaceAll (function );
253+ synchronized (this ) {
254+ permanentOverridesMutable .replaceAll (function );
255+ permanentOverridesView = null ;
256+ }
227257 boolean uvLock = BlockModelRotation .X0_Y0 .isUvLocked ();
228258 Transformation rotation = BlockModelRotation .X0_Y0 .getRotation ();
229259 bakedCache .replaceAll ((loc , oldModel ) -> {
230- if (loc .getMiddle () != rotation || loc .getRight () != uvLock || overridenLocations . contains (loc .getLeft ()))
260+ if (loc .getMiddle () != rotation || loc .getRight () != uvLock || getPermanentOverrides (). containsKey (loc .getLeft ()))
231261 return oldModel ;
232262 else
233263 return function .apply (loc .getLeft (), oldModel );
0 commit comments