Exemple #1
0
 public CloneDefinition(
     ICloneFactory cloneFactory,
     CloneDelegate <TEntity> cloneDelegate)
 {
     CloneFactory  = cloneFactory;
     CloneDelegate = cloneDelegate;
 }
Exemple #2
0
        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));
        }
Exemple #3
0
        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);
        }