feat(rcf):wip...

This commit is contained in:
Swann Martinez
2019-04-04 18:02:51 +02:00
parent 4123ffbb38
commit 3bf8da24db
2 changed files with 145 additions and 60 deletions

View File

@ -1,6 +1,7 @@
import asyncio import asyncio
import collections import collections
import logging import logging
from uuid import uuid4
import time import time
from enum import Enum from enum import Enum
@ -98,13 +99,20 @@ class RCFMessage(object):
id = None # User (string) id = None # User (string)
mtype = None # data mtype (string) mtype = None # data mtype (string)
body = None # data blob body = None # data blob
uuid = None
def __init__(self, key=None,uuid= None, id=None, mtype=None, body=None):
if uuid is None:
uuid = uuid4()
def __init__(self, key=None, id=None, mtype=None, body=None):
self.key = key self.key = key
self.uuid = uuid
self.mtype = mtype self.mtype = mtype
self.body = body self.body = body
self.id = id self.id = id
def store(self, dikt): def store(self, dikt):
"""Store me in a dict if I have anything to store""" """Store me in a dict if I have anything to store"""
# this currently erasing old value # this currently erasing old value
@ -116,25 +124,26 @@ class RCFMessage(object):
def send(self, socket): def send(self, socket):
"""Send key-value message to socket; any empty frames are sent as such.""" """Send key-value message to socket; any empty frames are sent as such."""
key = ''.encode() if self.key is None else self.key.encode() key = ''.encode() if self.key is None else self.key.encode()
print(self.mtype)
mtype = ''.encode() if self.mtype is None else self.mtype.encode() mtype = ''.encode() if self.mtype is None else self.mtype.encode()
body = ''.encode() if self.body is None else umsgpack.packb(self.body) body = ''.encode() if self.body is None else umsgpack.packb(self.body)
id = ''.encode() if self.id is None else self.id id = ''.encode() if self.id is None else self.id
try: try:
socket.send_multipart([key, id, mtype, body]) socket.send_multipart([key,self.uuid, id, mtype, body])
except: except:
logger.info("Fail to send {}".format(key)) logger.info("Fail to send {}".format(key))
@classmethod @classmethod
def recv(cls, socket): def recv(cls, socket):
"""Reads key-value message from socket, returns new kvmsg instance.""" """Reads key-value message from socket, returns new kvmsg instance."""
key, id, mtype, body = socket.recv_multipart(zmq.DONTWAIT) key,uuid, id, mtype, body = socket.recv_multipart(zmq.DONTWAIT)
key = key.decode() if key else None key = key.decode() if key else None
id = id if id else None id = id if id else None
mtype = mtype.decode() if body else None mtype = mtype.decode() if body else None
body = umsgpack.unpackb(body) if body else None body = umsgpack.unpackb(body) if body else None
return cls(key=key, id=id, mtype=mtype, body=body) return cls(key=key,uuid=uuid, id=id, mtype=mtype, body=body)
def dump(self): def dump(self):
if self.body is None: if self.body is None:
@ -269,7 +278,7 @@ class RCFClient():
await asyncio.sleep(0.0001) await asyncio.sleep(0.0001)
def push_update(self, key, mtype, body): def push_update(self, key, mtype, body):
rcfmsg = RCFMessage(key, self.id, mtype, body) rcfmsg = RCFMessage(key=key, id=self.id,mtype=mtype, body=body)
rcfmsg.send(self.push_sock) rcfmsg.send(self.push_sock)
def stop(self): def stop(self):

View File

