コード例 #1
0
ファイル: Message.cs プロジェクト: zhujingcheng/CP3
        /// <summary>
        /// Inserts a <see cref="Message"/> as the first child of a parent message.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The child's <see cref="Parent"/> field will be set to this message,
        /// as will that of its predecessors.
        /// </para>
        /// <para>
        /// If this message already has a child, the existing child will be appended
        /// as the "oldest" predecessor of the new child. <seealso cref="AddOldestPredecessor"/>
        /// </para>
        /// </remarks>
        /// <param name="newFirstChild">The child to insert.</param>
        public void InsertChild(Message newFirstChild)
        {
            if (newFirstChild.Parent != null)
            {
                throw new ArgumentException("A child Message cannot be inserted if it already has a parent Message.", "newFirstChild");
            }

            // Preserve the existing child.
            Message existing = this.Child;

            // Set the new first child and update its Parent references.
            this.Child = newFirstChild;
            for (Message sibling = newFirstChild; sibling != null; sibling = sibling.Predecessor)
            {
                sibling.Parent = this;
            }

            // Preserve the existing child (after the call to SetChildAndUpdateParents
            // because its Parent reference should already point to this message.
            newFirstChild.AddOldestPredecessor(existing);
        }
コード例 #2
0
ファイル: Message.cs プロジェクト: zhujingcheng/CP3
        /// <summary>
        /// Attempts to combine two forrests of messages.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public virtual void ZipInto(ref Message other)
        {
            if (this == other)
            {
                throw new ArgumentException("A message cannot be zipped into itself.", "other");
            }

            else if (other == null)
            {
                other = this;
                return;
            }

            else if (this.TargetId.Equals(other.TargetId))
            {
                if (this.Parent != other.Parent && this.Parent != null && other.Parent != null)
                {
                    throw new ArgumentException("Two child messages cannot be zipped if they have different parents.", "other");
                }

                // Attempt to copy this message's information into the other one.
                MergeAction result = this.MergeInto(other);

                switch (result)
                {
                case MergeAction.KeepBothInOrder:
                    // The default action: Insert this message chronologically after the other,
                    // and keep all children and information separately from both messages.
                    // (This is the same as if the messages were unrelated, below.)
                    this.AddOldestPredecessor(other);
                    other = this;
                    break;

                case MergeAction.DiscardOther:
                    // The information in this packet completely replaces that in the other.
                    // The other packet is now useless, so we steal its predecessors.
                    this.AddOldestPredecessor(other.Predecessor);
                    other.Predecessor = null;

                    // We can also recursively merge the children, being careful to copy
                    // from this message into the other to preserve chronological order.
                    this.ZipChildrenInto(other);

                    // Then move the children back to be children of this message.
                    // Disconnect the new children's parent first so InsertChild doesn't complain.
                    if (other.Child != null)
                    {
                        for (Message child = other.Child; child != null; child = child.Predecessor)
                        {
                            child.Parent = null;
                        }
                        this.InsertChild(other.Child);
                        other.Child = null;
                    }

                    // Having copied all children, predecessors, and information,
                    // replace the useless message with this one.
                    other = this;
                    break;

                case MergeAction.DiscardThis:
                    // The information in the other packet is "better" than in this packet,
                    // or the subclass has copied all relavent information to the other.
                    // This packet is now useless.  We can also recursively merge the children.
                    other.AddOldestPredecessor(this.Predecessor);
                    this.Predecessor = null;
                    this.ZipChildrenInto(other);
                    break;

                default:
                    throw new ArgumentException("Invalid MergedAction value returned by MergeInto.");
                }
            }
            else
            {
                // If the messages are unrelated, simply arrange them in chronological order,
                // and keep all children and information separately from both messages.
                // (This is the same as MergeAction.KeepBothInOrder, above.)
                this.AddOldestPredecessor(other);
                other = this;
            }
        }