feat(rcf):ground work on propertystreaming
This commit is contained in:
@ -27,14 +27,11 @@ from . import net_ui
|
|||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.types.Scene.message = bpy.props.StringProperty(default="Hi")
|
|
||||||
|
|
||||||
bsyncio.register()
|
bsyncio.register()
|
||||||
net_operators.register()
|
net_operators.register()
|
||||||
net_ui.register()
|
net_ui.register()
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
del bpy.types.Scene.message
|
|
||||||
bsyncio.unregister()
|
bsyncio.unregister()
|
||||||
net_operators.unregister()
|
net_operators.unregister()
|
||||||
net_ui.unregister()
|
net_ui.unregister()
|
@ -9,9 +9,8 @@ import struct
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
# TODO: Add message time and author stamp for reliabilty
|
# TODO: Add message time and author stamp for reliabilty
|
||||||
|
|
||||||
|
|
||||||
class RCFMessage(object):
|
class RCFMessage(object):
|
||||||
"""
|
"""
|
||||||
Message is formatted on wire as 2 frames:
|
Message is formatted on wire as 2 frames:
|
||||||
@ -35,16 +34,17 @@ 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 = '' if self.key is None else self.key
|
key = '' if self.key is None else self.key.encode()
|
||||||
body = '' if self.body is None else self.body
|
body = '' if self.body is None else umsgpack.packb(self.body)
|
||||||
socket.send_multipart([key, body])
|
socket.send_multipart([key, body])
|
||||||
|
|
||||||
@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, body = socket.recv_multipart()
|
key, body = socket.recv_multipart(zmq.NOBLOCK)
|
||||||
key = key if key else None
|
key = key.decode() if key else None
|
||||||
body = body if body else None
|
body = umsgpack.unpackb(body) if body else None
|
||||||
|
|
||||||
return cls(key=key, body=body)
|
return cls(key=key, body=body)
|
||||||
|
|
||||||
def dump(self):
|
def dump(self):
|
||||||
@ -75,7 +75,7 @@ class Client():
|
|||||||
self.task = asyncio.ensure_future(self.main())
|
self.task = asyncio.ensure_future(self.main())
|
||||||
|
|
||||||
self.property_map = {}
|
self.property_map = {}
|
||||||
self.message_store = []
|
|
||||||
logger.info("{} client initialized".format(id))
|
logger.info("{} client initialized".format(id))
|
||||||
|
|
||||||
def bind_ports(self):
|
def bind_ports(self):
|
||||||
@ -114,27 +114,18 @@ class Client():
|
|||||||
break
|
break
|
||||||
|
|
||||||
if self.pull_sock in socks:
|
if self.pull_sock in socks:
|
||||||
update = self.pull_sock.recv_multipart(zmq.NOBLOCK)
|
rcfmsg = RCFMessage.recv(self.pull_sock)
|
||||||
|
|
||||||
print(update)
|
rcfmsg.store(self.property_map)
|
||||||
|
rcfmsg.dump()
|
||||||
|
|
||||||
# TODO: Proper routing throught different socket / sub ?
|
for f in self.recv_callback:
|
||||||
if update[1].decode() == 'chat':
|
f(rcfmsg)
|
||||||
# Store message
|
|
||||||
self.message_store.append(
|
|
||||||
[update[0].decode('ascii'), umsgpack.unpackb(update[2])])
|
|
||||||
if update[1].decode() == 'chat':
|
|
||||||
pass
|
|
||||||
|
|
||||||
if self.recv_callback:
|
def push_update(self, key, body):
|
||||||
self.recv_callback()
|
rcfmsg = RCFMessage(key,body)
|
||||||
|
rcfmsg.send(self.push_sock)
|
||||||
def send_msg(self, msg):
|
# self.push_sock.send_multipart()
|
||||||
self.req_sock.send_multipart([b"chat",umsgpack.packb(msg)])
|
|
||||||
|
|
||||||
def send_update(self, msg):
|
|
||||||
|
|
||||||
self.push_sock.send_multipart()
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
logger.info("Stopping client")
|
logger.info("Stopping client")
|
||||||
@ -199,7 +190,10 @@ class Server():
|
|||||||
self.pub_sock.send_multipart(msg)
|
self.pub_sock.send_multipart(msg)
|
||||||
|
|
||||||
if self.collector_sock in socks:
|
if self.collector_sock in socks:
|
||||||
pass
|
msg = self.collector_sock.recv_multipart(zmq.NOBLOCK)
|
||||||
|
|
||||||
|
# Update all clients
|
||||||
|
self.pub_sock.send_multipart(msg)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
logger.info("Stopping server")
|
logger.info("Stopping server")
|
||||||
|
@ -2,6 +2,7 @@ import bpy
|
|||||||
from . import net_components
|
from . import net_components
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
import mathutils
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -9,12 +10,28 @@ client = None
|
|||||||
server = None
|
server = None
|
||||||
context = None
|
context = None
|
||||||
|
|
||||||
|
|
||||||
# CLIENT-SERVER
|
# CLIENT-SERVER
|
||||||
def refresh_window():
|
def refresh_window(msg):
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
|
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
|
||||||
|
|
||||||
|
def patch_scene(msg):
|
||||||
|
path = msg.key.split('/')
|
||||||
|
|
||||||
|
attribute = getattr(getattr(bpy.data,path[0])[path[1]],path[2])
|
||||||
|
print(type(attribute))
|
||||||
|
if type(attribute) == mathutils.Vector:
|
||||||
|
attribute = array2vector(msg.body)
|
||||||
|
|
||||||
|
def vector2array(v):
|
||||||
|
return [v.x,v.y,v.z]
|
||||||
|
|
||||||
|
def array2vector(a):
|
||||||
|
print(mathutils.Vector((a[0],a[1],a[2])))
|
||||||
|
return mathutils.Vector((a[0],a[1],a[2]))
|
||||||
|
|
||||||
class session_join(bpy.types.Operator):
|
class session_join(bpy.types.Operator):
|
||||||
bl_idname = "session.join"
|
bl_idname = "session.join"
|
||||||
bl_label = "join"
|
bl_label = "join"
|
||||||
@ -29,7 +46,9 @@ class session_join(bpy.types.Operator):
|
|||||||
global client
|
global client
|
||||||
|
|
||||||
username = str(context.scene.session_settings.username)
|
username = str(context.scene.session_settings.username)
|
||||||
client = net_components.Client(id=username ,recv_callback=refresh_window)
|
callbacks=[refresh_window,patch_scene]
|
||||||
|
|
||||||
|
client = net_components.Client(id=username ,recv_callback=callbacks)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
bpy.ops.asyncio.loop()
|
bpy.ops.asyncio.loop()
|
||||||
@ -52,7 +71,10 @@ class session_send(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
global client
|
global client
|
||||||
|
|
||||||
client.send_msg(self.message)
|
key = "objects/Cube/location"
|
||||||
|
value = vector2array(bpy.data.objects['Cube'].location)
|
||||||
|
|
||||||
|
client.push_update(key,value)
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@ -71,9 +93,10 @@ class session_create(bpy.types.Operator):
|
|||||||
global client
|
global client
|
||||||
|
|
||||||
username = str(context.scene.session_settings.username)
|
username = str(context.scene.session_settings.username)
|
||||||
|
callbacks=[refresh_window,patch_scene]
|
||||||
|
|
||||||
server = net_components.Server()
|
server = net_components.Server()
|
||||||
client = net_components.Client(id=username,recv_callback=refresh_window)
|
client = net_components.Client(id=username,recv_callback=callbacks)
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
|
10
net_ui.py
10
net_ui.py
@ -25,16 +25,16 @@ class SessionPanel(bpy.types.Panel):
|
|||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(scene,"message",text="")
|
|
||||||
row.operator("session.send").message = scene.message
|
row.operator("session.send")
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
# Debug area
|
# Debug area
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
area_msg = row.box()
|
area_msg = row.box()
|
||||||
if len(net_operators.client.message_store) > 0:
|
if len(net_operators.client.property_map) > 0:
|
||||||
for (id,msg) in net_operators.client.message_store:
|
for key,value in net_operators.client.property_map.items():
|
||||||
area_msg.label(text="{}:{}".format(id,msg))
|
area_msg.label(text="{}:{}".format(key,value))
|
||||||
else:
|
else:
|
||||||
area_msg.label(text="Empty")
|
area_msg.label(text="Empty")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user