node.dart 1.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

class AbstractNode {

  // AbstractNode represents a node in a tree.
  // The AbstractNode protocol is described in README.md.

  int _depth = 0;
  int get depth => _depth;
  void redepthChild(AbstractNode child) { // internal, do not call
    assert(child._attached == _attached);
    if (child._depth <= _depth) {
      child._depth = _depth + 1;
      child.redepthChildren();
    }
  }
  void redepthChildren() { // internal, do not call
    // override this in subclasses with child nodes
    // simply call redepthChild(child) for each child
  }

  bool _attached = false;
  bool get attached => _attached;
  void attach() {
    // override this in subclasses with child nodes
    // simply call attach() for each child then call your superclass
    _attached = true;
    attachChildren();
  }
  attachChildren() { } // workaround for lack of inter-class mixins in Dart
  void detach() {
    // override this in subclasses with child nodes
    // simply call detach() for each child then call your superclass
    _attached = false;
    detachChildren();
  }
  detachChildren() { } // workaround for lack of inter-class mixins in Dart

  AbstractNode _parent;
  AbstractNode get parent => _parent;
  void adoptChild(AbstractNode child) { // only for use by subclasses
    assert(child != null);
    assert(child._parent == null);
    child._parent = this;
    if (attached)
      child.attach();
    redepthChild(child);
  }
  void dropChild(AbstractNode child) { // only for use by subclasses
    assert(child != null);
    assert(child._parent == this);
    assert(child.attached == attached);
    child._parent = null;
    if (attached)
      child.detach();
  }

}