Merge pull request #2493 from alicevision/dev/inheritedAttributes

[core] Reference the attribute's instance type in its description
This commit is contained in:
Fabien Castan 2024-08-19 17:33:21 +02:00 committed by GitHub
commit d3561993ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 57 additions and 37 deletions

View file

@ -25,17 +25,7 @@ def attributeFactory(description, value, isOutput, node, root=None, parent=None)
root: (optional) parent Attribute (must be ListAttribute or GroupAttribute) root: (optional) parent Attribute (must be ListAttribute or GroupAttribute)
parent (BaseObject): (optional) the parent BaseObject if any parent (BaseObject): (optional) the parent BaseObject if any
""" """
if isinstance(description, desc.GroupAttribute): attr = description.instanceType(node, description, isOutput, root, parent)
cls = GroupAttribute
elif isinstance(description, desc.ListAttribute):
cls = ListAttribute
elif isinstance(description, desc.ChoiceParam):
cls = ChoiceParam
elif isinstance(description, desc.PushButtonParam):
cls = PushButtonParam
else:
cls = Attribute
attr = cls(node, description, isOutput, root, parent)
if value is not None: if value is not None:
attr._set_value(value, emitSignals=False) attr._set_value(value, emitSignals=False)
else: else:

View file

@ -35,28 +35,11 @@ class Attribute(BaseObject):
self._isDynamicValue = (self._value is None) self._isDynamicValue = (self._value is None)
self._valueType = None self._valueType = None
name = Property(str, lambda self: self._name, constant=True) def getInstanceType(self):
label = Property(str, lambda self: self._label, constant=True) """ Return the correct Attribute instance corresponding to the description. """
description = Property(str, lambda self: self._description, constant=True) # Import within the method to prevent cyclic dependencies
value = Property(Variant, lambda self: self._value, constant=True) from meshroom.core.attribute import Attribute
# isExpression: return Attribute
# The default value of the attribute's descriptor is a static string expression that should be evaluated at runtime.
# This property only makes sense for output attributes.
isExpression = Property(bool, lambda self: self._isExpression, constant=True)
# isDynamicValue
# The default value of the attribute's descriptor is None, so it's not an input value,
# but an output value that is computed during the Node's process execution.
isDynamicValue = Property(bool, lambda self: self._isDynamicValue, constant=True)
uid = Property(Variant, lambda self: self._uid, constant=True)
group = Property(str, lambda self: self._group, constant=True)
advanced = Property(bool, lambda self: self._advanced, constant=True)
enabled = Property(Variant, lambda self: self._enabled, constant=True)
semantic = Property(str, lambda self: self._semantic, constant=True)
uidIgnoreValue = Property(Variant, lambda self: self._uidIgnoreValue, constant=True)
validValue = Property(Variant, lambda self: self._validValue, constant=True)
errorMessage = Property(str, lambda self: self._errorMessage, constant=True)
visible = Property(bool, lambda self: self._visible, constant=True)
type = Property(str, lambda self: self.__class__.__name__, constant=True)
def validateValue(self, value): def validateValue(self, value):
""" Return validated/conformed 'value'. Need to be implemented in derived classes. """ Return validated/conformed 'value'. Need to be implemented in derived classes.
@ -88,6 +71,32 @@ class Attribute(BaseObject):
return False return False
return True return True
name = Property(str, lambda self: self._name, constant=True)
label = Property(str, lambda self: self._label, constant=True)
description = Property(str, lambda self: self._description, constant=True)
value = Property(Variant, lambda self: self._value, constant=True)
# isExpression:
# The default value of the attribute's descriptor is a static string expression that should be evaluated at runtime.
# This property only makes sense for output attributes.
isExpression = Property(bool, lambda self: self._isExpression, constant=True)
# isDynamicValue
# The default value of the attribute's descriptor is None, so it's not an input value,
# but an output value that is computed during the Node's process execution.
isDynamicValue = Property(bool, lambda self: self._isDynamicValue, constant=True)
uid = Property(Variant, lambda self: self._uid, constant=True)
group = Property(str, lambda self: self._group, constant=True)
advanced = Property(bool, lambda self: self._advanced, constant=True)
enabled = Property(Variant, lambda self: self._enabled, constant=True)
semantic = Property(str, lambda self: self._semantic, constant=True)
uidIgnoreValue = Property(Variant, lambda self: self._uidIgnoreValue, constant=True)
validValue = Property(Variant, lambda self: self._validValue, constant=True)
errorMessage = Property(str, lambda self: self._errorMessage, constant=True)
visible = Property(bool, lambda self: self._visible, constant=True)
type = Property(str, lambda self: self.__class__.__name__, constant=True)
# instanceType
# Attribute instance corresponding to the description
instanceType = Property(Variant, lambda self: self.getInstanceType(), constant=True)
class ListAttribute(Attribute): class ListAttribute(Attribute):
""" A list of Attributes """ """ A list of Attributes """
@ -99,9 +108,10 @@ class ListAttribute(Attribute):
self._joinChar = joinChar self._joinChar = joinChar
super(ListAttribute, self).__init__(name=name, label=label, description=description, value=[], uid=(), group=group, advanced=advanced, semantic=semantic, enabled=enabled, visible=visible) super(ListAttribute, self).__init__(name=name, label=label, description=description, value=[], uid=(), group=group, advanced=advanced, semantic=semantic, enabled=enabled, visible=visible)
elementDesc = Property(Attribute, lambda self: self._elementDesc, constant=True) def getInstanceType(self):
uid = Property(Variant, lambda self: self.elementDesc.uid, constant=True) # Import within the method to prevent cyclic dependencies
joinChar = Property(str, lambda self: self._joinChar, constant=True) from meshroom.core.attribute import ListAttribute
return ListAttribute
def validateValue(self, value): def validateValue(self, value):
if value is None: if value is None:
@ -130,6 +140,10 @@ class ListAttribute(Attribute):
return self._elementDesc.matchDescription(value[0], strict) return self._elementDesc.matchDescription(value[0], strict)
return True return True
elementDesc = Property(Attribute, lambda self: self._elementDesc, constant=True)
uid = Property(Variant, lambda self: self.elementDesc.uid, constant=True)
joinChar = Property(str, lambda self: self._joinChar, constant=True)
class GroupAttribute(Attribute): class GroupAttribute(Attribute):
""" A macro Attribute composed of several Attributes """ """ A macro Attribute composed of several Attributes """
@ -142,7 +156,10 @@ class GroupAttribute(Attribute):
self._brackets = brackets self._brackets = brackets
super(GroupAttribute, self).__init__(name=name, label=label, description=description, value={}, uid=(), group=group, advanced=advanced, semantic=semantic, enabled=enabled, visible=visible) super(GroupAttribute, self).__init__(name=name, label=label, description=description, value={}, uid=(), group=group, advanced=advanced, semantic=semantic, enabled=enabled, visible=visible)
groupDesc = Property(Variant, lambda self: self._groupDesc, constant=True) def getInstanceType(self):
# Import within the method to prevent cyclic dependencies
from meshroom.core.attribute import GroupAttribute
return GroupAttribute
def validateValue(self, value): def validateValue(self, value):
if value is None: if value is None:
@ -220,6 +237,7 @@ class GroupAttribute(Attribute):
allUids.extend(desc.uid) allUids.extend(desc.uid)
return allUids return allUids
groupDesc = Property(Variant, lambda self: self._groupDesc, constant=True)
uid = Property(Variant, retrieveChildrenUids, constant=True) uid = Property(Variant, retrieveChildrenUids, constant=True)
joinChar = Property(str, lambda self: self._joinChar, constant=True) joinChar = Property(str, lambda self: self._joinChar, constant=True)
brackets = Property(str, lambda self: self._brackets, constant=True) brackets = Property(str, lambda self: self._brackets, constant=True)
@ -336,11 +354,18 @@ class PushButtonParam(Param):
super(PushButtonParam, self).__init__(name=name, label=label, description=description, value=None, uid=uid, group=group, advanced=advanced, semantic=semantic, enabled=enabled, visible=visible) super(PushButtonParam, self).__init__(name=name, label=label, description=description, value=None, uid=uid, group=group, advanced=advanced, semantic=semantic, enabled=enabled, visible=visible)
self._valueType = None self._valueType = None
def getInstanceType(self):
# Import within the method to prevent cyclic dependencies
from meshroom.core.attribute import PushButtonParam
return PushButtonParam
def validateValue(self, value): def validateValue(self, value):
return value return value
def checkValueTypes(self): def checkValueTypes(self):
pass pass
class ChoiceParam(Param): class ChoiceParam(Param):
""" """
""" """
@ -362,6 +387,11 @@ class ChoiceParam(Param):
else: else:
self._valueType = type(self._value) self._valueType = type(self._value)
def getInstanceType(self):
# Import within the method to prevent cyclic dependencies
from meshroom.core.attribute import ChoiceParam
return ChoiceParam
def conformValue(self, value): def conformValue(self, value):
""" Conform 'value' to the correct type and check for its validity """ """ Conform 'value' to the correct type and check for its validity """
# We do not check that the value is in the list of values. # We do not check that the value is in the list of values.