Skip to content
This repository was archived by the owner on Mar 15, 2024. It is now read-only.

Commit 9a86961

Browse files
committed
Added JSON serializer post-load and pre-save hooks.
1 parent 2d8e4b9 commit 9a86961

File tree

5 files changed

+72
-11
lines changed

5 files changed

+72
-11
lines changed

src/main/java/com/badlogic/gdx/json/AnnotatedJson.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import com.badlogic.gdx.utils.Json;
66
import com.badlogic.gdx.utils.JsonWriter;
77

8-
import java.io.IOException;
8+
import java.io.*;
99
import java.util.function.Consumer;
1010
import java.util.function.Predicate;
1111

@@ -15,24 +15,32 @@
1515
*/
1616
public class AnnotatedJson {
1717

18-
public static <T> T read(FileHandle path, Class<T> clazz, Consumer<Json> setupJson) throws IOException {
18+
public static <T> Json newReader(Class<T> clazz, Consumer<Json> setupJson) {
1919

2020
Json json = new Json();
21-
2221
json.setSerializer(clazz, new AnnotatedJsonSerializer<>(json, clazz));
2322

2423
if (setupJson != null) {
2524
setupJson.accept(json);
2625
}
2726

27+
return json;
28+
}
29+
30+
public static <T> T read(FileHandle path, Class<T> clazz, Consumer<Json> setupJson) throws IOException {
31+
Json json = newReader(clazz, setupJson);
32+
return read(path, clazz, json);
33+
}
34+
35+
public static <T> T read(FileHandle path, Class<T> clazz, Json json) throws IOException {
2836
try {
2937
return json.fromJson(clazz, path);
3038
} catch (RuntimeException e) {
3139
throw new IOException(e);
3240
}
3341
}
3442

35-
public static <T> void write(FileHandle path, T object, Class<T> clazz, Consumer<Json> setupJson) {
43+
public static <T> Json newWriter(Class<T> clazz, Consumer<Json> setupJson) {
3644

3745
Json json = new Json(JsonWriter.OutputType.json);
3846
json.setSerializer(clazz, new AnnotatedJsonSerializer<>(json, clazz));
@@ -41,10 +49,25 @@ public static <T> void write(FileHandle path, T object, Class<T> clazz, Consumer
4149
setupJson.accept(json);
4250
}
4351

52+
return json;
53+
}
54+
55+
public static <T> void write(FileHandle path, T object, Class<T> clazz, Consumer<Json> setupJson) throws IOException {
56+
Json json = newWriter(clazz, setupJson);
57+
write(path, object, json);
58+
}
59+
60+
public static <T> void write(FileHandle path, T object, Json json) throws IOException {
61+
4462
String output = json.toJson(object);
4563
String prettyOutput = json.prettyPrint(output);
4664

47-
path.writeString(prettyOutput, false, "UTF-8");
65+
try (FileOutputStream fos = new FileOutputStream(path.file(), false)) {
66+
try (Writer writer = new OutputStreamWriter(fos, "UTF-8")) {
67+
writer.write(prettyOutput);
68+
writer.flush();
69+
}
70+
}
4871
}
4972

5073
/**
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.badlogic.gdx.json;
2+
3+
/**
4+
* Optional interface to customize JSON serialization. Classes annotated with
5+
* {@link com.badlogic.gdx.json.annotations.JsonSerializable} can implement this
6+
* interface to hook into the serialization process.
7+
*/
8+
public interface AnnotatedJsonObject {
9+
10+
/**
11+
* This function is called <i>before</i> writing the annotated object.
12+
*/
13+
void onJsonWrite();
14+
15+
/**
16+
* This function is called <i>after</i> reading the annotated object.
17+
*/
18+
void onJsonRead();
19+
20+
}

src/main/java/com/badlogic/gdx/json/AnnotatedJsonSerializer.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ public AnnotatedJsonSerializer(Json json, Class<T> clazz) {
7373
@Override
7474
public void write(Json json, T object, Class knownType) {
7575

76+
if (AnnotatedJsonObject.class.isAssignableFrom(clazz)) {
77+
((AnnotatedJsonObject) object).onJsonWrite();
78+
}
79+
7680
json.writeObjectStart();
7781

7882
if (annotation.dynamic()) {
@@ -266,6 +270,10 @@ public T read(Json json, JsonValue jsonData, Class type) {
266270
}
267271
}
268272

273+
if (AnnotatedJsonObject.class.isAssignableFrom(clazz)) {
274+
((AnnotatedJsonObject) object).onJsonRead();
275+
}
276+
269277
return object;
270278

271279
} catch (ReflectionException | ClassNotFoundException e) {
@@ -308,7 +316,21 @@ private void readObject(Json json, JsonValue jsonData, T object, FieldAdapter ad
308316
value = JsonFloatSerializer.decodeDoubleBits(
309317
json.readValue(accessible.getName(), String.class, jsonData), accessible.get(object));
310318
} else {
311-
value = json.readValue(accessible.getName(), fieldType, componentType, jsonData);
319+
try {
320+
value = json.readValue(accessible.getName(), fieldType, componentType, jsonData);
321+
} catch (SerializationException e) {
322+
// attempt to load again, using bit decoder - this allows loading of existing
323+
// data after an encodeFP() annotation property has been removed
324+
if (fieldType.equals(float.class)) {
325+
value = JsonFloatSerializer.decodeFloatBits(
326+
json.readValue(accessible.getName(), String.class, jsonData), accessible.get(object));
327+
} else if (fieldType.equals(double.class)) {
328+
value = JsonFloatSerializer.decodeDoubleBits(
329+
json.readValue(accessible.getName(), String.class, jsonData), accessible.get(object));
330+
} else {
331+
throw new SerializationException(e);
332+
}
333+
}
312334
}
313335

314336
if (value == null) {

src/main/java/com/badlogic/gdx/json/JsonArraySerializer.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
* Implementation of {@link com.badlogic.gdx.utils.Json.Serializer} to serialize {@link Array} containers.
99
*
1010
* This is used internally by {@link AnnotatedJsonSerializer}.
11-
*
12-
* @see {@link AnnotatedJsonSerializer}
1311
*/
1412
class JsonArraySerializer<V> implements Json.Serializer<Array<?>> {
1513

src/main/java/com/badlogic/gdx/json/JsonMapSerializer.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
* Implementation of {@link com.badlogic.gdx.utils.Json.Serializer} to serialize {@link Map} containers.
1111
*
1212
* This is used internally by {@link AnnotatedJsonSerializer}.
13-
*
14-
* @see {@link AnnotatedJsonSerializer}
1513
*/
1614
class JsonMapSerializer<K, V> implements Json.Serializer<Iterable<?>> {
1715

@@ -81,7 +79,7 @@ public Iterable<?> read(Json json, JsonValue jsonData, Class type) {
8179
return values;
8280
}
8381

84-
public interface KeyValueConsumer<M, K, V> {
82+
interface KeyValueConsumer<M, K, V> {
8583
void accept(M map, K key, V value);
8684
}
8785

0 commit comments

Comments
 (0)