Mercurial Hosting > luan
annotate src/luan/LuanCloner.java @ 1561:e1a13e707bf3
start immutable
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 05 Nov 2020 20:24:09 -0700 |
parents | e0cf0d108a77 |
children |
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; |
1335 | 4 import java.util.Collection; |
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 { |
785
d69d3c51c44e
more work on incremental cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
784
diff
changeset
|
9 public enum Type { COMPLETE, INCREMENTAL } |
d69d3c51c44e
more work on incremental cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
784
diff
changeset
|
10 |
d69d3c51c44e
more work on incremental cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
784
diff
changeset
|
11 public final Type type; |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
12 private final Map cloned = new IdentityHashMap(); |
1335 | 13 private Luan luan = null; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
14 |
785
d69d3c51c44e
more work on incremental cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
784
diff
changeset
|
15 public LuanCloner(Type type) { |
d69d3c51c44e
more work on incremental cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
784
diff
changeset
|
16 this.type = type; |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
17 } |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
18 |
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
19 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
|
20 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
|
21 return null; |
781
fbbdd369a13a
rename DeepCloner to LuanCloner
Franklin Schmidt <fschmidt@gmail.com>
parents:
775
diff
changeset
|
22 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
|
23 if( rtn == null ) { |
1335 | 24 if( obj instanceof Luan ) { |
25 if( luan != null ) | |
26 throw new RuntimeException("2 luans in "+type+" "+this+" - "+luan+" "+obj); | |
27 luan = (Luan)obj; | |
28 } | |
784
6a7c6879158d
revert shallowClone()
Franklin Schmidt <fschmidt@gmail.com>
parents:
782
diff
changeset
|
29 rtn = obj.shallowClone(); |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
30 cloned.put(obj,rtn); |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
31 obj.deepenClone(rtn,this); |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
32 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
33 return rtn; |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
34 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
35 |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
36 public Object[] clone(Object[] obj) { |
1561 | 37 if( obj==null || obj.length == 0 ) |
78
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
38 return obj; |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
39 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
|
40 if( rtn == null ) { |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
41 rtn = obj.clone(); |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
42 cloned.put(obj,rtn); |
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
43 for( int i=0; i<rtn.length; i++ ) { |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
44 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
|
45 } |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
46 } |
78
7c08b611125d
better deep cloning
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
77
diff
changeset
|
47 return rtn; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
48 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
49 |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
50 public Map clone(Map obj) { |
1561 | 51 if( obj==null ) |
52 return null; | |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
53 Map rtn = (Map)cloned.get(obj); |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
54 if( rtn == null ) { |
1335 | 55 try { |
56 rtn = obj.getClass().newInstance(); | |
57 } catch(InstantiationException e) { | |
58 throw new RuntimeException(e); | |
59 } catch(IllegalAccessException e) { | |
60 throw new RuntimeException(e); | |
61 } | |
1561 | 62 cloned.put(obj,rtn); |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
63 for( Object stupid : obj.entrySet() ) { |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
64 Map.Entry entry = (Map.Entry)stupid; |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
65 rtn.put( get(entry.getKey()), get(entry.getValue()) ); |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
66 } |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
67 } |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
68 return rtn; |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
69 } |
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
70 |
1335 | 71 public Collection clone(Collection obj) { |
1561 | 72 if( obj==null ) |
73 return null; | |
1335 | 74 Collection rtn = (Collection)cloned.get(obj); |
75 if( rtn == null ) { | |
76 try { | |
77 rtn = obj.getClass().newInstance(); | |
78 } catch(InstantiationException e) { | |
79 throw new RuntimeException(e); | |
80 } catch(IllegalAccessException e) { | |
81 throw new RuntimeException(e); | |
82 } | |
83 for( Object entry : (Collection)obj ) { | |
84 rtn.add( get(entry) ); | |
85 } | |
86 } | |
87 return rtn; | |
88 } | |
89 | |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
90 public Object get(Object obj) { |
781
fbbdd369a13a
rename DeepCloner to LuanCloner
Franklin Schmidt <fschmidt@gmail.com>
parents:
775
diff
changeset
|
91 if( obj instanceof LuanCloneable ) |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
92 return clone((LuanCloneable)obj); |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
93 if( obj instanceof Object[] ) |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
94 return clone((Object[])obj); |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
95 if( obj instanceof Map ) |
782
655280eab1e2
start limited cloning
Franklin Schmidt <fschmidt@gmail.com>
parents:
781
diff
changeset
|
96 return clone((Map)obj); |
1335 | 97 if( obj instanceof Collection ) |
98 return clone((Collection)obj); | |
433
c6bcb8859b93
make LuanState.registry a Map;
Franklin Schmidt <fschmidt@gmail.com>
parents:
195
diff
changeset
|
99 return obj; |
77
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
100 } |
4bf3d0c0b6b9
make LuanState cloneable
fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
parents:
diff
changeset
|
101 } |