I was looking at the could for Node I think that the empty construer should be:
private Node() {}
public Node() {}
I was looking at the could for Node I think that the empty construer should be:
private Node() {}
public Node() {}
No, there are empty constructors in there for things like serialization and so forth… ie. the ability to say Class.forName("…"), etc.
Then I think you should create a instance of children, or you should check if it is null in update ext.
Why, people who write deserialization routines should instantiate children as well since they would have serialized with children.
I mean the object children. You get a hard to fined bug, because children is null, making JME hard to use.
How and why are you using the empty constructor? It’s meant only for serialization, not for developer use.
I took advantage of the default constructor in my Keyframe controller.
class EmptyTriMesh extends TriMesh{
public EmptyTriMesh(){
this.texture=new Vector2f[1][];
}
public void setVertices(Vector3f[] storageArray){
this.vertex=storageArray;
}
public void setNormals(Vector3f[] storageArray){
this.normal=storageArray;
}
public void setColors(ColorRGBA[] storageArray){
this.color=storageArray;
}
public void setTextures(Vector2f[] storageArray){
this.texture[0]=storageArray;
}
public void setIndices(int[] storageArray){
this.indices=storageArray;
}
}
Ok, I’ve had a bit of breakfast now and am looking back at this a bit with a more level head. (so be prepared for a long winded post… :)) Empty constructors were added to major scene classes so they could be instantiated by name by loaders that would be responsible for setting important class fields with data. Ideally, such loaders would not have to know about each specific class, what fields it requires, and all about its constructors. Our current XML/Binary readers do need to know that information and thus have to be maintained if these objects change.
From another project I’ve done, I have a class agnostic xml loader and saver that can take any java object and it’s child fields, hashes, vectors, treesets, or whatever and store them to xml. It can also reinstantiate those classes from the xml. To do this though, it obviously requires an empty constructor, otherwise it would have to scout through possible constructors and take a guess at what data to send as arguments (a messy and flaw-prone approach.) I use this xml (de)serializer in my game to store and load terrain in jars… (very fast I might add)
Anyhow, history aside… If there is a call to use these special constructors for other uses, we should go in and have basic fields instantiated on all of them. Just remember though that every object is supposed to have at least a unique name, so we’d have to systemically create names which may look ugly or make it harder to tell scene sections apart – names assigned to a given node could change with each run, for example. Other classes may likewise require a basic set of data to properly construct unless you are prepared to manually set all fields (eg. as in the case of a loader.)
Ideally, such loaders would not have to know about each specific class, what fields it requires, and all about its constructors.
Yep, looks great, but as you see it required an empty constructor.
To be fair, the loader you’ve created has the potential to be more powerful in the jME world since it doesn’t have to be generic, etc. Have you tried saving a terrain object?
yes, any class deserialized with the newInstance() method needs to have an empty constructor or you’ll get an InstantiationException.
With reflection, I can create any class I want as long as I have the name of that class. For example, I can take the string "com.jme.scene.node" from a file and create that class. The problem is that just like in real java, reflection needs to know how to construct that class, IE which constructor to call. There are ways to call something besides the default constructor, but signaling how to call what constructor can be complex considering I have to construct the parameters of the constructor as well (which kind of brings us back to square one about the default constructor).
I agree, it just hasn’t been done yet. Consider that this is a .6 product.
I just had a really strange idea, and have no clue if this would work or not, but what about making the default constructor throw an “InternalUseException”. This way, users will know to definantly not use it. Whenever we want to use it for class instantiation purposes, we’ll just catch and throw that error ignoring it. Just a thought.