I've trying to encode all @Exposed variables inside a class as a ModelArrayCodec, but right now it's only saving @Exposed integers. I've added a test to the Skill class which added additional @Exposed integers and those are also saving. However, the doubles and strings are not saving. Any ideas on what I'm doing wrong?
ModelArrayCodec Class:
public class ModelArrayCodec<T> implements Codec<T[]> {
private final Class<T[]> clazz;
private CodecRegistry registry;
public ModelArrayCodec(Class<T[]> clazz) {
this.clazz = clazz;
}
public void setRegistry(CodecRegistry registry) {
this.registry = registry;
}
@Override
public void encode(final BsonWriter writer, final T[] value, final EncoderContext encoderContext) {
Class<T> componentType = this.componentType();
writer.writeStartArray();
for (final T cur : value) {
Codec<T> elementCodec = getElementCodec(componentType);
if (elementCodec == null) {
throw new IllegalStateException(String.format("Element codec not found for type %s", componentType));
}
if (cur == null) {
writer.writeNull();
} else {
elementCodec.encode(writer, cur, encoderContext);
}
}
writer.writeEndArray();
}
private Codec<T> getElementCodec(Class<T> componentType) {
return this.registry.get(componentType);
}
@Override
public T[] decode(final BsonReader reader, final DecoderContext decoderContext) {
Class<T> componentType = this.componentType();
ArrayList<T> list = new ArrayList<>();
reader.readStartArray();
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
Codec<T> elementCodec = getElementCodec(componentType);
if (elementCodec == null) {
throw new IllegalStateException(String.format("Element codec not found for type ", componentType));
}
if (reader.getCurrentBsonType() == BsonType.NULL) {
list.add(null);
reader.readNull();
} else {
T decode = elementCodec.decode(reader, decoderContext);
list.add(decode);
}
}
reader.readEndArray();
T[] array = (T[]) Array.newInstance(componentType, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}
return array;
}
private Class<T> componentType() {
return (Class<T>) this.clazz.getComponentType();
}
@Override
public Class<T[]> getEncoderClass() {
return this.clazz;
}
}
getCodecProviders method:
private CodecRegistry getCodecProviders() {
List<Convention> conventions = getConventions();
PojoCodecProvider pojoCodecProvider = PojoCodecProvider.builder()
.conventions(conventions)
.automatic(true)
.build();
CodecRegistry rootRegistry = fromProviders(
new ValueCodecProvider(),
new IterableCodecProvider(),
pojoCodecProvider
);
CodecRegistry codecs = fromCodecs(getCodecs());
ModelArrayCodec<?>[] arrayCodecs = arrayCodecs();
CodecRegistry arrayCodecRegistry = fromCodecs(arrayCodecs);
CodecRegistry registry = fromRegistries(rootRegistry, codecs, arrayCodecRegistry);
CodecRegistry mergedRegistry = fromRegistries(registry, codecs);
for (ModelArrayCodec<?> arrayCodec : arrayCodecs) {
arrayCodec.setRegistry(mergedRegistry);
}
return mergedRegistry;
}
getCodes() method:
private Codec<?>[] getCodecs() {
return new Codec[]{
new IntArrayCodec(),
new BooleanArrayCodec()
};
}
arrayCodes() method:
private ModelArrayCodec<?>[] arrayCodecs() {
return new ModelArrayCodec[]{
new ModelArrayCodec<>(Stat[].class)
};
}
@Exposed variables in the Skill class which I'm looking to save:
@Expose protected int boostedFor, depletedFor;
@Expose public int currentLevel;
public int fixedLevel;
@Expose public double experience;
To reiterate, only currentLevel is saving as intended. The others are being left out of the collection. I'm not getting any failure to encode messages printing. It's successfully encoding the class, but the variables aren't being stored in the Player Collection. Any ideas?