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() { private void saveTextureGallery() {
try (OutputStream out = storage.writeMeta(id, META_FILE_TEXTURES)) { try (OutputStream out = storage.writeMeta(id, META_FILE_TEXTURES)) {
this.textureGallery.writeTexturesFile(this.resourcePack, out); this.textureGallery.writeTexturesFile(out);
} catch (IOException ex) { } catch (IOException ex) {
Logger.global.logError("Failed to save textures for map '" + getId() + "'!", ex); Logger.global.logError("Failed to save textures for map '" + getId() + "'!", ex);
} }

View File

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