From 17c6b6dce8760d8069ecb7c8e119f3ba16bdf69f Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 7 Mar 2023 20:02:14 -0500 Subject: [PATCH] Improve handling of `ptAttribNamedResponder`. When a responder node is linked to a Python file node's ptAttribNamedResponder socket, it will now export with the same name as the node itself. In that way, the responder can be addressed in the attribute's value mapping in the Python script itself. --- korman/nodes/node_core.py | 8 ++++++++ korman/nodes/node_responder.py | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/korman/nodes/node_core.py b/korman/nodes/node_core.py index e3825ec..f3958ec 100644 --- a/korman/nodes/node_core.py +++ b/korman/nodes/node_core.py @@ -83,6 +83,14 @@ class PlasmaNodeBase: kwargs.get("so")) return exporter.mgr.find_create_key(pClass, **kwargs) + def _find_key(self, pClass, exporter, **kwargs): + """Finds a plKey specific to this node.""" + assert "name" not in kwargs + kwargs["name"] = self.get_key_name(issubclass(pClass, (plObjInterface, plSingleModifier)), + kwargs.pop("suffix", ""), kwargs.get("bl"), + kwargs.get("so")) + return exporter.mgr.find_key(pClass, **kwargs) + def find_input(self, key, idname=None): for i in self.inputs: if i.alias == key: diff --git a/korman/nodes/node_responder.py b/korman/nodes/node_responder.py index 9acaf3a..7b90fd1 100644 --- a/korman/nodes/node_responder.py +++ b/korman/nodes/node_responder.py @@ -85,7 +85,22 @@ class PlasmaResponderNode(PlasmaVersionedNode, bpy.types.Node): def get_key(self, exporter, so): return self._find_create_key(plResponderModifier, exporter, so=so) + def get_key_name(self, single, suffix=None, bl=None, so=None) -> str: + # If we're connected to a ptAttribNamedResponder, then we need to use our exact + # name in the node tree. This introduces potential collisions, so named responders + # are opt-in behavior. + if self.is_named_responder: + return self.name + else: + super().get_key_name(single, suffix, bl, so) + def export(self, exporter, bo, so): + # Ensure there is not already a Responder that matches this name in the PRP + # if we are a named responder. This will be a very rare error - the responder must + # be linked to a ptAttribNamedResponder for this to trigger. + if self.is_named_responder and self._find_key(plResponderModifier, exporter, so=so): + self.raise_error(f"A Responder named '{self.name}' has already been exported to this page.") + responder = self.get_key(exporter, so).object if not bo.plasma_net.manual_sdl: responder.setExclude("Responder") @@ -140,6 +155,16 @@ class PlasmaResponderNode(PlasmaVersionedNode, bpy.types.Node): # What exactly is a reused responder? All the messages are directed, after all... return True + @property + def is_named_responder(self) -> bool: + # Check to see if any of the Python attributes that we're linked to are ptAttribNamedResponder. + # We'll need to navigate from our keyref output socket (PFM socket) to the PFM attribute + # socket and test the `attribute_type` for all links. + return any( + (i.to_socket.attribute_type == "ptAttribNamedResponder" + for i in self.find_output_socket("keyref").links) + ) + @property def latest_version(self): return 2