Remove _added functions for nodes that can't be added during runtime

Among the machines, variants, materials, qualities and intents, only machines and materials can ever be added during runtime. For the rest, we don't need to listen to these signals.

Contributes to issue CURA-6600.
This commit is contained in:
Ghostkeeper 2019-08-16 16:28:42 +02:00
parent 97e77994a1
commit 80baeb9873
No known key found for this signature in database
GPG key ID: 86BEF881AE2CF276
6 changed files with 7 additions and 188 deletions

View file

@ -6,7 +6,6 @@ from typing import Dict, List
from UM.Logger import Logger from UM.Logger import Logger
from UM.Util import parseBool from UM.Util import parseBool
from UM.Settings.ContainerRegistry import ContainerRegistry # To find all the variants for this machine. from UM.Settings.ContainerRegistry import ContainerRegistry # To find all the variants for this machine.
from UM.Settings.Interfaces import ContainerInterface
from cura.Machines.ContainerNode import ContainerNode from cura.Machines.ContainerNode import ContainerNode
from cura.Machines.QualityGroup import QualityGroup # To construct groups of quality profiles that belong together. from cura.Machines.QualityGroup import QualityGroup # To construct groups of quality profiles that belong together.
from cura.Machines.QualityNode import QualityNode from cura.Machines.QualityNode import QualityNode
@ -36,7 +35,6 @@ class MachineNode(ContainerNode):
self.preferred_variant_name = my_metadata.get("preferred_variant_name", "") self.preferred_variant_name = my_metadata.get("preferred_variant_name", "")
self.preferred_quality_type = my_metadata.get("preferred_quality_type", "") self.preferred_quality_type = my_metadata.get("preferred_quality_type", "")
container_registry.containerAdded.connect(self._variantAdded)
self._loadAll() self._loadAll()
## Get the available quality groups for this machine. ## Get the available quality groups for this machine.
@ -101,19 +99,4 @@ class MachineNode(ContainerNode):
if len(global_qualities) == 0: # This printer doesn't override the global qualities. if len(global_qualities) == 0: # This printer doesn't override the global qualities.
global_qualities = container_registry.findInstanceContainersMetadata(type = "quality", definition = "fdmprinter", global_quality = True) # Otherwise pick the global global qualities. global_qualities = container_registry.findInstanceContainersMetadata(type = "quality", definition = "fdmprinter", global_quality = True) # Otherwise pick the global global qualities.
for global_quality in global_qualities: for global_quality in global_qualities:
self.global_qualities[global_quality["quality_type"]] = QualityNode(global_quality["id"], parent = self) self.global_qualities[global_quality["quality_type"]] = QualityNode(global_quality["id"], parent = self)
## When a variant gets added to the set of profiles, we need to update our
# tree here.
def _variantAdded(self, container: ContainerInterface):
if container.getMetaDataEntry("type") != "variant":
return # Not interested.
name = container.getMetaDataEntry("name")
if name in self.variants:
return # Already have this one.
if container.getMetaDataEntry("hardware_type") != "nozzle":
return # Only want nozzles in my tree.
if container.getMetaDataEntry("definition") != self.container_id:
return # Not a nozzle that fits in my machine.
self.variants[name] = VariantNode(container.getId(), machine = self)

View file

