Procházet zdrojové kódy

Add MantixExecutionContext

it isn't pretty and it increases complexity just a little bit
but I need to be able to store some extra information

I'm caught in a development paradox here. refactoring mantis to include this feature
the "right" way - by adding it to class init - would take a lot of work. Adding it at runtime
is still class composition, which is good, but spreads the code out to two different functions
so the only real danger is that I may overlook something and fail to set the value. which is
likely if I make big changes to how things are solved.

thing is, it simply isn't worth it to go to all this trouble until I get some benefit from the new
MantisExecutionContext.
So I am gonna do it this way - the messy, but easy and simple way - because it will free me to
start using the feature. Then, I will observe how my development is affected before I decide
what to do. After all... there are other ways to solve some of these problems.
Joseph Brandenburg před 6 měsíci
rodič
revize
308d78701a
3 změnil soubory, kde provedl 42 přidání a 9 odebrání
  1. 31 7
      base_definitions.py
  2. 8 2
      readtree.py
  3. 3 0
      schema_solve.py

+ 31 - 7
base_definitions.py

@@ -609,6 +609,31 @@ array_output_types = [
     'UtilityArrayGet', 'UtilityKDChoosePoint', 'UtilityKDChooseXForm',
 ]
 
+# TODO:
+#   - get the execution context in the execution code
+#   - from there, begin to use it for stuff I can't do without it
+#   - and slowly start transferring stuff to it
+
+# The Mantis Overlay class is used to store node-tree specific information
+#  such as inputs and outputs
+# used for e.g. allowing strings to pass as $variables in node names
+class MantisOverlay():
+    def __init__( self, parent, inputs, outputs, ):
+        pass
+
+# The MantisExecutionContext class is used to store the execution-specific variables
+# that are used when executing the tree
+# Importantly, it is NOT used to store variables between solutions, these belong to the
+#   tree itself.
+class MantisExecutionContext():
+    def __init__(
+            self,
+            base_tree,
+    ):
+        self.base_tree = base_tree
+        self.execution_id = base_tree.execution_id
+        self.b_objects=[] # objects created by Mantis during execution
+
 class MantisNode:
     """
         This class contains the basic interface for a Mantis Node.
@@ -617,7 +642,7 @@ class MantisNode:
     """
     def __init__(self, signature : tuple,
                  base_tree : bpy.types.NodeTree,
-                 socket_templates : list[MantisSocketTemplate]=[]):
+                 socket_templates : list[MantisSocketTemplate]=[],):
         self.base_tree=base_tree
         self.signature = signature
         self.inputs = MantisNodeSocketCollection(node=self, is_input=True)
@@ -630,6 +655,11 @@ class MantisNode:
         self.prepared = False
         self.executed = False
         self.socket_templates = socket_templates
+        self.mContext = None # for now I am gonna set this at runtime
+        # I know it isn't "beautiful OOP" or whatever, but it is just easier
+        # code should be simple and do things in the simplest way.
+        # in the future I can refactor it, but it will require changes to 100+
+        #  classes, instead of adding about 5 lines of code elsewhere.
         if self.socket_templates:
             self.init_sockets()
 
@@ -945,9 +975,3 @@ class MantisNodeSocketCollection(dict):
         """Makes the class iterable"""
         return iter(self.values())
 
-# The Mantis Solver class is used to store the execution-specific variables that are used
-#   when executing the tree
-class MantisSolver():
-    pass
-
-# GOAL: make the switch to "group overlay" paradigm

+ 8 - 2
readtree.py

@@ -282,7 +282,10 @@ def get_schema_length_dependencies(node, all_nodes={}):
 def parse_tree(base_tree):
     from uuid import uuid4
     base_tree.execution_id = uuid4().__str__() # set the unique id of this execution
-   
+    
+    from .base_definitions import MantisExecutionContext
+    mContext = MantisExecutionContext(base_tree=base_tree)
+
     import time
     data_start_time = time.time()
     # annoyingly I have to pass in values for all of the dicts because if I initialize them in the function call
@@ -303,6 +306,8 @@ def parse_tree(base_tree):
 
     from .base_definitions import array_output_types, GraphError
     for mantis_node in all_mantis_nodes.values():
+        # add the Mantis Context here, so that it available during parsing.
+        mantis_node.mContext = mContext
         if mantis_node.node_type in ["DUMMY"]: # clean up the groups
             if mantis_node.prototype.bl_idname in ("MantisNodeGroup", "NodeGroupOutput"):
                 continue
@@ -404,6 +409,8 @@ def parse_tree(base_tree):
         if (nc.node_type in ['XFORM']) and ("Relationship" in nc.inputs.keys()):
             if (new_nc := insert_lazy_parents(nc)):
                 kept_nc[new_nc.signature]=new_nc
+                # be sure to add the Mantis context.
+                new_nc.mContext =mContext
         kept_nc[nc.signature]=nc
     prWhite(f"Parsing tree took {time.time()-start_time} seconds.")
     prWhite("Number of Nodes: %s" % (len(kept_nc)))
@@ -450,7 +457,6 @@ def execution_error_cleanup(node, exception, switch_objects = [] ):
     prRed(f"Error: {exception} in node {node}")
     return exception
 
-
 def execute_tree(nodes, base_tree, context, error_popups = False):
     import bpy
     from time import time

+ 3 - 0
schema_solve.py

@@ -142,6 +142,7 @@ class SchemaSolver:
         for prototype_ui_node in self.tree.nodes:
             mantis_node_name = prototype_ui_node.name
             index_str = self.index_str()
+            mContext=self.node.mContext
             if isinstance(prototype_ui_node, SchemaUINode):
                 continue  # IGNORE the schema interface nodes, we already made them in __init__()
                 # they are reused for each iteration.
@@ -182,6 +183,8 @@ class SchemaSolver:
             if mantis_node.__class__.__name__ in custom_props_types:
                 setup_custom_props_from_np(mantis_node, prototype_ui_node)
             mantis_node.fill_parameters(prototype_ui_node)
+            # be sure to pass on the Mantis Context to them
+            mantis_node.mContext=mContext
 
 
     def handle_link_from_index_input(self, index, frame_mantis_nodes, ui_link):