@@ -44,6 +44,65 @@ public class FbxPrefab : MonoBehaviour
44
44
// component is really only about the editor.
45
45
#if UNITY_EDITOR
46
46
47
+ /// <summary>
48
+ /// Utility function: create the object, which must be null.
49
+ /// </summary>
50
+ /// <param name="item">Item.</param>
51
+ /// <typeparam name="T">The 1st type parameter.</typeparam>
52
+ public static void Initialize < T > ( ref T item ) where T : new ( )
53
+ {
54
+ if ( item != null ) { throw new FbxPrefabException ( ) ; }
55
+ item = new T ( ) ;
56
+ }
57
+
58
+ /// <summary>
59
+ /// Utility function: append an item to a list.
60
+ /// If the list is null, create it.
61
+ /// </summary>
62
+ public static void Append < T > ( ref List < T > thelist , T item )
63
+ {
64
+ if ( thelist == null ) {
65
+ thelist = new List < T > ( ) ;
66
+ }
67
+ thelist . Add ( item ) ;
68
+ }
69
+
70
+ /// <summary>
71
+ /// Utility function: append an item to a list in a dictionary of lists.
72
+ /// Create all the entries needed to append to the list.
73
+ /// The dictionary must not be null.
74
+ /// </summary>
75
+ public static void Append < K , V > ( ref Dictionary < K , List < V > > thedict , K key , V item )
76
+ {
77
+ if ( thedict == null ) {
78
+ thedict = new Dictionary < K , List < V > > ( ) ;
79
+ }
80
+ List < V > thelist ;
81
+ if ( ! thedict . TryGetValue ( key , out thelist ) || ( thelist == null ) ) {
82
+ thelist = new List < V > ( ) ;
83
+ thedict [ key ] = thelist ;
84
+ }
85
+ thelist . Add ( item ) ;
86
+ }
87
+
88
+ /// <summary>
89
+ /// Utility function: append an item to a list in a 2-level dictionary of lists.
90
+ /// Create all the entries needed to append to the list.
91
+ /// The dictionary must not be null.
92
+ /// </summary>
93
+ public static void Append < K1 , K2 , V > ( ref Dictionary < K1 , Dictionary < K2 , List < V > > > thedict , K1 key1 , K2 key2 , V item )
94
+ {
95
+ if ( thedict == null ) {
96
+ thedict = new Dictionary < K1 , Dictionary < K2 , List < V > > > ( ) ;
97
+ }
98
+ Dictionary < K2 , List < V > > thesubmap ;
99
+ if ( ! thedict . TryGetValue ( key1 , out thesubmap ) || thesubmap == null ) {
100
+ thesubmap = new Dictionary < K2 , List < V > > ( ) ;
101
+ thedict [ key1 ] = thesubmap ;
102
+ }
103
+ Append ( ref thesubmap , key2 , item ) ;
104
+ }
105
+
47
106
/// <summary>
48
107
/// Exception that denotes a likely programming error.
49
108
/// </summary>
@@ -75,15 +134,11 @@ public static FbxRepresentation FromTransform(Transform xfo) {
75
134
foreach ( Transform child in xfo ) {
76
135
children . Add ( child . name , FromTransform ( child ) ) ;
77
136
}
78
- var components = new Dictionary < string , List < string > > ( ) ;
137
+ Dictionary < string , List < string > > components = null ;
79
138
foreach ( var component in xfo . GetComponents < Component > ( ) ) {
80
139
var typeName = component . GetType ( ) . ToString ( ) ;
81
- List < string > comps ;
82
- if ( ! components . TryGetValue ( typeName , out comps ) ) {
83
- comps = new List < string > ( ) ;
84
- components [ typeName ] = comps ;
85
- }
86
- comps . Add ( UnityEditor . EditorJsonUtility . ToJson ( component ) ) ;
140
+ var jsonValue = UnityEditor . EditorJsonUtility . ToJson ( component ) ;
141
+ Append ( ref components , typeName , jsonValue ) ;
87
142
}
88
143
var fbxrep = new FbxRepresentation ( ) ;
89
144
fbxrep . children = children ;
@@ -142,14 +197,12 @@ static string UnEscapeString(string str, int index, int len) {
142
197
143
198
static FbxRepresentation FromJsonHelper ( string json , ref int index ) {
144
199
Consume ( '{' , json , ref index ) ;
145
- var fbxrep = new FbxRepresentation ( ) ;
146
200
if ( Consume ( '}' , json , ref index , required : false ) ) {
147
201
// this is a leaf; we're done.
202
+ return new FbxRepresentation ( ) ;
148
203
} else {
149
- // this is a node with important data
150
- fbxrep . children = new Dictionary < string , FbxRepresentation > ( ) ;
151
- fbxrep . components = new Dictionary < string , List < string > > ( ) ;
152
-
204
+ Dictionary < string , FbxRepresentation > children = null ;
205
+ Dictionary < string , List < string > > components = null ;
153
206
do {
154
207
Consume ( '"' , json , ref index ) ;
155
208
int nameStart = index ;
@@ -162,7 +215,8 @@ static FbxRepresentation FromJsonHelper(string json, ref int index) {
162
215
// the name of a C# type)
163
216
if ( name [ 0 ] == '-' ) {
164
217
var subrep = FromJsonHelper ( json , ref index ) ;
165
- fbxrep . children . Add ( name . Substring ( 1 ) , subrep ) ;
218
+ if ( children == null ) { children = new Dictionary < string , FbxRepresentation > ( ) ; }
219
+ children . Add ( name . Substring ( 1 ) , subrep ) ;
166
220
} else {
167
221
// Read the string. It won't have any quote marks
168
222
// in it, because we escape them using %-encoding
@@ -175,17 +229,18 @@ static FbxRepresentation FromJsonHelper(string json, ref int index) {
175
229
// We %-escaped the string so there would be no
176
230
// quotes (nor backslashes that might confuse other
177
231
// json parsers), now undo that.
178
- List < string > comps ;
179
- if ( ! fbxrep . components . TryGetValue ( name , out comps ) ) {
180
- comps = new List < string > ( ) ;
181
- fbxrep . components [ name ] = comps ;
182
- }
183
- comps . Add ( UnEscapeString ( json , componentStart , index - componentStart ) ) ;
232
+ var jsonComponent =
233
+ UnEscapeString ( json , componentStart , index - componentStart ) ;
234
+ Append ( ref components , name , jsonComponent ) ;
184
235
}
185
236
} while ( Consume ( ',' , json , ref index , required : false ) ) ;
186
237
Consume ( '}' , json , ref index ) ;
238
+
239
+ var fbxrep = new FbxRepresentation ( ) ;
240
+ fbxrep . children = children ;
241
+ fbxrep . components = components ;
242
+ return fbxrep ;
187
243
}
188
- return fbxrep ;
189
244
}
190
245
191
246
public static FbxRepresentation FromJson ( string json ) {
@@ -263,58 +318,6 @@ public static FbxRepresentation Find(FbxRepresentation rep, string key) {
263
318
/// </summary>
264
319
public class UpdateList
265
320
{
266
- /// <summary>
267
- /// Utility function: create the object, which must be null.
268
- /// </summary>
269
- /// <param name="item">Item.</param>
270
- /// <typeparam name="T">The 1st type parameter.</typeparam>
271
- public static void Initialize < T > ( ref T item ) where T : new ( )
272
- {
273
- if ( item != null ) { throw new FbxPrefabException ( ) ; }
274
- item = new T ( ) ;
275
- }
276
-
277
- /// <summary>
278
- /// Utility function: append an item to a list.
279
- /// If the list is null, create it.
280
- /// </summary>
281
- public static void Append < T > ( ref List < T > thelist , T item )
282
- {
283
- if ( thelist == null ) {
284
- thelist = new List < T > ( ) ;
285
- }
286
- thelist . Add ( item ) ;
287
- }
288
-
289
- /// <summary>
290
- /// Utility function: append an item to a list in a dictionary of lists.
291
- /// Create all the entries needed to append to the list.
292
- /// The dictionary must not be null.
293
- /// </summary>
294
- public static void Append < K , V > ( Dictionary < K , List < V > > thedict , K key , V item )
295
- {
296
- List < V > thelist ;
297
- if ( ! thedict . TryGetValue ( key , out thelist ) || ( thelist == null ) ) {
298
- thelist = new List < V > ( ) ;
299
- thedict [ key ] = thelist ;
300
- }
301
- thelist . Add ( item ) ;
302
- }
303
-
304
- /// <summary>
305
- /// Utility function: append an item to a list in a 2-level dictionary of lists.
306
- /// Create all the entries needed to append to the list.
307
- /// The dictionary must not be null.
308
- /// </summary>
309
- public static void Append < K1 , K2 , V > ( Dictionary < K1 , Dictionary < K2 , List < V > > > thedict , K1 key1 , K2 key2 , V item )
310
- {
311
- Dictionary < K2 , List < V > > thesubmap ;
312
- if ( ! thedict . TryGetValue ( key1 , out thesubmap ) || thesubmap == null ) {
313
- thesubmap = new Dictionary < K2 , List < V > > ( ) ;
314
- thedict [ key1 ] = thesubmap ;
315
- }
316
- Append ( thesubmap , key2 , item ) ;
317
- }
318
321
319
322
// We build up a flat list of names for the nodes of the old fbx,
320
323
// the new fbx, and the prefab. We also figure out the parents.
@@ -337,7 +340,7 @@ public void AddNode(string name, string parent) {
337
340
}
338
341
339
342
public void AddComponent ( string name , string typename , string jsonValue ) {
340
- Append ( m_components , name , typename , jsonValue ) ;
343
+ Append ( ref m_components , name , typename , jsonValue ) ;
341
344
}
342
345
343
346
public void AddComponents ( string name , string typename , IEnumerable < string > jsonValues ) {
@@ -442,13 +445,13 @@ public static HashSet<string> GetAllNames(params Data [] data) {
442
445
443
446
static void SetupDataHelper ( Data data , FbxRepresentation fbxrep , string parent )
444
447
{
448
+ foreach ( var kvp in fbxrep . components ) {
449
+ var typename = kvp . Key ;
450
+ var jsonValues = kvp . Value ;
451
+ data . AddComponents ( parent == null ? "" : parent , typename , jsonValues ) ;
452
+ }
445
453
foreach ( var child in FbxRepresentation . GetChildren ( fbxrep ) ) {
446
454
data . AddNode ( child , parent ) ;
447
- foreach ( var kvp in fbxrep . components ) {
448
- var typename = kvp . Key ;
449
- var jsonValues = kvp . Value ;
450
- data . AddComponents ( child , typename , jsonValues ) ;
451
- }
452
455
SetupDataHelper ( data , FbxRepresentation . Find ( fbxrep , child ) , child ) ;
453
456
}
454
457
}
@@ -479,6 +482,7 @@ void ClassifyDestroyCreateNodes()
479
482
480
483
// Figure out what nodes will exist after we create and destroy.
481
484
Initialize ( ref m_nodesInUpdatedPrefab ) ;
485
+ m_nodesInUpdatedPrefab . Add ( "" ) ; // the root is nameless
482
486
foreach ( var node in Data . GetAllNames ( m_prefab ) . Union ( m_nodesToCreate ) ) {
483
487
if ( m_nodesToDestroy . Contains ( node ) ) {
484
488
continue ;
@@ -533,25 +537,26 @@ void ClassifyReparenting()
533
537
}
534
538
}
535
539
536
- static void SetupComponentsMap ( Transform newFbx ,
537
- Dictionary < string , Dictionary < string , List < Component > > > nameMap )
538
- {
539
- foreach ( var component in newFbx . GetComponents < Component > ( ) ) {
540
- Append ( nameMap , newFbx . name , component . GetType ( ) . ToString ( ) , component ) ;
541
- }
542
- foreach ( Transform child in newFbx ) {
543
- SetupComponentsMap ( child , nameMap ) ;
544
- }
545
- }
546
-
547
540
void ClassifyComponents ( Transform newFbx )
548
541
{
549
542
Initialize ( ref m_componentsToDestroy ) ;
550
543
Initialize ( ref m_componentsToUpdate ) ;
551
544
552
545
// Flatten the list of components in the transform hierarchy so we can remember what to copy.
553
546
var components = new Dictionary < string , Dictionary < string , List < Component > > > ( ) ;
554
- SetupComponentsMap ( newFbx , components ) ;
547
+ var builder = new System . Text . StringBuilder ( ) ;
548
+ foreach ( var component in newFbx . GetComponentsInChildren < Component > ( ) ) {
549
+ string name ;
550
+ if ( component . transform == newFbx ) {
551
+ name = "" ;
552
+ } else {
553
+ name = component . name ;
554
+ }
555
+ var typename = component . GetType ( ) . ToString ( ) ;
556
+ builder . AppendFormat ( "\t {0}:{1}\n " , name , typename ) ;
557
+ Append ( ref components , name , typename , component ) ;
558
+ }
559
+ Debug . Log ( "Component map:\n " + builder . ToString ( ) ) ;
555
560
556
561
// What's the logic?
557
562
// First check if a component is present or absent. It's
@@ -597,8 +602,8 @@ void ClassifyComponents(Transform newFbx)
597
602
var newValues = m_new . GetComponentValues ( name , typename ) ;
598
603
var prefabValues = m_prefab . GetComponentValues ( name , typename ) ;
599
604
600
- Debug . Log ( string . Format ( "type {0}: {1} old / {2} new / {3} prefab" ,
601
- typename , oldValues . Count , newValues . Count , prefabValues . Count ) ) ;
605
+ Debug . Log ( string . Format ( "{4} - type {0}: {1} old / {2} new / {3} prefab" ,
606
+ typename , oldValues . Count , newValues . Count , prefabValues . Count , name ) ) ;
602
607
603
608
// TODO: handle multiplicity! The algorithm is eluding me right now...
604
609
// We'll need to do some kind of 3-way matching.
@@ -636,7 +641,7 @@ void ClassifyComponents(Transform newFbx)
636
641
var unityEngine = typeof ( Component ) . Assembly ;
637
642
foreach ( var typename in typesToDestroy ) {
638
643
var thetype = unityEngine . GetType ( typename ) ;
639
- Append ( m_componentsToDestroy , name , thetype ) ;
644
+ Append ( ref m_componentsToDestroy , name , thetype ) ;
640
645
}
641
646
}
642
647
@@ -647,7 +652,7 @@ void ClassifyComponents(Transform newFbx)
647
652
Debug . LogError ( string . Format ( "todo: multiplicity {0} on {1}:{2}" ,
648
653
components [ name ] [ typename ] . Count , name , typename ) ) ;
649
654
}
650
- Append ( m_componentsToUpdate , name , components [ name ] [ typename ] [ 0 ] ) ;
655
+ Append ( ref m_componentsToUpdate , name , components [ name ] [ typename ] [ 0 ] ) ;
651
656
}
652
657
}
653
658
}
0 commit comments