@ -4,7 +4,6 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import ContainerInterface
from cura.Machines.ContainerNode import ContainerNode from cura.Machines.ContainerNode import ContainerNode
from cura.Machines.QualityNode import QualityNode from cura.Machines.QualityNode import QualityNode
@ -20,10 +19,8 @@ class MaterialNode(ContainerNode):
super().__init__(container_id) super().__init__(container_id)
self.variant = variant self.variant = variant
self.qualities = {} # type: Dict[str, QualityNode] # Mapping container IDs to quality profiles. self.qualities = {} # type: Dict[str, QualityNode] # Mapping container IDs to quality profiles.
container_registry = ContainerRegistry.getInstance() my_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = container_id)[0]
my_metadata = container_registry.findContainersMetadata(id = container_id)[0]
self.base_file = my_metadata["base_file"] self.base_file = my_metadata["base_file"]
container_registry.containerAdded.connect(self._qualityAdded)
self._loadAll() self._loadAll()
def _loadAll(self) -> None: def _loadAll(self) -> None:
@ -47,39 +44,4 @@ class MaterialNode(ContainerNode):
for quality in qualities: for quality in qualities:
quality_id = quality["id"] quality_id = quality["id"]
if quality_id not in self.qualities: if quality_id not in self.qualities:
self.qualities[quality_id] = QualityNode(quality_id, parent = self) self.qualities[quality_id] = QualityNode(quality_id, parent = self)
def _qualityAdded(self, container: ContainerInterface) -> None:
if container.getMetaDataEntry("type") != "quality":
return # Not interested.
if not self.variant.machine.has_machine_quality:
if container.getMetaDataEntry("definition") != "fdmprinter":
return # Only want global qualities.
else:
if container.getMetaDataEntry("definition") != self.variant.machine.quality_definition:
return # Doesn't match the machine.
if container.getMetaDataEntry("variant") != self.variant.variant_name:
return # Doesn't match the variant.
# Detect if we're falling back to matching via GUID.
# If so, we might need to erase the current list and put just this one in (i.e. no longer use the fallback).
container_registry = ContainerRegistry.getInstance()
my_metadata = container_registry.findInstanceContainersMetadata(id = self.container_id)[0]
my_material_type = my_metadata.get("material")
allowed_material_ids = {metadata["id"] for metadata in container_registry.findInstanceContainersMetadata(type = "material", material = my_material_type)}
# Select any quality profile; if the material is not matching by material type, we've been falling back to GUID all along.
is_fallback_guid = len(self.qualities) == 0 or next(iter(self.qualities.values())).getMetaDataEntry("material") not in allowed_material_ids
if is_fallback_guid and container.getMetaDataEntry("material") in allowed_material_ids: # So far we needed the fallback, but no longer!
self.qualities.clear() # It'll get filled with the new quality profile then.
else:
if not is_fallback_guid:
if container.getMetaDataEntry("material") not in allowed_material_ids:
return # Doesn't match the material type.
else:
my_material_guid = my_metadata.get("GUID")
allowed_material_ids = {metadata["id"] for metadata in container_registry.findInstanceContainersMetadata(type = "material", guid = my_material_guid)}
if container.getMetaDataEntry("material") not in allowed_material_ids:
return # Doesn't match the material GUID.
quality_id = container.getId()
self.qualities[quality_id] = QualityNode(quality_id, parent = self)

View file

@ -4,7 +4,6 @@
from typing import Union, TYPE_CHECKING from typing import Union, TYPE_CHECKING
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import ContainerInterface
from cura.Machines.ContainerNode import ContainerNode from cura.Machines.ContainerNode import ContainerNode
from cura.Machines.IntentNode import IntentNode from cura.Machines.IntentNode import IntentNode
@ -21,7 +20,6 @@ class QualityNode(ContainerNode):
super().__init__(container_id) super().__init__(container_id)
self.parent = parent self.parent = parent
self.intents = {} # type: Dict[str, IntentNode] self.intents = {} # type: Dict[str, IntentNode]
ContainerRegistry.getInstance().containerAdded.connect(self._intentAdded)
self._loadAll() self._loadAll()
def _loadAll(self) -> None: def _loadAll(self) -> None:
@ -31,21 +29,4 @@ class QualityNode(ContainerNode):
if not isinstance(self.parent, MachineNode): # Not a global profile. if not isinstance(self.parent, MachineNode): # Not a global profile.
for intent in container_registry.findInstanceContainersMetadata(type = "intent", definition = self.parent.variant.machine.quality_definition, variant = self.parent.variant.variant_name, material = self.parent.base_file): for intent in container_registry.findInstanceContainersMetadata(type = "intent", definition = self.parent.variant.machine.quality_definition, variant = self.parent.variant.variant_name, material = self.parent.base_file):
self.intents[intent["id"]] = IntentNode(intent["id"], quality = self) self.intents[intent["id"]] = IntentNode(intent["id"], quality = self)
# Otherwise, there are no intents for global profiles. # Otherwise, there are no intents for global profiles.
def _intentAdded(self, container: ContainerInterface) -> None:
from cura.Machines.MachineNode import MachineNode # Imported here to prevent circular imports.
if container.getMetaDataEntry("type") != "intent":
return # Not interested if it's not an intent.
if isinstance(self.parent, MachineNode):
return # Global profiles don't have intents.
if container.getMetaDataEntry("definition") != self.parent.variant.machine.quality_definition:
return # Incorrect printer.
if container.getMetaDataEntry("variant") != self.parent.variant.variant_name:
return # Incorrect variant.
if container.getMetaDataEntry("material") != self.parent.base_file:
return # Incorrect material.
container_id = container.getId()
if container_id in self.intents:
return # Already have this.
self.intents[container_id] = IntentNode(container_id, quality = self)

