Example #1
0
    public static void RunTests()
    {
        LinkedNode a = new LinkedNode(3, new LinkedNode(5, new LinkedNode(7, null)));
        Console.WriteLine("a = " + Print(a));
        LinkedNode b = new LinkedNode(1, new LinkedNode(2, new LinkedNode(5, new LinkedNode(8, null))));
        Console.WriteLine("b = " + Print(b));
        LinkedNode c = Merge(a, b);
        Console.WriteLine("c = " + Print(c));

        DoublyLinkedNode d = new DoublyLinkedNode(3, new DoublyLinkedNode(5, new DoublyLinkedNode(7, null)));
        Console.WriteLine("d = " + Print(d));
        DoublyLinkedNode e = new DoublyLinkedNode(1, new DoublyLinkedNode(2, new DoublyLinkedNode(5, new DoublyLinkedNode(8, null))));
        Console.WriteLine("e = " + Print(e));
        DoublyLinkedNode f = Merge(d, e);
        Console.WriteLine("f = " + Print(f));
    }
Example #2
0
        /// <summary>
        /// Permanently transitions this lifetime to be either dead or immortal.
        /// No effect if already transitioned to the desired state.
        /// Invalid operation if already transitioned to another state.
        /// </summary>
        public void TransitionPermanently(Phase newPhase) {
            if (newPhase == Phase.Mortal) throw new ArgumentOutOfRangeException("newPhase");
            Action[] callbacks;
            lock (this) {
                // transition
                if (Phase == newPhase)
                    return;
                if (Phase != Phase.Mortal)
                    throw new InvalidOperationException(String.Format("Can't transition from {0} to {1}", Phase, newPhase));
                Phase = newPhase;

                // callbacks
                callbacks = _callbacks == null ? null : _callbacks.EnumerateOthers().ToArray();
                _callbacks = null;
            }
            if (callbacks != null)
                foreach (var callback in callbacks)
                    callback.Invoke();
        }
Example #3
0
    private static DoublyLinkedNode Merge(DoublyLinkedNode l1, DoublyLinkedNode l2)
    {
        DoublyLinkedNode head = null;
        DoublyLinkedNode l1p = l1, l2p = l2;
        if (l1.data < l2.data)
        {
            head = l1;
            l1p = l1.next;
            l1.prev = head;
        } else
        {
            head = l2;
            l2p = l2.next;
            l2.prev = head;
        }
        head.prev = null;
        DoublyLinkedNode cur = head;

        while (l1p != null && l2p != null)
        {
            if (l1p.data < l2p.data)
            {
                cur.next = l1p;
                l1p.prev = cur;
                l1p = l1p.next;
            } else
            {
                cur.next = l2p;
                l2p.prev = cur;
                l2p = l2p.next;
            }
            cur = cur.next;
        }

        cur.next = (l1p != null ? l1p : l2p);
        if (cur.next != null)
        {
            cur.next.prev = cur;
        }

        return head;
    }
Example #4
0
        /// <summary>
        /// Registers the given action to perform when this lifetime is either immortal or dead.
        /// The returned action will remove the registration (of the given action) if invoked before this lifetime becomes immortal or dead.
        /// Runs the given action synchronously if this lifetime is already immortal or dead.
        /// </summary>
        public RegistrationRemover Register(Action action) {
            // hold a weak reference to the node, to ensure it can be collected after the this soul becomes non-mortal
            WeakReference weakNode;
            lock (this) {
                // safe check for already finished
                if (Phase != Phase.Mortal) {
                    action();
                    return Soul.EmptyRemover;
                }

                // add callback for when finished
                if (_callbacks == null) _callbacks = DoublyLinkedNode<Action>.CreateEmptyCycle();
                weakNode = new WeakReference(_callbacks.Prepend(action));
            }

            // cleanup action that removes the registration
            return () => {
                var n = (DoublyLinkedNode<Action>)weakNode.Target;
                if (n == null) return;
                lock (this) n.Unlink();
            };
        }
Example #5
0
 internal DoublyLinkedNode(T value)
 {
     Value = value;
     Prev  = null;
     Next  = null;
 }
        private DoublyLinkedNode <Point> MinimumNode(DoublyLinkedNode <Point> parent, DoublyLinkedNode <Point> left, DoublyLinkedNode <Point> right, Dimension dimension)
        {
            var minimum = parent;

            if (left != null &&
                (dimension == Dimension.X && left.Item.X < minimum.Item.X || dimension == Dimension.Y && left.Item.Y < minimum.Item.Y))
            {
                minimum = left;
            }
            if (right != null &&
                (dimension == Dimension.X && right.Item.X < minimum.Item.X || dimension == Dimension.Y && right.Item.Y < minimum.Item.Y))
            {
                minimum = right;
            }
            return(minimum);
        }
Example #7
0
 public DoublyLinkedNode(int data, DoublyLinkedNode next)
 {
     this.data = data;
     this.next = next;
     if (next != null)
     {
         this.next.prev = this;
     }
 }
Example #8
0
 private static string Print(DoublyLinkedNode p)
 {
     string o = "f: " + p.data.ToString();
     while (p.next != null)
     {
         o += " -> " + p.next.data;
         p = p.next;
     }
     o += ',' + " b: " + p.data.ToString();
     while (p.prev != null)
     {
         o += " -> " + p.prev.data;
         p = p.prev;
     }
     return o;
 }