From d7b20dff37693492a16e6742d7e679808c4fe7a0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 17 Apr 2024 23:53:20 +0200 Subject: [PATCH 1/7] Workfile templates: add event system to Workfile Template Builder --- .../workfile/workfile_template_builder.py | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 5e63ba444a..f53aee6341 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -36,6 +36,7 @@ from ayon_core.lib import ( filter_profiles, attribute_definitions, ) +from ayon_core.lib.events import EventSystem from ayon_core.lib.attribute_definitions import get_attributes_keys from ayon_core.pipeline import Anatomy from ayon_core.pipeline.load import ( @@ -124,6 +125,8 @@ class AbstractTemplateBuilder(object): self._current_task_entity = _NOT_SET self._linked_folder_entities = _NOT_SET + self._event_system = EventSystem() + @property def project_name(self): if isinstance(self._host, HostBase): @@ -244,6 +247,14 @@ class AbstractTemplateBuilder(object): self._log = Logger.get_logger(repr(self)) return self._log + @property + def event_system(self): + """Event System of the Workfile templatee builder. + Returns: + EventSystem: The event system. + """ + return self._event_system + def refresh(self): """Reset cached data.""" @@ -257,6 +268,8 @@ class AbstractTemplateBuilder(object): self._project_settings = None + self._event_system = EventSystem() + self.clear_shared_data() self.clear_shared_populate_data() @@ -729,6 +742,16 @@ class AbstractTemplateBuilder(object): placeholder.set_finished() + # Trigger on_depth_processed event + self.event_system.emit( + topic="template.depth_processed", + data={ + "depth": iter_counter, + "placeholders_by_scene_id": placeholder_by_scene_id + }, + source="builder" + ) + # Clear shared data before getting new placeholders self.clear_shared_populate_data() @@ -747,6 +770,16 @@ class AbstractTemplateBuilder(object): placeholder_by_scene_id[identifier] = placeholder placeholders.append(placeholder) + # Trigger on_finished event + self.event_system.emit( + topic="template.finished", + data={ + "depth": iter_counter, + "placeholders_by_scene_id": placeholder_by_scene_id, + }, + source="builder" + ) + self.refresh() def _get_build_profiles(self): @@ -1102,6 +1135,41 @@ class PlaceholderPlugin(object): plugin_data[key] = value self.builder.set_shared_populate_data(self.identifier, plugin_data) + def register_on_finished_callback( + self, placeholder, callback, order=None + ): + self.register_callback( + placeholder, + topic="template.finished", + callback=callback, + order=order + ) + + def register_on_depth_processed_callback( + self, placeholder, callback, order=0 + ): + self.register_callback( + placeholder, + topic="template.depth_processed", + callback=callback, + order=order + ) + + def register_callback(self, placeholder, topic, callback, order=None): + + if order is None: + # Match placeholder order by default + order = placeholder.order + + # We must persist the callback over time otherwise it will be removed + # by the event system as a valid function reference. We do that here + # always just so it's easier to develop plugins where callbacks might + # be partials or lambdas + placeholder.data.setdefault("callbacks", []).append(callback) + self.log.debug("Registering '%s' callback: %s", topic, callback) + self.builder.event_system.add_callback(topic, callback, order=order) + + class PlaceholderItem(object): """Item representing single item in scene that is a placeholder to process. From edee279f15fa16b549db68e3adb6aba14fc2f541 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 18 Apr 2024 12:04:24 +0200 Subject: [PATCH 2/7] Do not store in placeholder data - it's up to the registering code itself to persist or use the `weakref_partial` implementation from the event system --- .../pipeline/workfile/workfile_template_builder.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index f53aee6341..d08c951b36 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -1161,16 +1161,10 @@ class PlaceholderPlugin(object): # Match placeholder order by default order = placeholder.order - # We must persist the callback over time otherwise it will be removed - # by the event system as a valid function reference. We do that here - # always just so it's easier to develop plugins where callbacks might - # be partials or lambdas - placeholder.data.setdefault("callbacks", []).append(callback) self.log.debug("Registering '%s' callback: %s", topic, callback) self.builder.event_system.add_callback(topic, callback, order=order) - class PlaceholderItem(object): """Item representing single item in scene that is a placeholder to process. From 2befe843dc6fe9168b156ccf9501c99ddd48fe9e Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 18 Apr 2024 12:05:06 +0200 Subject: [PATCH 3/7] Do not force order of the placeholder, allow it to be `None` --- .../pipeline/workfile/workfile_template_builder.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index d08c951b36..b27b614579 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -1146,7 +1146,7 @@ class PlaceholderPlugin(object): ) def register_on_depth_processed_callback( - self, placeholder, callback, order=0 + self, placeholder, callback, order=None ): self.register_callback( placeholder, @@ -1156,11 +1156,6 @@ class PlaceholderPlugin(object): ) def register_callback(self, placeholder, topic, callback, order=None): - - if order is None: - # Match placeholder order by default - order = placeholder.order - self.log.debug("Registering '%s' callback: %s", topic, callback) self.builder.event_system.add_callback(topic, callback, order=order) From 47c7e8634c9deafe307e25cfe4bb654851fbbb63 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 18 Apr 2024 12:10:45 +0200 Subject: [PATCH 4/7] Do not expose the `event_system` on the builder directly - but expose the register and trigger event methods --- .../workfile/workfile_template_builder.py | 60 ++++++++----------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index b27b614579..22a4c984bc 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -247,14 +247,6 @@ class AbstractTemplateBuilder(object): self._log = Logger.get_logger(repr(self)) return self._log - @property - def event_system(self): - """Event System of the Workfile templatee builder. - Returns: - EventSystem: The event system. - """ - return self._event_system - def refresh(self): """Reset cached data.""" @@ -743,7 +735,7 @@ class AbstractTemplateBuilder(object): placeholder.set_finished() # Trigger on_depth_processed event - self.event_system.emit( + self.trigger_event( topic="template.depth_processed", data={ "depth": iter_counter, @@ -771,7 +763,7 @@ class AbstractTemplateBuilder(object): placeholders.append(placeholder) # Trigger on_finished event - self.event_system.emit( + self.trigger_event( topic="template.finished", data={ "depth": iter_counter, @@ -905,6 +897,30 @@ class AbstractTemplateBuilder(object): "create_first_version": create_first_version } + def trigger_event(self, topic, data=None, source=None): + self._event_system.emit(topic, data, source) + + def register_event_callback(self, topic, callback, order=None): + self._event_system.add_callback(topic, callback, order=order) + + def register_on_finished_callback( + self, callback, order=None + ): + self.register_event_callback( + topic="template.finished", + callback=callback, + order=order + ) + + def register_on_depth_processed_callback( + self, callback, order=None + ): + self.register_event_callback( + topic="template.depth_processed", + callback=callback, + order=order + ) + @six.add_metaclass(ABCMeta) class PlaceholderPlugin(object): @@ -1135,30 +1151,6 @@ class PlaceholderPlugin(object): plugin_data[key] = value self.builder.set_shared_populate_data(self.identifier, plugin_data) - def register_on_finished_callback( - self, placeholder, callback, order=None - ): - self.register_callback( - placeholder, - topic="template.finished", - callback=callback, - order=order - ) - - def register_on_depth_processed_callback( - self, placeholder, callback, order=None - ): - self.register_callback( - placeholder, - topic="template.depth_processed", - callback=callback, - order=order - ) - - def register_callback(self, placeholder, topic, callback, order=None): - self.log.debug("Registering '%s' callback: %s", topic, callback) - self.builder.event_system.add_callback(topic, callback, order=order) - class PlaceholderItem(object): """Item representing single item in scene that is a placeholder to process. From da5abf836773283ccb4d1296a35258cc9106e443 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 19 Apr 2024 22:24:44 +0200 Subject: [PATCH 5/7] Update client/ayon_core/pipeline/workfile/workfile_template_builder.py --- .../pipeline/workfile/workfile_template_builder.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 22a4c984bc..a4fa2b4ddd 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -897,25 +897,25 @@ class AbstractTemplateBuilder(object): "create_first_version": create_first_version } - def trigger_event(self, topic, data=None, source=None): + def emit_event(self, topic, data=None, source=None): self._event_system.emit(topic, data, source) - def register_event_callback(self, topic, callback, order=None): + def add_event_callback(self, topic, callback, order=None): self._event_system.add_callback(topic, callback, order=order) - def register_on_finished_callback( + def add_on_finished_callback( self, callback, order=None ): - self.register_event_callback( + self.add_event_callback( topic="template.finished", callback=callback, order=order ) - def register_on_depth_processed_callback( + def add_on_depth_processed_callback( self, callback, order=None ): - self.register_event_callback( + self.add_event_callback( topic="template.depth_processed", callback=callback, order=order From 8194a7b07b1799ffafe960b25e0d86c2feaff258 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 19 Apr 2024 22:26:54 +0200 Subject: [PATCH 6/7] Return the values of the called functions --- .../workfile/workfile_template_builder.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index a4fa2b4ddd..d189e3e2d6 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -36,7 +36,7 @@ from ayon_core.lib import ( filter_profiles, attribute_definitions, ) -from ayon_core.lib.events import EventSystem +from ayon_core.lib.events import EventSystem, EventCallback, Event from ayon_core.lib.attribute_definitions import get_attributes_keys from ayon_core.pipeline import Anatomy from ayon_core.pipeline.load import ( @@ -897,16 +897,16 @@ class AbstractTemplateBuilder(object): "create_first_version": create_first_version } - def emit_event(self, topic, data=None, source=None): - self._event_system.emit(topic, data, source) + def emit_event(self, topic, data=None, source=None) -> Event: + return self._event_system.emit(topic, data, source) def add_event_callback(self, topic, callback, order=None): - self._event_system.add_callback(topic, callback, order=order) + return self._event_system.add_callback(topic, callback, order=order) def add_on_finished_callback( self, callback, order=None - ): - self.add_event_callback( + ) -> EventCallback: + return self.add_event_callback( topic="template.finished", callback=callback, order=order @@ -914,8 +914,8 @@ class AbstractTemplateBuilder(object): def add_on_depth_processed_callback( self, callback, order=None - ): - self.add_event_callback( + ) -> EventCallback: + return self.add_event_callback( topic="template.depth_processed", callback=callback, order=order From c50bd1498e820ed9af035578fbfe8f6c8ffb8854 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 30 Apr 2024 10:34:31 +0200 Subject: [PATCH 7/7] Apply suggestions from code review Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../pipeline/workfile/workfile_template_builder.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 64f2ad1c18..fc4ba3fe98 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -741,7 +741,7 @@ class AbstractTemplateBuilder(object): placeholder.set_finished() # Trigger on_depth_processed event - self.trigger_event( + self.emit_event( topic="template.depth_processed", data={ "depth": iter_counter, @@ -769,7 +769,7 @@ class AbstractTemplateBuilder(object): placeholders.append(placeholder) # Trigger on_finished event - self.trigger_event( + self.emit_event( topic="template.finished", data={ "depth": iter_counter, @@ -912,7 +912,7 @@ class AbstractTemplateBuilder(object): return self._event_system.add_callback(topic, callback, order=order) def add_on_finished_callback( - self, callback, order=None + self, callback, order=None ) -> EventCallback: return self.add_event_callback( topic="template.finished", @@ -921,7 +921,7 @@ class AbstractTemplateBuilder(object): ) def add_on_depth_processed_callback( - self, callback, order=None + self, callback, order=None ) -> EventCallback: return self.add_event_callback( topic="template.depth_processed",