예제 #1
0
        public static void EditProperty(Rect region, object container, InspectedProperty property, fiGraphMetadataChild metadata)
        {
            EditorGUI.BeginChangeCheck();

            object propertyValue = property.Read(container);
            object updatedValue  = EditPropertyDirect(region, property, propertyValue, metadata, container);

            if (EditorGUI.EndChangeCheck())
            {
                property.Write(container, updatedValue);

                // Make sure we propagate the changes up the edit stack. For example, if this property
                // is on a struct on a struct, then the top-level struct will not get modified without
                // propagation of the change check.
                GUI.changed = true;
            }
        }
        /// <summary>
        /// Restores a backup that was previously created.
        /// </summary>
        public static void RestoreBackup(fiSerializedObject serializedState)
        {
            Type targetType    = serializedState.Target.Target.GetType();
            var  inspectedType = InspectedType.Get(targetType);

            var serializationOperator = new fiSerializationOperator()
            {
                SerializedObjects = serializedState.ObjectReferences
            };

            // Fetch the serializer that the target uses
            Type serializerType = BehaviorTypeToSerializerTypeMap.GetSerializerType(targetType);
            var  serializer     = (BaseSerializer)fiSingletons.Get(serializerType);

            foreach (fiSerializedMember member in serializedState.Members)
            {
                // user requested a skip for restoring this property
                if (member.ShouldRestore.Enabled == false)
                {
                    continue;
                }

                InspectedProperty property = inspectedType.GetPropertyByName(member.Name);
                if (property != null)
                {
                    Type   storageType   = property.StorageType;
                    object restoredValue = serializer.Deserialize(storageType, member.Value, serializationOperator);
                    property.Write(serializedState.Target.Target, restoredValue);
                }
            }

            if (serializedState.Target.Target is ISerializedObject)
            {
                var serializedObj = ((ISerializedObject)serializedState.Target.Target);
                serializedObj.SaveState();
                serializedObj.RestoreState();
            }
        }
        private static bool TryToCopyValues(ISerializedObject newInstance)
        {
            if (string.IsNullOrEmpty(newInstance.SharedStateGuid))
            {
                return(false);
            }

            ISerializedObject originalInstance = null;

            lock (_skipSerializationQueue) {
                if (!_skipSerializationQueue.TryGetValue(newInstance.SharedStateGuid, out originalInstance))
                {
                    return(false);
                }
                _skipSerializationQueue.Remove(newInstance.SharedStateGuid);
            }

            // After a prefab is instantiated Unity will call a full
            // serialize/deserialize cycle on the object. We don't need to copy
            // values if the object references are the same.
            if (ReferenceEquals(newInstance, originalInstance))
            {
                return(true);
            }

            var inspectedType = InspectedType.Get(originalInstance.GetType());

            for (int i = 0; i < originalInstance.SerializedStateKeys.Count; ++i)
            {
                InspectedProperty property =
                    inspectedType.GetPropertyByName(originalInstance.SerializedStateKeys[i]) ??
                    inspectedType.GetPropertyByFormerlySerializedName(originalInstance.SerializedStateKeys[i]);
                property.Write(newInstance, property.Read(originalInstance));
            }
            return(true);
        }
예제 #4
0
        public void Write(object context, object value)
        {
            if (byType != null)
            {
                if (value != s_RemoveObject)
                {
                    value = InspectedType.Get((Type)value).CreateInstance();
                }
                byType[byType.Length - 1].Write(context, value);
                return;
            }

            // The property was potentially found on a different type. We need to
            // update it to associate with this type. It's very possible the
            // property will not even apply to context, in which case Write
            // becomes a no-op.
            InspectedProperty propertyToUse = byProperty;

            if (byProperty.MemberInfo.DeclaringType != context.GetType())
            {
                var childProp = InspectedType.Get(context.GetType()).GetPropertyByName(byProperty.Name);
                if (childProp != null)
                {
                    propertyToUse = childProp;
                }
                else
                {
                    return;
                }
            }

            if (byListIndex >= 0)
            {
                var read = propertyToUse.Read(context);
                var list = (IList)read;

                var elementType = InspectedType.Get(propertyToUse.StorageType).ElementType;

                if (value == s_RemoveObject)
                {
                    fiListUtility.RemoveAt(ref list, elementType, byListIndex);
                }
                else
                {
                    while (byListIndex >= list.Count)
                    {
                        fiListUtility.Add(ref list, elementType);
                    }
                    list[byListIndex] = value;
                }

                // Changing list will not update the actual array reference, so
                // we have to write back to the stored object.
                if (list is Array)
                {
                    propertyToUse.Write(context, list);
                }

                return;
            }

            if (byDictKey != null)
            {
                var read = propertyToUse.Read(context);
                var dict = (IDictionary)read;

                // TODO: Have a separate Write/Remove command, since you might
                //       want to set a dict field to null.
                if (value == s_RemoveObject)
                {
                    dict.Remove(byDictKey);
                }
                else
                {
                    dict[byDictKey] = value;
                }

                return;
            }

            if (value != s_RemoveObject)
            {
                propertyToUse.Write(context, value);
            }
            else
            {
                propertyToUse.Write(context, null);
            }
        }