public CloneDefinition( ICloneFactory cloneFactory, CloneDelegate <TEntity> cloneDelegate) { CloneFactory = cloneFactory; CloneDelegate = cloneDelegate; }
public ICloneDefinition <TEntity> Create <TEntity>(ICloneFactory cloneFactory) where TEntity : class { IExpressionBuilder expressionBuilder = ExpressionBuilderFactory.Create(); CloneDelegate <TEntity> cloneDelegate = AssembleExpression <TEntity>(expressionBuilder); return(new CloneDefinition <TEntity>(cloneFactory, cloneDelegate)); }
public TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema) { var runtimeSchema = TypeSchema.FromType(typeof(T), serializers.RuntimeVersion, this.GetType(), Version); var members = runtimeSchema.GetCompatibleMemberSet(targetSchema); this.deserializeImpl = Generator.GenerateDeserializeMethod <T>(il => Generator.EmitDeserializeFields(typeof(T), serializers, il, members)); this.serializeImpl = Generator.GenerateSerializeMethod <T>(il => Generator.EmitSerializeFields(typeof(T), serializers, il, members)); this.cloneImpl = Generator.GenerateCloneMethod <T>(il => Generator.EmitCloneFields(typeof(T), serializers, il)); this.clearImpl = Generator.GenerateClearMethod <T>(il => Generator.EmitClearFields(typeof(T), serializers, il)); return(targetSchema ?? runtimeSchema); }
private static void CloneScriptableSubAssets(Dictionary <int, Tuple <object, bool> > remap, object o, CloneDelegate clone) { int hashCode = RuntimeHelpers.GetHashCode(o); if (remap.ContainsKey(hashCode) == false) { remap.Add(hashCode, new Tuple <object, bool>(o, false)); } List <FieldInfo> fieldsInfos = GetAllFields(o.GetType(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fieldsInfos) { Type fieldType = fieldInfo.FieldType; if (fieldInfo.IsPublic == false) { if (fieldInfo.GetCustomAttribute <SerializeField>() == null) { continue; } } else { if (fieldInfo.GetCustomAttribute <NonSerializedAttribute>() != null) { continue; } } if (fieldType.IsArray) { Array array = fieldInfo.GetValue(o) as Array; if (array == null) { continue; } int arrayLength = array.Length; for (int i = 0; i < arrayLength; i++) { object asset = array.GetValue(i); if (asset == null) { continue; } Type assetType = asset.GetType(); if (assetType.IsPrimitive) { continue; } if (assetType.IsEnum) { continue; } if (assetType.IsGenericType) { continue; } if (assetType.IsConstructedGenericType) { continue; } int instanceId = RuntimeHelpers.GetHashCode(asset); Tuple <object, bool> result; if (remap.TryGetValue(instanceId, out result)) { if (result.Item2)//is clone { array.SetValue(result.Item1, i); } } else { if (asset is ScriptableObject) { ScriptableObject scriptableObject = clone(asset as ScriptableObject); if (scriptableObject != null) { asset = scriptableObject; remap.Add(instanceId, new Tuple <object, bool>(scriptableObject, true)); } else { remap.Add(instanceId, new Tuple <object, bool>(asset, false)); } } array.SetValue(asset, i); CloneScriptableSubAssets(remap, asset, clone); } } } else if (fieldType.IsGenericType && (fieldType.GetGenericTypeDefinition() == typeof(List <>))) { IList list = fieldInfo.GetValue(o) as IList; if (list == null) { continue; } int count = list.Count; for (var index = 0; index < count; index++) { object asset = list[index]; if (asset == null) { continue; } Type assetType = asset.GetType(); if (assetType.IsPrimitive) { continue; } if (assetType.IsEnum) { continue; } if (assetType.IsGenericType) { continue; } if (assetType.IsConstructedGenericType) { continue; } int instanceId = RuntimeHelpers.GetHashCode(asset); Tuple <object, bool> result; if (remap.TryGetValue(instanceId, out result)) { if (result.Item2)//is clone { list[index] = result.Item1; } } else { if (asset is ScriptableObject) { ScriptableObject scriptableObject = clone(asset as ScriptableObject); if (scriptableObject != null) { asset = scriptableObject; remap.Add(instanceId, new Tuple <object, bool>(scriptableObject, true)); } else { remap.Add(instanceId, new Tuple <object, bool>(asset, false)); } } list[index] = asset; CloneScriptableSubAssets(remap, asset, clone); } } } else { object asset = fieldInfo.GetValue(o); if (asset != null) { Type assetType = asset.GetType(); if (assetType.IsPrimitive) { continue; } if (assetType.IsEnum) { continue; } if (assetType.IsGenericType) { continue; } if (assetType.IsConstructedGenericType) { continue; } int instanceId = RuntimeHelpers.GetHashCode(asset); Tuple <object, bool> result; if (remap.TryGetValue(instanceId, out result)) { if (result.Item2)//is clone { fieldInfo.SetValue(o, result.Item1); } } else { if (asset is ScriptableObject) { ScriptableObject scriptableObject = clone(asset as ScriptableObject); if (scriptableObject != null) { asset = scriptableObject; remap.Add(instanceId, new Tuple <object, bool>(scriptableObject, true)); } else { remap.Add(instanceId, new Tuple <object, bool>(asset, false)); } } fieldInfo.SetValue(o, asset); CloneScriptableSubAssets(remap, asset, clone); } } } } }
public static T DeepCloneScriptableObject <T>(this T scriptableObject, out List <ScriptableObject> instances, CloneDelegate clone) where T : ScriptableObject { T copy = Object.Instantiate(scriptableObject); Dictionary <int, Tuple <object, bool> > objDictionary = new Dictionary <int, Tuple <object, bool> >(128); int hashCode = RuntimeHelpers.GetHashCode(scriptableObject); objDictionary.Add(hashCode, new Tuple <object, bool>(copy, true)); CloneScriptableSubAssets(objDictionary, copy, clone); instances = new List <ScriptableObject>(128); foreach (var o in objDictionary) { if (o.Value.Item2 == false)//not a clone { continue; } if (o.Value.Item1 is ScriptableObject) { instances.Add(o.Value.Item1 as ScriptableObject); } } return(copy); }