Blame mono/Contours/Circuit.cs

f6cc12
using System;
f6cc12
f6cc12
namespace Contours {
f6cc12
    public class Circuit<parent, child=""> where Parent: class where Child: class {</parent,>
f6cc12
        public class Entry {
f6cc12
            readonly Child owner;
f6cc12
            Circuit<parent, child=""> circuit;</parent,>
f6cc12
            Entry previous;
f6cc12
            Entry next;
f6cc12
f6cc12
            public Entry(Child owner) { this.owner = owner; }
f6cc12
f6cc12
            public Child getOwner() { return owner; }
f6cc12
            public Circuit<parent, child=""> getCircuit() { return circuit; }</parent,>
f6cc12
            public Parent getParent() {
f6cc12
                Circuit<parent, child=""> circuit = getCircuit();</parent,>
f6cc12
                return circuit == null ? null : circuit.getOwner();
f6cc12
            }
f6cc12
f6cc12
            public Entry getPreviousEntry() { return previous; }
f6cc12
            public Entry getNextEntry() { return next; }
f6cc12
f6cc12
            public Entry getPreviousEntryLinear() {
f6cc12
                Entry e = getPreviousEntry();
f6cc12
                return e == null || e == circuit.last ? null : e;
f6cc12
            }
f6cc12
            public Entry getNextEntryLinear() {
f6cc12
                Entry e = getNextEntry();
f6cc12
                return e == null || e == circuit.first ? null : e;
f6cc12
            }
f6cc12
f6cc12
            public Child getPrevious() {
f6cc12
                Entry e = getPreviousEntry();
f6cc12
                return e == null ? null : e.getOwner();
f6cc12
            }
f6cc12
            public Child getNext() {
f6cc12
                Entry e = getNextEntry();
f6cc12
                return e == null ? null : e.getOwner();
f6cc12
            }
f6cc12
f6cc12
            public Child getPreviousLinear() {
f6cc12
                Entry e = getPreviousEntryLinear();
f6cc12
                return e == null ? null : e.getOwner();
f6cc12
            }
f6cc12
            public Child getNextLinear() {
f6cc12
                Entry e = getNextEntryLinear();
f6cc12
                return e == null ? null : e.getOwner();
f6cc12
            }
f6cc12
f6cc12
            public void unlink() {
f6cc12
                if (previous != null) previous.next = next;
f6cc12
                if (next != null) next.previous = previous;
f6cc12
                
f6cc12
                if (circuit != null) {
f6cc12
                    if (circuit.first == this) {
f6cc12
                        circuit.first = next != this ? next : null;
f6cc12
                        circuit.last = previous != this ? previous : null;
f6cc12
                    }
f6cc12
                    --circuit.count;
f6cc12
                    circuit = null;
f6cc12
                }
f6cc12
                previous = null;
f6cc12
                next = null;
f6cc12
            }
f6cc12
f6cc12
            public void insertBack(Circuit<parent, child=""> circuit) {</parent,>
f6cc12
                unlink();
f6cc12
                if (circuit != null) {
f6cc12
                    if (circuit.empty()) {
f6cc12
                        this.circuit = circuit;
f6cc12
                        previous = next = this;
f6cc12
                        circuit.first = circuit.last = this;
f6cc12
                        ++circuit.count;
f6cc12
                    } else {
f6cc12
                        insertAfterOf(circuit.getLastEntry());
f6cc12
                    }
f6cc12
                }
f6cc12
            }
f6cc12
f6cc12
            public void insertFront(Circuit<parent, child=""> circuit) {</parent,>
f6cc12
                unlink();
f6cc12
                if (circuit != null) {
f6cc12
                    if (circuit.empty()) {
f6cc12
                        this.circuit = circuit;
f6cc12
                        previous = next = this;
f6cc12
                        circuit.first = circuit.last = this;
f6cc12
                        ++circuit.count;
f6cc12
                    } else {
f6cc12
                        insertBeforeOf(circuit.getFirstEntry());
f6cc12
                    }
f6cc12
                }
f6cc12
            }
f6cc12
f6cc12
            public void insertAfterOf(Entry entry) {
f6cc12
                if (entry == this) return;
f6cc12
                unlink();
f6cc12
                if (entry == null || entry.getCircuit() == null) return;
f6cc12
                
f6cc12
                previous = entry;
f6cc12
                next = entry.next;
f6cc12
                previous.next = this;
f6cc12
                if (next != null) next.previous = this;
f6cc12
                circuit = entry.getCircuit();
f6cc12
f6cc12
                if (circuit != null) {
f6cc12
                    if (circuit.getLastEntry() == entry)
f6cc12
                        circuit.last = this;
f6cc12
                    ++circuit.count;
f6cc12
               }
f6cc12
            }
f6cc12
f6cc12
            public void insertBeforeOf(Entry entry) {
f6cc12
                if (entry == this) return;
f6cc12
                unlink();
f6cc12
                if (entry == null || entry.getCircuit() == null) return;
f6cc12
                
f6cc12
                previous = entry.previous;
f6cc12
                next = entry;
f6cc12
                if (previous != null) previous.next = this;
f6cc12
                next.previous = this;
f6cc12
                circuit = entry.getCircuit();
f6cc12
f6cc12
                if (circuit != null) {
f6cc12
                    if (circuit.getFirstEntry() == entry)
f6cc12
                        circuit.first = this;
f6cc12
                    ++circuit.count;
f6cc12
                }
f6cc12
            }
f6cc12
f6cc12
            public void swapWith(Entry other) {
f6cc12
                if (other == this || other == null) return;
f6cc12
f6cc12
                Circuit<parent, child=""> otherCircuit = other.circuit;</parent,>
f6cc12
                Entry otherPrevious = other.previous;
f6cc12
                Entry otherNext = other.next;
f6cc12
f6cc12
                other.circuit = circuit;
f6cc12
                other.previous = previous;
f6cc12
                other.next = next;
f6cc12
f6cc12
                if (otherCircuit != null) {
f6cc12
                    if (otherCircuit.first == other)
f6cc12
                        otherCircuit.first = this;
f6cc12
                    if (otherCircuit.last == other)
f6cc12
                        otherCircuit.last = this;
f6cc12
                }
f6cc12
f6cc12
                if (circuit != null) {
f6cc12
                    if (circuit.first == this)
f6cc12
                        circuit.first = other;
f6cc12
                    if (circuit.last == this)
f6cc12
                        circuit.last = other;
f6cc12
                }
f6cc12
f6cc12
                circuit = otherCircuit;
f6cc12
                previous = otherPrevious;
f6cc12
                next = otherNext;
f6cc12
            }
f6cc12
        }
f6cc12
        
f6cc12
        readonly Parent owner;
f6cc12
        Entry first;
f6cc12
        Entry last;
f6cc12
        int count = 0;
f6cc12
f6cc12
        public Circuit(Parent owner) { this.owner = owner; }
f6cc12
f6cc12
        public Parent getOwner() { return owner; }
f6cc12
        public int getCount() { return count; }
f6cc12
f6cc12
        public Entry getFirstEntry() { return first; }
f6cc12
        public Entry getLastEntry() { return last; }
f6cc12
f6cc12
        public Child getFirst() {
f6cc12
            Entry e = getFirstEntry();
f6cc12
            return e == null ? null : e.getOwner();
f6cc12
        }
f6cc12
        public Child getLast() {
f6cc12
            Entry e = getLastEntry();
f6cc12
            return e == null ? null : e.getOwner();
f6cc12
        }
f6cc12
f6cc12
        public bool empty() { return getFirstEntry() == null; }
f6cc12
f6cc12
        public void clear() {
f6cc12
            while(!empty()) getFirstEntry().unlink();
f6cc12
        }
f6cc12
    }
f6cc12
}
f6cc12