feat(rcf): attempt to bring back the drawing module
This commit is contained in:
parent
6c565c089f
commit
b43e182094
37
client.py
37
client.py
@ -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()
|
||||
|
||||
|
||||
|
||||
|
4
draw.py
4
draw.py
@ -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":
|
||||
|
@ -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):
|
||||
"""
|
||||
|
10
message.py
10
message.py
@ -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:
|
||||
|
76
operators.py
76
operators.py
@ -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:
|
||||
|
13
server.py
13
server.py
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user