feat(rcf): attempt to bring back the drawing module

This commit is contained in:
Swann Martinez 2019-04-12 18:53:38 +02:00
parent 6c565c089f
commit b43e182094
No known key found for this signature in database
GPG Key ID: 414CCAFD8DA720E1
6 changed files with 99 additions and 45 deletions

View File

@ -59,7 +59,6 @@ class State(Enum):
ACTIVE = 3
class RCFClient(object):
ctx = None
pipe = None
@ -70,7 +69,7 @@ class RCFClient(object):
self.pipe, peer = zpipe(self.ctx)
self.queue = queue.Queue()
self.agent = threading.Thread(
target=rcf_client_agent, args=(self.ctx, peer,self.queue))
target=rcf_client_agent, args=(self.ctx, peer,self.queue),name="net-agent")
self.agent.daemon = True
self.agent.start()
@ -79,12 +78,12 @@ class RCFClient(object):
id, str) else id), (address.encode() if isinstance(
address, str) else address), b'%d' % port])
def set(self, key):
def set(self, key, value=None):
"""Set new value in distributed hash table
Sends [SET][key][value] to the agent
"""
self.pipe.send_multipart(
[b"SET", umsgpack.packb(key)])
[b"SET", umsgpack.packb(key),( umsgpack.packb(value) if value else umsgpack.packb('None') )])
def get(self, key):
"""Lookup value in distributed hash table
@ -114,6 +113,7 @@ class RCFClient(object):
else:
return umsgpack.unpackb(reply[0])
class RCFServer(object):
address = None # Server address
port = None # Server port
@ -125,8 +125,8 @@ class RCFServer(object):
self.port = port
self.snapshot = ctx.socket(zmq.DEALER)
self.snapshot.linger = 0
self.snapshot.connect("tcp://{}:{}".format(address.decode(), port))
self.snapshot.setsockopt(zmq.IDENTITY, id)
self.snapshot.connect("tcp://{}:{}".format(address.decode(), port))
self.subscriber = ctx.socket(zmq.SUB)
self.subscriber.setsockopt_string(zmq.SUBSCRIBE, '')
self.subscriber.connect("tcp://{}:{}".format(address.decode(), port+1))
@ -158,7 +158,7 @@ class RCFClientAgent(object):
self.publisher.linger = 0
self.serial, peer = zpipe(self.ctx)
self.serial_agent = threading.Thread(
target=serialization_agent, args=(self.ctx, peer))
target=serialization_agent, args=(self.ctx, peer), name="serial-agent")
self.serial_agent.daemon = True
self.serial_agent.start()
@ -182,7 +182,11 @@ class RCFClientAgent(object):
elif command == b"SET":
key = umsgpack.unpackb(msg[0])
value = None
value = helpers.dump(key)
value = umsgpack.unpackb(msg[1])
if value == 'None':
value = helpers.dump(key)
if value:
logger.info("{} dumped".format(key))
@ -195,9 +199,15 @@ class RCFClientAgent(object):
logger.error("Fail to dump ")
elif command == b"GET":
value = []
key = umsgpack.unpackb(msg[0])
value = self.property_map.get(key)
self.pipe.send(umsgpack.packb(value.body) if value else b'')
for k in self.property_map.keys():
if key in k:
value.append([k,self.property_map.get(k).body])
# value = [self.property_map.get(key) for key in keys]
# value = self.property_map.get(key)
self.pipe.send(umsgpack.packb(value) if value else b'')
elif command == b"LIST":
self.pipe.send(umsgpack.packb(list(self.property_map)))
@ -246,7 +256,7 @@ def rcf_client_agent(ctx, pipe,queue):
if agent.state == State.SYNCING:
# Store snapshot
if rcfmsg.key == "SNAPSHOT_END":
# logger.info("snapshot complete")
logger.info("snapshot complete")
agent.state = State.ACTIVE
else:
helpers.load(rcfmsg.key,rcfmsg.body)
@ -254,7 +264,8 @@ def rcf_client_agent(ctx, pipe,queue):
elif agent.state == State.ACTIVE:
if rcfmsg.id != agent.id:
# update_queue.put((rcfmsg.key,rcfmsg.body))
helpers.load(rcfmsg.key,rcfmsg.body)
with lock:
helpers.load(rcfmsg.key,rcfmsg.body)
# logger.info("load")
# agent.serial.send_multipart([b"LOAD", umsgpack.packb(rcfmsg.key), umsgpack.packb(rcfmsg.body)])
@ -298,6 +309,7 @@ class SerializationAgent(object):
key = umsgpack.unpackb(msg[0])
value = umsgpack.unpackb(msg[1])
helpers.load(key,value)
@ -307,7 +319,6 @@ class SerializationAgent(object):
def serialization_agent(ctx, pipe):
agent = SerializationAgent(ctx, pipe)
global stop
while True:
if stop:
@ -325,3 +336,5 @@ def serialization_agent(ctx, pipe):
if agent.pipe in items:
agent.control_message()

View File

@ -47,7 +47,7 @@ def get_client_view_rect():
v2 = get_target(region, rv3d, (width, height))
v4 = get_target(region, rv3d, (width, 0))
coords = (v1, v2, v3, v4)
coords = [v1, v2, v3, v4]
indices = (
(1, 3), (2, 1), (3, 0), (2, 0)
)
@ -105,6 +105,8 @@ class HUD(object):
self.draw_items.clear()
clients = self.client.get("Client")
for key, values in self.client.property_map.items():
if 'net' in key and values.body is not None and values.id != self.client.id:
if values.mtype == "clientObject":

View File

@ -41,7 +41,9 @@ def load(key, value):
elif target_type == 'Camera':
load_default(target=target, data=value,
create=True, type=target_type)
elif target_type == 'Client':
pass
def resolve_bpy_path(path):
"""

