Эх сурвалжийг харах

Get String Variables at Execution Time

Joseph Brandenburg 2 долоо хоног өмнө
parent
commit
909a4fe43e
2 өөрчлөгдсөн 55 нэмэгдсэн , 56 устгасан
  1. 34 37
      base_definitions.py
  2. 21 19
      utilities.py

+ 34 - 37
base_definitions.py

@@ -852,40 +852,45 @@ class MantisNode:
         for conn in self.hierarchy_connections:
             conn.reset_execution_recursive()
 
+    def get_interface_signature(self):
+        interface_signature = (*self.signature[:-1], 'InputInterface')
+        ui_name = self.ui_signature[-1]
+        name = self.signature[-1]
+        if ui_name != name:
+            schema_suffix = ''
+            for i in range(len(name)):
+                if name[i] == ui_name[i]: continue
+                break
+            schema_suffix = name[i+1:]
+            interface_signature = (*interface_signature[:-1],
+                                'InputInterface'+schema_suffix)
+        return interface_signature
 
     # TODO: make this MUCH more efficient!
     # alternatively: call this ONCE when initializing the tree, precache results?
     def apply_string_variables(self, string):
         # We get the mContext, iterate through the signature, and string-replace variables
         # this function should be called by evaluate_input if the result is a string.
-        all_vars = {} # maybe the individual nodes should store this as a class member, too...
-        name=""
-        do_once = False
+        result=string; name=""
         for i in range(len(self.signature[:-1])):
-            if i == 0:
-                continue
+            if i == 0: continue # it is None or AUTOGENERATED or something
             name+=self.signature[i]
-            prWhite(name)
-            vars = self.mContext.string_variables.get(name, None)
-            if vars is None:
-                prRed("Can't get string variables for node")
-                print (vars, type(vars))
-                prRed (name)
-                prWhite(self.mContext.string_variables.keys())
-                for k in self.mContext.string_variables.keys():
-                    print (name == k)
-                    print (len(name), name,)
-                    print (len(k), k)
-                raise RuntimeError
-                continue
-            elif not vars:
-                prRed(self)
-            for var_name, var_value in vars.items():
-                do_once=True
-                string = string.replace("$"+var_name, var_value)
-        if do_once == False:
-            raise NotImplementedError
-        return string
+        vars = self.mContext.string_variables.get(name, None)
+        if vars is None:
+            raise RuntimeError("Can't get string variables for node")
+        elif not vars:
+            prWhite(f"INFO: No vars available for {self}")
+        var_name_keys = list(vars.keys()); var_name_keys.sort(key=lambda a : -len(a))
+        for var_name in var_name_keys:
+            var_value = vars[var_name]
+            if var_value is None:
+                interface_signature = self.get_interface_signature()
+                interface_node = self.base_tree.parsed_tree.get(interface_signature)
+                from .utilities import set_string_variables_at_execution
+                set_string_variables_at_execution(interface_node, var_name)
+                var_value = vars[var_name]                
+            result = result.replace("$"+var_name, var_value)
+        return result
 
     def evaluate_input(self, input_name, index=0)  -> Any:
         from .node_container_common import trace_single_line
@@ -894,17 +899,9 @@ class MantisNode:
         # this trace() should give a key error if there is a problem
         #  it is NOT handled here because it should NOT happen - so I want the error message.
         trace = trace_single_line(self, input_name, index)
-        try:
-            prop = trace[0][-1].parameters[trace[1].name] #trace[0] = the list of traced nodes; read its parameters
-        except Exception as e:
-            print (trace[0][-1])
-            print (trace[1].name)
-            print (trace[0][-1].parameters.keys())
-            print (trace[0][-1].parameters.values())
-            raise e
-        if isinstance(prop, str) and "$" in prop:
-            print (self, prop)
-            prop = self.apply_string_variables(prop)
+        prop = trace[0][-1].parameters[trace[1].name] #trace[0] = the list of traced nodes; read its parameters
+        # apply the string variables if possible
+        if isinstance(prop, str) and "$" in prop: prop = self.apply_string_variables(prop)
         return prop
 
     def fill_parameters(self, ui_node=None)  -> None:

+ 21 - 19
utilities.py

@@ -111,31 +111,33 @@ def get_node_prototype(sig, base_tree):
 # This one is the simplest case so it is easiest to use its own function.
 def set_string_variables_at_creation_time(n, prototype, mContext):
     # we're gonna store the variables using the node's signature
-    prev_group_key = ''
-    prev_group_vars = {}
-    for i in range(len(n.signature[:-1])):
-        if i == 0: continue # this will cut any AUTOGEN or None in the base
-        prev_group_key+=n.signature[i]
-        prev_group_vars=mContext.string_variables.get(prev_group_key, {})
-    # IS THIS WISE???
-    from copy import deepcopy # so nothing spooky will happen
-    group_vars = mContext.string_variables["".join(n.signature[1:])] = deepcopy(prev_group_vars)
+    group_key = ''.join(n.signature[1:])
+    # Get the variables if they exist, otherwise just get a dict
+    group_vars=mContext.string_variables.get(group_key, {})
+    mContext.string_variables[group_key]=group_vars
     for input in prototype.inputs:
         if hasattr(input, "default_value") and not input.is_linked:
             if isinstance (input.default_value, str):
                 group_vars[input.name]=input.default_value
             elif hasattr(input.default_value, "name"):
                 group_vars[input.name]=input.default_value.name
-
-
-def set_string_variables_during_exec(n, mContext):
-    print(n)
-    pass
-    # so for this we need to get the UI node to get the string
-    # when a node is executed, we check for string variables that were set at runtime
-    # we need the dummy node for this
-
-
+        elif hasattr(input, "default_value") and input.is_linked:
+            group_vars[input.name]=None
+
+def set_string_variables_at_execution(interface_node, var_name):
+    # get the ID of the input
+    prototype = get_node_prototype(interface_node.signature[1:-1], 
+                                   interface_node.base_tree)
+    tree = prototype.node_tree
+    for interface_item in tree.interface.items_tree:
+        if interface_item.item_type == 'PANEL': continue
+        if interface_item.name == var_name: break
+    else:
+        prRed(f"Failed to get value for variable ${var_name}."); return
+    var_value = interface_node.evaluate_input(interface_item.identifier)
+    group_key = ''.join(interface_node.signature[1:-1])
+    group_vars=interface_node.mContext.string_variables.get(group_key, {})
+    group_vars[var_name]=var_value
 
 ##################################################################################################
 # groups and changing sockets -- this is used extensively by Schema.