Skip to content

Commit

Permalink
Stop looping execution (#4516)
Browse files Browse the repository at this point in the history
* fix the problem when new scene events come during execution of a tree and execution start looping
* make scene handler close to impossible to cancel to prevent events which are impossible to handle
  • Loading branch information
Durman authored Jun 12, 2022
1 parent fd136d7 commit 9888971
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 8 deletions.
8 changes: 6 additions & 2 deletions core/group_update_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ def control_center(event):
for main_tree in trees_graph[event.tree]:
us.UpdateTree.get(main_tree).add_outdated(trees_graph[main_tree, event.tree])
if main_tree.sv_process:
ts.tasks.add(ts.Task(main_tree, us.UpdateTree.main_update(main_tree)))
ts.tasks.add(ts.Task(main_tree,
us.UpdateTree.main_update(main_tree),
is_scene_update=False))

# topology of a group tree was changed
elif type(event) is ev.GroupTreeEvent:
Expand All @@ -40,7 +42,9 @@ def control_center(event):
for main_tree in trees_graph[event.tree]:
us.UpdateTree.get(main_tree).add_outdated(trees_graph[main_tree, event.tree])
if main_tree.sv_process:
ts.tasks.add(ts.Task(main_tree, us.UpdateTree.main_update(main_tree)))
ts.tasks.add(ts.Task(main_tree,
us.UpdateTree.main_update(main_tree),
is_scene_update=False))

# Connections between trees were changed
elif type(event) is ev.TreesGraphEvent:
Expand Down
15 changes: 13 additions & 2 deletions core/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,23 @@ def __bool__(self):

def add(self, task: 'Task'):
"""Add new tasks to run them via timer"""

if task.is_scene_update:
# scene event can be excepted only as first event
# in all other cases it can be generated by tree evaluation
# and can lead to infinite loop of updates
if self._current is not None:
return

# print(f"Add {task=}")
self._todo.add(task)

@profile(section="UPDATE")
def run(self):
"""Run given tasks to update trees and report execution process in the
header of a node tree editor"""
max_duration = 0.15 # 0.15 is max timer frequency
# 0.15 is max timer frequency
max_duration = 10 if self.current.is_scene_update else 0.15
duration = 0

while self.current:
Expand Down Expand Up @@ -153,13 +163,14 @@ class Task:
"""Generator which should update some node tree. The task is hashable, and
it is equal to another task if booth of them update the same tree.
The generator is suspendable and can limit its execution by given time"""
def __init__(self, tree, updater):
def __init__(self, tree, updater, is_scene_update):
""":tree: tree which should be updated
:_updater: generator which should update given tree
:is_exhausted: the status of the generator - read only
:last_node: last node which going to be processed by the generator
- read only"""
self.tree: SvTree = tree
self.is_scene_update: bool = is_scene_update
self.is_exhausted = False
self.last_node = None

Expand Down
16 changes: 12 additions & 4 deletions core/update_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,25 @@ def control_center(event):
elif type(event) is ev.SceneEvent:
if event.tree.sv_scene_update and event.tree.sv_process:
UpdateTree.get(event.tree).is_scene_updated = False
ts.tasks.add(ts.Task(event.tree, UpdateTree.main_update(event.tree)))
ts.tasks.add(ts.Task(event.tree,
UpdateTree.main_update(event.tree),
is_scene_update=True))

# nodes changed properties
elif type(event) is ev.PropertyEvent:
tree = UpdateTree.get(event.tree)
tree.add_outdated(event.updated_nodes)
if event.tree.sv_process:
ts.tasks.add(ts.Task(event.tree, UpdateTree.main_update(event.tree)))
ts.tasks.add(ts.Task(event.tree,
UpdateTree.main_update(event.tree),
is_scene_update=False))

# update the whole tree anyway
elif type(event) is ev.ForceEvent:
UpdateTree.reset_tree(event.tree)
ts.tasks.add(ts.Task(event.tree, UpdateTree.main_update(event.tree)))
ts.tasks.add(ts.Task(event.tree,
UpdateTree.main_update(event.tree),
is_scene_update=False))

# mark that the tree topology has changed
# also this can be called (by Blender) during undo event in this case all
Expand All @@ -64,7 +70,9 @@ def control_center(event):
elif type(event) is ev.TreeEvent:
UpdateTree.get(event.tree).is_updated = False
if event.tree.sv_process:
ts.tasks.add(ts.Task(event.tree, UpdateTree.main_update(event.tree)))
ts.tasks.add(ts.Task(event.tree,
UpdateTree.main_update(event.tree),
is_scene_update=False))

# new file opened
elif type(event) is ev.FileEvent:
Expand Down

0 comments on commit 9888971

Please sign in to comment.