View file

@ -4,14 +4,6 @@ import pytest
from UM.Settings.Interfaces import ContainerInterface from UM.Settings.Interfaces import ContainerInterface
from cura.Machines.MachineNode import MachineNode from cura.Machines.MachineNode import MachineNode
machine_node_variant_added_test_data = [({"type": "Not a variant!"}, ["Variant One", "Variant Two"]), # Wrong type
({"type": "variant", "name": "Variant One"}, ["Variant One", "Variant Two"]), # Name already added
({"type": "variant", "name": "Variant Three", "hardware_type": "Not a nozzle"}, ["Variant One", "Variant Two"]), # Wrong hardware type
({"type": "variant", "name": "Variant Three", "hardware_type": "nozzle", "definition": "machine_3"}, ["Variant One", "Variant Two"]), # Wrong definition ID
({"type": "variant", "name": "Variant Three", "hardware_type": "nozzle", "definition": "machine_1"}, ["Variant One", "Variant Two", "Variant Three"])] # Yay! It's finally added
metadata_dict = {} metadata_dict = {}
@ -44,18 +36,4 @@ def test_machineNodeInit(container_registry):
# As variants get stored by name, we want to check if those get added. # As variants get stored by name, we want to check if those get added.
assert "Variant One" in machine_node.variants assert "Variant One" in machine_node.variants
assert "Variant Two" in machine_node.variants assert "Variant Two" in machine_node.variants
assert len(machine_node.variants) == 2 # And ensure that *only* those two got added. assert len(machine_node.variants) == 2 # And ensure that *only* those two got added.
@pytest.mark.parametrize("metadata,variant_result_list", machine_node_variant_added_test_data)
def test_machineNodeVariantAdded(container_registry, metadata, variant_result_list):
machine_node = createMachineNode("machine_1", container_registry)
with patch("cura.Machines.MachineNode.VariantNode"): # We're not testing the variant node here, so patch it out.
with patch.dict(metadata_dict, metadata):
mocked_container = createMockedInstanceContainer()
machine_node._variantAdded(mocked_container)
assert len(variant_result_list) == len(machine_node.variants)
for name in variant_result_list:
assert name in machine_node.variants

View file

@ -6,21 +6,6 @@ from cura.Machines.MaterialNode import MaterialNode
instance_container_metadata_dict = {"fdmprinter": {"no_variant": [{"id": "quality_1", "material": "material_1"}]}, instance_container_metadata_dict = {"fdmprinter": {"no_variant": [{"id": "quality_1", "material": "material_1"}]},
"machine_1": {"variant_1": {"material_1": [{"id": "quality_2", "material": "material_1"}, {"id": "quality_3","material": "material_1"}]}}} "machine_1": {"variant_1": {"material_1": [{"id": "quality_2", "material": "material_1"}, {"id": "quality_3","material": "material_1"}]}}}
quality_metadata_machine_quality_test_data = [({"type": "Not a quality"}, ["quality_2", "quality_3"]), # Wrong type
({"type": "quality", "definition": "machine_2"}, ["quality_2", "quality_3"]), # Wrong defintion
({"type": "quality", "definition": "machine_1", "variant": "variant_2"}, ["quality_2", "quality_3"]), # Wrong variant
({"type": "quality", "definition": "machine_1", "variant": "variant_1", "material": "material_2"}, ["quality_2", "quality_3"]), # wrong material
]
quality_metadata_no_machine_quality =[({"type": "Not a quality"}, ["quality_1"]), # Wrong type
({"type": "quality", "definition": "machine_1"}, ["quality_1"]), # Wrong defintion (it needs fdmprinter)
({"type": "quality", "definition": "fdmprinter", "variant": "variant_2"}, ["quality_1", "quality_4"]), # Wrong variant, but should be added (as we ignore the variant)
({"type": "quality", "definition": "fdmprinter", "variant": "variant_1", "material": "material_2"}, ["quality_1", "quality_4"]), # wrong material, but should be added (as we ignore the material)
({"type": "quality", "definition": "fdmprinter", "variant": "variant_1", "material": "material_1"}, ["quality_1", "quality_4"]),
]
metadata_dict = {} metadata_dict = {}
@ -86,45 +71,4 @@ def test_materialNodeInit_MachineQuality(container_registry):
assert len(node.qualities) == 2 assert len(node.qualities) == 2
assert "quality_2" in node.qualities assert "quality_2" in node.qualities
assert "quality_3" in node.qualities assert "quality_3" in node.qualities
@pytest.mark.parametrize("metadata,qualities_result_list", quality_metadata_machine_quality_test_data)
def test_qualityAdded_hasMachineQuality(container_registry, metadata, qualities_result_list):
variant_node = MagicMock()
variant_node.variant_name = "variant_1"
variant_node.machine.has_machine_quality = True
variant_node.machine.quality_definition = "machine_1"
container = createMockedInstanceContainer("quality_4")
with patch("cura.Machines.MaterialNode.QualityNode"):
with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)):
node = MaterialNode("material_1", variant_node)
with patch.dict(metadata_dict, metadata):
node._qualityAdded(container)
assert len(qualities_result_list) == len(node.qualities)
for name in qualities_result_list:
assert name in node.qualities
@pytest.mark.parametrize("metadata,qualities_result_list", quality_metadata_no_machine_quality)
def test_qualityAdded_noMachineQuality(container_registry, metadata, qualities_result_list):
variant_node = MagicMock()
variant_node.variant_name = "variant_1"
variant_node.machine.has_machine_quality = False
container = createMockedInstanceContainer("quality_4")
with patch("cura.Machines.MaterialNode.QualityNode"):
with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)):
node = MaterialNode("material_1", variant_node)
with patch.dict(metadata_dict, metadata):
node._qualityAdded(container)
assert len(qualities_result_list) == len(node.qualities)
for name in qualities_result_list:
assert name in node.qualities

