findComponent<T> method

  1. @override
T findComponent<T>(
  1. Find<T> finder,
  2. TreeNode? scope
)
override

Implementation

@override
T findComponent<T>(Find<T> finder, TreeNode? scope) {
  TreeNode? search(TreeNode node, Find<T> finder) {
    if (node case ServiceTreeNode(:final instance?)
        when finder.isCandidate(instance)) {
      return node;
    }

    for (final child in node.children) {
      if (search(child, finder) case final result?) {
        return result;
      }
    }

    return null;
  }

  TreeNode? peerSearch(TreeNode node, Find<T> finder) {
    if (node.parent case final parent?) {
      for (final child in parent.children) {
        if (child == node) continue;
        if (search(child, finder) case final result?) {
          return result;
        }
      }

      return peerSearch(parent, finder);
    }

    return null;
  }

  if (scope == null && _root != null) {
    final resultNode = search(_root!, finder);
    if (resultNode == null) {
      if (null is T) {
        return null as T;
      } else {
        throw ApiException('Could not find component with $finder.');
      }
    }
    return (resultNode as ServiceTreeNode).instance as T;
  } else if (scope case final node?) {
    final resultNode = peerSearch(node, finder);
    if (resultNode == null) {
      if (null is T) {
        return null as T;
      } else {
        throw ApiException('Could not find component with $finder.');
      }
    }
    return (resultNode as ServiceTreeNode).instance as T;
  } else {
    if (null is T) {
      return null as T;
    } else {
      throw const ApiException('Component tree not initialized.');
    }
  }
}