Merge remote-tracking branch 'origin/feature/OP-4194_Remote-publisher-controller' into enhancement/OP-3075_houdini-new-publisher

This commit is contained in:
Ondřej Samohel 2022-10-18 16:43:04 +02:00
commit bee610a2c1
No known key found for this signature in database
GPG key ID: 02376E18990A97C6
25 changed files with 2517 additions and 573 deletions

View file

@ -200,6 +200,16 @@ class AttributeValues(object):
def changes(self):
return self.calculate_changes(self._data, self._origin_data)
def apply_changes(self, changes):
for key, item in changes.items():
old_value, new_value = item
if new_value is None:
if key in self:
self.pop(key)
elif self.get(key) != new_value:
self[key] = new_value
class CreatorAttributeValues(AttributeValues):
"""Creator specific attribute values of an instance.
@ -333,6 +343,21 @@ class PublishAttributes:
changes[key] = (value, None)
return changes
def apply_changes(self, changes):
for key, item in changes.items():
if isinstance(item, dict):
self._data[key].apply_changes(item)
continue
old_value, new_value = item
if new_value is not None:
raise ValueError(
"Unexpected type \"{}\" expected None".format(
str(type(new_value))
)
)
self.pop(key)
def set_publish_plugins(self, attr_plugins):
"""Set publish plugins attribute definitions."""
@ -731,6 +756,97 @@ class CreatedInstance:
if member not in self._members:
self._members.append(member)
def serialize_for_remote(self):
return {
"data": self.data_to_store(),
"orig_data": copy.deepcopy(self._orig_data)
}
@classmethod
def deserialize_on_remote(cls, serialized_data, creator_items):
"""Convert instance data to CreatedInstance.
This is fake instance in remote process e.g. in UI process. The creator
is not a full creator and should not be used for calling methods when
instance is created from this method (matters on implementation).
Args:
serialized_data (Dict[str, Any]): Serialized data for remote
recreating. Should contain 'data' and 'orig_data'.
creator_items (Dict[str, Any]): Mapping of creator identifier and
objects that behave like a creator for most of attribute
access.
"""
instance_data = copy.deepcopy(serialized_data["data"])
creator_identifier = instance_data["creator_identifier"]
creator_item = creator_items[creator_identifier]
family = instance_data.get("family", None)
if family is None:
family = creator_item.family
subset_name = instance_data.get("subset", None)
obj = cls(
family, subset_name, instance_data, creator_item, new=False
)
obj._orig_data = serialized_data["orig_data"]
return obj
def remote_changes(self):
"""Prepare serializable changes on remote side.
Returns:
Dict[str, Any]: Prepared changes that can be send to client side.
"""
return {
"changes": self.changes(),
"asset_is_valid": self._asset_is_valid,
"task_is_valid": self._task_is_valid,
}
def update_from_remote(self, remote_changes):
"""Apply changes from remote side on client side.
Args:
remote_changes (Dict[str, Any]): Changes created on remote side.
"""
self._asset_is_valid = remote_changes["asset_is_valid"]
self._task_is_valid = remote_changes["task_is_valid"]
changes = remote_changes["changes"]
creator_attributes = changes.pop("creator_attributes", None) or {}
publish_attributes = changes.pop("publish_attributes", None) or {}
if changes:
self.apply_changes(changes)
if creator_attributes:
self.creator_attributes.apply_changes(creator_attributes)
if publish_attributes:
self.publish_attributes.apply_changes(publish_attributes)
def apply_changes(self, changes):
"""Apply changes created via 'changes'.
Args:
Dict[str, Tuple[Any, Any]]: Instance changes to apply. Same values
are kept untouched.
"""
for key, item in changes.items():
old_value, new_value = item
if new_value is None:
if key in self:
self.pop(key)
else:
current_value = self.get(key)
if current_value != new_value:
self[key] = new_value
class CreateContext:
"""Context of instance creation.
@ -818,6 +934,10 @@ class CreateContext:
def instances(self):
return self._instances_by_id.values()
@property
def instances_by_id(self):
return self._instances_by_id
@property
def publish_attributes(self):
"""Access to global publish attributes."""
@ -977,7 +1097,8 @@ class CreateContext:
and creator_class.host_name != self.host_name
):
self.log.info((
"Creator's host name is not supported for current host {}"
"Creator's host name \"{}\""
" is not supported for current host \"{}\""
).format(creator_class.host_name, self.host_name))
continue