View file

@ -1,21 +1,12 @@
from unittest.mock import patch, MagicMock from unittest.mock import patch, MagicMock
import pytest import pytest
from cura.Machines.MaterialNode import MaterialNode
from cura.Machines.QualityNode import QualityNode from cura.Machines.QualityNode import QualityNode
instance_container_metadata_dict = {"fdmprinter": {"variant_1": {"material_1": [{"id": "intent_1"}, {"id": "intent_2"}]}}, instance_container_metadata_dict = {"fdmprinter": {"variant_1": {"material_1": [{"id": "intent_1"}, {"id": "intent_2"}]}},
"machine_1": {"variant_2": {"material_2": [{"id": "intent_3"}, {"id": "intent_4"}]}}} "machine_1": {"variant_2": {"material_2": [{"id": "intent_3"}, {"id": "intent_4"}]}}}
intent_metadata_intent_added_data = [({"type": "Not an intent"}, ["intent_3", "intent_4"]), # Wrong type
({"type": "intent", "definition": "machine_9000"}, ["intent_3", "intent_4"]), # wrong definition
({"type": "intent", "definition": "machine_1", "variant": "variant_299101"}, ["intent_3", "intent_4"]), # wrong variant
({"type": "intent", "definition": "machine_1", "variant": "variant_2", "material": "super cool material!"}, ["intent_3", "intent_4"]), # Wrong material
({"type": "intent", "definition": "machine_1", "variant": "variant_2", "material": "material_2"}, ["intent_3", "intent_4", "intent_9001"]), # Yay, all good.
]
metadata_dict = {} metadata_dict = {}
@ -55,24 +46,4 @@ def test_qualityNode_machine_1(container_registry):
assert len(node.intents) == 2 assert len(node.intents) == 2
assert "intent_3" in node.intents assert "intent_3" in node.intents
assert "intent_4" in node.intents assert "intent_4" in node.intents
@pytest.mark.parametrize("metadata,intent_result_list", intent_metadata_intent_added_data)
def test_intentNodeAdded(container_registry, metadata, intent_result_list):
material_node = MagicMock()
material_node.variant.machine.quality_definition = "machine_1"
material_node.variant.variant_name = "variant_2"
material_node.base_file = "material_2"
intent_container = createMockedInstanceContainer("intent_9001")
with patch("cura.Machines.QualityNode.IntentNode"):
with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)):
node = QualityNode("quality_1", material_node)
with patch.dict(metadata_dict, metadata):
node._intentAdded(intent_container)
assert len(intent_result_list) == len(node.intents)
for identifier in intent_result_list:
assert identifier in node.intents