Răsfoiți Sursa

Modified the clone function lookup to support inheritence.
It's just too useful for things like Mesh which has a dozen
or more subclasses... more useful than the limitations.

Paul Speed 9 ani în urmă
părinte
comite
f7c16e878e
1 a modificat fișierele cu 21 adăugiri și 5 ștergeri
  1. 21 5
      jme3-core/src/main/java/com/jme3/util/clone/Cloner.java

+ 21 - 5
jme3-core/src/main/java/com/jme3/util/clone/Cloner.java

@@ -277,10 +277,12 @@ public class Cloner {
     }
 
     /**
-     *  Sets a custom CloneFunction for the exact Java type.  Note: no inheritence
-     *  checks are performed so a function must be registered for each specific type
-     *  that it handles.  By default ListCloneFunction is registered for
-     *  ArrayList, LinkedList, CopyOnWriteArrayList, Vector, Stack, and JME's SafeArrayList.
+     *  Sets a custom CloneFunction for implementations of the specified Java type.  Some
+     *  inheritance checks are made but no disambiguation is performed.
+     *  <p>Note: in the general case, it is better to register against specific classes and
+     *  not super-classes or super-interfaces unless you know specifically that they are cloneable.</p>
+     *  <p>By default ListCloneFunction is registered for ArrayList, LinkedList, CopyOnWriteArrayList,
+     *  Vector, Stack, and JME's SafeArrayList.</p>
      */
     public <T> void setCloneFunction( Class<T> type, CloneFunction<T> function ) {
         if( function == null ) {
@@ -296,7 +298,21 @@ public class Cloner {
      */
     @SuppressWarnings("unchecked")
     public <T> CloneFunction<T> getCloneFunction( Class<T> type ) {
-        return (CloneFunction<T>)functions.get(type);
+        CloneFunction<T> result = (CloneFunction<T>)functions.get(type);
+        if( result == null ) {
+            // Do a more exhaustive search
+            for( Map.Entry<Class, CloneFunction> e : functions.entrySet() ) {
+                if( e.getKey().isAssignableFrom(type) ) {
+                    result = e.getValue();
+                    break;
+                }
+            }
+            if( result != null ) {
+                // Cache it for later
+                functions.put(type, result);
+            }
+        }
+        return result;
     }
 
     /**