namespace Unity.UIWidgets.foundation { {% macro AbstractNodeMixin(with) %} {% set className = 'AbstractNode' if with == '' else 'AbstractNodeMixin' + with %} {% set extends = '' if with == '' else ' : ' + with %} public class {{className}} {{extends}} { public int depth { get { return _depth; } } int _depth = 0; protected void redepthChild({{className}} child) { D.assert(child.owner == owner); if (child._depth <= _depth) { child._depth = _depth + 1; child.redepthChildren(); } } public virtual void redepthChildren() { } public object owner { get { return _owner; } } object _owner; public bool attached { get { return _owner != null; } } public virtual void attach(object owner) { D.assert(owner != null); D.assert(_owner == null); _owner = owner; } public virtual void detach() { D.assert(_owner != null); _owner = null; D.assert(parent == null || attached == parent.attached); } public {{className}} parent { get { return _parent; } } {{className}} _parent; protected virtual void adoptChild({{className}} child) { D.assert(child != null); D.assert(child._parent == null); D.assert(() => { var node = this; while (node.parent != null) { node = node.parent; } D.assert(node != child); // indicates we are about to create a cycle return true; }); child._parent = this; if (attached) { child.attach(_owner); } redepthChild(child); } protected virtual void dropChild({{className}} child) { D.assert(child != null); D.assert(child._parent == this); D.assert(child.attached == attached); child._parent = null; if (attached) { child.detach(); } } } {% endmacro %} {{ AbstractNodeMixin('') }} {{ AbstractNodeMixin('DiagnosticableTree') }} }