Closed bryanbrunt closed 3 years ago
However, if you have a component like below with an int index = 0, then the serializer will not serialize the component. The serializer essentially deletes this data.
Any default-valued primitive fields (and string fields) are omitted from the json as they're set to the default value automatically upon instantiating the component.
@Test
public void save_component_with_default_values() throws Exception {
int defaultIndex = 0;
int customIndex = 4;
EntityEdit ee1 = world.createEntity().edit();
ee1.create(InventoryPosition.class).index = defaultIndex; // default value
ee1.create(SerializationTag.class).tag = "field with default value";
EntityEdit ee2 = world.createEntity().edit();
ee2.create(InventoryPosition.class).index = customIndex; // custom value
ee2.create(SerializationTag.class).tag = "field with custom value";
world.process();
EntitySubscription inventories = subscriptions.get(all(InventoryPosition.class));
String json = save(inventories, wsm);
deleteAll();
ByteArrayInputStream is = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
SaveFileFormat l = wsm.load(is, SaveFileFormat.class);
world.process();
assertEquals(2, inventories.getEntities().size());
assertEquals(defaultIndex, l.get("field with default value")
.getComponent(InventoryPosition.class).index);
assertEquals(customIndex, l.get("field with custom value")
.getComponent(InventoryPosition.class).index);
}
The saved json looks as follows:
{
"metadata": {
"version": 1
},
"componentIdentifiers": {
"com.artemis.component.InventoryPosition": "InventoryPosition"
},
"entities": {
"3": {
"archetype": 9,
"key": "field with default value",
"components": {}
},
"4": {
"archetype": 9,
"key": "field with custom value",
"components": {
"InventoryPosition": {
"index": 4
}
}
}
},
"archetypes": {
"9": [
"InventoryPosition"
]
}
}
Both entities point to the same archetype 9 (the archetype is the same as the compositionId), which contains the InventoryPosition
component.
If you're processing the json in something external, where default values aren't known, there's always:
// don't omit default-valued fields
((JsonArtemisSerializer) wsm.getSerializer()).setUsePrototypes(false);
A workaround has been provided. Closing as answered.
JsonArtemisSerializer just doesn't serialize int and boolean fields on components that are 0 and false.
Why?
The potentially counter argument against serializing these zero and false primitive fields is that when those fields de-serialize they will be set to zero and false anyway.
However, if you have a component like below with an int index = 0, then the serializer will not serialize the component. The serializer essentially deletes this data.
When you go to deserialize, the component doesn't exist.
This is a loss of data issue. An index of 0 for this component is possibly valid.
public class InventoryPosition extends Component { public int index; }