diff options
Diffstat (limited to 'cura/Machines/ContainerTree.py')
-rw-r--r-- | cura/Machines/ContainerTree.py | 149 |
1 files changed, 88 insertions, 61 deletions
diff --git a/cura/Machines/ContainerTree.py b/cura/Machines/ContainerTree.py index a7bb0610bd..904f66e96e 100644 --- a/cura/Machines/ContainerTree.py +++ b/cura/Machines/ContainerTree.py @@ -19,17 +19,16 @@ if TYPE_CHECKING: from UM.Settings.ContainerStack import ContainerStack -## This class contains a look-up tree for which containers are available at -# which stages of configuration. -# -# The tree starts at the machine definitions. For every distinct definition -# there will be one machine node here. -# -# All of the fallbacks for material choices, quality choices, etc. should be -# encoded in this tree. There must always be at least one child node (for -# nodes that have children) but that child node may be a node representing the -# empty instance container. class ContainerTree: + """This class contains a look-up tree for which containers are available at which stages of configuration. + + The tree starts at the machine definitions. For every distinct definition there will be one machine node here. + + All of the fallbacks for material choices, quality choices, etc. should be encoded in this tree. There must + always be at least one child node (for nodes that have children) but that child node may be a node representing + the empty instance container. + """ + __instance = None # type: Optional["ContainerTree"] @classmethod @@ -43,13 +42,15 @@ class ContainerTree: self.materialsChanged = Signal() # Emitted when any of the material nodes in the tree got changed. cura.CuraApplication.CuraApplication.getInstance().initializationFinished.connect(self._onStartupFinished) # Start the background task to load more machine nodes after start-up is completed. - ## Get the quality groups available for the currently activated printer. - # - # This contains all quality groups, enabled or disabled. To check whether - # the quality group can be activated, test for the - # ``QualityGroup.is_available`` property. - # \return For every quality type, one quality group. def getCurrentQualityGroups(self) -> Dict[str, "QualityGroup"]: + """Get the quality groups available for the currently activated printer. + + This contains all quality groups, enabled or disabled. To check whether the quality group can be activated, + test for the ``QualityGroup.is_available`` property. + + :return: For every quality type, one quality group. + """ + global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack() if global_stack is None: return {} @@ -58,14 +59,15 @@ class ContainerTree: extruder_enabled = [extruder.isEnabled for extruder in global_stack.extruderList] return self.machines[global_stack.definition.getId()].getQualityGroups(variant_names, material_bases, extruder_enabled) - ## Get the quality changes groups available for the currently activated - # printer. - # - # This contains all quality changes groups, enabled or disabled. To check - # whether the quality changes group can be activated, test for the - # ``QualityChangesGroup.is_available`` property. - # \return A list of all quality changes groups. def getCurrentQualityChangesGroups(self) -> List["QualityChangesGroup"]: + """Get the quality changes groups available for the currently activated printer. + + This contains all quality changes groups, enabled or disabled. To check whether the quality changes group can + be activated, test for the ``QualityChangesGroup.is_available`` property. + + :return: A list of all quality changes groups. + """ + global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack() if global_stack is None: return [] @@ -74,31 +76,43 @@ class ContainerTree: extruder_enabled = [extruder.isEnabled for extruder in global_stack.extruderList] return self.machines[global_stack.definition.getId()].getQualityChangesGroups(variant_names, material_bases, extruder_enabled) - ## Ran after completely starting up the application. def _onStartupFinished(self) -> None: + """Ran after completely starting up the application.""" + currently_added = ContainerRegistry.getInstance().findContainerStacks() # Find all currently added global stacks. JobQueue.getInstance().add(self._MachineNodeLoadJob(self, currently_added)) - ## Dictionary-like object that contains the machines. - # - # This handles the lazy loading of MachineNodes. class _MachineNodeMap: + """Dictionary-like object that contains the machines. + + This handles the lazy loading of MachineNodes. + """ + def __init__(self) -> None: self._machines = {} # type: Dict[str, MachineNode] - ## Returns whether a printer with a certain definition ID exists. This - # is regardless of whether or not the printer is loaded yet. - # \param definition_id The definition to look for. - # \return Whether or not a printer definition exists with that name. def __contains__(self, definition_id: str) -> bool: + """Returns whether a printer with a certain definition ID exists. + + This is regardless of whether or not the printer is loaded yet. + + :param definition_id: The definition to look for. + + :return: Whether or not a printer definition exists with that name. + """ + return len(ContainerRegistry.getInstance().findContainersMetadata(id = definition_id)) > 0 - ## Returns a machine node for the specified definition ID. - # - # If the machine node wasn't loaded yet, this will load it lazily. - # \param definition_id The definition to look for. - # \return A machine node for that definition. def __getitem__(self, definition_id: str) -> MachineNode: + """Returns a machine node for the specified definition ID. + + If the machine node wasn't loaded yet, this will load it lazily. + + :param definition_id: The definition to look for. + + :return: A machine node for that definition. + """ + if definition_id not in self._machines: start_time = time.time() self._machines[definition_id] = MachineNode(definition_id) @@ -106,46 +120,58 @@ class ContainerTree: Logger.log("d", "Adding container tree for {definition_id} took {duration} seconds.".format(definition_id = definition_id, duration = time.time() - start_time)) return self._machines[definition_id] - ## Gets a machine node for the specified definition ID, with default. - # - # The default is returned if there is no definition with the specified - # ID. If the machine node wasn't loaded yet, this will load it lazily. - # \param definition_id The definition to look for. - # \param default The machine node to return if there is no machine - # with that definition (can be ``None`` optionally or if not - # provided). - # \return A machine node for that definition, or the default if there - # is no definition with the provided definition_id. def get(self, definition_id: str, default: Optional[MachineNode] = None) -> Optional[MachineNode]: + """Gets a machine node for the specified definition ID, with default. + + The default is returned if there is no definition with the specified ID. If the machine node wasn't + loaded yet, this will load it lazily. + + :param definition_id: The definition to look for. + :param default: The machine node to return if there is no machine with that definition (can be ``None`` + optionally or if not provided). + + :return: A machine node for that definition, or the default if there is no definition with the provided + definition_id. + """ + if definition_id not in self: return default return self[definition_id] - ## Returns whether we've already cached this definition's node. - # \param definition_id The definition that we may have cached. - # \return ``True`` if it's cached. def is_loaded(self, definition_id: str) -> bool: + """Returns whether we've already cached this definition's node. + + :param definition_id: The definition that we may have cached. + + :return: ``True`` if it's cached. + """ + return definition_id in self._machines - ## Pre-loads all currently added printers as a background task so that - # switching printers in the interface is faster. class _MachineNodeLoadJob(Job): - ## Creates a new background task. - # \param tree_root The container tree instance. This cannot be - # obtained through the singleton static function since the instance - # may not yet be constructed completely. - # \param container_stacks All of the stacks to pre-load the container - # trees for. This needs to be provided from here because the stacks - # need to be constructed on the main thread because they are QObject. + """Pre-loads all currently added printers as a background task so that switching printers in the interface is + faster. + """ + def __init__(self, tree_root: "ContainerTree", container_stacks: List["ContainerStack"]) -> None: + """Creates a new background task. + + :param tree_root: The container tree instance. This cannot be obtained through the singleton static + function since the instance may not yet be constructed completely. + :param container_stacks: All of the stacks to pre-load the container trees for. This needs to be provided + from here because the stacks need to be constructed on the main thread because they are QObject. + """ + self.tree_root = tree_root self.container_stacks = container_stacks super().__init__() - ## Starts the background task. - # - # The ``JobQueue`` will schedule this on a different thread. def run(self) -> None: + """Starts the background task. + + The ``JobQueue`` will schedule this on a different thread. + """ + Logger.log("d", "Started background loading of MachineNodes") for stack in self.container_stacks: # Load all currently-added containers. if not isinstance(stack, GlobalStack): continue @@ -156,3 +182,4 @@ class ContainerTree: definition_id = stack.definition.getId() if not self.tree_root.machines.is_loaded(definition_id): _ = self.tree_root.machines[definition_id] + Logger.log("d", "All MachineNode loading completed")
\ No newline at end of file |