################# MainTaskComposer ################# Purpose ------- The ``MainTaskComposer`` builds a Task/LeafTask tree (MainTask) starting from a command map entry and the current Component Manager context. It resolves: * the root task properties (execution type and allowed conditions), * nested task composition, * subsystem selection and argument binding based on available resources, * generation of INTERNAL tasks targeting Component Manager methods. Composition workflow -------------------- The composition process is initiated by calling ``compose()``: 1. The command entry is retrieved from the command map using the command name. 2. The allowed execution conditions are extracted (attribute name and allowed values). 3. A draft Task tree is created recursively from the map. 4. Empty branches are removed (tasks with no subtasks are discarded). 5. Trackers are instantiated for the remaining Task nodes. Recursive task building ----------------------- Task nodes are built according to two patterns: * **Composite tasks** (contain ``type`` and ``tasks`` keys) These produce a Task with a list of subtasks. Subtasks may themselves be composite tasks or handler keywords. * **Handler keywords** Keywords such as ``cbf``, ``pss``, ``pst``, ``csp_subs`` and ``internal`` are resolved into LeafTasks (or a Task grouping multiple LeafTasks). Unsupported keywords result in a composition error. Subsystem selection and guards ------------------------------ For DEVICE LeafTasks, the composer selects target components from the Component Manager context. For each candidate component, the composer evaluates the guard condition defined by ``allowed_states`` (``attr_name`` and allowed values) against the component attribute. Only components matching the guard condition are selected as execution targets. Argument binding ---------------- For DEVICE tasks, LeafTask input arguments (``argin``) are derived from the Component Manager resources configuration. If no suitable component is found (or no applicable resources exist), the corresponding LeafTask is not created. Cleaning of empty branches -------------------------- After building the draft tree, the composer removes tasks whose list of subtasks is empty. This ensures that commands with partially unavailable resources can still produce a valid executable task tree containing only meaningful actions. See also :doc:`command_map`, :doc:`../task_execution/maintask_executor`, and :doc:`../task_tracker/index`.