com.artemis.io.EntitySerializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of artemis-odb-serializer-json Show documentation
Show all versions of artemis-odb-serializer-json Show documentation
Fork of Artemis Entity System Framework.
package com.artemis.io;
import com.artemis.*;
import com.artemis.annotations.Transient;
import com.artemis.annotations.Wire;
import com.artemis.components.SerializationTag;
import com.artemis.managers.GroupManager;
import com.artemis.managers.TagManager;
import com.artemis.utils.Bag;
import com.artemis.utils.ImmutableBag;
import com.esotericsoftware.jsonbeans.Json;
import com.esotericsoftware.jsonbeans.JsonSerializer;
import com.esotericsoftware.jsonbeans.JsonValue;
import com.esotericsoftware.jsonbeans.ObjectMap;
import java.util.*;
@Wire(failOnNull = false)
public class EntitySerializer implements JsonSerializer {
private final Bag components = new Bag();
private final ComponentNameComparator comparator = new ComponentNameComparator();
private final World world;
private final ReferenceTracker referenceTracker;
private GroupManager groupManager;
private TagManager tagManager;
private final Collection registeredTags;
private final ObjectMap> componentClasses;
private boolean isSerializingEntity;
private ComponentMapper saveTagMapper;
SerializationKeyTracker keyTracker;
Map> types = new HashMap>();
private IdentityHashMap, String> lookupMap;
public EntitySerializer(World world, ReferenceTracker referenceTracker) {
this.world = world;
this.referenceTracker = referenceTracker;
world.inject(this);
componentClasses = new ObjectMap>();
registeredTags = (tagManager != null)
? tagManager.getRegisteredTags()
: Collections.EMPTY_LIST;
}
void preLoad() {
keyTracker = new SerializationKeyTracker();
}
void preWrite(SaveFileFormat save) {
lookupMap = save.componentIdentifiers;
}
@Override
public void write(Json json, Entity e, Class knownType) {
// need to track this in case the components of an entity
// reference another entity - if so, we only want to record
// the id
if (isSerializingEntity) {
json.writeValue(e.getId());
return;
} else {
isSerializingEntity = true;
}
world.getComponentManager().getComponentsFor(e.getId(), components);
components.sort(comparator);
json.writeObjectStart();
writeTag(json, e);
writeKeyTag(json, e);
writeGroups(json, e);
json.writeObjectStart("components");
for (int i = 0, s = components.size(); s > i; i++) {
Component c = components.get(i);
if (c.getClass().getAnnotation(Transient.class) != null)
continue;
String componentIdentifier = lookupMap.get(c.getClass());
json.writeObjectStart(componentIdentifier);
json.writeFields(c);
json.writeObjectEnd();
}
json.writeObjectEnd();
json.writeObjectEnd();
components.clear();
isSerializingEntity = false;
}
private ComponentLookupSerializer componentLookup(Json json) {
return (ComponentLookupSerializer) json.getSerializer(IdentityHashMap.class);
}
private void writeTag(Json json, Entity e) {
for (String tag : registeredTags) {
if (tagManager.getEntity(tag) != e)
continue;
json.writeValue("tag", tag);
break;
}
}
private void writeKeyTag(Json json, Entity e) {
if (saveTagMapper.has(e)) {
String key = saveTagMapper.get(e).tag;
if (key != null)
json.writeValue("key", key);
}
}
private void writeGroups(Json json, Entity e) {
if (groupManager == null)
return;
ImmutableBag groups = groupManager.getGroups(e);
if (groups.size() == 0)
return;
json.writeArrayStart("groups");
for (String group : groups) {
json.writeValue(group);
}
json.writeArrayEnd();
}
@Override
public Entity read(Json json, JsonValue jsonData, Class type) {
// need to track this in case the components of an entity
// reference another entity - if so, we only want to read
// the id
if (isSerializingEntity) {
int entityId = json.readValue(Integer.class, jsonData);
// creating a temporary entity; this will later be translated
// to the correct entity
return FakeEntityFactory.create(world, entityId);
} else {
isSerializingEntity = true;
}
Entity e = world.createEntity();
jsonData = readTag(jsonData, e);
jsonData = readKeyTag(jsonData, e);
jsonData = readGroups(jsonData, e);
// when we deserialize a single entity
if (!"components".equals(jsonData.name()))
jsonData = jsonData.child;
assert("components".equals(jsonData.name));
JsonValue component = jsonData.child;
EntityEdit edit = e.edit();
while (component != null) {
assert(component.name() != null);
Class extends Component> componentType = types.get(component.name);
Component c = edit.create(componentType);
json.readFields(c, component);
// if component contains entity references, add
// entity reference operations
referenceTracker.addEntityReferencingComponent(c);
component = component.next;
}
isSerializingEntity = false;
return edit.getEntity();
}
private JsonValue readGroups(JsonValue jsonData, Entity e) {
if ("groups".equals(jsonData.name)) {
JsonValue group = jsonData.child;
while (group != null) {
groupManager.add(e, group.asString());
group = group.next;
}
jsonData = jsonData.next;
}
return jsonData;
}
private JsonValue readTag(JsonValue jsonData, Entity e) {
if ("tag".equals(jsonData.name)) {
tagManager.register(jsonData.asString(), e);
jsonData = jsonData.next;
}
return jsonData;
}
private JsonValue readKeyTag(JsonValue jsonData, Entity e) {
if ("key".equals(jsonData.name)) {
String key = jsonData.asString();
keyTracker.register(key, e);
saveTagMapper.create(e).tag = key;
jsonData = jsonData.next;
}
return jsonData;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy