1
0
mirror of https://github.com/openeggbert/sprite-utils.git synced 2025-03-14 23:33:28 +01:00

Refactoring

This commit is contained in:
Robert Vokac 2024-07-30 18:27:21 +02:00
parent f0921bd31b
commit ac1db49e01
No known key found for this signature in database
GPG Key ID: C459E1E4B4A986BB
3 changed files with 115 additions and 88 deletions

View File

@ -10,7 +10,7 @@
N: Robert Vokac
E: mail@robertvokac.com
W: https://nanoboot.org
P: 4096R/E3329055 322B D109 0AA8 C324 EA9C 72F5 693D 30BE E332 9055
W: https://robertvokac.com
P: 4096R/C459E1E4 B209 C3F1 25C7 2618 FB18 AC8E C459 E1E4 B4A9 86BB
D: Founder
S: Czech Republic

View File

@ -1,7 +1,22 @@
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
///////////////////////////////////////////////////////////////////////////////////////////////
// sprite-utils: Tool used to work with sprites
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package org.nanoboot.spriteutils.core;
import java.io.File;
@ -9,6 +24,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.Data;
import lombok.ToString;
@ -29,83 +45,93 @@ public class SpriteSheet {
public SpriteSheet(File file) {
List<SpriteSheetRow> rows = new ArrayList<>();
String text = Utils.readTextFromFile(file);
text.lines().skip(1).takeWhile(l->!l.contains("skipskip"))
text.lines().skip(1).takeWhile(l -> !l.contains("skipskip"))
.forEach(l -> {
final SpriteSheetRow spriteSheetRow = new SpriteSheetRow(l);
processLine(l, rows);
});
saveComputedFile(file, text, rows);
if (lastSpriteSheetRow != null) {
if (!spriteSheetRow.file.equals(lastSpriteSheetRow.file)) {
lastSpriteSheetRow = null;
}
}
if (lastSpriteSheetRow == null) {
spriteSheetRow.numberPerSheet = 1;
if (spriteSheetRow.getRow() != 1) {
String msg = "Row of the first sprite in file must be equal to 1, but value for file " + spriteSheetRow.file + " is " + spriteSheetRow.getRow();
throw new SpriteUtilsException(msg);
}
if (spriteSheetRow.getColumn() != 1) {
String msg = "Column of the first sprite in file must be equal to 1, but value for file " + spriteSheetRow.file + " is " + spriteSheetRow.getColumn();
throw new SpriteUtilsException(msg);
}
}
} else {
spriteSheetRow.numberPerSheet = lastSpriteSheetRow.numberPerSheet + 1;
if(spriteSheetRow.row > lastSpriteSheetRow.row) {
if(spriteSheetRow.row != (lastSpriteSheetRow.row + 1)) {
throw new SpriteUtilsException("Unexpected row for " + spriteSheetRow.createId());
}
}
if(spriteSheetRow.row < lastSpriteSheetRow.row) {
throw new SpriteUtilsException("Unexpected row for " + spriteSheetRow.createId());
}
if(spriteSheetRow.row == lastSpriteSheetRow.row) {
if(spriteSheetRow.column != (lastSpriteSheetRow.column + 1))
throw new SpriteUtilsException("Unexpected column for " + spriteSheetRow.createId());
}
}
rows.add(spriteSheetRow);
if (!map.containsKey(spriteSheetRow.file)) {
map.put(spriteSheetRow.file, new ArrayList<>());
}
map.get(spriteSheetRow.file).add(spriteSheetRow);
if (spriteSheetRow.x == -1) {
if (spriteSheetRow.column == 1) {
spriteSheetRow.x = 0;
} else {
if (lastX == -1) {
throw new SpriteUtilsException("Could not compute X for " + spriteSheetRow.createId());
} else {
spriteSheetRow.x = lastX + lastWidth;
}
}
}
lastX = spriteSheetRow.getX();
lastWidth = spriteSheetRow.getWidth();
if (spriteSheetRow.height <= 0) {
if (lastHeight == -1) {
throw new SpriteUtilsException("Could not compute height for " + spriteSheetRow.createId());
} else {
spriteSheetRow.height = lastHeight + ((-1) * spriteSheetRow.height);
}
}
lastHeight = spriteSheetRow.height;
lastSpriteSheetRow = spriteSheetRow;
System.out.println(spriteSheetRow.toCsvLine());
});
private void saveComputedFile(File file, String text, List<SpriteSheetRow> rows) {
File computed = new File(file.getAbsolutePath() + ".computed.csv");
if(computed.exists()){
if (computed.exists()) {
computed.delete();
}
StringBuilder sb = new StringBuilder(text.lines().limit(1).findFirst().orElse(""));
sb.append("\n");
rows.stream().forEach(r-> {
sb.append(r.toCsvLine()).append("\n");
rows.stream().forEach(r -> {
sb.append(r.toCsvLine()).append("\n");
});
Utils.writeTextToFile(sb.toString(), computed);
}
private void processLine(String line, List<SpriteSheetRow> rows) throws SpriteUtilsException {
final SpriteSheetRow spriteSheetRow = new SpriteSheetRow(line);
validateRow(spriteSheetRow);
updateSpriteSheetRow(spriteSheetRow);
rows.add(spriteSheetRow);
updateMap(spriteSheetRow);
System.out.println(spriteSheetRow.toCsvLine());
}
private void updateSpriteSheetRow(final SpriteSheetRow spriteSheetRow) {
if (spriteSheetRow.x == -1) {
spriteSheetRow.x = (spriteSheetRow.column == 1) ? 0
: Optional.of(lastX == -1 ? null : (lastX + lastWidth)).orElseThrow(() -> new SpriteUtilsException("Could not compute X for " + spriteSheetRow.createId()));
}
lastX = spriteSheetRow.getX();
lastWidth = spriteSheetRow.getWidth();
if (spriteSheetRow.height <= 0) {
spriteSheetRow.height = Optional.of((lastHeight != -1) ? (lastHeight + (-spriteSheetRow.height)) : null).orElseThrow(() -> new SpriteUtilsException("Could not compute height for " + spriteSheetRow.createId()));
}
lastHeight = spriteSheetRow.height;
lastSpriteSheetRow = spriteSheetRow;
}
private void updateMap(final SpriteSheetRow spriteSheetRow) {
if (!map.containsKey(spriteSheetRow.file)) {
map.put(spriteSheetRow.file, new ArrayList<>());
}
map.get(spriteSheetRow.file).add(spriteSheetRow);
}
private void validateRow(final SpriteSheetRow spriteSheetRow) {
if (lastSpriteSheetRow != null) {
if (!spriteSheetRow.file.equals(lastSpriteSheetRow.file)) {
lastSpriteSheetRow = null;
}
}
if (lastSpriteSheetRow == null) {
validateFirstRow(spriteSheetRow);
} else {
validateSubsequentRow(spriteSheetRow);
}
}
private void validateSubsequentRow(SpriteSheetRow spriteSheetRow) {
spriteSheetRow.numberPerSheet = lastSpriteSheetRow.numberPerSheet + 1;
if (spriteSheetRow.row > lastSpriteSheetRow.row) {
if (spriteSheetRow.row != (lastSpriteSheetRow.row + 1)) {
throw new SpriteUtilsException("Unexpected row for " + spriteSheetRow.createId());
}
} else if (spriteSheetRow.row < lastSpriteSheetRow.row) {
throw new SpriteUtilsException("Unexpected row for " + spriteSheetRow.createId());
} else if (spriteSheetRow.column != (lastSpriteSheetRow.column + 1)) {
throw new SpriteUtilsException("Unexpected column for " + spriteSheetRow.createId());
}
}
private void validateFirstRow(SpriteSheetRow spriteSheetRow) {
if (spriteSheetRow.getRow() != 1 || spriteSheetRow.getColumn() != 1) {
throw new SpriteUtilsException("Invalid initial row or column for file " + spriteSheetRow.file);
}
spriteSheetRow.numberPerSheet = 1;
}
public List<SpriteSheetRow> getSpriteSheets(String file) {

View File

@ -17,13 +17,11 @@
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package org.nanoboot.spriteutils.core;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Data;
import lombok.ToString;
@ -50,19 +48,21 @@ public class SpriteSheetRow {
public SpriteSheetRow(String csvLine) {
String[] csvColumn = csvLine.split(";");
if (csvColumn.length < 10) {
throw new IllegalArgumentException("CSV line does not contain enough (10) columns.");
}
int i = 0;
file = csvColumn[i++];
group = csvColumn[i++];
numberInGroup = Integer.valueOf(csvColumn[i++]);
row = Integer.valueOf(csvColumn[i++]);
column = Integer.valueOf(csvColumn[i++]);
String xString = csvColumn[i++];
x = xString.isBlank() ? -1 : Integer.valueOf(xString);
y = Integer.valueOf(csvColumn[i++]);
width = Integer.valueOf(csvColumn[i++]);
height = Integer.valueOf(csvColumn[i++]);
numberInGroup = Integer.parseInt(csvColumn[i++]);
row = Integer.parseInt(csvColumn[i++]);
column = Integer.parseInt(csvColumn[i++]);
x = csvColumn[i++].isBlank() ? -1 : Integer.parseInt(csvColumn[i - 1]);
y = Integer.parseInt(csvColumn[i++]);
width = Integer.parseInt(csvColumn[i++]);
height = Integer.parseInt(csvColumn[i++]);
if (column > 1) {
height = height * (-1);
height = -height;
}
notes = csvColumn.length >= 10 ? csvColumn[i++] : "";
tags = csvColumn.length > 11 ? csvColumn[i++] : "";
@ -72,9 +72,10 @@ public class SpriteSheetRow {
return file + __ + group + __ + numberInGroup;
}
private static final String __ = "__";
private static final String DELIMITER = ";";
public String toCsvLine() {
List<String> l = Stream.of(
List<String> fields = Arrays.asList(
file,
group,
String.valueOf(numberInGroup),
@ -86,9 +87,9 @@ public class SpriteSheetRow {
String.valueOf(height),
notes,
tags,
String.valueOf(numberPerSheet)).toList();
return l.stream().collect(Collectors.joining(";"));
String.valueOf(numberPerSheet)
);
return String.join(DELIMITER, fields);
}
}