From f457824eae70f074a0c21b147878e10d07163be7 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 86a2d3f..a8f9abc 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 10ccf69..b93ff55 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