addOrGetNode method
Implementation
Future<Node> addOrGetNode(Type nodeType,
{Object? tag, bool root = false, int depth = 0}) =>
_lockFor(nodeType, tag: tag).synchronized(() async {
Node? existing = getNode(nodeType, tag: tag);
bool instanced = Node.$nodeAnnotation<Instanced>(nodeType) != null;
if (instanced || existing == null) {
PrecisionStopwatch p = PrecisionStopwatch.start();
existing = Curse.clazz(nodeType).constructors.first.construct();
nodes.add(existing!);
existing.$pool = this;
if (root) {
logger ??= existing.logger;
}
existing.$tag = tag;
existing.$rootNode = root;
List<Future> work = [];
for (VariableMirror f in existing.$dependencyFields()) {
Object? tag = (f.metadata
.where((m) => m.reflectee is Tag)
.map((m) => m.reflectee as Tag)
.firstOrNull)
?.value;
work.add(
addOrGetNode(f.type.reflectedType, tag: tag, depth: depth + 1)
.then((d) {
d.$referenceCount++;
reflect(existing).setField(f.simpleName, d);
}));
}
await Future.wait(work);
for (Future<void> Function(Node, NodeStorage, PrecisionStopwatch) f
in onStartPipeline) {
await f(existing, storage, p);
}
}
return existing;
});