예제 #1
0
        private static void ProcessMember(ref ComputeUpdateOperationState state, UpdateMemberInfo animationPath, UpdatableMember updatableMember, List <object> temporaryObjectsList)
        {
            int leaveOffset    = 0;
            var leaveOperation = UpdateOperationType.Invalid;

            var updatableField = updatableMember as UpdatableField;

            if (updatableField != null)
            {
                // Apply field offset
                state.NewOffset += updatableField.Offset;

                if (state.ParseElementEnd == animationPath.Name.Length)
                {
                    // Leaf node, perform the set operation
                    state.UpdateOperations.Add(new UpdateOperation
                    {
                        Type         = updatableField.GetSetOperationType(),
                        Member       = updatableField,
                        AdjustOffset = state.NewOffset - state.PreviousOffset,
                        DataOffset   = animationPath.DataOffset,
                    });
                    state.PreviousOffset = state.NewOffset;
                }
                else if (!updatableField.MemberType.GetTypeInfo().IsValueType)
                {
                    // Only in case of objects we need to enter into them
                    state.UpdateOperations.Add(new UpdateOperation
                    {
                        Type         = UpdateOperationType.EnterObjectField,
                        Member       = updatableField,
                        AdjustOffset = state.NewOffset - state.PreviousOffset,
                    });
                    leaveOperation       = UpdateOperationType.Leave;
                    leaveOffset          = state.NewOffset;
                    state.PreviousOffset = state.NewOffset = 0;
                }
            }
            else
            {
                var updatableProperty = updatableMember as UpdatablePropertyBase;
                if (updatableProperty != null)
                {
                    if (state.ParseElementEnd == animationPath.Name.Length)
                    {
                        // Leaf node, perform the set the value
                        state.UpdateOperations.Add(new UpdateOperation
                        {
                            Type         = updatableProperty.GetSetOperationType(),
                            Member       = updatableProperty,
                            AdjustOffset = state.NewOffset - state.PreviousOffset,
                            DataOffset   = animationPath.DataOffset,
                        });
                        state.PreviousOffset = state.NewOffset;
                    }
                    else
                    {
                        // Otherwise enter into the property
                        bool isStruct             = updatableProperty.MemberType.GetTypeInfo().IsValueType;
                        int  temporaryObjectIndex = -1;

                        if (isStruct)
                        {
                            // Struct properties need a storage area so that we can later set the updated value back into the property
                            leaveOperation       = UpdateOperationType.LeaveAndCopyStructPropertyBase;
                            temporaryObjectIndex = temporaryObjectsList.Count;
                            temporaryObjectsList.Add(Activator.CreateInstance(updatableProperty.MemberType));
                        }
                        else
                        {
                            leaveOperation = UpdateOperationType.Leave;
                        }

                        state.UpdateOperations.Add(new UpdateOperation
                        {
                            Type            = updatableProperty.GetEnterOperationType(),
                            Member          = updatableProperty,
                            AdjustOffset    = state.NewOffset - state.PreviousOffset,
                            DataOffset      = temporaryObjectIndex,
                            SkipCountIfNull = -1,
                        });

                        leaveOffset          = state.NewOffset;
                        state.PreviousOffset = state.NewOffset = 0;
                    }
                }
            }

            // No need to add the last part of the path, as we rarely set and then enter (and if we do we need to reevaluate updated value anyway)
            if (state.ParseElementEnd < animationPath.Name.Length)
            {
                state.StackPath.Add(new AnimationBuilderStackEntry(updatableMember.MemberType, state.ParseElementStart, state.ParseElementEnd, state.UpdateOperations.Count - 1)
                {
                    Member            = updatableMember,
                    LeaveOperation    = leaveOperation,
                    LeaveOffset       = leaveOffset,
                    ObjectStartOffset = state.NewOffset
                });
            }
        }
예제 #2
0
        private static void ProcessMember(ref ComputeUpdateOperationState state, UpdateMemberInfo animationPath, UpdatableMember updatableMember, List<object> temporaryObjectsList)
        {
            int leaveOffset = 0;
            var leaveOperation = UpdateOperationType.Invalid;

            var updatableField = updatableMember as UpdatableField;
            if (updatableField != null)
            {
                // Apply field offset
                state.NewOffset += updatableField.Offset;

                if (state.ParseElementEnd == animationPath.Name.Length)
                {
                    // Leaf node, perform the set operation
                    state.UpdateOperations.Add(new UpdateOperation
                    {
                        Type = updatableField.GetSetOperationType(),
                        Member = updatableField,
                        AdjustOffset = state.NewOffset - state.PreviousOffset,
                        DataOffset = animationPath.DataOffset,
                    });
                    state.PreviousOffset = state.NewOffset;
                }
                else if (!updatableField.MemberType.GetTypeInfo().IsValueType)
                {
                    // Only in case of objects we need to enter into them
                    state.UpdateOperations.Add(new UpdateOperation
                    {
                        Type = UpdateOperationType.EnterObjectField,
                        Member = updatableField,
                        AdjustOffset = state.NewOffset - state.PreviousOffset,
                    });
                    leaveOperation = UpdateOperationType.Leave;
                    leaveOffset = state.NewOffset;
                    state.PreviousOffset = state.NewOffset = 0;
                }
            }
            else
            {
                var updatableProperty = updatableMember as UpdatablePropertyBase;
                if (updatableProperty != null)
                {
                    if (state.ParseElementEnd == animationPath.Name.Length)
                    {
                        // Leaf node, perform the set the value
                        state.UpdateOperations.Add(new UpdateOperation
                        {
                            Type = updatableProperty.GetSetOperationType(),
                            Member = updatableProperty,
                            AdjustOffset = state.NewOffset - state.PreviousOffset,
                            DataOffset = animationPath.DataOffset,
                        });
                        state.PreviousOffset = state.NewOffset;
                    }
                    else
                    {
                        // Otherwise enter into the property
                        bool isStruct = updatableProperty.MemberType.GetTypeInfo().IsValueType;
                        int temporaryObjectIndex = -1;

                        if (isStruct)
                        {
                            // Struct properties need a storage area so that we can later set the updated value back into the property
                            leaveOperation = UpdateOperationType.LeaveAndCopyStructPropertyBase;
                            temporaryObjectIndex = temporaryObjectsList.Count;
                            temporaryObjectsList.Add(Activator.CreateInstance(updatableProperty.MemberType));
                        }
                        else
                        {
                            leaveOperation = UpdateOperationType.Leave;
                        }

                        state.UpdateOperations.Add(new UpdateOperation
                        {
                            Type = updatableProperty.GetEnterOperationType(),
                            Member = updatableProperty,
                            AdjustOffset = state.NewOffset - state.PreviousOffset,
                            DataOffset = temporaryObjectIndex,
                            SkipCountIfNull = -1,
                        });

                        leaveOffset = state.NewOffset;
                        state.PreviousOffset = state.NewOffset = 0;
                    }
                }
            }

            // No need to add the last part of the path, as we rarely set and then enter (and if we do we need to reevaluate updated value anyway)
            if (state.ParseElementEnd < animationPath.Name.Length)
            {
                state.StackPath.Add(new AnimationBuilderStackEntry(updatableMember.MemberType, state.ParseElementStart, state.ParseElementEnd, state.UpdateOperations.Count - 1)
                {
                    Member = updatableMember,
                    LeaveOperation = leaveOperation,
                    LeaveOffset = leaveOffset,
                    ObjectStartOffset = state.NewOffset
                });
            }
        }