From f7c16e878ea5350efb8ac369a1b07116c7a88bf4 Mon Sep 17 00:00:00 2001 From: Paul Speed Date: Sun, 27 Mar 2016 05:38:43 -0400 Subject: [PATCH] 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. --- .../main/java/com/jme3/util/clone/Cloner.java | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/util/clone/Cloner.java b/jme3-core/src/main/java/com/jme3/util/clone/Cloner.java index be34755be..ba202e463 100644 --- a/jme3-core/src/main/java/com/jme3/util/clone/Cloner.java +++ b/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. + *

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.

+ *

By default ListCloneFunction is registered for ArrayList, LinkedList, CopyOnWriteArrayList, + * Vector, Stack, and JME's SafeArrayList.

*/ public void setCloneFunction( Class type, CloneFunction function ) { if( function == null ) { @@ -296,7 +298,21 @@ public class Cloner { */ @SuppressWarnings("unchecked") public CloneFunction getCloneFunction( Class type ) { - return (CloneFunction)functions.get(type); + CloneFunction result = (CloneFunction)functions.get(type); + if( result == null ) { + // Do a more exhaustive search + for( Map.Entry 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; } /**