Mercurial Hosting > luan
annotate src/luan/LuanCloner.java @ 784:6a7c6879158d
revert shallowClone()
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 30 Aug 2016 12:08:49 -0600 |
parents | 655280eab1e2 |
children | d69d3c51c44e |
rev | line source |
---|---|
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
1 package luan; |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
2 |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
3 import java.util.Map; |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
4 import java.util.HashMap; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
5 import java.util.IdentityHashMap; |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
6 |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
7 |
781
fbbdd369a13a
rename DeepCloner to LuanCloner
Franklin Schmidt <fschmidt@gmail.com>
parents:
775
diff
changeset
|
8 public final class LuanCloner { |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
9 public final boolean deep; |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
10 private final Map cloned = new IdentityHashMap(); |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
11 |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
12 public LuanCloner(boolean deep) { |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
13 this.deep = deep; |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
14 } |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
15 |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
16 public LuanCloneable clone(LuanCloneable obj) { |
195
24ede40ee0aa
make MetatableGetter DeepCloneable, scoped, and secure
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
171
diff
changeset
|
17 if( obj==null ) |
24ede40ee0aa
make MetatableGetter DeepCloneable, scoped, and secure
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
171
diff
changeset
|
18 return null; |
781
fbbdd369a13a
rename DeepCloner to LuanCloner
Franklin Schmidt <fschmidt@gmail.com>
parents:
775
diff
changeset
|
19 LuanCloneable rtn = (LuanCloneable)cloned.get(obj); |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
20 if( rtn == null ) { |
784
6a7c6879158d
revert shallowClone()
Franklin Schmidt <fschmidt@gmail.com>
parents:
782
diff
changeset
|
21 rtn = obj.shallowClone(); |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
22 cloned.put(obj,rtn); |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
23 obj.deepenClone(rtn,this); |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
24 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
25 return rtn; |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
26 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
27 |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
28 public Object[] clone(Object[] obj) { |
78
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
29 if( obj.length == 0 ) |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
30 return obj; |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
31 Object[] rtn = (Object[])cloned.get(obj); |
78
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
32 if( rtn == null ) { |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
33 rtn = obj.clone(); |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
34 cloned.put(obj,rtn); |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
35 for( int i=0; i<rtn.length; i++ ) { |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
36 rtn[i] = get(rtn[i]); |
78
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
37 } |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
38 } |
78
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
39 return rtn; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
40 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
41 |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
42 public Map clone(Map obj) { |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
43 if( !obj.getClass().equals(HashMap.class) ) |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
44 throw new RuntimeException("can only clone HashMap"); |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
45 Map rtn = (Map)cloned.get(obj); |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
46 if( rtn == null ) { |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
47 rtn = new HashMap(); |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
48 for( Object stupid : obj.entrySet() ) { |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
49 Map.Entry entry = (Map.Entry)stupid; |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
50 rtn.put( get(entry.getKey()), get(entry.getValue()) ); |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
51 } |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
52 } |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
53 return rtn; |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
54 } |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
55 |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
56 public Object get(Object obj) { |
781
fbbdd369a13a
rename DeepCloner to LuanCloner
Franklin Schmidt <fschmidt@gmail.com>
parents:
775
diff
changeset
|
57 if( obj instanceof LuanCloneable ) |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
58 return clone((LuanCloneable)obj); |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
59 if( obj instanceof Object[] ) |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
60 return clone((Object[])obj); |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
61 if( obj instanceof Map ) |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
62 return clone((Map)obj); |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
63 return obj; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
64 } |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
65 /* |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
66 public Object check(Object obj) { |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
67 if( deep ) |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
68 throw new RuntimeException(); |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
69 if( !(obj instanceof LuanCloneable) ) |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
70 return obj; |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
71 LuanCloneable lc = (LuanCloneable)obj; |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
72 return lc.getCloner() == this ? lc : clone(lc); |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
73 } |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
74 */ |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
75 } |