1313#    You should have received a copy of the GNU General Public License 
1414#    along with Korman.  If not, see <http://www.gnu.org/licenses/>. 
1515
16+ from  __future__ import  annotations 
17+ 
1618import  bpy 
1719from  bpy .props  import  * 
1820
1921from  collections .abc  import  Iterable 
2022from  contextlib  import  contextmanager 
2123from  pathlib  import  Path 
24+ from  typing  import  * 
25+ 
2226from  PyHSPlasma  import  * 
2327
2428from  .. import  enum_props 
6872_attrib_key_types  =  {
6973    "ptAttribSceneobject" : plFactory .ClassIndex ("plSceneObject" ),
7074    "ptAttribSceneobjectList" : plFactory .ClassIndex ("plSceneObject" ),
71-     "ptAttribActivator" : plFactory .ClassIndex ("plLogicModifier" ),
72-     "ptAttribActivatorList" : plFactory .ClassIndex ("plLogicModifier" ),
73-     "ptAttribNamedActivator" : plFactory .ClassIndex ("plLogicModifier" ),
75+     "ptAttribActivator" : (plFactory .ClassIndex ("plLogicModifier" ),
76+                           plFactory .ClassIndex ("plPythonFileMod" )),
77+     "ptAttribActivatorList" : (plFactory .ClassIndex ("plLogicModifier" ),
78+                               plFactory .ClassIndex ("plPythonFileMod" )),
79+     "ptAttribNamedActivator" : (plFactory .ClassIndex ("plLogicModifier" ),
80+                                plFactory .ClassIndex ("plPythonFileMod" )),
7481    "ptAttribResponder" : plFactory .ClassIndex ("plResponderModifier" ),
7582    "ptAttribResponderList" : plFactory .ClassIndex ("plResponderModifier" ),
7683    "ptAttribNamedResponder" : plFactory .ClassIndex ("plResponderModifier" ),
@@ -187,6 +194,17 @@ class PlasmaPythonFileNode(PlasmaVersionedNode, bpy.types.Node):
187194    bl_label  =  "Python File" 
188195    bl_width_default  =  290 
189196
197+     # Yas, a PythonFileMod can activate another PythonFileMod 
198+     pl_attrib  =  {"ptAttribActivator" , "ptAttribActivatorList" , "ptAttribNamedActivator" }
199+ 
200+     output_sockets : dict [str , dict [str , Any ]] =  {
201+         "satisfies" : {
202+             "text" : "Satisfies" ,
203+             "type" : "PlasmaConditionSocket" ,
204+             "valid_link_nodes" : "PlasmaPythonFileNode" ,
205+         },
206+     }
207+ 
190208    def  _poll_pytext (self , value ):
191209        return  value .name .endswith (".py" )
192210
@@ -304,7 +322,7 @@ def export(self, exporter, bo, so):
304322                param .value  =  i 
305323
306324                if  not  socket .is_simple_value :
307-                     self ._export_key_attrib (exporter , bo , so , i , socket )
325+                     self ._export_key_attrib (exporter , bo , so , pfm ,  i , socket )
308326                pfm .addParameter (param )
309327
310328    def  _export_ancillary_sceneobject (self , exporter , bo , so : plSceneObject ) ->  None :
@@ -317,7 +335,7 @@ def _export_ancillary_sceneobject(self, exporter, bo, so: plSceneObject) -> None
317335                exporter .report .msg (f"Marking RT light '{ so .key .name }  , so .key .name )
318336                light .setProperty (plLightInfo .kLPMovable , True )
319337
320-     def  _export_key_attrib (self , exporter , bo , so   : plSceneObject , key   : plKey , socket ) ->  None :
338+     def  _export_key_attrib (self , exporter , bo , so : plSceneObject , pfm :  plPythonFileMod ,  key : plKey , socket ) ->  None :
321339        if  key  is  None :
322340            exporter .report .warn ("Attribute '{}' didn't return a key and therefore will be unavailable to Python" ,
323341                                 self .id_data .name , socket .links [0 ].name )
@@ -333,17 +351,21 @@ def _export_key_attrib(self, exporter, bo, so : plSceneObject, key : plKey, sock
333351                                 self .id_data .name , socket .links [0 ].from_node .name ,
334352                                 plFactory .ClassName (key .type ))
335353
336-         if  isinstance (key .object , plSceneObject ):
337-             self ._export_ancillary_sceneobject (exporter , bo , key .object )
354+         key_object  =  key .object 
355+         if  isinstance (key_object , plSceneObject ):
356+             self ._export_ancillary_sceneobject (exporter , bo , key_object )
357+         elif  isinstance (key_object , plPythonFileMod ):
358+             key_object .addReceiver (pfm .key )
338359
339360    def  _get_attrib_sockets (self , idx ):
340361        for  i  in  self .inputs :
341362            if  i .attribute_id  ==  idx :
342363                yield  i 
343364
344365    def  generate_valid_links_for (self , context , socket , is_output ):
345-         # Python nodes have no outputs... 
346-         assert  is_output  is  False 
366+         if  is_output :
367+             yield  from  PlasmaNodeBase .generate_valid_links_for (self , context , socket , True )
368+             return 
347369
348370        attrib_type  =  socket .attribute_type 
349371        for  i  in  bpy .types .Node .__subclasses__ ():
@@ -493,6 +515,10 @@ def update(self):
493515                    while  len (unconnected ) >  1 :
494516                        self .inputs .remove (unconnected .pop ())
495517
518+             # Make sure the output sockets are present and accounted for. 
519+             self ._update_extant_sockets (self .output_sockets , self .outputs )
520+             self ._update_init_sockets (self .output_sockets , self .outputs )
521+ 
496522    @property  
497523    def  latest_version (self ):
498524        return  2 
0 commit comments