Added MonoGame Pipeline's IntermediateSerializer and needed classes from the pipeline and MonoGame.Framework.Utilities to make AnimationEditor capable of reading Dictionaries
83 lines
3.2 KiB
C#
83 lines
3.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
|
|
namespace Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate
|
|
{
|
|
internal class GenericCollectionHelper
|
|
{
|
|
public static bool IsGenericCollectionType(Type type, bool checkAncestors)
|
|
{
|
|
return GetCollectionElementType(type, checkAncestors) != null;
|
|
}
|
|
|
|
private static Type GetCollectionElementType(Type type, bool checkAncestors)
|
|
{
|
|
if (!checkAncestors && type.BaseType != null && FindCollectionInterface(type.BaseType) != null)
|
|
return null;
|
|
|
|
var collectionInterface = FindCollectionInterface(type);
|
|
if (collectionInterface == null)
|
|
return null;
|
|
|
|
return collectionInterface.GetGenericArguments()[0];
|
|
}
|
|
|
|
private static Type FindCollectionInterface(Type type)
|
|
{
|
|
var interfaces = type.FindInterfaces((t, o) =>
|
|
{
|
|
if (t.IsGenericType)
|
|
return t.GetGenericTypeDefinition() == typeof(ICollection<>);
|
|
return false;
|
|
}, null);
|
|
|
|
return (interfaces.Length == 1)
|
|
? interfaces[0]
|
|
: null;
|
|
}
|
|
|
|
private readonly ContentTypeSerializer _contentSerializer;
|
|
private readonly PropertyInfo _countProperty;
|
|
private readonly MethodInfo _addMethod;
|
|
|
|
public GenericCollectionHelper(IntermediateSerializer serializer, Type type)
|
|
{
|
|
var collectionElementType = GetCollectionElementType(type, false);
|
|
_contentSerializer = serializer.GetTypeSerializer(collectionElementType);
|
|
|
|
var collectionType = typeof(ICollection<>).MakeGenericType(collectionElementType);
|
|
_countProperty = collectionType.GetProperty("Count");
|
|
_addMethod = collectionType.GetMethod("Add", new[] { collectionElementType });
|
|
}
|
|
|
|
public bool ObjectIsEmpty(object list)
|
|
{
|
|
return (int) _countProperty.GetValue(list, null) == 0;
|
|
}
|
|
|
|
public void ScanChildren(ContentTypeSerializer.ChildCallback callback, object collection)
|
|
{
|
|
foreach (var item in (IEnumerable) collection)
|
|
if (item != null)
|
|
callback(_contentSerializer, item);
|
|
}
|
|
|
|
public void Serialize(IntermediateWriter output, object collection, ContentSerializerAttribute format)
|
|
{
|
|
var itemFormat = new ContentSerializerAttribute();
|
|
itemFormat.ElementName = format.CollectionItemName;
|
|
foreach (var item in (IEnumerable) collection)
|
|
output.WriteObject(item, itemFormat, _contentSerializer);
|
|
}
|
|
|
|
public void Deserialize(IntermediateReader input, object collection, ContentSerializerAttribute format)
|
|
{
|
|
var itemFormat = new ContentSerializerAttribute();
|
|
itemFormat.ElementName = format.CollectionItemName;
|
|
while (input.MoveToElement(format.CollectionItemName))
|
|
_addMethod.Invoke(collection, new[] { input.ReadObject<object>(itemFormat, _contentSerializer) });
|
|
}
|
|
}
|
|
} |