walkByNodesAsync<R> method
Future<R?>
walkByNodesAsync<R>(
- Iterable<
Node< from, {T> > - required GraphWalkNodeOutputsProviderAsync<
T> outputsProvider, - required GraphWalkNodeProcessorAsync<
T, R> process, - GraphWalkSideBranchProcessorAsync<
T, R> ? processSideBranches, - bool expandSideBranches = false,
- int? maxDepth,
A generic walk algorithm using Nodes.
Implementation
Future<R?> walkByNodesAsync<R>(
Iterable<Node<T>> from, {
required GraphWalkNodeOutputsProviderAsync<T> outputsProvider,
required GraphWalkNodeProcessorAsync<T, R> process,
GraphWalkSideBranchProcessorAsync<T, R>? processSideBranches,
bool expandSideBranches = false,
int? maxDepth,
}) async {
maxDepth ??= defaultMaxDepth;
final processed = _processedNodes;
final queue = ListQueue<GraphNodeStep<T>>();
if (sortByInputDependency) {
from = from.sortedByInputDependency();
}
queue.addAll(from.toGraphRootStep(this));
while (queue.isNotEmpty) {
final step = queue.removeFirst();
final node = step.node;
var processCount = processed.increment(node);
if (processCount <= maxExpansion && step.depth <= maxDepth) {
if (processRoots || step.isNotRoot) {
var ret = await process(step);
if (ret == null && processSideBranches != null) {
var sideBranches = _computeSideBranch(node, processed);
if (sideBranches.isNotEmpty) {
if (sortByInputDependency) {
sideBranches = sideBranches.sortedByInputDependency();
}
ret = await processSideBranches(step, sideBranches);
}
}
if (ret != null) {
if (ret is GraphWalkingInstructionResult) {
return ret.result as R?;
} else if (ret is GraphWalkingInstructionOperation) {
switch (ret.operation) {
case GraphWalkingOperation.stop:
return null;
case GraphWalkingOperation.next:
continue;
}
} else if (ret is GraphWalkingInstructionSetExpansionCounter) {
processed[node] = ret.count;
} else if (ret is GraphWalkingInstructionSetNodesExpansionCounter) {
processed.addCounter(ret.counter);
} else {
return _resolveWalkProcessReturn<T, R>(node, ret);
}
}
}
if (stopMatcher.matchesNode(node)) {
return _resolveWalkProcessReturn<T, R>(node, true);
}
List<Node<T>>? sideBranches;
if (expandSideBranches && processSideBranches == null) {
sideBranches = _computeSideBranch(node, processed);
if (sortByInputDependency) {
sideBranches = sideBranches.sortedByInputDependency();
}
}
var outputs = await outputsProvider(step, node);
if (sortByInputDependency) {
outputs = outputs?.sortedByInputDependency();
}
var nextStepsSideBranches =
sideBranches?.toGraphNodeStep(step, sideBranch: true);
var nextStepsOutputs = outputs?.toGraphNodeStep(step);
queue.addAllToScanQueue2(nextStepsSideBranches, nextStepsOutputs, bfs);
}
}
return _resolveWalkProcessReturn<T, R>(null, false);
}