@@ -67,6 +67,24 @@ public static void Append<T>(ref List<T> thelist, T item)
67
67
thelist . Add ( item ) ;
68
68
}
69
69
70
+ public static void Add < K , V > ( ref Dictionary < K , V > thedict , K key , V value )
71
+ {
72
+ if ( thedict == null ) {
73
+ thedict = new Dictionary < K , V > ( ) ;
74
+ }
75
+ thedict . Add ( key , value ) ;
76
+ }
77
+
78
+ public static V GetOrCreate < K , V > ( Dictionary < K , V > thedict , K key ) where V : new ( )
79
+ {
80
+ V value ;
81
+ if ( ! thedict . TryGetValue ( key , out value ) ) {
82
+ value = new V ( ) ;
83
+ thedict [ key ] = value ;
84
+ }
85
+ return value ;
86
+ }
87
+
70
88
/// <summary>
71
89
/// Utility function: append an item to a list in a dictionary of lists.
72
90
/// Create all the entries needed to append to the list.
@@ -77,12 +95,12 @@ public static void Append<K, V>(ref Dictionary<K, List<V>> thedict, K key, V ite
77
95
if ( thedict == null ) {
78
96
thedict = new Dictionary < K , List < V > > ( ) ;
79
97
}
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 ) ;
98
+ GetOrCreate ( thedict , key ) . Add ( item ) ;
99
+ }
100
+
101
+ public static void Append < K , V > ( Dictionary < K , List < V > > thedict , K key , V item )
102
+ {
103
+ GetOrCreate ( thedict , key ) . Add ( item ) ;
86
104
}
87
105
88
106
/// <summary>
@@ -95,12 +113,8 @@ public static void Append<K1, K2, V>(ref Dictionary<K1, Dictionary<K2, List<V>>>
95
113
if ( thedict == null ) {
96
114
thedict = new Dictionary < K1 , Dictionary < K2 , List < V > > > ( ) ;
97
115
}
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 ) ;
116
+ var thesubmap = GetOrCreate ( thedict , key1 ) ;
117
+ Append ( thesubmap , key2 , item ) ;
104
118
}
105
119
106
120
/// <summary>
@@ -120,30 +134,29 @@ public class FbxRepresentation
120
134
/// The key is the name, which is assumed to be unique.
121
135
/// The value is, recursively, the representation of that subtree.
122
136
/// </summary>
123
- Dictionary < string , FbxRepresentation > children ;
137
+ Dictionary < string , FbxRepresentation > m_children ;
124
138
125
139
/// <summary>
126
140
/// Children of this node.
127
141
/// The key is the name of the type of the Component. We accept that there may be several.
128
142
/// The value is the json for the component, to be decoded with EditorJsonUtility.
129
143
/// </summary>
130
- public Dictionary < string , List < string > > components { get ; private set ; }
144
+ Dictionary < string , List < string > > m_components ;
131
145
132
- public static FbxRepresentation FromTransform ( Transform xfo ) {
133
- var children = new Dictionary < string , FbxRepresentation > ( ) ;
146
+ /// <summary>
147
+ /// Build a hierarchical representation based on a transform.
148
+ /// </summary>
149
+ public FbxRepresentation ( Transform xfo )
150
+ {
151
+ m_children = new Dictionary < string , FbxRepresentation > ( ) ;
134
152
foreach ( Transform child in xfo ) {
135
- children . Add ( child . name , FromTransform ( child ) ) ;
153
+ m_children . Add ( child . name , new FbxRepresentation ( child ) ) ;
136
154
}
137
- Dictionary < string , List < string > > components = null ;
138
155
foreach ( var component in xfo . GetComponents < Component > ( ) ) {
139
156
var typeName = component . GetType ( ) . ToString ( ) ;
140
157
var jsonValue = UnityEditor . EditorJsonUtility . ToJson ( component ) ;
141
- Append ( ref components , typeName , jsonValue ) ;
158
+ Append ( ref m_components , typeName , jsonValue ) ;
142
159
}
143
- var fbxrep = new FbxRepresentation ( ) ;
144
- fbxrep . children = children ;
145
- fbxrep . components = components ;
146
- return fbxrep ;
147
160
}
148
161
149
162
// todo: use a real json parser
@@ -195,14 +208,13 @@ static string UnEscapeString(string str, int index, int len) {
195
208
return builder . ToString ( ) ;
196
209
}
197
210
198
- static FbxRepresentation FromJsonHelper ( string json , ref int index ) {
211
+ void InitFromJson ( string json , ref int index )
212
+ {
199
213
Consume ( '{' , json , ref index ) ;
200
214
if ( Consume ( '}' , json , ref index , required : false ) ) {
201
215
// this is a leaf; we're done.
202
- return new FbxRepresentation ( ) ;
216
+ return ;
203
217
} else {
204
- Dictionary < string , FbxRepresentation > children = null ;
205
- Dictionary < string , List < string > > components = null ;
206
218
do {
207
219
Consume ( '"' , json , ref index ) ;
208
220
int nameStart = index ;
@@ -214,9 +226,8 @@ static FbxRepresentation FromJsonHelper(string json, ref int index) {
214
226
// component (which can't start with a - because it's
215
227
// the name of a C# type)
216
228
if ( name [ 0 ] == '-' ) {
217
- var subrep = FromJsonHelper ( json , ref index ) ;
218
- if ( children == null ) { children = new Dictionary < string , FbxRepresentation > ( ) ; }
219
- children . Add ( name . Substring ( 1 ) , subrep ) ;
229
+ var subrep = new FbxRepresentation ( json , ref index ) ;
230
+ Add ( ref m_children , name . Substring ( 1 ) , subrep ) ;
220
231
} else {
221
232
// Read the string. It won't have any quote marks
222
233
// in it, because we escape them using %-encoding
@@ -231,29 +242,28 @@ static FbxRepresentation FromJsonHelper(string json, ref int index) {
231
242
// json parsers), now undo that.
232
243
var jsonComponent =
233
244
UnEscapeString ( json , componentStart , index - componentStart ) ;
234
- Append ( ref components , name , jsonComponent ) ;
245
+ Append ( ref m_components , name , jsonComponent ) ;
235
246
}
236
247
} while ( Consume ( ',' , json , ref index , required : false ) ) ;
237
248
Consume ( '}' , json , ref index ) ;
238
-
239
- var fbxrep = new FbxRepresentation ( ) ;
240
- fbxrep . children = children ;
241
- fbxrep . components = components ;
242
- return fbxrep ;
243
249
}
244
250
}
245
251
246
- public static FbxRepresentation FromJson ( string json ) {
247
- if ( json . Length == 0 ) { return new FbxRepresentation ( ) ; }
252
+ public FbxRepresentation ( string json , ref int index ) {
253
+ InitFromJson ( json , ref index ) ;
254
+ }
255
+
256
+ public FbxRepresentation ( string json ) {
257
+ if ( json . Length == 0 ) { return ; }
248
258
int index = 0 ;
249
- return FromJsonHelper ( json , ref index ) ;
259
+ InitFromJson ( json , ref index ) ;
250
260
}
251
261
252
262
void ToJsonHelper ( System . Text . StringBuilder builder ) {
253
263
builder . Append ( "{" ) ;
254
264
bool first = true ;
255
- if ( children != null ) {
256
- foreach ( var kvp in children . OrderBy ( kvp => kvp . Key ) ) {
265
+ if ( m_children != null ) {
266
+ foreach ( var kvp in m_children . OrderBy ( kvp => kvp . Key ) ) {
257
267
if ( ! first ) { builder . Append ( ',' ) ; }
258
268
else { first = false ; }
259
269
@@ -262,8 +272,8 @@ void ToJsonHelper(System.Text.StringBuilder builder) {
262
272
kvp . Value . ToJsonHelper ( builder ) ;
263
273
}
264
274
}
265
- if ( components != null ) {
266
- foreach ( var kvp in components . OrderBy ( kvp => kvp . Key ) ) {
275
+ if ( m_components != null ) {
276
+ foreach ( var kvp in m_components . OrderBy ( kvp => kvp . Key ) ) {
267
277
var name = kvp . Key ;
268
278
foreach ( var componentValue in kvp . Value ) {
269
279
if ( ! first ) { builder . Append ( ',' ) ; }
@@ -286,22 +296,30 @@ public string ToJson() {
286
296
}
287
297
288
298
public static bool IsLeaf ( FbxRepresentation rep ) {
289
- return rep == null || rep . children == null ;
299
+ return rep == null || rep . m_children == null ;
290
300
}
291
301
292
302
public static HashSet < string > GetChildren ( FbxRepresentation rep ) {
293
303
if ( IsLeaf ( rep ) ) {
294
304
return new HashSet < string > ( ) ;
295
305
} else {
296
- return new HashSet < string > ( rep . children . Keys ) ;
306
+ return new HashSet < string > ( rep . m_children . Keys ) ;
307
+ }
308
+ }
309
+
310
+ public static IEnumerable < KeyValuePair < string , List < string > > > GetComponents ( FbxRepresentation rep ) {
311
+ if ( rep == null || rep . m_components == null ) {
312
+ return new KeyValuePair < string , List < string > > [ 0 ] ;
313
+ } else {
314
+ return rep . m_components ;
297
315
}
298
316
}
299
317
300
318
public static FbxRepresentation Find ( FbxRepresentation rep , string key ) {
301
319
if ( IsLeaf ( rep ) ) { return null ; }
302
320
303
321
FbxRepresentation child ;
304
- if ( rep . children . TryGetValue ( key , out child ) ) {
322
+ if ( rep . m_children . TryGetValue ( key , out child ) ) {
305
323
return child ;
306
324
}
307
325
return null ;
@@ -323,7 +341,7 @@ public class UpdateList
323
341
// the new fbx, and the prefab. We also figure out the parents.
324
342
class Data {
325
343
// Parent of each node, by name.
326
- // Value (parent) may be null, key (node) is never null .
344
+ // The empty-string name is the root of the prefab/fbx .
327
345
Dictionary < string , string > m_parents ;
328
346
329
347
// Component value by name and type, with multiplicity.
@@ -359,7 +377,7 @@ public string GetParent(string name) {
359
377
if ( m_parents . TryGetValue ( name , out parent ) ) {
360
378
return parent ;
361
379
} else {
362
- return null ;
380
+ return "" ;
363
381
}
364
382
}
365
383
@@ -445,10 +463,10 @@ public static HashSet<string> GetAllNames(params Data [] data) {
445
463
446
464
static void SetupDataHelper ( Data data , FbxRepresentation fbxrep , string parent )
447
465
{
448
- foreach ( var kvp in fbxrep . components ) {
466
+ foreach ( var kvp in FbxRepresentation . GetComponents ( fbxrep ) ) {
449
467
var typename = kvp . Key ;
450
468
var jsonValues = kvp . Value ;
451
- data . AddComponents ( parent == null ? "" : parent , typename , jsonValues ) ;
469
+ data . AddComponents ( parent , typename , jsonValues ) ;
452
470
}
453
471
foreach ( var child in FbxRepresentation . GetChildren ( fbxrep ) ) {
454
472
data . AddNode ( child , parent ) ;
@@ -459,7 +477,7 @@ static void SetupDataHelper(Data data, FbxRepresentation fbxrep, string parent)
459
477
static void SetupData ( ref Data data , FbxRepresentation fbxrep )
460
478
{
461
479
Initialize ( ref data ) ;
462
- SetupDataHelper ( data , fbxrep , null ) ;
480
+ SetupDataHelper ( data , fbxrep , "" ) ;
463
481
}
464
482
465
483
void ClassifyDestroyCreateNodes ( )
@@ -512,7 +530,7 @@ void ClassifyReparenting()
512
530
// trying to destroy objects that are already destroyed
513
531
// because a parent got there first. Maybe there's a
514
532
// faster way to do it, but performance seems OK.
515
- m_reparentings . Add ( name , null ) ;
533
+ m_reparentings . Add ( name , "" ) ;
516
534
continue ;
517
535
}
518
536
@@ -638,6 +656,10 @@ void ClassifyComponents(Transform newFbx)
638
656
639
657
// Figure out the types so we can destroy them.
640
658
if ( typesToDestroy != null ) {
659
+ // TODO: handle monobehaviour in other assemblies
660
+ // Sample use: using custom attributes in fbx to drive
661
+ // unity behaviour by adding a monobehaviour in an
662
+ // assetpostprocessor.
641
663
var unityEngine = typeof ( Component ) . Assembly ;
642
664
foreach ( var typename in typesToDestroy ) {
643
665
var thetype = unityEngine . GetType ( typename ) ;
@@ -675,8 +697,8 @@ public UpdateList(
675
697
FbxPrefab prefab )
676
698
{
677
699
SetupData ( ref m_old , oldFbx ) ;
678
- SetupData ( ref m_new , FbxRepresentation . FromTransform ( newFbx ) ) ;
679
- SetupData ( ref m_prefab , FbxRepresentation . FromTransform ( prefab . transform ) ) ;
700
+ SetupData ( ref m_new , new FbxRepresentation ( newFbx ) ) ;
701
+ SetupData ( ref m_prefab , new FbxRepresentation ( prefab . transform ) ) ;
680
702
681
703
ClassifyDestroyCreateNodes ( ) ;
682
704
ClassifyReparenting ( ) ;
@@ -733,7 +755,7 @@ public void ImplementUpdates(FbxPrefab prefabInstance)
733
755
var name = kvp . Key ;
734
756
var parent = kvp . Value ;
735
757
Transform parentNode ;
736
- if ( parent == null ) {
758
+ if ( string . IsNullOrEmpty ( parent ) ) {
737
759
parentNode = prefabInstance . transform ;
738
760
} else {
739
761
parentNode = prefabNodes [ parent ] ;
@@ -847,7 +869,7 @@ void CompareAndUpdate()
847
869
updates . ImplementUpdates ( fbxPrefab ) ;
848
870
849
871
// Update the representation of the history to match the new fbx.
850
- var newFbxRep = FbxRepresentation . FromTransform ( m_fbxModel . transform ) ;
872
+ var newFbxRep = new FbxRepresentation ( m_fbxModel . transform ) ;
851
873
var newFbxRepString = newFbxRep . ToJson ( ) ;
852
874
fbxPrefab . m_fbxHistory = newFbxRepString ;
853
875
@@ -880,7 +902,7 @@ public string GetFbxAssetPath()
880
902
/// </summary>
881
903
public FbxRepresentation GetFbxHistory ( )
882
904
{
883
- return FbxRepresentation . FromJson ( m_fbxHistory ) ;
905
+ return new FbxRepresentation ( m_fbxHistory ) ;
884
906
}
885
907
886
908
/// <summary>
@@ -937,7 +959,7 @@ public void SetSourceModel(GameObject fbxModel) {
937
959
// This is the first time we've seen the FBX file. Assume that
938
960
// it's the original FBX. Further assume that the user is happy
939
961
// with the prefab as it is now, so don't update it to match the FBX.
940
- m_fbxHistory = FbxRepresentation . FromTransform ( m_fbxModel . transform ) . ToJson ( ) ;
962
+ m_fbxHistory = new FbxRepresentation ( m_fbxModel . transform ) . ToJson ( ) ;
941
963
} else {
942
964
// Case 3.
943
965
// User wants to reconnect or change the connection.
0 commit comments