Fix texture-gallery not preserving textures that are missing after a resource(pack) change

This commit is contained in:
Lukas Rieger (Blue) 2023-12-11 12:35:12 +01:00
parent ef728dee06
commit a0b47f1bd5
No known key found for this signature in database
GPG Key ID: 2D09EC5ED2687FF2
2 changed files with 46 additions and 19 deletions

View File

@ -181,7 +181,7 @@ public class BmMap {
private void saveTextureGallery() {
try (OutputStream out = storage.writeMeta(id, META_FILE_TEXTURES)) {
this.textureGallery.writeTexturesFile(this.resourcePack, out);
this.textureGallery.writeTexturesFile(out);
} catch (IOException ex) {
Logger.global.logError("Failed to save textures for map '" + getId() + "'!", ex);
}

View File

@ -42,49 +42,53 @@ import java.util.Map;
@DebugDump
public class TextureGallery {
private final Map<ResourcePath<Texture>, Integer> ordinalMap;
private final Map<ResourcePath<Texture>, TextureMapping> textureMappings;
private int nextId;
public TextureGallery() {
this.ordinalMap = new HashMap<>();
this.textureMappings = new HashMap<>();
this.nextId = 0;
}
public void clear() {
this.ordinalMap.clear();
this.textureMappings.clear();
this.nextId = 0;
}
public int get(@Nullable ResourcePath<Texture> textureResourcePath) {
if (textureResourcePath == null) textureResourcePath = ResourcePack.MISSING_TEXTURE;
Integer ordinal = ordinalMap.get(textureResourcePath);
return ordinal != null ? ordinal : 0;
TextureMapping mapping = textureMappings.get(textureResourcePath);
return mapping != null ? mapping.getId() : 0;
}
public synchronized int put(ResourcePath<Texture> textureResourcePath) {
Integer ordinal = ordinalMap.putIfAbsent(textureResourcePath, nextId);
if (ordinal == null) return nextId++;
return ordinal;
public synchronized void put(ResourcePath<Texture> textureResourcePath) {
textureMappings.compute(textureResourcePath, (r, mapping) -> {
if (mapping == null)
return new TextureMapping(nextId++, textureResourcePath.getResource());
Texture texture = textureResourcePath.getResource();
if (texture != null) mapping.setTexture(texture);
return mapping;
});
}
public synchronized void put(ResourcePack resourcePack) {
this.put(ResourcePack.MISSING_TEXTURE); // put this first
resourcePack.getTextures().keySet()
.stream()
.sorted(Comparator.comparing(Key::getFormatted))
.forEach(this::put);
}
public void writeTexturesFile(ResourcePack resourcePack, OutputStream out) throws IOException {
public void writeTexturesFile(OutputStream out) throws IOException {
Texture[] textures = new Texture[nextId];
Arrays.fill(textures, Texture.MISSING);
ordinalMap.forEach((textureResourcePath, ordinal) -> {
Texture texture = textureResourcePath.getResource(resourcePack::getTexture);
if (texture != null) textures[ordinal] = texture;
// make sure the resource-path doesn't get lost
if (textures[ordinal].getResourcePath().equals(ResourcePack.MISSING_TEXTURE))
textures[ordinal] = Texture.missing(textureResourcePath);
this.textureMappings.forEach((textureResourcePath, mapping) -> {
int ordinal = mapping.getId();
Texture texture = mapping.getTexture();
if (texture == null) texture = Texture.missing(textureResourcePath);
textures[ordinal] = texture;
});
try (Writer writer = new OutputStreamWriter(out)) {
@ -103,7 +107,7 @@ public class TextureGallery {
for (int ordinal = 0; ordinal < textures.length; ordinal++) {
Texture texture = textures[ordinal];
if (texture != null) {
gallery.ordinalMap.put(texture.getResourcePath(), ordinal);
gallery.textureMappings.put(texture.getResourcePath(), new TextureMapping(ordinal, texture));
}
}
} catch (JsonIOException ex) {
@ -112,4 +116,27 @@ public class TextureGallery {
return gallery;
}
static class TextureMapping {
private final int id;
private @Nullable Texture texture;
public TextureMapping(int id, @Nullable Texture texture) {
this.id = id;
this.texture = texture;
}
public int getId() {
return id;
}
public @Nullable Texture getTexture() {
return texture;
}
public void setTexture(@Nullable Texture texture) {
this.texture = texture;
}
}
}