mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-15 02:37:49 -06:00
CURA-4848 Global stack now does its infinite resolve prevention on per thread basis
This commit is contained in:
parent
cde3799702
commit
def86defe6
1 changed files with 9 additions and 11 deletions
|
@ -1,6 +1,8 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
import threading
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty
|
from PyQt5.QtCore import pyqtProperty
|
||||||
|
@ -30,7 +32,8 @@ class GlobalStack(CuraContainerStack):
|
||||||
# This property is used to track which settings we are calculating the "resolve" for
|
# This property is used to track which settings we are calculating the "resolve" for
|
||||||
# and if so, to bypass the resolve to prevent an infinite recursion that would occur
|
# and if so, to bypass the resolve to prevent an infinite recursion that would occur
|
||||||
# if the resolve function tried to access the same property it is a resolve for.
|
# if the resolve function tried to access the same property it is a resolve for.
|
||||||
self._resolving_settings = set()
|
# Per thread we have our own resolving_settings, or strange things sometimes occur.
|
||||||
|
self._resolving_settings = defaultdict(set) # keys are thread names
|
||||||
|
|
||||||
## Get the list of extruders of this stack.
|
## Get the list of extruders of this stack.
|
||||||
#
|
#
|
||||||
|
@ -91,16 +94,10 @@ class GlobalStack(CuraContainerStack):
|
||||||
|
|
||||||
# Handle the "resolve" property.
|
# Handle the "resolve" property.
|
||||||
if self._shouldResolve(key, property_name, context):
|
if self._shouldResolve(key, property_name, context):
|
||||||
self._resolving_settings.add(key)
|
current_thread = threading.current_thread()
|
||||||
|
self._resolving_settings[current_thread.name].add(key)
|
||||||
resolve = super().getProperty(key, "resolve", context)
|
resolve = super().getProperty(key, "resolve", context)
|
||||||
if key not in self._resolving_settings:
|
self._resolving_settings[current_thread.name].remove(key)
|
||||||
# For debugging CURA-4848, if it happens
|
|
||||||
Logger.log("e", "Key [%s] should really have been in set(%s). Now I'm gonna crash", key, str(self._resolving_settings))
|
|
||||||
Logger.log("d", "------ context ------")
|
|
||||||
for stack in context.stack_of_containers:
|
|
||||||
Logger.log("d", "Context: %s", stack.getId())
|
|
||||||
Logger.log("d", "------ context end ------")
|
|
||||||
self._resolving_settings.remove(key)
|
|
||||||
if resolve is not None:
|
if resolve is not None:
|
||||||
return resolve
|
return resolve
|
||||||
|
|
||||||
|
@ -152,7 +149,8 @@ class GlobalStack(CuraContainerStack):
|
||||||
# Do not try to resolve anything but the "value" property
|
# Do not try to resolve anything but the "value" property
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if key in self._resolving_settings:
|
current_thread = threading.current_thread()
|
||||||
|
if key in self._resolving_settings[current_thread.name]:
|
||||||
# To prevent infinite recursion, if getProperty is called with the same key as
|
# To prevent infinite recursion, if getProperty is called with the same key as
|
||||||
# we are already trying to resolve, we should not try to resolve again. Since
|
# we are already trying to resolve, we should not try to resolve again. Since
|
||||||
# this can happen multiple times when trying to resolve a value, we need to
|
# this can happen multiple times when trying to resolve a value, we need to
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue