فهرست منبع

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 11 ماه پیش
والد
کامیت
308d78701a
3فایلهای تغییر یافته به همراه42 افزوده شده و 9 حذف شده
  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):