Modified the JmeCloneable's clone() method to be jmeClone() so that

implementing objects will still be able to keep a regular public
clone() method that may do their own selective deep cloning.  This
allows explicit demarcation between the normal 'user' facing clone()
and the two step cloning process used by Cloner.

Specifically, this will let Spatial continue to have a clone() method
that operates as it does today... with its new guts essentially calling
a properly configured Cloner.
cleanup_build_scripts
Paul Speed 9 years ago
parent 68425480cb
commit 10947e8b50
  1. 16
      jme3-core/src/main/java/com/jme3/util/clone/Cloner.java
  2. 16
      jme3-core/src/main/java/com/jme3/util/clone/JmeCloneable.java
  3. 10
      jme3-examples/src/main/java/jme3test/app/TestCloner.java

@ -221,7 +221,17 @@ public class Cloner {
clone = arrayClone(object); clone = arrayClone(object);
// Array clone already indexes the clone // Array clone already indexes the clone
} else if( object instanceof JmeCloneable ) {
// Use the two-step cloning semantics
clone = ((JmeCloneable)object).jmeClone();
// Store the object in the identity map so that any circular references
// are resolvable
index.put(object, clone);
((JmeCloneable)clone).cloneFields(this, object);
} else if( object instanceof Cloneable ) { } else if( object instanceof Cloneable ) {
// Perform a regular Java shallow clone // Perform a regular Java shallow clone
try { try {
clone = javaClone(object); clone = javaClone(object);
@ -236,12 +246,6 @@ public class Cloner {
throw new IllegalArgumentException("Object is not cloneable, type:" + type); throw new IllegalArgumentException("Object is not cloneable, type:" + type);
} }
// Finally, check to see if the object implements special field cloning
// behavior.
if( clone instanceof JmeCloneable ) {
((JmeCloneable)clone).cloneFields(this, object);
}
return type.cast(clone); return type.cast(clone);
} }

@ -61,9 +61,21 @@ package com.jme3.util.clone;
public interface JmeCloneable extends Cloneable { public interface JmeCloneable extends Cloneable {
/** /**
* Performs a shallow clone of the object. * Performs a regular shallow clone of the object. Some fields
* may also be cloned but generally only if they will never be
* shared with other objects. (For example, local Vector3fs and so on.)
*
* <p>This method is separate from the regular clone() method
* so that objects might still maintain their own regular java clone()
* semantics (perhaps even using Cloner for those methods). However,
* because Java's clone() has specific features in the sense of Object's
* clone() implementation, it's usually best to have some path for
* subclasses to bypass the public clone() method that might be cloning
* fields and instead get at the superclass protected clone() methods.
* For example, through super.jmeClone() or another protected clone
* method that some base class eventually calls super.clone() in.</p>
*/ */
public Object clone(); public Object jmeClone();
/** /**
* Implemented to perform deep cloning for this object, resolving * Implemented to perform deep cloning for this object, resolving

@ -170,6 +170,12 @@ public class TestCloner {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public Parent jmeClone() {
// Ok to delegate to clone() in this case because no deep
// cloning is done there.
return clone();
}
public void cloneFields( Cloner cloner, Object original ) { public void cloneFields( Cloner cloner, Object original ) {
this.ro = cloner.clone(ro); this.ro = cloner.clone(ro);
@ -224,7 +230,7 @@ public class TestCloner {
return links; return links;
} }
public GraphNode clone() { public GraphNode jmeClone() {
try { try {
return (GraphNode)super.clone(); return (GraphNode)super.clone();
} catch( CloneNotSupportedException e ) { } catch( CloneNotSupportedException e ) {
@ -267,7 +273,7 @@ public class TestCloner {
} }
} }
public ArrayHolder clone() { public ArrayHolder jmeClone() {
try { try {
return (ArrayHolder)super.clone(); return (ArrayHolder)super.clone();
} catch( CloneNotSupportedException e ) { } catch( CloneNotSupportedException e ) {

Loading…
Cancel
Save