refactor: remove refesh session mecanism with client api calls to avoid UI freeze during heavy tasks upload
This commit is contained in:
43
client.py
43
client.py
@ -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
|
||||
else:
|
||||
return umsgpack.unpackb(reply[0])
|
||||
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 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
|
||||
|
10
helpers.py
10
helpers.py
@ -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(
|
||||
|
53
operators.py
53
operators.py
@ -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):
|
||||
|
BIN
test.blend
BIN
test.blend
Binary file not shown.
24
ui.py
24
ui.py
@ -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]
|
||||
|
Reference in New Issue
Block a user