build method Null safety

  1. @mustCallSuper
Future<void> build()

Builds the Module and all subModules within it.

It is recommended not to override build() nor put logic in build() unless you have good reason to do so. Aim to build up relevant logic in the constructor.

All logic within this Module must be defined before the call to super.build(). When overriding this method, you should call super.build() as the last thing that you do, and you must always call it.

This method traverses connectivity inwards from this Module's inputs and outputs to determine which Modules are contained within it. During this process, it will set a variety of additional information within the hierarchy.

This function can be used to consume real wallclock time for things like starting up interactions with independent processes (e.g. cosimulation).

This function should only be called one time per Module.

The hierarchy is built "bottom-up", so leaf-level Modules are built before the Modules which contain them.

Implementation

@mustCallSuper
Future<void> build() async {
  if (hasBuilt) {
    throw Exception(
        'This Module has already been built, and can only be built once.');
  }

  // construct the list of modules within this module
  // 1) trace from outputs of this module back to inputs of this module
  for (final output in _outputs.values) {
    await _traceOutputForModuleContents(output, dontAddSignal: true);
  }
  // 2) trace from inputs of all modules to inputs of this module
  for (final input in _inputs.values) {
    await _traceInputForModuleContents(input, dontAddSignal: true);
  }

  // set unique module instance names for submodules
  final uniquifier = Uniquifier();
  for (final module in _modules) {
    module._uniqueInstanceName = uniquifier.getUniqueName(
        initialName: Sanitizer.sanitizeSV(module.name),
        reserved: module.reserveName);
  }

  _hasBuilt = true;
}