refactor: remove refesh session mecanism with client api calls to avoid UI freeze during heavy tasks upload

This commit is contained in:
Swann Martinez
2019-06-10 18:26:44 +02:00
parent 65bbb089fc
commit ad88350546
5 changed files with 47 additions and 83 deletions

View File

@ -14,18 +14,18 @@ import zmq
from . import helpers, message
from .libs import dump_anything, umsgpack
lock = threading.Lock()
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
CONNECT_TIMEOUT = 2
WATCH_FREQUENCY = 0.1
WAITING_TIME = 0.001
SERVER_MAX = 1
DUMP_AGENTS_NUMBER = 1
lock = threading.Lock()
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
instance = None
class State(Enum):
INITIAL = 1
SYNCING = 2
@ -61,10 +61,10 @@ class Client(object):
self.ctx = zmq.Context()
self.pipe, peer = zpipe(self.ctx)
self.store = {}
self.serial_product = queue.Queue()
self.serial_feed = queue.Queue()
self.stop_event = threading.Event()
# Net agent
self.net_agent = threading.Thread(
target=net_worker,
@ -83,7 +83,7 @@ class Client(object):
# Sync agent
self.watchdog_agent = threading.Thread(
target=watchdog_worker, args=(self.serial_feed, 0.2, self.stop_event), name="watchdog-agent")
target=watchdog_worker, args=(self.serial_feed,WATCH_FREQUENCY, self.stop_event), name="watchdog-agent")
self.watchdog_agent.daemon = True
self.watchdog_agent.start()
@ -147,7 +147,6 @@ class Client(object):
self.serial_feed.put(('STOP', None, None))
# READ-ONLY FUNCTIONS
def get(self, key):
"""Lookup value in distributed hash table
Sends [GET][key] to the agent and waits for a value response
@ -185,16 +184,24 @@ class Client(object):
return dump_list
def state(self):
if not self.is_busy():
self.pipe.send_multipart([b"STATE"])
try:
reply = self.pipe.recv_multipart()
except KeyboardInterrupt:
return
if self.net_agent is None or not self.net_agent.is_alive():
return 1 #State.INITIAL
elif self.net_agent.is_alive() and self.store.keys():
return 3 # State.ACTIVE
else:
return umsgpack.unpackb(reply[0])
else:
return None
return 2 #State.SYNCING
# # return self.state
# if not self.is_busy():
# self.pipe.send_multipart([b"STATE"])
# try:
# reply = self.pipe.recv_multipart()
# except KeyboardInterrupt:
# return
# else:
# return umsgpack.unpackb(reply[0])
# else:
# return None
class Server(object):
@ -223,7 +230,7 @@ class ClientAgent(object):
property_map = None
publisher = None
id = None
state = State.INITIAL
state = None
server = None
serial = None
serialisation_agent = None

View File

@ -72,7 +72,7 @@ def load(key, value):
target = resolve_bpy_path(key)
target_type = key.split('/')[0]
logger.info("load {}".format(key))
logger.debug("load {}".format(key))
if value == "None":
return
@ -176,7 +176,7 @@ def load_armature(target=None, data=None, create=False):
target_new_b = target.edit_bones.new[eb]
dump_anything.load(target_new_b, data['bones'][eb])
logger.info(eb)
logger.debug(eb)
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
fp.close()
@ -330,7 +330,7 @@ def load_collection(target=None, data=None, create=False):
target.children.link(
bpy.data.collections[collection])
else:
logger.info(target.name)
logger.debug(target.name)
for collection in target.children.keys():
if collection not in data["children"]:
@ -371,14 +371,14 @@ def load_scene(target=None, data=None, create=False):
# load collections
# TODO: Recursive link
logger.info("check for scene childs")
logger.debug("check for scene childs")
for collection in data["collection"]["children"]:
logger.debug(collection)
if collection not in target.collection.children.keys():
target.collection.children.link(
bpy.data.collections[collection])
logger.info("check for scene child to remove")
logger.debug("check for scene child to remove")
for collection in target.collection.children.keys():
if collection not in data["collection"]["children"]:
target.collection.children.unlink(

View File

@ -18,14 +18,11 @@ from .libs import umsgpack
logger = logging.getLogger(__name__)
# client_instance = None
client_keys = None
client_state = 1
server = None
context = None
def clean_scene(elements=helpers.BPY_TYPES.keys()):
for datablock in elements:
datablock_ref =getattr(bpy.data, helpers.BPY_TYPES[datablock])
@ -84,21 +81,8 @@ def init_datablocks():
client.instance.set(key)
def refresh_session_data():
global client_keys, client_state
keys = client.instance.list()
if keys:
client_keys = keys
state = client.instance.state()
if state:
client_state = state
def default_tick():
refresh_session_data()
upload_client_instance_position()
return .2
@ -158,22 +142,6 @@ class SessionJoinOperator(bpy.types.Operator):
return {"FINISHED"}
class SessionRefreshOperator(bpy.types.Operator):
bl_idname = "session.refresh"
bl_label = "refresh"
bl_description = "refresh client ui keys "
bl_options = {"REGISTER"}
@classmethod
def poll(cls, context):
return True
def execute(self, context):
refresh_session_data()
return {"FINISHED"}
class SessionPropertyAddOperator(bpy.types.Operator):
bl_idname = "session.add_prop"
bl_label = "add"
@ -279,7 +247,6 @@ class SessionStopOperator(bpy.types.Operator):
def execute(self, context):
global server
global client_keys, client_state
net_settings = context.window_manager.session
@ -295,9 +262,8 @@ class SessionStopOperator(bpy.types.Operator):
# del client_instance
# client_instance = None
client_keys = None
net_settings.is_admin = False
client_state = 1
unregister_ticks()
draw.renderer.stop()
@ -332,7 +298,6 @@ class SessionPropertyRightOperator(bpy.types.Operator):
def execute(self, context):
global server
global client_keys, client_state
net_settings = context.window_manager.session
@ -380,7 +345,6 @@ class SessionSnapUserOperator(bpy.types.Operator):
# TODO: Rename to match official blender convention
classes = (
SessionJoinOperator,
SessionRefreshOperator,
SessionPropertyAddOperator,
SessionPropertyGetOperator,
SessionStopOperator,
@ -392,8 +356,6 @@ classes = (
def is_replicated(update):
# global client_keys
# dickt = dict(client_keys)
object_type = update.id.bl_rna.__class__.__name__
object_name = update.id.name
@ -409,7 +371,7 @@ def is_replicated(update):
if client.instance.exist(key):
return True
else:
logger.info("{} Not rep".format(key))
logger.debug("{} Not rep".format(key))
return False
@ -435,17 +397,14 @@ def toogle_update_dirty(context, update):
data_ref = get_datablock_from_update(update,context)
if data_ref:
logger.info(update.id.bl_rna.__class__.__name__)
logger.debug(update.id.bl_rna.__class__.__name__)
data_ref.is_dirty= True
def depsgraph_update(scene):
global client_keys
global client_state
ctx = bpy.context
if client_state == 3:
if client.instance.state() == 3:
if ctx.mode in ['OBJECT','PAINT_GPENCIL']:
updates = ctx.view_layer.depsgraph.updates
@ -496,7 +455,6 @@ def register():
def unregister():
global server
global client_keys
draw.unregister()
@ -511,7 +469,6 @@ def unregister():
if client.instance:
client.instance.exit()
client.instance = None
del client_keys
from bpy.utils import unregister_class
for cls in reversed(classes):

Binary file not shown.

24
ui.py
View File

@ -1,6 +1,6 @@
import bpy
from . import client, operators
from . import client
from . import operators
@ -22,7 +22,7 @@ class SESSION_PT_settings(bpy.types.Panel):
window_manager = context.window_manager
row = layout.row()
if operators.client_state == 1:
if not client.instance or (client.instance and client.instance.state() == 1):
row = layout.row()
box = row.box()
row = box.row()
@ -75,7 +75,7 @@ class SESSION_PT_settings(bpy.types.Panel):
row.operator("session.join", text="CONNECT")
else:
if operators.client_state == 3:
if client.instance.state() == 3:
row = layout.row()
row.operator("session.stop", icon='QUIT', text="Exit")
@ -107,7 +107,7 @@ class SESSION_PT_user(bpy.types.Panel):
@classmethod
def poll(cls, context):
return operators.client_state == 3
return client.instance and client.instance.state() == 3
def draw(self, context):
@ -117,8 +117,9 @@ class SESSION_PT_user(bpy.types.Panel):
scene = context.window_manager
# Create a simple row.
row = layout.row()
if operators.client_keys and len(operators.client_keys) > 0:
for key in operators.client_keys:
client_keys = client.instance.list()
if client_keys and len(client_keys) > 0:
for key in client_keys:
if 'Client' in key[0]:
info = ""
item_box = row.box()
@ -152,7 +153,7 @@ class SESSION_PT_properties(bpy.types.Panel):
@classmethod
def poll(cls, context):
return operators.client_state == 3
return client.instance and client.instance.state() == 3
def draw(self, context):
layout = self.layout
@ -174,11 +175,10 @@ class SESSION_PT_properties(bpy.types.Panel):
# Property area
area_msg = row.box()
area_msg.operator("session.refresh", text="",
icon="UV_SYNC_SELECT")
if operators.client_keys and len(operators.client_keys) > 0:
client_keys = client.instance.list()
if client_keys and len(client_keys) > 0:
for item in sorted(operators.client_keys, key=get_client_key):
for item in sorted(client_keys, key=get_client_key):
owner = 'toto'
try:
owner = item[1]