|
2 | 2 | using System; |
3 | 3 | using System.Collections.Generic; |
4 | 4 | using System.Linq; |
| 5 | +using System.Runtime.CompilerServices; |
5 | 6 |
|
6 | 7 | namespace AssetsTools.NET |
7 | 8 | { |
@@ -255,108 +256,136 @@ public AssetTypeValueField ReadType(AssetsFileReader reader, AssetTypeValueField |
255 | 256 | } |
256 | 257 | else |
257 | 258 | { |
258 | | - if (type == AssetValueType.String) |
| 259 | + ReadPrimitiveType(reader, valueField, type, refMan); |
| 260 | + } |
| 261 | + |
| 262 | + } |
| 263 | + return valueField; |
| 264 | + } |
| 265 | + |
| 266 | + /// <summary> |
| 267 | + /// Deserialize a single primtive field and its children. |
| 268 | + /// This method only works for strings, numbers, and ManagedReferencesRegistry. |
| 269 | + /// </summary> |
| 270 | + /// <param name="reader">The reader to use.</param> |
| 271 | + /// <param name="valueField">The empty base value field to use.</param> |
| 272 | + /// <param name="type">The value type of the template field.</param> |
| 273 | + /// <param name="refMan">The ref type manager to use, if reading a MonoBehaviour using a ref type.</param> |
| 274 | + /// <returns>The deserialized base field.</returns> |
| 275 | +#if NETSTANDARD2_0_OR_GREATER |
| 276 | + [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| 277 | +#endif |
| 278 | + public void ReadPrimitiveType(AssetsFileReader reader, AssetTypeValueField valueField, AssetValueType type, RefTypeManager refMan) |
| 279 | + { |
| 280 | + if (type == AssetValueType.String) |
| 281 | + { |
| 282 | + valueField.Children = new List<AssetTypeValueField>(0); |
| 283 | + int length = reader.ReadInt32(); |
| 284 | + valueField.Value = new AssetTypeValue(reader.ReadBytes(length), true); |
| 285 | + reader.Align(); |
| 286 | + } |
| 287 | + else if (type == AssetValueType.ManagedReferencesRegistry) |
| 288 | + { |
| 289 | + ReadManagedReferencesRegistryType(reader, valueField, refMan); |
| 290 | + } |
| 291 | + else |
| 292 | + { |
| 293 | + int childCount = valueField.TemplateField.Children.Count; |
| 294 | + if (childCount == 0) |
| 295 | + { |
| 296 | + valueField.Children = new List<AssetTypeValueField>(0); |
| 297 | + switch (type) |
259 | 298 | { |
260 | | - valueField.Children = new List<AssetTypeValueField>(0); |
261 | | - int length = reader.ReadInt32(); |
262 | | - valueField.Value = new AssetTypeValue(reader.ReadBytes(length), true); |
263 | | - reader.Align(); |
| 299 | + case AssetValueType.Int8: |
| 300 | + valueField.Value = new AssetTypeValue(reader.ReadSByte()); |
| 301 | + break; |
| 302 | + case AssetValueType.UInt8: |
| 303 | + valueField.Value = new AssetTypeValue(reader.ReadByte()); |
| 304 | + break; |
| 305 | + case AssetValueType.Bool: |
| 306 | + valueField.Value = new AssetTypeValue(reader.ReadBoolean()); |
| 307 | + break; |
| 308 | + case AssetValueType.Int16: |
| 309 | + valueField.Value = new AssetTypeValue(reader.ReadInt16()); |
| 310 | + break; |
| 311 | + case AssetValueType.UInt16: |
| 312 | + valueField.Value = new AssetTypeValue(reader.ReadUInt16()); |
| 313 | + break; |
| 314 | + case AssetValueType.Int32: |
| 315 | + valueField.Value = new AssetTypeValue(reader.ReadInt32()); |
| 316 | + break; |
| 317 | + case AssetValueType.UInt32: |
| 318 | + valueField.Value = new AssetTypeValue(reader.ReadUInt32()); |
| 319 | + break; |
| 320 | + case AssetValueType.Int64: |
| 321 | + valueField.Value = new AssetTypeValue(reader.ReadInt64()); |
| 322 | + break; |
| 323 | + case AssetValueType.UInt64: |
| 324 | + valueField.Value = new AssetTypeValue(reader.ReadUInt64()); |
| 325 | + break; |
| 326 | + case AssetValueType.Float: |
| 327 | + valueField.Value = new AssetTypeValue(reader.ReadSingle()); |
| 328 | + break; |
| 329 | + case AssetValueType.Double: |
| 330 | + valueField.Value = new AssetTypeValue(reader.ReadDouble()); |
| 331 | + break; |
264 | 332 | } |
265 | | - else if (type == AssetValueType.ManagedReferencesRegistry) |
266 | | - { |
267 | | - // todo: error handling like in array |
268 | | - if (refMan == null) |
269 | | - throw new Exception("refMan MUST be set to deserialize objects with ref types!"); |
270 | 333 |
|
271 | | - valueField.Children = new List<AssetTypeValueField>(0); |
272 | | - ManagedReferencesRegistry registry = new ManagedReferencesRegistry(); |
273 | | - valueField.Value = new AssetTypeValue(registry); |
274 | | - int registryChildCount = valueField.TemplateField.Children.Count; |
275 | | - if (registryChildCount != 2) |
276 | | - throw new Exception($"Expected ManagedReferencesRegistry to have two children, found {registryChildCount} instead!"); |
| 334 | + if (valueField.TemplateField.IsAligned) |
| 335 | + reader.Align(); |
| 336 | + } |
| 337 | + else if (type != AssetValueType.None) |
| 338 | + { |
| 339 | + throw new Exception("Cannot read value of field with children!"); |
| 340 | + } |
| 341 | + } |
| 342 | + } |
| 343 | + |
| 344 | + /// <summary> |
| 345 | + /// Deserialize a ManagedReferencesRegistry field. |
| 346 | + /// </summary> |
| 347 | + /// <param name="reader">The reader to use.</param> |
| 348 | + /// <param name="valueField">The empty base value field to use.</param> |
| 349 | + /// <param name="refMan">The ref type manager to use, if reading a MonoBehaviour using a ref type.</param> |
| 350 | + /// <returns>The deserialized base field.</returns> |
| 351 | + public void ReadManagedReferencesRegistryType(AssetsFileReader reader, AssetTypeValueField valueField, RefTypeManager refMan) |
| 352 | + { |
| 353 | + if (refMan == null) |
| 354 | + throw new Exception($"{nameof(refMan)} must be non-null to deserialize objects with ref types."); |
| 355 | + |
| 356 | + valueField.Children = new List<AssetTypeValueField>(0); |
| 357 | + ManagedReferencesRegistry registry = new ManagedReferencesRegistry(); |
| 358 | + valueField.Value = new AssetTypeValue(registry); |
| 359 | + int registryChildCount = valueField.TemplateField.Children.Count; |
| 360 | + if (registryChildCount != 2) |
| 361 | + throw new Exception($"Expected ManagedReferencesRegistry to have two children, found {registryChildCount} instead!"); |
277 | 362 |
|
278 | | - registry.version = reader.ReadInt32(); |
279 | | - registry.references = new List<AssetTypeReferencedObject>(); |
| 363 | + registry.version = reader.ReadInt32(); |
| 364 | + registry.references = new List<AssetTypeReferencedObject>(); |
280 | 365 |
|
281 | | - if (registry.version == 1) |
282 | | - { |
283 | | - while (true) |
284 | | - { |
285 | | - // rid is consecutive starting at 0 |
286 | | - var refdObject = MakeReferencedObject(reader, registry.version, registry.references.Count, refMan); |
287 | | - if (refdObject.type.Equals(AssetTypeReference.TERMINUS)) |
288 | | - { |
289 | | - break; |
290 | | - } |
291 | | - registry.references.Add(refdObject); |
292 | | - } |
293 | | - } |
294 | | - else |
295 | | - { |
296 | | - int childCount = reader.ReadInt32(); |
297 | | - for (int i = 0; i < childCount; i++) |
298 | | - { |
299 | | - // rid is read from data |
300 | | - var refdObject = MakeReferencedObject(reader, registry.version, -1, refMan); |
301 | | - registry.references.Add(refdObject); |
302 | | - } |
303 | | - } |
304 | | - } |
305 | | - else |
| 366 | + if (registry.version == 1) |
| 367 | + { |
| 368 | + while (true) |
| 369 | + { |
| 370 | + // rid is consecutive starting at 0 |
| 371 | + var refdObject = MakeReferencedObject(reader, registry.version, registry.references.Count, refMan); |
| 372 | + if (refdObject.type.Equals(AssetTypeReference.TERMINUS)) |
306 | 373 | { |
307 | | - int childCount = valueField.TemplateField.Children.Count; |
308 | | - if (childCount == 0) |
309 | | - { |
310 | | - valueField.Children = new List<AssetTypeValueField>(0); |
311 | | - switch (valueField.TemplateField.ValueType) |
312 | | - { |
313 | | - case AssetValueType.Int8: |
314 | | - valueField.Value = new AssetTypeValue(reader.ReadSByte()); |
315 | | - break; |
316 | | - case AssetValueType.UInt8: |
317 | | - valueField.Value = new AssetTypeValue(reader.ReadByte()); |
318 | | - break; |
319 | | - case AssetValueType.Bool: |
320 | | - valueField.Value = new AssetTypeValue(reader.ReadBoolean()); |
321 | | - break; |
322 | | - case AssetValueType.Int16: |
323 | | - valueField.Value = new AssetTypeValue(reader.ReadInt16()); |
324 | | - break; |
325 | | - case AssetValueType.UInt16: |
326 | | - valueField.Value = new AssetTypeValue(reader.ReadUInt16()); |
327 | | - break; |
328 | | - case AssetValueType.Int32: |
329 | | - valueField.Value = new AssetTypeValue(reader.ReadInt32()); |
330 | | - break; |
331 | | - case AssetValueType.UInt32: |
332 | | - valueField.Value = new AssetTypeValue(reader.ReadUInt32()); |
333 | | - break; |
334 | | - case AssetValueType.Int64: |
335 | | - valueField.Value = new AssetTypeValue(reader.ReadInt64()); |
336 | | - break; |
337 | | - case AssetValueType.UInt64: |
338 | | - valueField.Value = new AssetTypeValue(reader.ReadUInt64()); |
339 | | - break; |
340 | | - case AssetValueType.Float: |
341 | | - valueField.Value = new AssetTypeValue(reader.ReadSingle()); |
342 | | - break; |
343 | | - case AssetValueType.Double: |
344 | | - valueField.Value = new AssetTypeValue(reader.ReadDouble()); |
345 | | - break; |
346 | | - } |
347 | | - |
348 | | - if (valueField.TemplateField.IsAligned) |
349 | | - reader.Align(); |
350 | | - } |
351 | | - else if (valueField.TemplateField.ValueType != AssetValueType.None) |
352 | | - { |
353 | | - throw new Exception("Cannot read value of field with children!"); |
354 | | - } |
| 374 | + break; |
355 | 375 | } |
| 376 | + registry.references.Add(refdObject); |
| 377 | + } |
| 378 | + } |
| 379 | + else |
| 380 | + { |
| 381 | + int childCount = reader.ReadInt32(); |
| 382 | + for (int i = 0; i < childCount; i++) |
| 383 | + { |
| 384 | + // rid is read from data |
| 385 | + var refdObject = MakeReferencedObject(reader, registry.version, -1, refMan); |
| 386 | + registry.references.Add(refdObject); |
356 | 387 | } |
357 | | - |
358 | 388 | } |
359 | | - return valueField; |
360 | 389 | } |
361 | 390 |
|
362 | 391 | public AssetTypeTemplateField this[string name] |
|
0 commit comments