private string GenerateSerializationSurrogate(Type type) { string ns = typeof(SerializationSurrogates).Namespace; StringBuilder classSB = new StringBuilder(); if (type.Namespace != null) { ns += "." + type.Namespace.Replace(".", "NS.") + "NS"; } classSB.AppendFrmt(0, "namespace {0}", ns); classSB.AppendLine(0, "{"); classSB.AppendLine(1, "#if RT_USE_PROTOBUF"); classSB.AppendLine(1, "[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]"); classSB.AppendLine(1, "#endif"); classSB.AppendLine(1, "#if !UNITY_WINRT"); classSB.AppendFrmt(1, "public class {0} : {1}", type.Name + m_settings.SurrogatePostfix, typeof(ISerializationSurrogate).Name); classSB.AppendLine(1, "#else"); classSB.AppendFrmt(1, "public class {0}", type.Name + m_settings.SurrogatePostfix); classSB.AppendLine(1, "#endif"); classSB.AppendLine(1, "{"); MethodInfo getObjectDataMethod = Strong.MethodInfo <ISerializationSurrogate>(x => new Action <object, SerializationInfo, StreamingContext>(x.GetObjectData)); MethodInfo setObjectDataMethod = Strong.MethodInfo <ISerializationSurrogate>(x => new Func <object, SerializationInfo, StreamingContext, ISurrogateSelector, object>(x.SetObjectData)); HashSet <string> exceptProperties; m_exceptProperties.TryGetValue(type, out exceptProperties); if (exceptProperties == null) { exceptProperties = new HashSet <string>(); } FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Where(f => IsTypeSupported(f.FieldType) /*&& f.FieldType.IsSerializable*/) .Where(f => m_settings.IncludeObsoleteTypes || !f.IsDefined(typeof(ObsoleteAttribute), true)).ToArray(); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Where(p => IsTypeSupported(p.PropertyType) && /*p.PropertyType.IsSerializable &&*/ p.GetSetMethod() != null && p.GetGetMethod() != null && !exceptProperties.Contains(p.Name) && p.GetIndexParameters().Length == 0) .Where(p => m_settings.IncludeObsoleteTypes || !p.IsDefined(typeof(ObsoleteAttribute), true)).ToArray(); if (fields.Length > 0 || properties.Length > 0) { for (int i = 0; i < fields.Length; ++i) { FieldInfo field = fields[i]; if (field.FieldType.IsEnum()) { classSB.AppendFrmt(2, "public uint {0};", field.Name); } else { classSB.AppendFrmt(2, "public {0} {1};", field.FieldType.FullName.Replace("+", "."), field.Name); } } for (int i = 0; i < properties.Length; ++i) { PropertyInfo property = properties[i]; if (property.PropertyType.IsEnum()) { classSB.AppendFrmt(2, "public uint {0};", property.Name); } else { classSB.AppendFrmt(2, "public {0} {1};", property.PropertyType.FullName.Replace("+", "."), property.Name); } } classSB.AppendFrmt(2, "public static implicit operator {0}({1} v)", type.FullName.Replace('+', '.'), type.Name + m_settings.SurrogatePostfix); classSB.AppendLine(2, "{"); classSB.AppendFrmt(3, "{0} o = new {0}();", type.FullName.Replace('+', '.')); for (int i = 0; i < fields.Length; ++i) { FieldInfo field = fields[i]; if (field.FieldType.IsEnum()) { classSB.AppendFrmt(3, "o.{0} = ({1})v.{0};", field.Name, field.FieldType.FullName.Replace('+', '.')); } else { classSB.AppendFrmt(3, "o.{0} = v.{0};", field.Name); } } for (int i = 0; i < properties.Length; ++i) { PropertyInfo property = properties[i]; if (property.PropertyType.IsEnum()) { classSB.AppendFrmt(3, "o.{0} = ({1})v.{0};", property.Name, property.PropertyType.FullName.Replace('+', '.')); } else { classSB.AppendFrmt(3, "o.{0} = v.{0};", property.Name); } } classSB.AppendLine(3, "return o;"); classSB.AppendLine(2, "}"); classSB.AppendFrmt(2, "public static implicit operator {0}({1} v)", type.Name + m_settings.SurrogatePostfix, type.FullName.Replace('+', '.')); classSB.AppendLine(2, "{"); classSB.AppendFrmt(3, "{0} o = new {0}();", type.Name + m_settings.SurrogatePostfix); for (int i = 0; i < fields.Length; ++i) { FieldInfo field = fields[i]; if (field.FieldType.IsEnum()) { classSB.AppendFrmt(3, "o.{0} = (uint)v.{0};", field.Name); } else { classSB.AppendFrmt(3, "o.{0} = v.{0};", field.Name); } } for (int i = 0; i < properties.Length; ++i) { PropertyInfo property = properties[i]; if (property.PropertyType.IsEnum()) { classSB.AppendFrmt(3, "o.{0} = (uint)v.{0};", property.Name); } else { classSB.AppendFrmt(3, "o.{0} = v.{0};", property.Name); } } classSB.AppendLine(3, "return o;"); classSB.AppendLine(2, "}"); classSB.AppendLine(2, "#if !UNITY_WINRT"); classSB.AppendFrmt(2, "public void {0}(object obj, SerializationInfo info, StreamingContext context)", getObjectDataMethod.Name); classSB.AppendLine(2, "{"); classSB.AppendFrmt(3, "{0} o = ({0})obj;", type.FullName.Replace('+', '.')); for (int i = 0; i < fields.Length; ++i) { FieldInfo field = fields[i]; classSB.AppendFrmt(3, "info.AddValue(\"{0}\", o.{0});", field.Name); } for (int i = 0; i < properties.Length; ++i) { PropertyInfo property = properties[i]; classSB.AppendFrmt(3, "info.AddValue(\"{0}\", o.{0});", property.Name); } classSB.AppendLine(2, "}"); classSB.AppendFrmt(2, "public object {0}(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)", setObjectDataMethod.Name); classSB.AppendLine(2, "{"); classSB.AppendFrmt(3, "{0} o = ({0})obj;", type.FullName.Replace('+', '.')); for (int i = 0; i < fields.Length; ++i) { FieldInfo field = fields[i]; string fieldTypeName; if (m_primitiveNames.ContainsKey(field.FieldType)) { fieldTypeName = m_primitiveNames[field.FieldType]; } else { fieldTypeName = field.FieldType.FullName.Replace('+', '.'); } classSB.AppendFrmt(3, "o.{0} = ({1})info.GetValue(\"{0}\", typeof({1}));", field.Name, fieldTypeName); } for (int i = 0; i < properties.Length; ++i) { PropertyInfo property = properties[i]; string propertyTypeName; if (m_primitiveNames.ContainsKey(property.PropertyType)) { propertyTypeName = m_primitiveNames[property.PropertyType]; } else { propertyTypeName = property.PropertyType.FullName.Replace('+', '.'); } classSB.AppendFrmt(3, "o.{0} = ({1})info.GetValue(\"{0}\", typeof({1}));", property.Name, propertyTypeName); } classSB.AppendLine(3, "return o;"); classSB.AppendLine(2, "}"); classSB.AppendLine(2, "#endif"); } else { classSB.AppendFrmt(2, "public static implicit operator {0}({1} v)", type.FullName.Replace('+', '.'), type.Name + m_settings.SurrogatePostfix); classSB.AppendLine(2, "{"); classSB.AppendFrmt(3, "{0} o = new {0}();", type.FullName.Replace('+', '.')); classSB.AppendLine(3, "return o;"); classSB.AppendLine(2, "}"); classSB.AppendFrmt(2, "public static implicit operator {0}({1} v)", type.Name + m_settings.SurrogatePostfix, type.FullName.Replace('+', '.')); classSB.AppendLine(2, "{"); classSB.AppendFrmt(3, "{0} o = new {0}();", type.Name + m_settings.SurrogatePostfix); classSB.AppendLine(3, "return o;"); classSB.AppendLine(2, "}"); classSB.AppendLine(2, "#if !UNITY_WINRT"); classSB.AppendFrmt(2, "public void {0}(object obj, SerializationInfo info, StreamingContext context) {{ }}", getObjectDataMethod.Name); classSB.AppendFrmt(2, "public object {0}(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) {{ return obj; }}", setObjectDataMethod.Name); classSB.AppendLine(2, "#endif"); } classSB.AppendLine(1, "}"); classSB.AppendLine(0, "}"); return(classSB.ToString()); }
private string GeneratePersistentType(Type type, Type[] derived, HashSet <Type> persistentTypes) { Type persistentDataType = typeof(PersistentData); string typeFullName = type.FullName.Replace('+', '.'); string persistentTypeName = GetPersistentTypeName(type); string persistentTypeNs = GetNormalizedNS(type, persistentTypes); string baseTypeFullName; if (!type.IsSubclassOf(typeof(UnityObject))) { Type baseType = persistentDataType; baseTypeFullName = baseType.FullName.Replace('+', '.'); } else { Type baseType = type.BaseType; baseTypeFullName = CombineNamespaceWithTypeName(GetNormalizedNS(baseType, persistentTypes), GetPersistentTypeName(baseType)); } MethodInfo getInstanceIDSMethod = Strong.MethodInfo <UnityObject[]>(x => new Func <long[]>(x.GetMappedInstanceID)); MethodInfo getInstanceIDMethod = Strong.MethodInfo <UnityObject>(x => new Func <long>(x.GetMappedInstanceID)); MethodInfo loadFormMethod = Strong.MethodInfo <PersistentData>(x => new Action <UnityObject>(x.ReadFrom)); StringBuilder loadFromSB = new StringBuilder(); loadFromSB.AppendFrmt(2, "public override void {0}(object obj)", loadFormMethod.Name); loadFromSB.AppendLine(2, "{"); loadFromSB.AppendFrmt(3, "base.{0}(obj);", loadFormMethod.Name); loadFromSB.AppendLine(3, "if(obj == null)"); loadFromSB.AppendLine(3, "{"); loadFromSB.AppendLine(4, "return;"); loadFromSB.AppendLine(3, "}"); loadFromSB.AppendFrmt(3, "{0} o = ({0})obj;", typeFullName); MethodInfo resolveMethod = Strong.MethodInfo <Dictionary <long, UnityObject> >(x => new Func <long, UnityObject>(x.Get)); MethodInfo saveToMethod = Strong.MethodInfo <PersistentData>(x => new Func <UnityObject, Dictionary <long, UnityObject>, object>(x.WriteTo)); StringBuilder saveToSB = new StringBuilder(); saveToSB.AppendFrmt(2, "public override object {0}(object obj, System.Collections.Generic.Dictionary<long, {1}> objects)", saveToMethod.Name, typeof(UnityObject).FullName); saveToSB.AppendLine(2, "{"); saveToSB.AppendFrmt(3, "obj = base.{0}(obj, objects);", saveToMethod.Name); saveToSB.AppendLine(3, "if(obj == null)"); saveToSB.AppendLine(3, "{"); saveToSB.AppendLine(4, "return null;"); saveToSB.AppendLine(3, "}"); saveToSB.AppendFrmt(3, "{0} o = ({0})obj;", typeFullName); StringBuilder getDepSB = new StringBuilder(); getDepSB.AppendLine(2, "protected override void GetDependencies(System.Collections.Generic.Dictionary<long, UnityEngine.Object> dependencies, object obj)"); getDepSB.AppendLine(2, "{"); getDepSB.AppendLine(3, "base.GetDependencies(dependencies, obj);"); getDepSB.AppendLine(3, "if(obj == null)"); getDepSB.AppendLine(3, "{"); getDepSB.AppendLine(4, "return;"); getDepSB.AppendLine(3, "}"); getDepSB.AppendFrmt(3, "{0} o = ({0})obj;", typeFullName); MethodInfo findDepMethod = Strong.MethodInfo <PersistentData>(x => new Action <Dictionary <long, UnityObject>, Dictionary <long, UnityObject>, bool>(x.FindDependencies)); StringBuilder findDepSB = new StringBuilder(); findDepSB.AppendFrmt(2, "public override void {0}<T>(System.Collections.Generic.Dictionary<long, T> dependencies, System.Collections.Generic.Dictionary<long, T> objects, bool allowNulls)", findDepMethod.Name); findDepSB.AppendLine(2, "{"); findDepSB.AppendFrmt(3, "base.{0}(dependencies, objects, allowNulls);", findDepMethod.Name); StringBuilder classSB = new StringBuilder(); classSB.AppendLine(m_settings.Header); classSB.AppendLine(); classSB.AppendFrmt(0, "namespace {0}", persistentTypeNs); classSB.AppendLine(0, "{"); classSB.AppendLine(1, "#if RT_USE_PROTOBUF"); classSB.AppendLine(1, "[ProtoContract(AsReferenceDefault = true, ImplicitFields = ImplicitFields.AllFields)]"); for (int i = 0; i < derived.Length; ++i) { Type derivedType = derived[i]; string derivedTypeName = GetPersistentTypeName(derivedType); string derivedTypeNS = GetNormalizedNS(derivedType, persistentTypes); string derivedTypeFullName = CombineNamespaceWithTypeName(derivedTypeNS, derivedTypeName); classSB.AppendFrmt(1, "[ProtoInclude({0}, typeof({1}))]", m_uniqueId, derivedTypeFullName); m_uniqueId++; } classSB.AppendLine(1, "#endif"); classSB.AppendLine(1, "[System.Serializable]"); classSB.AppendFrmt(1, "public class {0} : {1}", persistentTypeName, baseTypeFullName); classSB.AppendLine(1, "{"); classSB.Append(methodsPlaceholder); int addedPropertiesCount = 0; int addedUnityPropertiesCount = 0; int addedPersistentPropertiesCount = 0; bool requireSetter = true;// typeof(ParticleSystem) != type; PropertyInfo[] properties = GetSerializableProperties(type, requireSetter); for (int i = 0; i < properties.Length; ++i) { PropertyInfo property = properties[i]; Type propertyType = property.PropertyType; bool isUnityObjectProperty = IsUnityObjectType(propertyType); bool isPersistentProperty = ContainsType(propertyType, persistentTypes); string propertyName = property.Name; string propertyTypeName; if (isUnityObjectProperty) { if (propertyType.IsArray) { propertyTypeName = "long[]"; } else { propertyTypeName = "long"; } } else if (isPersistentProperty) { propertyTypeName = CombineNamespaceWithTypeName(GetNormalizedNS(propertyType, persistentTypes), GetPersistentTypeName(propertyType)); if (propertyType.IsArray) { persistentTypeName += "[]"; } } else { if (propertyType.IsNested) { propertyTypeName = propertyType.FullName.Replace("+", "."); } else { propertyTypeName = propertyType.FullName; if (m_primitiveNames.ContainsKey(propertyType)) { propertyTypeName = m_primitiveNames[propertyType]; } } } bool isOverrideMethod = false; MethodInfo getMethod = property.GetGetMethod(false); if (getMethod.IsVirtual) { isOverrideMethod = getMethod.GetBaseDefinition() != getMethod; } if (!isOverrideMethod) //No need to generate properties for overriden properties { if (propertyType.IsEnum()) { classSB.AppendFrmt(2, "public uint {0};", propertyName); } else { classSB.AppendFrmt(2, "public {0} {1};", propertyTypeName, propertyName); } classSB.AppendLine(); if (isUnityObjectProperty) { if (propertyType.IsArray) { loadFromSB.AppendFrmt(3, "{0} = o.{0}.{1}();", propertyName, getInstanceIDSMethod.Name); saveToSB.AppendFrmt(3, "o.{0} = Resolve<{1}, UnityEngine.Object>({0}, objects);", propertyName, propertyType.GetElementType().FullName); getDepSB.AppendFrmt(3, "AddDependencies(o.{0}, dependencies);", propertyName); findDepSB.AppendFrmt(3, "AddDependencies({0}, dependencies, objects, allowNulls);", propertyName); } else { loadFromSB.AppendFrmt(3, "{0} = o.{0}.{1}();", propertyName, getInstanceIDMethod.Name); saveToSB.AppendFrmt(3, "o.{0} = ({1})objects.{2}({0});", propertyName, propertyType.FullName, resolveMethod.Name); getDepSB.AppendFrmt(3, "AddDependency(o.{0}, dependencies);", propertyName); findDepSB.AppendFrmt(3, "AddDependency({0}, dependencies, objects, allowNulls);", propertyName); } addedUnityPropertiesCount++; } else if (isPersistentProperty) { loadFromSB.AppendFrmt(3, "{0} = Read({0}, o.{0});", propertyName); saveToSB.AppendFrmt(3, "o.{0} = Write(o.{0}, {0}, objects);", propertyName); getDepSB.AppendFrmt(3, "GetDependencies({0}, o.{0}, dependencies);", propertyName); findDepSB.AppendFrmt(3, "FindDependencies({0}, dependencies, objects, allowNulls);", propertyName); addedPersistentPropertiesCount++; } else { if (propertyType.IsEnum()) { loadFromSB.AppendFrmt(3, "{0} = (uint)o.{0};", propertyName); } else { loadFromSB.AppendFrmt(3, "{0} = o.{0};", propertyName); } if (propertyName == "tag") { saveToSB.AppendFrmt(3, "try {{ o.{0} = {0}; }}", propertyName); saveToSB.AppendLine(3, "catch (UnityEngine.UnityException e) { UnityEngine.Debug.LogWarning(e.Message); }"); } else { if (propertyType.IsEnum()) { saveToSB.AppendFrmt(3, "o.{0} = ({1}){0};", propertyName, propertyTypeName); } else { saveToSB.AppendFrmt(3, "o.{0} = {0};", propertyName); } } } addedPropertiesCount++; } } if (addedPropertiesCount > 0) { loadFromSB.AppendLine(2, "}"); getDepSB.AppendLine(2, "}"); findDepSB.AppendLine(2, "}"); saveToSB.AppendLine(3, "return o;"); saveToSB.AppendLine(2, "}"); saveToSB.AppendLine(); saveToSB.Append(loadFromSB.ToString()).AppendLine(); saveToSB.Append(findDepSB.ToString()).AppendLine(); if (addedUnityPropertiesCount > 0 || addedPersistentPropertiesCount > 0) { saveToSB.Append(getDepSB.ToString()).AppendLine(); } classSB.AppendLine(1, "}"); classSB.AppendLine("}"); StringBuilder usingsSB = new StringBuilder(); usingsSB.AppendLine("#define RT_USE_PROTOBUF"); usingsSB.AppendLine("#if RT_USE_PROTOBUF"); usingsSB.AppendLine("using ProtoBuf;"); usingsSB.AppendLine("#endif"); if (addedUnityPropertiesCount > 0) { string dictionaryExtNs = typeof(DictionaryExt).Namespace; string objectExtNs = typeof(ObjectExt).Namespace; if (!string.IsNullOrEmpty(dictionaryExtNs)) { usingsSB.AppendFrmt(0, "using {0};", dictionaryExtNs); } if (dictionaryExtNs != objectExtNs) { if (!string.IsNullOrEmpty(objectExtNs)) { usingsSB.AppendFrmt(0, "using {0}", objectExtNs); } } } return(usingsSB.Append(classSB.Replace(methodsPlaceholder, saveToSB.ToString()).ToString()).ToString()); } StringBuilder useProtobuf = new StringBuilder(); useProtobuf.AppendLine("#define RT_USE_PROTOBUF"); useProtobuf.AppendLine("#if RT_USE_PROTOBUF"); useProtobuf.AppendLine("using ProtoBuf;"); useProtobuf.AppendLine("#endif"); classSB.AppendLine(1, "}"); classSB.AppendLine("}"); return(useProtobuf.Append(classSB.Replace(methodsPlaceholder, string.Empty)).ToString()); }
public override PropertyDescriptor[] GetProperties(ComponentEditor editor, object converter) { ILocalization lc = IOC.Resolve <ILocalization>(); bool overrideVoxelSize = editor.NotNullComponents.OfType <NavMeshSurface>().All(nms => nms.overrideVoxelSize); bool overrideTileSize = editor.NotNullComponents.OfType <NavMeshSurface>().All(nms => nms.overrideTileSize); MemberInfo agentTypeInfo = Strong.MemberInfo((NavMeshSurface x) => x.agentTypeID); MemberInfo collectObjectsInfo = Strong.MemberInfo((NavMeshSurface x) => x.collectObjects); MemberInfo useGeometryInfo = Strong.MemberInfo((NavMeshSurface x) => x.useGeometry); MemberInfo defaultAreaInfo = Strong.MemberInfo((NavMeshSurface x) => x.defaultArea); MemberInfo overrideVoxelSizeInfo = Strong.MemberInfo((NavMeshSurface x) => x.overrideVoxelSize); MemberInfo voxelSizeInfo = Strong.MemberInfo((NavMeshSurface x) => x.voxelSize); MemberInfo overrideTileSizeInfo = Strong.MemberInfo((NavMeshSurface x) => x.overrideTileSize); MemberInfo tileSizeInfo = Strong.MemberInfo((NavMeshSurface x) => x.tileSize); MemberInfo buildHightMesh = Strong.MemberInfo((NavMeshSurface x) => x.buildHeightMesh); MethodInfo bakeMethodInfo = Strong.MethodInfo((NavMeshSurface x) => x.BuildNavMesh()); MethodInfo clearMethodInfo = Strong.MethodInfo((NavMeshSurface x) => x.RemoveData()); int settingsCount = NavMesh.GetSettingsCount(); RangeOptions.Option[] agentTypes = new RangeOptions.Option[settingsCount]; for (int i = 0; i < settingsCount; ++i) { var id = NavMesh.GetSettingsByIndex(i).agentTypeID; var name = NavMesh.GetSettingsNameFromID(id); agentTypes[i] = new RangeOptions.Option(name, id); } List <PropertyDescriptor> descriptors = new List <PropertyDescriptor>(); descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_AgentType"), editor.Components, agentTypeInfo) { Range = new RangeOptions(agentTypes) }); descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_CollectObjects"), editor.Components, collectObjectsInfo)); descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_UseGeometry"), editor.Components, useGeometryInfo)); descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_DefaultArea"), editor.Components, defaultAreaInfo)); descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_OverrideVoxelSize"), editor.Components, overrideVoxelSizeInfo) { ValueChangedCallback = () => editor.BuildEditor() }); if (overrideVoxelSize) { descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_VoxelSize"), editor.Components, voxelSizeInfo)); } descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_OverrideTileSize"), editor.Components, overrideTileSizeInfo) { ValueChangedCallback = () => editor.BuildEditor() }); if (overrideTileSize) { descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_TileSize"), editor.Components, tileSizeInfo)); } descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_BuildHeightMesh"), editor.Components, buildHightMesh)); descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_Bake"), editor.Components, bakeMethodInfo) { ValueChangedCallback = () => editor.BuildEditor() }); descriptors.Add(new PropertyDescriptor(lc.GetString("ID_RTNavigation_NavMeshAgentComponentDescriptor_Clear"), editor.Components, clearMethodInfo) { ValueChangedCallback = () => editor.BuildEditor() }); return(descriptors.ToArray()); }