I have an anonymous inner class of a factory for each of my block types in my puzzle game. What I am trying to do is, on the save of a level, save these static final instances into a j3o. This works.
However when I try to load them I get an error because the importer tries to instantiate a new object of these classes.
For example, here is the actual factory interface:
package Engine.Blocks;
import Engine.Main;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.Savable;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
public abstract class BlockFactory<T extends BlockSuper> implements Savable {
public abstract T create(Main main, Vector3f pos, Node level, boolean creating);
public void read(JmeImporter ex){
}
public void write(JmeExporter ex){
}
}
As well as one of the inner classes:
public static final BlockFactory<Block_Wall> wallBlockFactory = new BlockFactory() {
public Block_Wall create(Main main, Vector3f pos, Node level, boolean creating) {
return new Block_Wall(main, (int) pos.x, (int) pos.y, (int) pos.z, level, creating);
}
};
So I try to load them up and it, naturally, tries to create a new instance of the wallBlockFactory, which you will see that I put as the default in the following code (From Level, which implements Savable) :
public void write(JmeExporter ex) throws IOException {
BlockFactory[] xDef = {wallBlockFactory};
BlockFactory[] yDef = {wallBlockFactory};
BlockFactory[] zDef = {wallBlockFactory};
BlockFactory[] xBlocks = new BlockFactory[(int) levelSize.x];
BlockFactory[] yBlocks = new BlockFactory[(int) levelSize.x];
BlockFactory[] zBlocks = new BlockFactory[(int) levelSize.x];
for (int i = 0; i < blocks.length; i++) {
xBlocks[i] = blocks[i][0][0].getFactory();
yBlocks[i] = blocks[0][i][0].getFactory();
zBlocks[i] = blocks[0][0][i].getFactory();
}
OutputCapsule capsule = ex.getCapsule(this);
capsule.write(this, "level", new BatchNode("blocks"));
capsule.write(xBlocks, "xBlocks", xDef);
capsule.write(yBlocks, "yBlocks", yDef);
capsule.write(zBlocks, "zBlocks", zDef);
capsule.write(levelSize, "levelSize", new Vector3f(100, 100, 100));
}
public void read(JmeImporter im) throws IOException {
InputCapsule capsule = im.getCapsule(this);
levelSize = (Vector3f) capsule.readSavable("levelSize", new Vector3f(100, 100, 100));
BlockFactory[] xDef = {wallBlockFactory};
BlockFactory[] yDef = {wallBlockFactory};
BlockFactory[] zDef = {wallBlockFactory};
BlockFactory[] xBlocks = new BlockFactory[(int) levelSize.x];
BlockFactory[] yBlocks = new BlockFactory[(int) levelSize.x];
BlockFactory[] zBlocks = new BlockFactory[(int) levelSize.x];
xBlocks = (BlockFactory[]) capsule.readSavableArray("xBlocks", xDef);
yBlocks = (BlockFactory[]) capsule.readSavableArray("yBlocks", yDef);
zBlocks = (BlockFactory[]) capsule.readSavableArray("zBlocks", zDef);
BlockFactory[] copyBlocks = new BlockFactory[xBlocks.length + yBlocks.length + zBlocks.length];
System.arraycopy(xBlocks, 0, copyBlocks, 0, xBlocks.length);
System.arraycopy(yBlocks, 0, copyBlocks, xBlocks.length, yBlocks.length);
System.arraycopy(zBlocks, 0, copyBlocks, xBlocks.length + yBlocks.length, zBlocks.length);
BlockFactory[][][] toLoad = new BlockFactory[(int) levelSize.x][(int) levelSize.y][(int) levelSize.z];
int index = 0;
for (int x = 0; x < toLoad.length; x++) {
for (int y = 0; y < toLoad[0].length; y++) {
for (int z = 0; z < toLoad[0][0].length; z++) {
toLoad[x][y][z] = copyBlocks[index++];
}
}
}
}
What I am trying to achieve is the ability to just be able to create factories and blocks types and have them load in dynamically. Since there is no data that can’t just be regenerated with a new instance of a Block class I am trying to just save the factories.
I realize that I could create enums or string id’s and have a bunch of if statements in the read method, however as I said I would prefer for it to be dynamic.
Thanks for any help guys.