Kaynağa Gözat

Fix: Schema Solve fails trying to solve ancestor schema

Schema may solve their children, but NEVER their ancestors!
They will solve as soon as their length is determined, so their hierarchy dependencies
may not be ready. Because of insufficient caution, schema would reach out into their
dependency hierarchy and solve all their ancestors to resolve dependencies - even
other schema! As it turns out, these are not only impossible to solve from here,
because for whatever reason the context is bad - but they are also totally redundant
and serve no purpose other than to slow mantis down and cause errors.

Currently all my test files work when I use this code. (Stegosaurus files, component pack).
Joseph Brandenburg 6 ay önce
ebeveyn
işleme
3c7a4c7fca
2 değiştirilmiş dosya ile 20 ekleme ve 23 silme
  1. 2 21
      readtree.py
  2. 18 2
      schema_solve.py

+ 2 - 21
readtree.py

@@ -242,11 +242,6 @@ def get_schema_length_dependencies(node, all_nodes={}):
     """
     deps = []
     prepare_links_to = ['Schema Length', 'Array', 'Index']
-    if node.node_type == "DUMMY_SCHEMA":
-        for item in node.prototype.node_tree.interface.items_tree:
-            if item.item_type == 'PANEL': continue
-            if item.parent:
-                prepare_links_to.append(item.identifier)
     def extend_dependencies_from_inputs(node):
         for inp in node.inputs.values():
             for l in inp.links:
@@ -342,27 +337,16 @@ def parse_tree(base_tree):
     solve_only_these = set(solve_only_these)
 
     solve_layer = unsolved_schema.copy(); solve_layer.extend(roots)
-    from .schema_containers import TellClasses as schema_classes
     while(solve_layer):
         n = solve_layer.pop()
-        # Remove schema nodes if they were added in error.
-        if isinstance(n, tuple(schema_classes())):
-            if n in solve_only_these:
-                solve_only_these.remove(n)
+        if n not in solve_only_these:
             continue
-        # Check if this node, or any nodes that depend on it, are in the list.
-        for child in [n]+ n.hierarchy_connections:
-            if child in solve_only_these: break
-            else: # removes the unneeded node from the solve-layer
-                continue
 
         if n.signature in all_schema.keys():
             for dep in n.hierarchy_dependencies:
                 if dep not in schema_solve_done and (dep in solve_only_these):
-                    if dep.prepared: # HACK HACK HACK
+                    if dep.prepared:
                         continue 
-                        # For some reason, the Schema Solver is able to detect and resolve
-                        # dependencies outside of solve_only_these. So I have to figure out why.
                     solve_layer.appendleft(n)
                     break
             else:
@@ -393,9 +377,6 @@ def parse_tree(base_tree):
                     if conn not in schema_solve_done and conn not in solve_layer:
                         solve_layer.appendleft(conn)
                 continue
-        # If the above does not cover every case, there is an error in the graph
-        if (n in solve_only_these):
-            raise GraphError("ERROR: Mantis has failed to build the graph. Please Report this as a bug.")
     if unsolved_schema:
         raise RuntimeError("Failed to resolve all schema declarations")
     # I had a problem with this looping forever. I think it is resolved... but I don't know lol

+ 18 - 2
schema_solve.py

@@ -401,23 +401,39 @@ class SchemaSolver:
         connection = incoming.from_node.outputs[incoming.from_socket].connect(node=to_node, socket=ui_link.to_socket.name)
         init_connections(incoming.from_node)
                     
+    def test_is_sub_schema(self, other):
+        for i in range(len(other.natural_signature)-1): # -1, we don't want to check this node, obviously
+            if self.node.natural_signature[:i+1]:
+                return False
+        return True
+
     def prepare_nodes(self, unprepared):
         # At this point, we've already run a pretty exhaustive preperation phase to prep the schema's dependencies
         # So we should not need to add any new dependencies unless there is a bug elsewhere.
         # and in fact, I could skip this in some cases, and should investigate if profiling reveals a slowdown here.
+        forbidden=set()
+        # forbid some nodes - they aren't necessary to solve the schema & cause problems.
         while unprepared:
             nc = unprepared.pop()
             if sum([dep.prepared for dep in nc.hierarchy_dependencies]) == len(nc.hierarchy_dependencies):
                 nc.bPrepare()
                 if nc.node_type == 'DUMMY_SCHEMA':
                     self.solve_nested_schema(nc)
-
+            elif nc.node_type == 'DUMMY_SCHEMA' and not self.test_is_sub_schema(nc):
+                forbidden.add(nc)
+                continue # do NOT add this as a dependency.
             else: # Keeping this for-loop as a fallback, it should never add dependencies though
+                can_add_me = True
                 for dep in nc.hierarchy_dependencies:
                     if not dep.prepared and dep not in unprepared:
+                        if dep in forbidden:
+                            can_add_me=False
+                            forbidden.add(nc) # forbid the parent, too
+                            continue
                         prOrange(f"Adding dependency... {dep}")
                         unprepared.appendleft(dep)
-                unprepared.appendleft(nc) # just rotate them until they are ready.
+                if can_add_me:
+                    unprepared.appendleft(nc) # just rotate them until they are ready.
 
     def solve_iteration(self):
         """ Solve an iteration of the schema.