How Does run_as work?
ModuleManager::run_as
is the workhorse of running a call graph. The point
of this page is to succinctly summarize the behind-the-scenes actions of this
function.
The call graph of ModuleManager::run_as
(as seen from C++) is summarized in
Fig. 15. Briefly:
Many users enter the call graph via
ModuleManager::run_as
; however, this method simply wraps retrieving the specified module and forwarding the results to that module’sModule::run_as
method.Module::run_as
is the typed user interface. It works with the objects’ native C++ types, i.e., inputs and results are actual C++ objects. Under the hoodModule::run_as
is responsible for type-erasing inputs and restoring types to results.PropertyType::wrap_inputs
this is the method thatModule::run_as
calls to type-erase the inputs. The property type class is essentially a schema written in terms of domain-specific types.With type-erased inputs the next call is to the type-erased user-interface,
Module::run
.The first thing
Module::run
does is to merge the user-provided inputs with the bound inputs. The result is the full set of inputs for the module.Next,
Module::run
determines if the module is ready to run, e.g., does it have all the inputs needed to run? Has a submodule been assigned to each callback point? Is each submodule ready to run?Assuming the module is ready to run,
Module::run
then locks the module (and all submodules). A locked module can no longer have its options or submodules changed.After locking the module, the actual module contents are run via
ModuleBase::run
(which calls the derived class’srun_
method).The results of
Module::run
are type-erased, so the final step is forModule::run_as
to restore their types before returning them to the user.