private void WriteElement(MemberDefinition definition, Type propertyType, object node)
{
var type = definition.CachedField.FieldType;
bool dataArea = definition.DataArea || (Writer == DataWriter);
switch (definition.Type)
{
case MemberType.Inline:
if (definition.SerializationKind == SerializationKind.UserMember)
definition.Serializer.Write(this.GR2, this, definition, node);
else
WriteStruct(type, node, false);
break;
case MemberType.Reference:
{
WriteReference(node);
if (node != null)
{
GR2.QueueStructWrite(Type, dataArea, definition, type, node);
}
break;
}
case MemberType.VariantReference:
{
if (node != null)
{
var inferredType = node.GetType();
if (definition.TypeSelector != null)
{
var variantType = definition.TypeSelector.SelectType(definition, node);
if (variantType != null)
inferredType = variantType;
}
WriteStructReference(GR2.LookupStructDefinition(inferredType));
WriteReference(node);
GR2.QueueStructWrite(Type, dataArea, definition, inferredType, node);
}
else
{
WriteStructReference(null);
WriteReference(null);
}
break;
}
case MemberType.ArrayOfReferences:
{
// Serializing as a struct member is nooooot a very good idea here.
// Debug.Assert(kind != SerializationKind.UserMember);
var list = node as System.Collections.IList;
WriteArrayIndicesReference(list);
if (list != null && list.Count > 0)
{
GR2.QueueArrayWrite(Type, dataArea, type.GetGenericArguments().Single(), definition, list);
}
break;
}
case MemberType.ReferenceToArray:
{
var list = node as System.Collections.IList;
WriteArrayIndicesReference(list);
if (list != null && list.Count > 0)
{
GR2.QueueArrayWrite(Type, dataArea, type.GetGenericArguments().Single(), definition, list);
}
break;
}
case MemberType.ReferenceToVariantArray:
{
var list = node as System.Collections.IList;
if (list != null && list.Count > 0)
{
var inferredType = list[0].GetType();
if (definition.TypeSelector != null)
{
var variantType = definition.TypeSelector.SelectType(definition, node);
if (variantType != null)
inferredType = variantType;
}
WriteStructReference(GR2.LookupStructDefinition(inferredType));
WriteArrayIndicesReference(list);
GR2.QueueArrayWrite(Type, dataArea, inferredType, definition, list);
}
else
{
WriteStructReference(null);
WriteArrayIndicesReference(list);
}
break;
}
case MemberType.String:
WriteStringReference(node as string);
break;
case MemberType.Transform:
var transform = node as Transform;
Writer.Write(transform.Flags);
for (int i = 0; i < 3; i++)
Writer.Write(transform.Translation[i]);
Writer.Write(transform.Rotation.X);
Writer.Write(transform.Rotation.Y);
Writer.Write(transform.Rotation.Z);
Writer.Write(transform.Rotation.W);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
Writer.Write(transform.ScaleShear[i, j]);
}
break;
case MemberType.Real16:
Writer.Write((Half)node);
break;
case MemberType.Real32:
Writer.Write((Single)node);
break;
case MemberType.Int8:
case MemberType.BinormalInt8:
Writer.Write((SByte)node);
break;
case MemberType.UInt8:
case MemberType.NormalUInt8:
Writer.Write((Byte)node);
break;
case MemberType.Int16:
case MemberType.BinormalInt16:
Writer.Write((Int16)node);
break;
case MemberType.UInt16:
case MemberType.NormalUInt16:
Writer.Write((UInt16)node);
break;
case MemberType.Int32:
Writer.Write((Int32)node);
break;
case MemberType.UInt32:
Writer.Write((UInt32)node);
break;
default:
throw new ParsingException(String.Format("Unhandled member type: {0}", definition.Type.ToString()));
}
}