mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-24 07:03:56 -06:00
Rework container tree structure
This sets up a few new classes, subclasses of ContainerNode. This is intended to simplify the current structure in the QualityManager. Contributes to issue CURA-6600.
This commit is contained in:
parent
037f1967c8
commit
9fda7bd0b9
6 changed files with 136 additions and 63 deletions
|
@ -1,64 +1,71 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from typing import Optional, Any, Dict, Union, TYPE_CHECKING
|
||||
|
||||
from collections import OrderedDict
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Logger import Logger
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from UM.Decorators import deprecated
|
||||
|
||||
|
||||
##
|
||||
# A metadata / container combination. Use getContainer() to get the container corresponding to the metadata.
|
||||
#
|
||||
# ContainerNode is a multi-purpose class. It has two main purposes:
|
||||
# 1. It encapsulates an InstanceContainer. It contains that InstanceContainer's
|
||||
# - metadata (Always)
|
||||
# - container (lazy-loaded when needed)
|
||||
# 2. It also serves as a node in a hierarchical InstanceContainer lookup table/tree.
|
||||
# This is used in Variant, Material, and Quality Managers.
|
||||
## A node in the container tree. It represents one container.
|
||||
#
|
||||
# The container it represents is referenced by its container_id. During normal
|
||||
# use of the tree, this container is not constructed. Only when parts of the
|
||||
# tree need to get loaded in the container stack should it get constructed.
|
||||
class ContainerNode:
|
||||
__slots__ = ("_metadata", "_container", "children_map")
|
||||
## Creates a new node for the container tree.
|
||||
# \param container_id The ID of the container that this node should
|
||||
# represent.
|
||||
# \param parent The parent container node, if any.
|
||||
def __init__(self, container_id: str, parent: Optional["ContainerNode"]) -> None:
|
||||
self.container_id = container_id
|
||||
self.parent = parent
|
||||
self._container = None # type: Optional[InstanceContainer]
|
||||
self.children_map = {} # type: Dict[str, ContainerNode] # Mapping from container ID to container node.
|
||||
|
||||
def __init__(self, metadata: Optional[Dict[str, Any]] = None) -> None:
|
||||
self._metadata = metadata
|
||||
self._container = None # type: Optional[InstanceContainer]
|
||||
self.children_map = OrderedDict() # type: ignore # This is because it's children are supposed to override it.
|
||||
|
||||
## Get an entry value from the metadata
|
||||
## Get an entry from the metadata of the container that this node contains.
|
||||
# \param entry The metadata entry key to return.
|
||||
# \param default If the metadata is not present or the container is not
|
||||
# found, the value of this default is returned.
|
||||
# \return The value of the metadata entry, or the default if it was not
|
||||
# present.
|
||||
@deprecated("Get the metadata from the container with the ID of this node yourself.", "4.3")
|
||||
def getMetaDataEntry(self, entry: str, default: Any = None) -> Any:
|
||||
if self._metadata is None:
|
||||
container_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = self.container_id)
|
||||
if len(container_metadata) == 0:
|
||||
return default
|
||||
return self._metadata.get(entry, default)
|
||||
return container_metadata[0].get(entry, default)
|
||||
|
||||
def getMetadata(self) -> Dict[str, Any]:
|
||||
if self._metadata is None:
|
||||
return {}
|
||||
return self._metadata
|
||||
## Get the child with the specified container ID.
|
||||
# \param child_id The container ID to get from among the children.
|
||||
# \return The child node, or ``None`` if no child is present with the
|
||||
# specified ID.
|
||||
@deprecated("Iterate over the children instead of requesting them one by one.", "4.3")
|
||||
def getChildNode(self, child_id: str) -> Optional["ContainerNode"]:
|
||||
return self.children_map.get(child_id)
|
||||
|
||||
def getChildNode(self, child_key: str) -> Optional["ContainerNode"]:
|
||||
return self.children_map.get(child_key)
|
||||
@deprecated("Use `.container` instead.", "4.3")
|
||||
def getContainer(self) -> Optional[InstanceContainer]:
|
||||
return self.container
|
||||
|
||||
def getContainer(self) -> Optional["InstanceContainer"]:
|
||||
if self._metadata is None:
|
||||
Logger.log("e", "Cannot get container for a ContainerNode without metadata.")
|
||||
return None
|
||||
|
||||
if self._container is None:
|
||||
container_id = self._metadata["id"]
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
container_list = ContainerRegistry.getInstance().findInstanceContainers(id = container_id)
|
||||
if not container_list:
|
||||
Logger.log("e", "Failed to lazy-load container [{container_id}]. Cannot find it.".format(container_id = container_id))
|
||||
## The container that this node's container ID refers to.
|
||||
#
|
||||
# This can be used to finally instantiate the container in order to put it
|
||||
# in the container stack.
|
||||
# \return A container.
|
||||
@property
|
||||
def container(self) -> Optional[InstanceContainer]:
|
||||
if not self._container:
|
||||
container_list = ContainerRegistry.getInstance().findInstanceContainers(id = self.container_id)
|
||||
if len(container_list) == 0:
|
||||
Logger.log("e", "Failed to lazy-load container [{container_id}]. Cannot find it.".format(container_id = self.container_id))
|
||||
error_message = ConfigurationErrorMessage.getInstance()
|
||||
error_message.addFaultyContainers(container_id)
|
||||
error_message.addFaultyContainers(self.container_id)
|
||||
return None
|
||||
self._container = container_list[0]
|
||||
|
||||
return self._container
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "%s[%s]" % (self.__class__.__name__, self.getMetaDataEntry("id"))
|
||||
return "%s[%s]" % (self.__class__.__name__, self.container_id)
|
Loading…
Add table
Add a link
Reference in a new issue