Browse Source

Fix: undo causes tree to refuse to execute

Joseph Brandenburg 6 months ago
parent
commit
6f3ff2dc35
2 changed files with 13 additions and 32 deletions
  1. 8 27
      __init__.py
  2. 5 5
      base_definitions.py

+ 8 - 27
__init__.py

@@ -237,14 +237,11 @@ def execute_handler(scene):
         trees = [p.node_tree for p in context.space_data.path]
         if not trees: return
         if (node_tree := trees[0]).bl_idname in ['MantisTree']:
-            if node_tree.is_exporting:
-                return
-            if node_tree.prevent_next_exec : node_tree.prevent_next_exec = False
-            elif node_tree.tree_valid and node_tree.do_live_update and not (node_tree.is_executing):
-                scene.render.use_lock_interface = True
+            # check here instead of in execute_tree because these  values can be
+            #  modified at weird times and checking from the handler is more consistent
+            if ( node_tree.tree_valid) and ( node_tree.do_live_update ):
                 node_tree.execute_tree(context)
-                scene.render.use_lock_interface = False
-                node_tree.tree_valid = False
+                node_tree.tree_valid=False
 
 versioning_node_tasks = [
     #relevant bl_idnames      # task
@@ -346,29 +343,15 @@ def on_animation_playback_post_handler(scene,depsgraph):
     for t in bpy.data.node_groups:
         if t.bl_idname in ['MantisTree', 'SchemaTree']:
             t.is_executing = False
-@persistent
-def on_undo_pre_handler(scene): # the undo will trigger a depsgraph update
-    for t in bpy.data.node_groups: # so we enable prevent_next_exec.
-        if t.bl_idname in ['MantisTree', 'SchemaTree']:
-            t.prevent_next_exec = True
 
 @persistent
 def on_undo_post_handler(scene): # the undo will trigger a depsgraph update
     for t in bpy.data.node_groups: # so we enable prevent_next_exec.
         if t.bl_idname in ['MantisTree', 'SchemaTree']:
             t.prevent_next_exec = True
-
-@persistent
-def on_save_pre_handler(scene): # save-as will trigger a depsgraph update
-    for t in bpy.data.node_groups: # so we enable prevent_next_exec.
-        if t.bl_idname in ['MantisTree', 'SchemaTree']:
-            t.prevent_next_exec = True
-# annoyingly, regular save does not trigger a DG update so we also need this:
-@persistent
-def on_save_post_handler(scene): # The DG has already updated and we can disable this.
-    for t in bpy.data.node_groups:
-        if t.bl_idname in ['MantisTree', 'SchemaTree']:
-            t.prevent_next_exec = False
+            t.hash=""
+            # set the tree to invalid to trigger a tree update
+            # since the context data is wiped by an undo.
 
 def register():
     from bpy.utils import register_class
@@ -390,12 +373,10 @@ def register():
     # add the handlers
     bpy.app.handlers.depsgraph_update_pre.insert(0, update_handler)
     bpy.app.handlers.depsgraph_update_post.insert(0, execute_handler)
-    bpy.app.handlers.save_pre.insert(0, on_save_pre_handler)
-    bpy.app.handlers.save_post.insert(0, on_save_post_handler)
     bpy.app.handlers.load_post.insert(0, version_update_handler)
     bpy.app.handlers.animation_playback_pre.insert(0, on_animation_playback_pre_handler)
     bpy.app.handlers.animation_playback_post.insert(0, on_animation_playback_post_handler)
-    bpy.app.handlers.undo_pre.insert(0, on_undo_pre_handler)
+    bpy.app.handlers.undo_post.insert(0, on_undo_post_handler)
     # I'm adding mine in first to ensure other addons don't mess up mine
     # but I am a good citizen! so my addon won't mess up yours! probably...
 

+ 5 - 5
base_definitions.py

@@ -135,9 +135,6 @@ class MantisTree(NodeTree):
                 self.is_executing = False
 
     def display_update(self, context):
-        my_hash = str( hash_tree(self) )
-        if my_hash != self.hash:
-            return
         if self.is_exporting:
             return
         self.is_executing = True
@@ -156,17 +153,20 @@ class MantisTree(NodeTree):
 
     def execute_tree(self,context, error_popups = False):
         self.prevent_next_exec = False
-        if self.is_exporting:
+        if not self.hash:
+            return
+        if self.is_exporting or self.is_executing:
             return
-        # return
         prGreen("Executing Tree: %s" % self.name)
         self.is_executing = True
         from . import readtree
         try:
+            context.scene.render.use_lock_interface = True
             readtree.execute_tree(self.parsed_tree, self, context, error_popups)
         except RecursionError as e:
             prRed("Recursion error while parsing tree.")
         finally:
+            context.scene.render.use_lock_interface = False
             self.is_executing = False
 
 class SchemaTree(NodeTree):