@ -6,6 +6,7 @@ import asyncio
import queue import queue
from operator import itemgetter from operator import itemgetter
import uuid
import bgl import bgl
import blf import blf
import bpy import bpy
@ -25,7 +26,8 @@ server = None
context = None context = None
drawer = None drawer = None
update_list = {} update_list = {}
update_tasks = queue.Queue() push_tasks = queue.Queue()
pull_tasks = queue.Queue()
def add_update(type, item): def add_update(type, item):
try: try:
@ -80,10 +82,10 @@ def resolve_bpy_path(path):
""" """
Get bpy property value from path Get bpy property value from path
""" """
path = path.split('/')
item = None item = None
try: try:
path = path.split('/')
item = getattr(bpy.data, CORRESPONDANCE[path[0]])[path[1]] item = getattr(bpy.data, CORRESPONDANCE[path[0]])[path[1]]
except: except:
@ -439,61 +441,61 @@ def update_scene(msg):
net_vars = bpy.context.scene.session_settings net_vars = bpy.context.scene.session_settings
pull_tasks.put(msg.key)
# if net_vars.active_object: # if net_vars.active_object:
# if net_vars.active_object.name in msg.key: # if net_vars.active_object.name in msg.key:
# raise ValueError() # raise ValueError()
if 'net' not in msg.key: # if 'net' not in msg.key:
target = resolve_bpy_path(msg.key) # target = resolve_bpy_path(msg.key)
if target: # if target:
target.is_updating = True # target.is_updating = True
if msg.mtype == 'Object': # if msg.mtype == 'Object':
load_object(target=target, data=msg.body, # load_object(target=target, data=msg.body,
create=net_vars.load_data) # create=net_vars.load_data)
global drawer # global drawer
drawer.draw() # drawer.draw()
elif msg.mtype == 'Mesh': # elif msg.mtype == 'Mesh':
load_mesh(target=target, data=msg.body, # load_mesh(target=target, data=msg.body,
create=net_vars.load_data) # create=net_vars.load_data)
elif msg.mtype == 'Collection': # elif msg.mtype == 'Collection':
load_collection(target=target, data=msg.body, # load_collection(target=target, data=msg.body,
create=net_vars.load_data) # create=net_vars.load_data)
elif msg.mtype == 'Material': # elif msg.mtype == 'Material':
load_material(target=target, data=msg.body, # load_material(target=target, data=msg.body,
create=net_vars.load_data) # create=net_vars.load_data)
elif msg.mtype == 'Grease Pencil': # elif msg.mtype == 'Grease Pencil':
load_gpencil(target=target, data=msg.body, # load_gpencil(target=target, data=msg.body,
create=net_vars.load_data) # create=net_vars.load_data)
elif msg.mtype == 'Scene': # elif msg.mtype == 'Scene':
load_scene(target=target, data=msg.body, # load_scene(target=target, data=msg.body,
create=net_vars.load_data) # create=net_vars.load_data)
elif 'Light' in msg.mtype: # elif 'Light' in msg.mtype:
load_light(target=target, data=msg.body, # load_light(target=target, data=msg.body,
create=net_vars.load_data) # create=net_vars.load_data)
else: # else:
load_default(target=target, data=msg.body, # load_default(target=target, data=msg.body,
create=net_vars.load_data, type=msg.mtype) # create=net_vars.load_data, type=msg.mtype)
else: # else:
if msg.mtype == 'client': # if msg.mtype == 'client':
refresh_window() # refresh_window()
elif msg.mtype == 'clientObject': # elif msg.mtype == 'clientObject':
selected_objects = [] # selected_objects = []
for k, v in client.property_map.items(): # for k, v in client.property_map.items():
if v.mtype == 'clientObject': # if v.mtype == 'clientObject':
if client.id != v.id: # if client.id != v.id:
selected_objects.append(v.body['object']) # selected_objects.append(v.body['object'])
for obj in bpy.data.objects: # for obj in bpy.data.objects:
if obj.name in selected_objects: # if obj.name in selected_objects:
obj.hide_select = True # obj.hide_select = True
else: # else:
obj.hide_select = False # obj.hide_select = False
refresh_window() # refresh_window()
def push(data_type,id): def push(data_type,id):
if data_type == 'Material': if data_type == 'Material':
@ -513,21 +515,92 @@ def push(data_type,id):
if data_type == 'Scene': if data_type == 'Scene':
dump_datablock(bpy.data.scenes[id], 4) dump_datablock(bpy.data.scenes[id], 4)
def pull(keystore):
global client
net_vars = bpy.context.scene.session_settings
body = client.property_map[keystore].body
data_type = client.property_map[keystore].mtype
target = resolve_bpy_path(keystore)
if target:
target.is_updating = True
if data_type == 'Object':
load_object(target=target, data=body,
create=net_vars.load_data)
global drawer
drawer.draw()
elif data_type == 'Mesh':
load_mesh(target=target, data=body,
create=net_vars.load_data)
elif data_type == 'Collection':
load_collection(target=target, data=body,
create=net_vars.load_data)
elif data_type == 'Material':
load_material(target=target, data=body,
create=net_vars.load_data)
elif data_type == 'Grease Pencil':
load_gpencil(target=target, data=body,
create=net_vars.load_data)
elif data_type == 'Scene':
load_scene(target=target, data=body,
create=net_vars.load_data)
elif 'Light' in data_type:
load_light(target=target, data=body,
create=net_vars.load_data)
elif data_type == 'Camera':
load_default(target=target, data=body,
create=net_vars.load_data, type=mtype)
elif data_type == 'client':
refresh_window()
elif data_type == 'clientObject':
selected_objects = []
for k, v in client.property_map.items():
if v.mtype == 'clientObject':
if client.id != v.id:
selected_objects.append(v.body['object'])
for obj in bpy.data.objects:
if obj.name in selected_objects:
obj.hide_select = True
else:
obj.hide_select = False
refresh_window()
recv_callbacks = [update_scene] recv_callbacks = [update_scene]
post_init_callbacks = [refresh_window] post_init_callbacks = [refresh_window]
def default_tick(): def default_tick():
if not update_tasks.empty():
update = update_tasks.get() # for op in bpy.context.window_manager.operators:
# try:
# if isinstance(op.uuid,tuple):
# op.uuid = str(uuid.uuid4())
# except Exception as e:
# print("error on {} {}".format(op.name,e))
if not push_tasks.empty():
update = push_tasks.get()
print(update) print(update)
try: try:
push(update[0],update[1]) push(update[0],update[1])
except: except Exception as e:
pass print("push error: {}".format(e))
if not pull_tasks.empty():
try:
pull(pull_tasks.get())
except Exception as e:
print("pull error: {}".format(e))
return 0.1 return 0.1
def mesh_tick(): def mesh_tick():
mesh = get_update("Mesh") mesh = get_update("Mesh")
@ -572,6 +645,7 @@ def register_ticks():
bpy.app.timers.register(object_tick) bpy.app.timers.register(object_tick)
bpy.app.timers.register(default_tick) bpy.app.timers.register(default_tick)
def unregister_ticks(): def unregister_ticks():
# REGISTER Updaters # REGISTER Updaters
global drawer global drawer
@ -826,8 +900,10 @@ def depsgraph_update(scene):
push = True push = True
# Update selected object # Update selected object
for update in updates.items(): for update in updates.items():
updated_data = update[1] updated_data = update[1]
if updated_data.id.is_updating: if updated_data.id.is_updating:
updated_data.id.is_updating = False updated_data.id.is_updating = False
push = False push = False
@ -844,14 +920,14 @@ def depsgraph_update(scene):
if update[2] == "Master Collection": if update[2] == "Master Collection":
pass pass
elif update[1] in SUPPORTED_TYPES: elif update[1] in SUPPORTED_TYPES:
update_tasks.put((update[1], update[2])) push_tasks.put((update[1], update[2]))
# elif scene.session_settings.active_object and updated_data.id.name == scene.session_settings.active_object.name: # elif scene.session_settings.active_object and updated_data.id.name == scene.session_settings.active_object.name:
# if updated_data.is_updated_transform or updated_data.is_updated_geometry: # if updated_data.is_updated_transform or updated_data.is_updated_geometry:
# add_update(updated_data.id.bl_rna.name, updated_data.id.name) # add_update(updated_data.id.bl_rna.name, updated_data.id.name)
# elif updated_data.id.bl_rna.name in [SUPPORTED_TYPES]: # elif updated_data.id.bl_rna.name in [SUPPORTED_TYPES]:
# update_tasks.put((updated_data.id.bl_rna.name, updated_data.id.name)) # push_tasks.put((updated_data.id.bl_rna.name, updated_data.id.name))
# for c in reversed(updates.items()): # for c in reversed(updates.items()):
# if c[1].is_updated_geometry: # if c[1].is_updated_geometry: