refactor: moveconnection handlers to the main thread

This commit is contained in:
Swann
2020-10-01 10:58:30 +02:00
parent ba98875560
commit 04b13cc0b7
2 changed files with 95 additions and 50 deletions

View File

@ -35,6 +35,8 @@ from replication.constants import (FETCHED,
class Delayable(): class Delayable():
"""Delayable task interface """Delayable task interface
""" """
def __init__(self):
self.is_registered = False
def register(self): def register(self):
raise NotImplementedError raise NotImplementedError
@ -53,13 +55,20 @@ class Timer(Delayable):
""" """
def __init__(self, duration=1): def __init__(self, duration=1):
super().__init__()
self._timeout = duration self._timeout = duration
self._running = True self._running = True
def register(self): def register(self):
"""Register the timer into the blender timer system """Register the timer into the blender timer system
""" """
bpy.app.timers.register(self.main)
if not self.is_registered:
bpy.app.timers.register(self.main)
self.is_registered = True
logging.debug(f"Register {self.__class__.__name__}")
else:
logging.debug(f"Timer {self.__class__.__name__} already registered")
def main(self): def main(self):
self.execute() self.execute()
@ -205,11 +214,16 @@ class DynamicRightSelectTimer(Timer):
class Draw(Delayable): class Draw(Delayable):
def __init__(self): def __init__(self):
super().__init__()
self._handler = None self._handler = None
def register(self): def register(self):
self._handler = bpy.types.SpaceView3D.draw_handler_add( if not self.is_registered:
self.execute, (), 'WINDOW', 'POST_VIEW') self._handler = bpy.types.SpaceView3D.draw_handler_add(
self.execute, (), 'WINDOW', 'POST_VIEW')
logging.debug(f"Register {self.__class__.__name__}")
else:
logging.debug(f"Drow {self.__class__.__name__} already registered")
def execute(self): def execute(self):
raise NotImplementedError() raise NotImplementedError()
@ -350,3 +364,15 @@ class SessionUserSync(Timer):
new_key = ui_users.add() new_key = ui_users.add()
new_key.name = user new_key.name = user
new_key.username = user new_key.username = user
class SessionBackgroundExecutor(Timer):
def __init__(self, timout=1, execution_queue=None):
super().__init__(timout)
self.execution_queue = execution_queue
def execute(self):
while not self.execution_queue.empty():
function = self.execution_queue.get()
logging.debug(f"Executing {function.__name__}")
function()

View File

@ -25,10 +25,9 @@ import string
import time import time
from operator import itemgetter from operator import itemgetter
from pathlib import Path from pathlib import Path
from subprocess import PIPE, Popen, TimeoutExpired
import zmq
import shutil import shutil
from pathlib import Path from pathlib import Path
from queue import Queue
import bpy import bpy
import mathutils import mathutils
@ -44,13 +43,70 @@ from replication.interface import Session
client = None client = None
background_exec_queue = Queue()
delayables = [] delayables = []
stop_modal_executor = False stop_modal_executor = False
def on_connection_start():
"""Session connection init hander
"""
settings = utils.get_preferences()
runtime_settings = bpy.context.window_manager.session
# Step 1: Constrect nodes
for node in client._graph.list_ordered():
node_ref = client.get(node)
if node_ref.state == FETCHED:
node_ref.resolve()
# Step 2: Load nodes
for node in client._graph.list_ordered():
node_ref = client.get(node)
if node_ref.state == FETCHED:
node_ref.apply()
# Step 3: Launch presence overlay
if runtime_settings.enable_presence:
presence.renderer.run()
# Step 4: Register blender timers
for d in delayables:
d.register()
if settings.update_method == 'DEPSGRAPH':
bpy.app.handlers.depsgraph_update_post.append(depsgraph_evaluation)
def on_connection_end():
"""Session connection finished handler
"""
global delayables, stop_modal_executor
settings = utils.get_preferences()
# Step 1: Unregister blender timers
for d in delayables:
try:
d.unregister()
except:
continue
stop_modal_executor = True
# Step 2: Unregister presence renderer
presence.renderer.stop()
if settings.update_method == 'DEPSGRAPH':
bpy.app.handlers.depsgraph_update_post.remove(
depsgraph_evaluation)
# Step 3: remove file handled
logger = logging.getLogger()
for handler in logger.handlers:
if isinstance(handler, logging.FileHandler):
logger.removeHandler(handler)
# OPERATORS # OPERATORS
class SessionStartOperator(bpy.types.Operator): class SessionStartOperator(bpy.types.Operator):
bl_idname = "session.start" bl_idname = "session.start"
bl_label = "start" bl_label = "start"
@ -189,60 +245,23 @@ class SessionStartOperator(bpy.types.Operator):
session_update = delayable.SessionStatusUpdate() session_update = delayable.SessionStatusUpdate()
session_user_sync = delayable.SessionUserSync() session_user_sync = delayable.SessionUserSync()
session_background_executor = delayable.SessionBackgroundExecutor(execution_queue=background_exec_queue)
session_update.register() session_update.register()
session_user_sync.register() session_user_sync.register()
session_background_executor.register()
delayables.append(session_background_executor)
delayables.append(session_update) delayables.append(session_update)
delayables.append(session_user_sync) delayables.append(session_user_sync)
@client.register('on_connection') @client.register('on_connection')
def initialize_session(): def initialize_session():
settings = utils.get_preferences() background_exec_queue.put(on_connection_start)
for node in client._graph.list_ordered():
node_ref = client.get(node)
if node_ref.state == FETCHED:
node_ref.resolve()
for node in client._graph.list_ordered():
node_ref = client.get(node)
if node_ref.state == FETCHED:
node_ref.apply()
# Launch drawing module
if runtime_settings.enable_presence:
presence.renderer.run()
# Register blender main thread tools
for d in delayables:
d.register()
if settings.update_method == 'DEPSGRAPH':
bpy.app.handlers.depsgraph_update_post.append(
depsgraph_evaluation)
@client.register('on_exit') @client.register('on_exit')
def desinitialize_session(): def desinitialize_session():
global delayables, stop_modal_executor background_exec_queue.put(on_connection_end)
settings = utils.get_preferences()
for d in delayables:
try:
d.unregister()
except:
continue
stop_modal_executor = True
presence.renderer.stop()
if settings.update_method == 'DEPSGRAPH':
bpy.app.handlers.depsgraph_update_post.remove(
depsgraph_evaluation)
logger = logging.getLogger()
for handler in logger.handlers:
if isinstance(handler, logging.FileHandler):
logger.removeHandler(handler)
bpy.ops.session.apply_armature_operator() bpy.ops.session.apply_armature_operator()