View File

@ -48,25 +48,23 @@ class RCFMessage(object):
def send(self, socket):
"""Send key-value message to socket; any empty frames are sent as such."""
key = ''.encode() if self.key is None else self.key.encode()
mtype = ''.encode() if self.mtype is None else self.mtype.encode()
body = ''.encode() if self.body is None else umsgpack.packb(self.body)
id = ''.encode() if self.id is None else self.id
try:
socket.send_multipart([key, id, mtype, body])
socket.send_multipart([key, id, body])
except:
logger.info("Fail to send {} {}".format(key, id))
print("Fail to send {} {}".format(key, id))
@classmethod
def recv(cls, socket):
"""Reads key-value message from socket, returns new kvmsg instance."""
key, id, mtype, body = socket.recv_multipart(zmq.DONTWAIT)
key, id, body = socket.recv_multipart(zmq.DONTWAIT)
key = key.decode() if key else None
id = id if id else None
mtype = mtype.decode() 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, id=id, body=body)
def dump(self):
if self.body is None:

View File

@ -17,7 +17,7 @@ from bpy_extras import view3d_utils
from gpu_extras.batch import batch_for_shader
from . import client, ui, draw, helpers
from .libs import umsgpack
logger = logging.getLogger(__name__)
@ -85,21 +85,29 @@ def refresh_window():
def upload_client_instance_position():
global client_instance
username = bpy.context.scene.session_settings.username
if client_instance:
key = "net/client_instances/{}".format(client_instance.id.decode())
key = "Client/{}".format(username)
# key = "Object/Cube"
print(key)
try:
current_coords = net_draw.get_client_instance_view_rect()
data = client_instance.property_map[key].body
if data is None:
data = {}
data['location'] = current_coords
color = bpy.context.scene.session_settings.client_instance_color
data['color'] = (color.r, color.g, color.b, 1)
client_instance.push_update(key, 'client_instance', data)
elif current_coords[0] != data['location'][0]:
data['location'] = current_coords
client_instance.push_update(key, 'client_instance', data)
current_coords = draw.get_client_view_rect()
client = client_instance.get(key)
# print((client[0][1][b'location']))
# if data is None:
# data = {}
# data['location'] = current_coords
# color = bpy.context.scene.session_settings.client_instance_color
# data['color'] = (color.r, color.g, color.b, 1)
# client_instance.push_update(key, 'client_instance', data)
if current_coords != client[0][1][b'location']:
print(current_coords)
print(client[0][1][b'location'])
client[0][1][b'location'] = current_coords
client_instance.set(key, client[0][1])
except:
pass
@ -305,11 +313,11 @@ def default_tick():
# print("pull error: {}".format(e))
# bpy.ops.session.refresh()
global client_instance
# global client_instance
if not client_instance.queue.empty():
update = client_instance.queue.get()
helpers.load(update[0],update[1])
# if not client_instance.queue.empty():
# update = client_instance.queue.get()
# helpers.load(update[0],update[1])
return 0.001
@ -342,18 +350,18 @@ def material_tick():
def draw_tick():
# drawing
global drawer
# global drawer
drawer.draw()
# drawer.draw()
# Upload
upload_client_instance_position()
return 0.2
return 1
def register_ticks():
# REGISTER Updaters
# bpy.app.timers.register(draw_tick)
bpy.app.timers.register(draw_tick)
# bpy.app.timers.register(mesh_tick)
# bpy.app.timers.register(object_tick)
bpy.app.timers.register(default_tick)
@ -363,7 +371,7 @@ def unregister_ticks():
# REGISTER Updaters
# global drawer
# drawer.unregister_handlers()
# bpy.app.timers.unregister(draw_tick)
bpy.app.timers.unregister(draw_tick)
# bpy.app.timers.unregister(mesh_tick)
# bpy.app.timers.unregister(object_tick)
bpy.app.timers.unregister(default_tick)
@ -446,6 +454,24 @@ class session_add_property(bpy.types.Operator):
return {"FINISHED"}
class session_get_property(bpy.types.Operator):
bl_idname = "session.get_prop"
bl_label = "get"
bl_description = "broadcast a property to connected client_instances"
bl_options = {"REGISTER"}
@classmethod
def poll(cls, context):
return True
def execute(self, context):
global client_instance
client_instance.get("client")
return {"FINISHED"}
class session_remove_property(bpy.types.Operator):
bl_idname = "session.remove_prop"
bl_label = "remove"
@ -592,6 +618,7 @@ classes = (
session_join,
session_refresh,
session_add_property,
session_get_property,
session_stop,
session_create,
session_settings,
@ -642,6 +669,7 @@ def depsgraph_update(scene):
# if updated_data.is_updated_transform:
# add_update(updated_data.id.bl_rna.name, updated_data.id.name)
# else:
if is_dirty(updates):
for update in ordered(updates):
if update[2] == "Master Collection":
@ -650,7 +678,7 @@ def depsgraph_update(scene):
client_instance.set("{}/{}".format(update[1], update[2]))
if len(updates) is 1 and len(bpy.context.selected_objects)>0:
if len(bpy.context.selected_objects)>0:
updated_data = updates[0]
if updated_data.id.name == bpy.context.selected_objects[0].name:
if updated_data.is_updated_transform or updated_data.is_updated_geometry:

View File

@ -8,7 +8,7 @@ import message
logger = logging.getLogger("Server")
logging.basicConfig(level=logging.DEBUG)
SUPPORTED_TYPES = [ 'Material',
SUPPORTED_TYPES = [ 'Client', 'Material',
'Texture', 'Light', 'Camera','Mesh', 'Grease Pencil', 'Object', 'Action', 'Armature','Collection', 'Scene']
class RCFServerAgent():
@ -66,6 +66,17 @@ class RCFServerAgent():
request = msg[1]
if request == b"SNAPSHOT_REQUEST":
client_key = "Client/{}".format(identity.decode())
if client_key not in self.property_map.keys():
logger.info("New user:{}".format(identity.decode()))
client_dict = {}
client_dict['location'] = [0,0,0]
client_dict['active_object'] = ''
client_store = message.RCFMessage(key=client_key, id=identity,body=client_dict)
logger.info(client_store)
client_store.store(self.property_map)
pass
else:
logger.info("Bad snapshot request")